smrealms /
smr
We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.
| 1 | <?php declare(strict_types=1); |
||
| 2 | |||
| 3 | use Smr\Chess\ChessGame; |
||
| 4 | use Smr\Chess\Colour; |
||
| 5 | use Smr\Container\DiContainer; |
||
| 6 | use Smr\Database; |
||
| 7 | use Smr\Epoch; |
||
| 8 | |||
| 9 | function debug(string $message, mixed $debugObject = null): void { |
||
| 10 | echo date('Y-m-d H:i:s - ') . $message . ($debugObject !== null ? EOL . var_export($debugObject, true) : '') . EOL; |
||
| 11 | $db = Database::getInstance(); |
||
| 12 | $logID = $db->insert('npc_logs', [ |
||
| 13 | 'script_id' => defined('SCRIPT_ID') ? SCRIPT_ID : 0, |
||
| 14 | 'npc_id' => 0, |
||
| 15 | 'time' => 'NOW()', |
||
| 16 | 'message' => $db->escapeString($message), |
||
| 17 | 'debug_info' => $db->escapeString(var_export($debugObject, true)), |
||
| 18 | 'var' => $db->escapeString(''), |
||
| 19 | ]); |
||
| 20 | |||
| 21 | // On the first call to debug, we need to update the script_id retroactively |
||
| 22 | if (!defined('SCRIPT_ID')) { |
||
| 23 | define('SCRIPT_ID', $logID); |
||
| 24 | $db->write('UPDATE npc_logs SET script_id=' . SCRIPT_ID . ' WHERE log_id=' . SCRIPT_ID); |
||
| 25 | } |
||
| 26 | } |
||
| 27 | |||
| 28 | try { |
||
| 29 | // global config |
||
| 30 | require_once(realpath(dirname(__FILE__)) . '/../../bootstrap.php'); |
||
| 31 | |||
| 32 | debug('Script started'); |
||
| 33 | |||
| 34 | // Enable NPC-specific conditions |
||
| 35 | DiContainer::getContainer()->set('NPC_SCRIPT', true); |
||
| 36 | |||
| 37 | $descriptorSpec = [ |
||
| 38 | 0 => ['pipe', 'r'], // stdin is a pipe that the child will read from |
||
| 39 | 1 => ['pipe', 'w'], // stdout is a pipe that the child will write to |
||
| 40 | ]; |
||
| 41 | proc_open(UCI_CHESS_ENGINE, $descriptorSpec, $pipes); |
||
| 42 | $toEngine =& $pipes[0]; |
||
| 43 | $fromEngine =& $pipes[1]; |
||
| 44 | |||
| 45 | function readFromEngine(bool $block = true): void { |
||
| 46 | global $fromEngine; |
||
| 47 | stream_set_blocking($fromEngine, $block); |
||
| 48 | while (($s = fgets($fromEngine)) !== false) { |
||
| 49 | debug('<-- ' . trim($s)); |
||
| 50 | stream_set_blocking($fromEngine, false); |
||
| 51 | } |
||
| 52 | } |
||
| 53 | function writeToEngine(string $s, bool $block = true, bool $read = true): void { |
||
| 54 | global $toEngine; |
||
| 55 | debug('--> ' . $s); |
||
| 56 | fwrite($toEngine, $s . EOL); |
||
| 57 | if ($read === true) { |
||
| 58 | readFromEngine($block); |
||
| 59 | } |
||
| 60 | } |
||
| 61 | |||
| 62 | readFromEngine(); |
||
| 63 | writeToEngine('uci'); |
||
| 64 | writeToEngine('setoption name Hash value ' . UCI_HASH_SIZE_MB, false); |
||
| 65 | writeToEngine('isready'); |
||
| 66 | writeToEngine('ucinewgame', false); |
||
| 67 | |||
| 68 | while (true) { |
||
| 69 | // The next "page request" must occur at an updated time. |
||
| 70 | Epoch::update(); |
||
| 71 | |||
| 72 | foreach (ChessGame::getNPCMoveGames(true) as $chessGame) { |
||
| 73 | debug('Looking at game: ' . $chessGame->getChessGameID()); |
||
| 74 | writeToEngine('position fen ' . $chessGame->getFENString(), false); |
||
| 75 | writeToEngine('go ' . ($chessGame->getCurrentTurnColour() == Colour::White ? 'w' : 'b') . 'time ' . UCI_TIME_PER_MOVE_MS, true, false); |
||
| 76 | stream_set_blocking($fromEngine, true); |
||
| 77 | $move = ''; |
||
| 78 | while (!str_starts_with($move, 'bestmove')) { |
||
| 79 | $move = fgets($fromEngine); |
||
| 80 | if ($move === false) { |
||
| 81 | throw new Exception('Failed to get move from the UCI engine'); |
||
| 82 | } |
||
| 83 | $move = trim($move); |
||
| 84 | debug('<-- ' . $move); |
||
| 85 | if (str_starts_with($move, 'Seg')) { |
||
| 86 | // Segfault |
||
| 87 | debug('UCI engine segfaulted?'); |
||
| 88 | exit; |
||
| 89 | } |
||
| 90 | } |
||
| 91 | debug('Move info: ', $move); |
||
| 92 | $move = explode(' ', $move); |
||
| 93 | |||
| 94 | debug('Taking move: ', $move[1]); |
||
| 95 | $chessGame->tryAlgebraicMove($move[1]); |
||
| 96 | writeToEngine('ucinewgame', false); |
||
| 97 | } |
||
| 98 | // Always sleep for a while to make sure that PHP can't run at 100%. |
||
| 99 | usleep(UCI_SLEEP_BETWEEN_CYCLES_US); |
||
| 100 | } |
||
| 101 | |||
| 102 | } catch (Throwable $e) { |
||
| 103 | logException($e); |
||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
| 104 | } |
||
| 105 |