Code Monkey home page Code Monkey logo

cards-ts's Introduction

Cards-TS

Github CI npm version GitHub Last Commit Typescript Documentation

This is a card game framework and various card game implementations. The core package contains the framework and useful components, including functionality to display a card game in the command line. The various other packages are card game implementations.

Can I Have That is a house variation on Continental Rummy. Hearts and Euchre are trick-taking games. Other implementations of card games or expansions of the core library are welcome.

Getting Started

We use pnpm workspaces to support a number of games on top of the core library. See the documentation pages here or see the wiki articles here.

Running a card game with npx

npx @cards-ts/hearts # or can-i-have-that, etc.

Running a card game locally

Building

pnpm i # typically only needed the first time
pnpm buildall # use "--include-dependencies --scope=@cards-ts/$GAME" to just build the game dependencies

Running

GAME=can-i-have-that # or hearts, etc.
pnpm start --filter=@cards-ts/$GAME

or

GAME=can-i-have-that # or hearts, etc.
cd packages/$GAME
pnpm start

Testing

The tests in spec folder test that each game exports a minimum number of fields and that the bots will be able to complete the game successfully (Run with pnpm start in the folder locally). Each package can also contain a spec folder as well for unit testing components with mocha (Run all with pnpm testall or in a package with pnpm test).

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

Authors

See also the list of contributors who participated in this project.

cards-ts's People

Contributors

dependabot[bot] avatar github-actions[bot] avatar johnameyer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

danya0365 papiguy

cards-ts's Issues

Game state serialization

While most of the state is now in a form that is serializable, the part tied up in the game driver async/generator is not. Some sort of state machine should be created to allow this to be preserved.

Handler rework

As identified in #42 , the current setup works well but requires every concrete handler implementation to re-implement the message function and all future systems. Since this functionality also falls into classes e.g. bot discards messages, intermediary handler sends it to the intermediary, e.t.c. we should be able to break these up using an entity-component-system-type setup.

Support game-state diff

Might be useful at some level to just generate the diffs that responses from users or general game flow cause. Possible use might be to send only the change to users, or not send to users at all if nothing has changed from their perspective.

Additional hand checking functionality

Penalties should be less severe - don't slap the user with their entire hand if any of their plays are invalid
Should objects be recreated to make sure there is no object modification used to work around the checks?

Library contracts

