Recently I have been building https://peer2peergames.com, a site where two or more people play a board or card game against each other in a browser, each moving when they get round to it. Every game on it needs an engine: the rules, the endings, a bot to stand in when nobody else is online. So I wrote them, one dist at a time, each with the same discipline, the engine does no input and no output, a game is a pure function of its moves, and a terminal front end sits on top so I could play the thing before it had a web page. Cribbage was the one that existed before the site, everything after it was built for it.
That is how I have ended up with twenty plus terminal games and little memory of which script wanted which params.
So now I have one command.
$ cpanm Game::Terminal
$ game
That gives you a menu. Arrow keys move, enter plays, q leaves, and a letter jumps to the next game starting with it. When the game you picked ends, win or lose or you ragequit, the menu is back with a line saying what happened.
Game 21 games
> backgammon board 2 backgammon
brandubh board 2 the Irish 7 by 7 tafl game
checkers board 2 English draughts
chess board 2 chess
cribbage card 2 cribbage
dominoes tile 2-4 draw dominoes with All Fives scoring
durak card 2 Podkidnoy Durak, the Russian beating game
fanorona board 2 the board game of Madagascar
floppy arcade 1 a one-button bird through a field of tubes
gin card 2 gin rummy
go board 2 Go
mahjong tile 4 Mahjong, Chinese Official rules
maze puzzle 1 mazes in the terminal
merrills board 2 Nine Men's Morris
oware board 2 the African sow and capture game, Abapa rules
reversi board 2 Reversi, with its 1883 opening
royalur board 2 the Royal Game of Ur
schnapsen card 2 Schnapsen
sixtysix card 2 Sixty-Six, the German parent of Schnapsen
snake arcade 1 the classic snake game
xiangqi board 2 xiangqi, Chinese chess
backgammon: Game::Backgammon::Terminal 0.03, options: game backgammon --help
checkers finished with status 1 (lost)
up and down to choose, enter to play, a letter to jump, q to quit
Yes, that last line of status is real. The checkers bot is not kind at level 4.
How it works
The obvious way to build a launcher is to exec the installed scripts. I did not do that, and the reason is the menu: I wanted it to come back when a game ends, and I wanted that to work the same on every platform without a shell in the loop.
So every game now has a class method with one boring, binding promise:
my $status = Game::Checkers::Terminal->run(@ARGV);
It parses its own options from the array it is given, plays, and returns the exit status: 0 if you won, drew or quit, 1 if you lost, 2 for a bad option. It never calls exit. Each game's bin/ script is now two lines, use and exit ...->run(@ARGV), and the launcher just requires the class and calls the same method in its own process.
If you have a terminal game of your own and you want it in the menu, that run contract is the whole price of admission. Return the status, do not exit, take your arguments as a list. The roster is data; adding a row is a pull request though.
Where this is going
The terminal is one skin over these engines. The other as mentioned is the one they were written for https://peer2peergames.com.
A mobile app for peer2peergames is in development and coming soon. Same games, same engines.
Until then, cpanm Game::Terminal installs all twenty one games.
Top comments (0)