Coder Social home page Coder Social logo

taklib's Introduction

taklib

A scala library for the Tak board game

Build Status Coverage Status Codacy Badge

Example usage

import com.github.daenyth.taklib._
val invalid: Either[String, Game] = Game.fromTps("invalid")
// invalid: Either[String,com.github.daenyth.taklib.Game] = Left(`[' expected but `i' found)
val game = Game.fromTps("[ 1,2,1,2,1/2,1,2,1,2/1,2,1,2,1/2,1,2,1,2/1,2,1,2,1 12 2 ]").getOrElse(throw new Exception)
// game: com.github.daenyth.taklib.Game = com.github.daenyth.taklib.Game@78c4cfdd
val winner = game.winner
// winner: Option[com.github.daenyth.taklib.GameEndResult] = Some(FlatWin(White))
val game = Game.ofSize(6).getOrElse(throw new Exception())
// game: com.github.daenyth.taklib.Game = com.github.daenyth.taklib.Game@5cf72de5
val winner = game.winner
// winner: Option[com.github.daenyth.taklib.GameEndResult] = None
val next: MoveResult[Game] = game.takeTurn(PlayFlat(Black, BoardIndex(1, 1)))
// next: com.github.daenyth.taklib.MoveResult[com.github.daenyth.taklib.Game] = OkMove(com.github.daenyth.taklib.Game@66f6a349)

Release status

Taklib is currently alpha status - there may be bugs and the api is not stable yet

What you can do now

  • Create new games with an empty board
  • Create a new game from a TPS string
  • Create a (potentially completed) game from a PTN file, including games beginning with TPS tags
  • Play moves that are checked for validity
  • Detect all game-ending conditions
  • Run a rudimentary interactive mode on the command line
  • Add your own custom game rules
  • Run an HTTP REST server that accepts tps and move input, returning tps.

Interactive game on the command line

sbt takcli/run

TPS Server

sbt tpsserver/run

The server runs on localhost:8080 and listens for POST requests to /tpsMove with a json payload like

{
  "tps" : "x6/x6/x6/x6/x6/x6 1 1",
  "move" : "a1"
}

For example:

# python
import requests
requests.post("http://localhost:8080/tpsMove", json={
  "tps" : "x6/x6/x6/x6/x6/x6 1 1",
  "move" : "a1"
}).json()
# {u'OkMove': {u'nextState': u'1,x,x,x,x,x/x,x,x,x,x,x/x,x,x,x,x,x/x,x,x,x,x,x/x,x,x,x,x,x/x,x,x,x,x,x 2 1'}}

requests.post("http://localhost:8080/tpsMove", json={
  "tps" : "invalid",
  "move" : "a1"
}).json()
# {u'errors': [u"TPS: string matching regex `(1|2)+[SC]?' expected but `i' found"]}

requests.post("http://localhost:8080/tpsMove", json={
  "tps" : "1,1,1,1,1,x/x6/x6/x6/x6/x6 1 1",
  "move" : "a6"
}).json()
# {u'GameOver': {u'finalState': u'1,1,1,1,1,1/x,x,x,x,x,x/x,x,x,x,x,x/x,x,x,x,x,x/x,x,x,x,x,x/x,x,x,x,x,x 2 1',
#   u'result': {u'RoadWin': {u'player': {u'White': {}}}}}}

The exact json structure is likely going to be changed. Right now it's automatically derived from the internal representation, rather than being designed to be easy to use directly.

Add custom rules

Create a RuleSet to make new games with

scala> Game.ofSize(7, DefaultRules)
res0: Either[String,com.github.daenyth.taklib.Game] = scala.Left(Bad game size: 7)

// A new variant with a size-7 board that has 40 flatstones and 7 capstones per player!
scala> Game.ofSize(7, new RuleSet {
     | val rules = DefaultRules.rules
     | val expectedStoneColor = DefaultRules.expectedStoneColor
     | val stoneCounts = DefaultRules.stoneCounts + ((7, (40, 7)))
     | })
res1: Either[String,com.github.daenyth.taklib.Game] = scala.Right(com.github.daenyth.taklib.Game@517564bf)

Goals

  • Easy to use
  • Type safe interface
  • Thread safe - taklib is fully based off immutable data structures, so is inherantly thread safe
  • Able to support branching history with arbitrary rollback/rollforward (not implemented yet)

Non-goals

  • Not aiming to be the fastest runtime - I'm not benchmarking anything until the project is much more stable.
  • Stable API - for now. This is a new library, and so the api can change without notice as I find better ways to do things.
  • Supporting scala.js - for now. It should be possible with little effort but it's not a priority. Patches welcome
  • Scalaz usage. Taklib will only support cats

Testing

sbt test

License

Taklib is under the AGPL3. For more information, see COPYING

taklib's People

Contributors

daenyth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

taklib's Issues

Create a server module implementing the playtak.com protocol

Implement the playtak.com backend protocol so that the existing playtak.com frontend can talk to a taklib-based backend.

This will require some user management to be set up as well.

  • Start with 2 hardcoded account credentials
  • /dev/null all chat, implement game state commands
  • Add backend talking to db with accounts as raw fixture data
  • implement chat
  • implement account creation

Alternately, start with the user management and chat, and ignore the game management - use the user account system to build async play (#7)

Implement Game.toPtn

  • Game.toPtn
  • Unit test creating a game and round-tripping through Game.fromPtn should be equal
  • Creating a game from Ptn (grab from playtak history) and doing .toPtn should be equal
    • At least for the move history - for now we can drop info from the headers

Remove TurnAction.player

It complicates things quite a bit since we often end up with things like Player => TurnAction, due to the fact that many sources of TurnActions (ptn etc) don't provide the player as part of the data, only implicitly by context (eg ptn move column; playtak protocol game object)

Switch from scalaz to cats

This will allow easier integration with the wider ecosystem as more things (ie http4s, doobie) stabilize on cats.

First target is the main taklib module.
Much less important is the scalaz.Task usage in takcli

Write a real client-server protocol

It should support

  • User management & community aspects
  • Support realtime play (a la playtak.com)
  • Support async play
  • Multiple rulesets at the same time (create game with explicit ruleset)
  • Start a game from non-empty state

Ideally it should be

  • Stateless via REST
  • But optionally also able to open a websocket for live subscriptions to games/chats

Serialization format?

  • Something well typed. Investigate avro, parquet, protobuf3, thrift

To do some time after #6

Create async play server module

To complement the playtak real time backend, support async play.

This can probably happen after #6 is done and the user management is in place.

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.