As the library has generally settled and common usages known, we should consider the higher form of the library as we look towards a 1.0 release. (This is a high level issue and doesn't contain anything specifically actionable, actionable tasks will be linked)

Things to consider:

  • Do the StateTransformer and ResponseValidator classes need to be exported? Would there ever be a case these would be overriden?
    • Considered in #47
  • Can we wrap more common functionality/boiler-plate into a class?
    • Considered in #47
  • Can we add a test to make sure everything is exported and proper?
    • Considered in #47
  • Can we add hooks to the driver class to support open/close principal?
  • Can we decide how to handle the higher level abstractions and common functionality of the game like names and chat?
  • Can we clean up the ideas of sync vs async handlers and the queues?
  • Can we make the handler <> intermediary <> presenter nicer and fallback if operations are not supported?
  • Can we add a built-in package lookup/import by game type?
  • Can we avoid including the web presenter/remove dependencies on console libraries?
  • Can we break out the state from being passed in the handler methods?
    • Nope, but we can change a protocol so that it is only sent before a change.
  • Can we make the game state iterator FSMs less verbose, more declarative? Redux-esque architecture perhaps?

Clarify serializable vs presentable

Currently presentable (things we should print to the user) is used in place of what should be serializable (things we know by default how to convert to/from JSON), and preferably the former should be a subset of the latter. The deck for example should be serializable but not presentable.

Lobby mechanic

Add mechanic for setting up a game before launching it to the framework

Ref #104

State componentization

Rather than having a flat state for each game, refactor common functionality into separate components that can be chosen arbitrarily by games. Consumers should be able to expect a subset of the state (e.g. only {messages: MessagesState}). As well, use controllers to wrap each component so that only expected operations are performed and the state remains consistent.

Allow for game suspension

Currently, a game loop will continue completely until it is done. Ideally, in a hosted scenario, there should be a mechanism by which the awaits for user decisions are abstracted so that user action is not actually waited upon.

Chat mechanic

Would be ideal for the platform to support sending of chat messages of some form and implementation of how that would look for the 'intermediary'.

Clean up async vs sync handlers

Currently, the handlers and intermediaries use a system of returning a promise to indicate that the data has been sent wherever, and uses the response queue to push promises or synchronous results. However, this doesn't particularly make sense for Euchre, as the intermediary has two distinct sends (maybe a generator at the intermediary level?). As an initial implementation, we may just clear up the ordering of events or prevent the game from continuing before all grouped events are processed (and remove the undefined event for Euchre).

Game tutorials

Game packages should include some kind of mechanism to simulate the game and prompt the user for certain actions

GameManager component wrapper

As outlined in #42 , there isn't a real pressing need to have the ResponseValidator, StateTransformer, or GameStateIterator broken out as separate components in the exports. As such there should be a 'GameManager' class that contains the logic to instantiate those components as well as use them in the common paths. As well, we can then add a 'test' (typescript type assertion) to check the types.

Clean in prepublishOnly

Noticed in the most recent release that built changes from a PR branch were published on the main branch, which should not be the case. Need to verify if incremental build will always attempt that or whether we will need to clean before building.

War implementation

Implementation of the game 'war.' Not very interesting to play, but good to have from a testing and demo stand-point.

Separate handler data from messages

Today, we encapsulate handler data inside of each and every message type which is quite repetitive across the structs as well as the relevant handlers and validators.

Ideally the data would be brought out to a new struct encapsulating the message

Ideally as a part of making this change we could clean up how the handlers process this data - namely allowing them to have strict typing through generics

Migrate off of Lerna and setup actions publishing

Lerna has caused a number of headaches due to:

  1. it publishing to git before actually publishing to npm / building packages
  2. it using the global typescript over the locally installed one (e.g. lerna run prepack works fine

along with others, causing around a 50% success rate when trying to publish a new version.

We should also try to move away from local publishing and towards publishing in a Github action.

Reimplement the names mechanic

The names mechanism was removed in order to support the shared interface of all the Handlers methods but should be added back in a event-cognizant manner.

Engine genericization

It should be possible to make the engine generic, to make an easy template for implementing other card games.

Player timeouts

Support of limiting a waiting period on an action and default handler in that scenario.

Would be useful for Mafia or others

Support sending messages mid-waiting

Support sending a message once a player has completed an action, regardless of if the group has.

In war, for example, there is no harm to saying what the player flipped over while waiting on the opponent.

Will have to involve modifying the checks of when the iterator runs or moving message functionality out of there entirely.

Validation rework

As identified in #62

  • Can we make validation more declarative - i.e. type matchers on fields, then high level validation if need be
    • hasCard
  • Can we sharpen up our event validation the same way we are for states? Length checks, type checks, etc.
  • Potentially implement message-type expectation validation (e.g. at this stage we are expecting only certain events
    • This may live better as a larger scale task about also clarifying the ordering of events, async ness, etc.
    • Moved to #125 / #113

Mafia implementation

Interest had been expressed in an online form for playing mafia and this is well within the capabilities of the platform.

Framework-managed whose-turn

The 'whose-turn' designation should not be managed by the individual libraries, but instead wrapped into the larger frame of the 'waiting on player' concept.

Example:
If a library needs every player to respond, then the naive implementation of the current whose-turn would be to say that it is waiting on everyone. To be more accurate, the incoming responses would need to filter through this mechanic to update. This is shared functionality and so it should be supported on a higher level.

Fix console-user getting stuck with live cards

As a user, if my hand was entirely live after I had gone down, the game should give me a way to play on others.
As a user, if my hand was entirely live and I can't go down, this should be handled somehow (grabbing cards from the deck until not live? simply ending the round there?)

Break up can-i-have-that turn response

The can-i-have-that TurnResponseMessage can be broken up into multiple segments since the player naturally only does one at a time and this would reflect real play better.

Of course the discard message is what signifies that the turn is over.

Reimplement console coloring

For certain games, it might be nice to identify a formatting setting that might, for example in hearts, visually identify cards that give points.

Add bot tests

There should be tests to make sure that the bots can follow the rules in a majority of scenarios, finish the game, do not take too long with their turns, and perform significantly better than a random bot (i.e. a bot that makes valid choices randomly).

String variables/interpolation

Allow for messages to contain references (like the player's name) for things that can change over time / be processed separately.

Add toObj and fromObj to StateTransformer

Since most of the state transformers just use JSON stringify and parse under the hood, we can move that up to the parent class and have children only override to/fromObj.

Intermediary defaults

The base intermediary class should support 'advanced' components by breaking them down to the user as a composite of simpler components. That way, when a new component is introduced, it does not have to be supported by all the intermediaries.

Game metadata

Game packages should vend some sort of metadata e.g. description, type of game, number of players

Add package tests

For libraries that are game implementations (e.g. hearts and can-i-have-that, not core), there should be a (package) test that ensures that a minimum set of members are exported that would make it possible to be run (by the framework or on a server) in a game-agnostic manner. As well, the test should make sure that the game can run through to the end using the default bots.

Add additional game settings

As a user, I would like to have some control over how the game is set up
E.g. smaller deck, different point values, different bots, e.t.c.

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.