There's a Makefile included with the following targets:
all-- Calls firstsetupand thenbuildsetup-- Set up everything: install ghc and dependencies. (Needsstack,elmandelm-test.)build-- Build the server and the client.server-start-- Callsbuildand then starts the server. Open http://localhost:8080/ in your Browser. Requests sent to this server will trigger a recompilation (via make) of the client code (if its changed).
JSON Message from Server to Client after two game moves. Last move comes first, thats fp style (Head of the List).
{
"cards": ["Eel", "Rabbit", "Tiger", "Rooster", "Horse"],
"history": [
{ "color": "Black", "card": "Rooster", "from": [1, 4], "move": [-1, -1] },
{ "color": "White", "card": "Eel", "from": [2, 0], "move": [-1, 1] }
]
}
JSON Message from Client to server after third game move.
{"color":"White","card":"Rabbit","from":[3,0],"move":[1,1]}
The Game logic is implemented entirely on the client side only. So there's no checking for cheating on the server side currently! This is on purpose because I want to use it for demonstration.
Feel free to play the older non-multiplayer version here since it doesn't want you to setup a backend server.
The Server is my first haskell project. So don't expect very much. I still do not understand monads ;)
You can easily test the API with some simple curl commands. The 1 before /onitama is the API Version.
Get all Games:
curl http://localhost:8080/1/onitama/summary -w "\n"
Alice posts a new Game and gets a table-number (= game-number):
curl -X POST http://localhost:8080/1/onitama/new -w "\n"
Response: ID (ID is table/game id e.g: 3)
Alice joins her new table 3:
curl -X PUT "http://localhost:8080/1/onitama?table=3&name=Alice" -w "\n"
Response: responseGame, responseToken (e.g.: a4cd5ddc-71a3-41a2-bff2-0c516df006d3)
Bob joins table 3 as black Player (and leaves it):
curl -X PUT "http://localhost:8080/1/onitama?table=3&name=Bob" -w "\n"
Response: responseGame, responseToken (e.g.: f5ea6fb0-2527-46d8-b0ab-9e861cf55395)
Bob rejoins table 3:
curl -X PUT "http://localhost:8080/1/onitama?table=3&name=Bob&token=f5ea6fb0-2527-46d8-b0ab-9e861cf55395" -w "\n"
Response: responseGame and old responseToken (e.g.: f5ea6fb0-2527-46d8-b0ab-9e861cf55395)
Bob posts a new GameMove to Game 3:
curl -X POST -d '{"color": "White","card": "Ox","from": [3,0],"move": [0,1]}' -H 'Content-Type: application/json' "http://localhost:8080/1/onitama?table=3&token=a4cd5ddc-71a3-41a2-bff2-0c516df006d3" -w "\n"
Response: {"color": "White","card": "Ox","from": [3,0],"move": [0,1]}
Alice fetches Game 3 to see Bobs last move:
curl "http://localhost:8080/1/onitama?table=3" -w "\n"
In the order in which I would like to tackle them.
- GetGame with UUID in the URL should work to
- GetGames should also return all playernames with gameids.
- GameIds from 1 to infinity instead of UUID
- Change API to /VERSION/GAMENAME?table=GAMEID
- Authetification by player name using sessions-ids
- Save sessions in local storage
- Implement http polling temporarily.
- The common card should determine, which player starts the game.
- Check for checkmate!
- JSON for GameMove is to verbose. Simplyfy it to something like
{"move":"white:c1b2:elephant"} - Use WebSocket to get new moves without the need to do http polling.
- Implement Chat feature
- Add support for the Cards from the Senseis Path explansion.
Thanks to https://github.com/haskell-servant/example-servant-elm