play board games with me
web/: Vue.js web frontend. Talks withapi/.api/: Python/Flask REST API. Talks withengine/.engine/: Node.js server-side game logic engine.games/: Game modules.
Install OS dependencies: Python 3 and Node.js.
Create .env as appropriate.
Install npm/pip dependencies:
./setup.shFinally, run everything using ./start.sh:
./start.sh engine
./start.sh api
./start.sh web
For development without internet access, it can be useful to have api/ talk
to a local PostgreSQL instance.
Install PostgreSQL if you have not:
# Mac:
brew install postgresql
# Ubuntu:
apt install postgresql
systemctl enable postgresql
systemctl start postgresql
Set up the database as follows:
sudo su postgres
psql
create database tableflip;
create user ${YOUR_USERNAME};
# (Possibly optional)
grant all privileges on database tableflip to ${YOUR_USERNAME};
Create the tables and populate them with sample data:
./start.sh shell
from api import models
models.init_db()
models.sample_data()
Replace the DATABASE_URL in .env:
DATABASE_URL="postgresql://localhost/tableflip"
./start.sh api should now talk to the local Postgres.
One of Tableflip's most impressive features is its extensible architecture for creating new games. A game is defined as a set of three data structures:
game_state: All the information in the game.game_view: The information that a particular player can see in the game.action: A description of an action taken by a player.
And eight mostly-pure functions:
initial_state(num_players): game_state- Creates an initial game state for
pplayers.
- Creates an initial game state for
player_view(game_state, player_id): game_view- Gets of a view of the game state for a given player.
current_players(game_state): [player_id]- Gets the list of players who may make actions at the current time.
has_legal_action(game_view): bool- Determines whether a player with the given
game_viewcan make any actions.
- Determines whether a player with the given
is_action_legal(game_view, action): bool- Determines whether the given
actionis legal with player's the givengame_view.
- Determines whether the given
perform_action(game_state, player_id, action): game_state- Applies an action to a game state to produce a new game state.
is_game_finished(game_state): boolean- Determines whether the game is finished.
winners(game_state): [player_id]- Determines a list of winners for the game.