diff --git a/app/library/Controllers/IndexController.php b/app/library/Controllers/IndexController.php index 64cab40..7d685d5 100644 --- a/app/library/Controllers/IndexController.php +++ b/app/library/Controllers/IndexController.php @@ -3,6 +3,7 @@ namespace App\Controllers; use App\GameLogic; +use App\Models\PlayersTable; use App\Views\IndexView; use App\Views\AbstractView; use App\Views\JsonView; @@ -29,6 +30,21 @@ private function getGridSize(): int return $gridSize; } + private function getCurrentTimeString(): string + { + return date('Y-m-d h:i:s'); + } + + private function calculateElapsedTime($startTimeU): int + { + if (!is_numeric($startTimeU)) { + return 0; + } + + $now = (int) date('U'); + return ($now - (int) $startTimeU); + } + /** * It is used in Ajax requests. * @noinspection PhpUnused @@ -40,6 +56,9 @@ public function opponentsTurnAction(): AbstractView $request = json_decode($requestJson, true); $matrix = $request['matrix'] ?? []; + $playerName = $request['player_name'] ?? 'Unknown player'; + $gridSize = $request['grid_size'] ?? 3; + $startTime = $request['start_time'] ?? 0; $gameLogic = new GameLogic($matrix); @@ -49,12 +68,17 @@ public function opponentsTurnAction(): AbstractView $row = 0; $col = 0; if (!$isPlayerWin && $gameLogic->isFreeCellsLeft()) { - list($row, $col) = $gameLogic->findBestMove(); + list($row, $col) = $gameLogic->findAMove(); $gameLogic->setComputersMove($row, $col); $isGameOver = $gameLogic->isGameOver(); $isComputerWin = $gameLogic->doWeHaveWinner(); } + if ($isPlayerWin) { + $playersTable = new PlayersTable(); + $playersTable->addRow($playerName, $gridSize, $this->calculateElapsedTime($startTime), $this->getCurrentTimeString()); + } + $view = new JsonView(); $view->data = [ 'is_game_over' => $isGameOver, diff --git a/app/library/Controllers/LeaderboardController.php b/app/library/Controllers/LeaderboardController.php index 4b257c4..f9883d0 100644 --- a/app/library/Controllers/LeaderboardController.php +++ b/app/library/Controllers/LeaderboardController.php @@ -13,8 +13,10 @@ public function indexAction(): AbstractView $view = new LeaderboardView(); // Todo: redo this crap! - $players = (new PlayersTable())->getLeaders(10); + $players = (new PlayersTable())->getTotalLeaders(); + $playerCount = count((new PlayersTable())->getAllUniquePlayers()); $view->players = $players; + $view->playerCount = $playerCount; return $view; } diff --git a/app/library/GameLogic.php b/app/library/GameLogic.php index 0715dc3..2f84a27 100644 --- a/app/library/GameLogic.php +++ b/app/library/GameLogic.php @@ -45,6 +45,33 @@ public function findBestMove(): array return $this->findBestMove(); } + /** + * At least it doesn't recurse... + */ + public function findAMove(): array + { + $freeRows = $this->findPlayableRows(); + $freeRow = array_rand($freeRows); + $freeColumn = $freeRows[$freeRow][array_rand($freeRows[$freeRow])]; + + return [$freeRow, $freeColumn]; + } + + public function findPlayableRows(): array + { + $playableRows = []; + + foreach($this->matrix as $index => $row) { + $freeCells = array_keys($row, ''); + + if(count($freeCells)) { + $playableRows[$index] = $freeCells; + } + } + + return $playableRows; + } + public function setComputersMove(int $row, int $col): void { $this->matrix[$row][$col] = 'O'; diff --git a/app/library/Models/PlayersTable.php b/app/library/Models/PlayersTable.php index 8183613..0a4c204 100644 --- a/app/library/Models/PlayersTable.php +++ b/app/library/Models/PlayersTable.php @@ -20,6 +20,8 @@ public function getLeaders(int $gridSize): array FROM players WHERE grid_size = :grid_size + ORDER BY + play_time_seconds ASC ", [ ':grid_size' => $gridSize, @@ -27,6 +29,39 @@ public function getLeaders(int $gridSize): array ); } + public function getTotalLeaders(): array + { + return $this->executeSql( + " + SELECT + name, + play_time_seconds, + grid_size, + ctime + FROM players + ORDER BY + grid_size DESC, + play_time_seconds ASC + LIMIT 20 + ", + [] + ); + } + + public function getAllUniquePlayers(): array + { + return $this->executeSQL( + " + SELECT DISTINCT + name + FROM players + ORDER BY + name ASC + ", + [] + ); + } + public function addRow(string $name, int $gridSize, int $playTimeSeconds, string $date): void { $this->executeSql( diff --git a/app/library/Views/IndexView.php b/app/library/Views/IndexView.php index b22bc37..c50313d 100644 --- a/app/library/Views/IndexView.php +++ b/app/library/Views/IndexView.php @@ -4,11 +4,13 @@ class IndexView extends AbstractView { - public int $gridSize; + public int $gridSize; + public string $playerName; public function __construct() { - $this->setTitle("Hello player!"); + $this->playerName = ($_GET['player_name']) ?? "Player Name"; + $this->setTitle( "Hello " . $this->playerName . "!"); } public function render(): void diff --git a/app/library/Views/Layouts/app.phtml b/app/library/Views/Layouts/app.phtml index 29d86bd..3d50f28 100644 --- a/app/library/Views/Layouts/app.phtml +++ b/app/library/Views/Layouts/app.phtml @@ -17,7 +17,7 @@ use App\Views\Layouts\AppLayout; - +
diff --git a/app/library/Views/LeaderboardView.php b/app/library/Views/LeaderboardView.php index 72e46d5..956df5e 100644 --- a/app/library/Views/LeaderboardView.php +++ b/app/library/Views/LeaderboardView.php @@ -7,6 +7,9 @@ class LeaderboardView extends AbstractView /** @var array[][] */ public array $players; + /** @var int */ + public int $playerCount; + public function __construct() { $this->setTitle("Leaderboard"); diff --git a/app/library/Views/index.phtml b/app/library/Views/index.phtml index 81feac5..a8fbc66 100644 --- a/app/library/Views/index.phtml +++ b/app/library/Views/index.phtml @@ -8,6 +8,8 @@ ?> @@ -31,7 +34,7 @@ $button_id = 'game_grid_' . $row . '_' . $col; ?>| + | Name | +Play time (s) | +Grid size | +Date | +
|---|---|---|---|---|
| = $row+1 ?> | += ($this->players[$row]['name']) ?? '' ?> | += ($this->players[$row]['play_time_seconds']) ?? '' ?> | += ($this->players[$row]['grid_size']) ?? '' ?> | += ($this->players[$row]['ctime']) ?? '' ?> | +