So I'm messing around with making quarantine-friendly version of the like-Cards-Against-Humanity-But-With-Comics game Joking Hazard. I'm thinking each game will just be a single .json file on the server, each client will be a SPA in the browser, the endpoints will be humble PHP scripts that update the file - the clients will poll and get an updated version of the whole game state, and then modify it according to the rules.
It's surprisingly tricky to teach a computer to referee even a medium complexity board or card game (It reminds me I need to go back and update Score-Matic for Dixit, another lovely boardgame, but it's casual-friendly creative/artsy mojo is marred by a fiddly scoring system).
I think I am basically making a state machine: not counting the games red cards (a slight fork) the core game loop is something like
vvv
[create-game(username)] /* put all cards in deck */
vvv
GAME_SIGNUP (add username) <<< [join-game(username)] /* assign 7 cards from deck */
vvv
[start-game]
vvv
NEW_ROUND <<< next judge assigned, deck-picks-card
v
v
REG_ROUND
vvv
[judge-picks-card(cardoff, judgepos)
vvv
REG_PLAYERS_PICK <<< [reg-player-pick(cardoff)
vvv
(all players_pick)
vvv
REG_JUDGE_PICK <<< [reg-judge-pick(player)] /*shows all picks to everyone */
vvv
END_ROUND
vvv
[judge-ends-turn]
vvv
So one challenge will be making sure each client can update the gamestate without stomping on other people's play- PHP supports filelocking, though you have to start using syntax more complicated than good ol' file_put_contents() - since there's a lot of boilerplate, I'm going to use a callbacks to a shared function:
function updateGame($gamename, $function){
if(! preg_match('/^[A-Z][A-Z][A-Z][A-Z]$/',$gamename)) {
echo "shenanigans!";
return;
}
$filename = "games/$gamename.json";
//Open the File Stream
$handle = fopen($filename,"r+");
//Lock File, error if unable to lock
if(flock($handle, LOCK_EX)) {
$oldguts = fread($handle, filesize($filename)); //get current state
$newguts = call_user_func($function,$oldguts); //update state
ftruncate($handle, 0); //Truncate the file to 0
rewind($handle); //Set write pointer to beginning of file
fwrite($handle, $newguts); //Write the new Hit Count
flock($handle, LOCK_UN); //Unlock File
} else {
echo "Could not Lock File!";
}
//Close Stream
fclose($handle);
}
Heh, this is extremely FP! Get a copy of the state, modify it, replace the old state.
So my test code for a call back for this was like:
function addSomething($oldraw){
$content = json_decode($oldraw,true);
$content["foo"] = array();
$content["foo"]["bar"] = "baz2";
$content["foo"]["bat"] = "bag2";
return json_encode($content);
}
It feels a little odd to pass in the function as a string, but whatevs.
No comments:
Post a Comment