Skip to content

Instantly share code, notes, and snippets.

@collegeman
Created August 12, 2019 19:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save collegeman/3b0dcf36a96fdaa26f6e984eab81cd1a to your computer and use it in GitHub Desktop.
Save collegeman/3b0dcf36a96fdaa26f6e984eab81cd1a to your computer and use it in GitHub Desktop.
Games are coming... XOXO. <3
<?php
namespace Games;
use Arcade;
use App\User;
use Games\Models\Game;
use Illuminate\Http\Request;
class TicTacToe extends Cabinet {
/**
* Start a new game of TicTacToe
* @param User $player
* @param Game $game
* @param Request $request
* @return array|Game|void|null
* @throws \Illuminate\Validation\ValidationException
*/
public function startGame(User $player, Game $game, Request $request)
{
$game->assertCreatedBy($player);
$game->shufflePlayers();
$game->getCurrentPlayer()->data->table->set('token', 'X')->save();
$game->getNextPlayer()->data->table->set('token', 'O')->save();
}
/**
* Player places their token into a position, sometimes resulting in the end of the game
* @param User $player
* @param Game $game
* @param Request $request
* @return array|Game|void|null
* @throws \Illuminate\Validation\ValidationException
*/
public function makeMove(User $player, Game $game, Request $request)
{
$data = $this->validate($request, [
'position' => 'required|in:1,2,3,4,5,6,7,8,9',
]);
$game->assertCurrentPlayer($player);
$token = $player->data->table->assertNotEmpty('token');
$game->board->assertEmpty($position = "grid.{$data['position']}");
$game->board->save($position, $token);
if ($result = $this->isOver($game)) {
if ($token === 'C') {
$game->end($request);
} else if ($token === $result) {
$game->end($request, $player);
} else {
$game->end($request, $game->getNextPlayer());
}
} else {
$game->movePlayToNextPlayer();
}
}
/**
* Test the given Game to determine if it's over
* @param Game $game
* @return bool|string
*/
public function isOver(Game $game)
{
$state = '';
for($position=1; $position<=9; $position++) {
$state .= $game->board["grid.{$position}"] ?: '_';
}
// build regular expression for win states:
$x_wins = "/^(" . implode('|', [
// horizontal rows:
"XXX......",
"...XXX...",
"......XXX",
// vertical rows:
"X..X..X..",
".X..X..X.",
"..X..X..X",
// diagonals:
"X...X...X",
"..X.X.X..",
]) . ")$/";
// create O-version with a simple string replacement
$o_wins = str_replace('X', 'O', $x_wins);
if (preg_match($x_wins, $state)) {
return 'X';
} else if (preg_match($o_wins, $state)) {
return 'O';
} else if (stripos($state, '_') === false) {
return 'C'; // "cat," the draw-state
} else {
return false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment