Giter VIP home page Giter VIP logo

joguin2's People

Contributors

programaker avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

joguin2's Issues

Change default effect to ZIO

Related to #5. In the future we'll have multiple effects to choose, but currently the default one is cats-effect.

As ZIO is getting stronger everyday in the community (many talks, posts, related projects...), making it the default would be a good opportunity to take a look at it and practice a little.

Also, cats-effect is blocking #11 =(

Turn game step programs into functions

We are using classes to model the Free programs to have the convenience of importing all algebras at the top to make them accessible to the private helper functions, but the program is actually only a function - play().

Try to figure out a more FP design without the classes, if possible and if worths it. Sometimes it’s better to let Scala be Scala πŸ˜„

Changes for GameProgress and its Persistent sibling

Writing the tests for the Game Steps that require a GameProgress made me think that this class is not so well designed - for example, Gen[GameProgress] is using GameProgress logic, which means code that need to be tested is being used as input to other tests =/

Add Optics to the project

After issue#8, GameProgress update became more complicated. Better use a Lens to focus on the experience.

def increaseMainCharacterExperience(experiencePoints: Experience): GameProgress =
    refineV[ExperienceR](mainCharacter.experience.value + experiencePoints.value)
      .map(updatedXp => copy(mainCharacter = mainCharacter.copy(experience = updatedXp))) 
      .getOrElse(this)

Add proper error handling

In the current version, errors coming from type refinement or IO are not being properly handled. The idea is:

  • Make all functions that can cause errors return Either[Error, A] (Refined already use Either, which makes things easier).

  • Create an ErrorStep, to inform the error to the player and quit the game. The message to the player should be high level, but it can provide a way to generate a low level error report to "send to the developers"

Game crashes when run through jar

The game works well when run by sbt or IDE, but when the scripts build.sh and run.sh are used, it crashes - always when player chooses 'Fight' when asked to 'Fight or Retreat'.

When did it start? What changes caused it?

Add log algebra

It would be great to show how to do logs in a Free Monad approach!

Quit game at any time

Currently, the player can't quit the game whenever he/she wants, only at specific moments. Make "Quit" step accessible from any step.

Remove functions from Game Steps

Functions to parse options, functions that do not depend on the implicit algebras... they could be moved from the Steps and go to the package.

This way, we can keep the Step classes as "namespaces containing partially-applied functions"

Move experience to MainCharacter

Now, the argument to keep the experience separated from MainCharacter is not making much sense... Let's go to a more obvious design.

Fix intermittent test failure

[info] PersistentGameProgress_Properties:
[info] - converting a GameProgress into PersistentGameProgress and back, gives the same GameProgress as Some
[info] - converting an invalid PersistentGameProgress to GameProgress gives None *** FAILED ***
[info]   TestFailedException was thrown during property evaluation.
[info]     Message: Some(GameProgress(MainCharacter(,Female,43,0),Vector(),0,Set())) was not empty
[info]     Location: (PersistentGameProgress_Properties.scala:83)
[info]     Occurred when passed generated values (
[info]       arg0 = PersistentMainCharacter(,Female,43,0), // 3 shrinks
[info]       arg1 = 14, // 3 shrinks
[info]       arg2 = Vector(),
[info]       arg3 = 0, // 27 shrinks
[info]       arg4 = List() // 2 shrinks
[info]     )

Create "environments" for game step programs

Some game steps require, like, 4 different algebras to do their work, all provided via implicits. With all the ZIO buzz, what about create some "environment" and pass only it implicitly? It would help with #19

Changes for City and Invasion

Proposed redesign:

sealed abstract class City extends Product with Serializable

object City {
	final case class Free(name: Name, country: Country)
	final case class Invaded(city: City.Free, terraformDevice: TerraformDevice)
}

Then, in GameProgress:

final case class GameProgress(
  mainCharacter: MainCharacter,
  cities: Vector[City],
  defeatedInvasions: Count
)

We can remove the defeatedInvasionsTrack: Set[Index] and replace with pattern-matching. Also, Invasion won't be necessary anymore.

Remove PersistentGameProgress & friends

Related to #4

Maintaining these parallel "persistent" types is causing more trouble than just implement the Encoders and Decoders for Circe. In the beginning it was simple and Circe deals with built-in types automatically, but then I need to change the persistent types every time GameProgress changes (and it is changing a lot).

Also (in theory) there is a 3rd-party extension circe-refined that could help dealing with the refinements.

Use sealed abstract classes and Product with Serializable

The "ideal" sum type should be something like:

sealed abstract class Frunfles extends Product with Serializable
final case class Foo(x: String) extends Frunfles 
final case class Bar extends Frunfles 
final case class Qux(y: Int) extends Frunfles

This design avoid sealed traits and always add "extends Product with Serializable".
The reasons for this are:

https://typelevel.org/blog/2018/05/09/product-with-serializable.html
and
https://stackoverflow.com/questions/35249901/scala-client-composition-with-traits-vs-implementing-an-abstract-class/35251513#35251513

Change properties to conf (HOCON) files

Replace the properties files that hold the messages with conf files in HOCON syntax.
Also, replace Java's ResourceBundle with PureConfig https://github.com/pureconfig/pureconfig.

The messages could be read as Map[MessageSource#Key, String] or we can define a proper case class for it, dunno... it would be great to use the MessageSources and Keys themselves to get the messages instead of mapping them to Strings.

It is related to #3, so don't forget the localization.

Add support for more languages

Message source interpreter only knows English; the locale is hardcoded. Let's add at least one more language: pt-BR of course =P

Choose the concrete effect at runtime

It will be fun to add a runtime parameter to choose the concrete effect when running the game. It currently only uses cats IO.

This way we can use cats.IO, ZIO, ...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.