function savePromotion() { global $mysql; global $movesArray, $FENarray, $curTurn; $num_moves = count($FENarray) - 1; // subtract one for initpos // when we run the promotion script, the color to be promoted // is the oppposite of the color who's turn it is $piece = $_POST['promotion']; if ('white' == $curTurn) { $piece = strtolower($piece); } // save the promoted piece in the movesArray $movesArray[$num_moves]['promo'] = $piece; // seperate the FEN board from the rest of the FEN $FEN = $FENarray[$num_moves]; $FENbits = trim(substr($FEN, strpos($FEN, ' '))); $xFEN = expandFEN(substr($FEN, 0, strpos($FEN, ' '))); // insert the promoted piece sqr2idx($movesArray[$num_moves]['toSq'], $idx); FENplace($xFEN, $idx, $movesArray[$num_moves]['promo']); // and repack the FEN $FENhead = packFEN($xFEN); $FEN = $FENhead . ' ' . $FENbits; // and save the new and improved FEN to the history $query = "\n\t\tSELECT MAX(h_time)\n\t\tFROM " . T_HISTORY . "\n\t\tWHERE h_game_id = '{$_SESSION['game_id']}'\n\t"; $result = $mysql->fetch_value($query, __LINE__, __FILE__); $query = "\n\t\tUPDATE " . T_HISTORY . "\n\t\tSET h_fen = '{$FEN}'\n\t\tWHERE h_game_id = '{$_SESSION['game_id']}'\n\t\t\tAND h_time = '{$result}'\n\t"; $mysql->query($query, __LINE__, __FILE__); updateTimestamp(); }
/** public function save * Saves all changed data to the database * * @param void * @action saves the game data * @return void */ public function save() { call(__METHOD__); // grab the base game data $query = "\n\t\t\tSELECT state\n\t\t\t\t, extra_info\n\t\t\t\t, modify_date\n\t\t\tFROM " . self::GAME_TABLE . "\n\t\t\tWHERE game_id = '{$this->id}'\n\t\t\t\tAND state <> 'Waiting'\n\t\t"; $game = $this->_mysql->fetch_assoc($query); call($game); $update_modified = false; if (!$game) { throw new MyException(__METHOD__ . ': Game data not found for game #' . $this->id); } $this->_log('DATA SAVE: #' . $this->id . ' @ ' . time() . "\n" . ' - ' . $this->modify_date . "\n" . ' - ' . strtotime($game['modify_date'])); // test the modified date and make sure we still have valid data call($this->modify_date); call(strtotime($game['modify_date'])); if ($this->modify_date != strtotime($game['modify_date'])) { $this->_log('== FAILED =='); throw new MyException(__METHOD__ . ': Trying to save game (#' . $this->id . ') with out of sync data'); } $update_game = false; call($game['state']); call($this->state); if ($game['state'] != $this->state) { $update_game['state'] = $this->state; if ('Finished' == $this->state) { $update_game['winner_id'] = $this->_players[$this->_pharaoh->winner]['player_id']; } if (in_array($this->state, array('Finished', 'Draw'))) { try { $this->_add_stats(); } catch (MyException $e) { // do nothing, it gets logged } } } $diff = array_compare($this->_extra_info, self::$_EXTRA_INFO_DEFAULTS); $update_game['extra_info'] = $diff[0]; ksort($update_game['extra_info']); $update_game['extra_info'] = serialize($update_game['extra_info']); if ('a:0:{}' == $update_game['extra_info']) { $update_game['extra_info'] = null; } if (0 === strcmp($game['extra_info'], $update_game['extra_info'])) { unset($update_game['extra_info']); } if ($update_game) { $update_modified = true; $this->_mysql->insert(self::GAME_TABLE, $update_game, " WHERE game_id = '{$this->id}' "); } // update the board $color = $this->_players['player']['color']; call($color); call('IN-GAME SAVE'); // grab the current board from the database $query = "\n\t\t\tSELECT *\n\t\t\tFROM " . self::GAME_HISTORY_TABLE . "\n\t\t\tWHERE game_id = '{$this->id}'\n\t\t\tORDER BY move_date DESC\n\t\t\tLIMIT 1\n\t\t"; $move = $this->_mysql->fetch_assoc($query); $board = $move['board']; call($board); $new_board = packFEN($this->_pharaoh->get_board()); call($new_board); list($new_move, $new_hits) = $this->_pharaoh->get_move(); call($new_move); call($new_hits); if (is_array($new_hits)) { $new_hits = implode(',', $new_hits); } if ($new_board != $board) { call('UPDATED BOARD'); $update_modified = true; $this->_current_move_extra_info['laser_fired'] = (bool) $this->can_fire_laser(); $this->_current_move_extra_info['laser_hit'] = (bool) $this->_pharaoh->laser_hit; $diff = array_compare($this->_current_move_extra_info, self::$_HISTORY_EXTRA_INFO_DEFAULTS); $m_extra_info = $diff[0]; ksort($m_extra_info); $m_extra_info = serialize($m_extra_info); if ('a:0:{}' == $m_extra_info) { $m_extra_info = null; } $this->_mysql->insert(self::GAME_HISTORY_TABLE, array('board' => $new_board, 'move' => $new_move, 'hits' => $new_hits, 'extra_info' => $m_extra_info, 'game_id' => $this->id)); } // update the game modified date if ($update_modified) { $this->_mysql->insert(self::GAME_TABLE, array('modify_date' => NULL), " WHERE game_id = '{$this->id}' "); } }
function movetoFEN() { global $FENarray, $movesArray, $board, $COLS, $initpos, $pieceColor; $num_moves = count($FENarray) - 1; // get the post info out foreach ($_POST as $key => $var) { ${$key} = $var; } // reverse row and col so i don't confuse myself $colFrom = $fromCol; $colTo = $toCol; $rowFrom = $fromRow; $rowTo = $toRow; // and convert it to something we can use colrow2idx($colFrom, $rowFrom, $idxFrom); colrow2idx($colTo, $rowTo, $idxTo); // get the current FEN data $FENitems = explode(' ', $FENarray[$num_moves]); $thatFEN = expandFEN($FENitems[0]); $CM = $FENitems[1]; $CI = $FENitems[2]; $EP = $FENitems[3]; $PN = $FENitems[4]; $MN = $FENitems[5]; $newEP = '-'; // get original placement of rooks $origARookPos = strpos($initpos, 'R'); $origHRookPos = strrpos($initpos, 'R'); $origKingPos = strpos($initpos, 'K'); // separate the castle indicator $WK = false !== strpos($CI, 'K') ? 'K' : ''; $WQ = false !== strpos($CI, 'Q') ? 'Q' : ''; $BK = false !== strpos($CI, 'k') ? 'k' : ''; $BQ = false !== strpos($CI, 'q') ? 'q' : ''; // put board into expanded FEN string $xFEN = ""; for ($i = 7; $i >= 0; $i--) { for ($j = 0; $j < 8; $j++) { $xFEN .= $board[$i][$j]; } } // get the piece that is moving $piece = FENplace($xFEN, $idxFrom); // check for castling move if ('false' != $_POST['castleMove']) { if ('white' == $pieceColor[$piece]) { // clear the castle indicators $WK = ''; $WQ = ''; // make the move if ('a' == $_POST['castleMove']) { FENplace($xFEN, $origKingPos + 56, '0'); // delete the king FENplace($xFEN, $origARookPos + 56, '0'); // delete the rook FENplace($xFEN, 2 + 56, 'K'); // place the king FENplace($xFEN, 3 + 56, 'R'); // place the rook } elseif ('h' == $_POST['castleMove']) { FENplace($xFEN, $origKingPos + 56, '0'); // delete the king FENplace($xFEN, $origHRookPos + 56, '0'); // delete the rook FENplace($xFEN, 6 + 56, 'K'); // place the king FENplace($xFEN, 5 + 56, 'R'); // place the rook } else { die("castleMove is incorrect"); } } elseif ('black' == $pieceColor[$piece]) { // clear the castle indicators $BK = ''; $BQ = ''; // make the move if ('a' == $_POST['castleMove']) { FENplace($xFEN, $origKingPos, '0'); // delete the king FENplace($xFEN, $origARookPos, '0'); // delete the rook FENplace($xFEN, 2, 'k'); // place the king FENplace($xFEN, 3, 'r'); // place the rook } elseif ('h' == $_POST['castleMove']) { FENplace($xFEN, $origKingPos, '0'); // delete the king FENplace($xFEN, $origHRookPos, '0'); // delete the rook FENplace($xFEN, 6, 'k'); // place the king FENplace($xFEN, 5, 'r'); // place the rook } else { die("castleMove is incorrect"); } } else { echo "<pre>"; for ($i = 0; $i < $idxFrom; $i++) { echo " "; } echo "|\n"; echo $xFEN . "</pre>"; } } else { // make the move $piece = FENplace($xFEN, $idxFrom, '0'); $capt = FENplace($xFEN, $idxTo, $piece); $PN++; // if we have a pawn advance, or a capture if ('P' == strtoupper($piece) || '0' != $capt) { $PN = 0; } // reset the ply count // if we have a pawn double advance if ('P' == strtoupper($piece) && 2 == abs($rowFrom - $rowTo)) { colrow2til($colTo, ($rowFrom + $rowTo) * 0.5, $newEP); } // set the en passant indicator // if we moved a castling piece if ('K' == $piece) { $WK = ''; $WQ = ''; } elseif ('k' == $piece) { $BK = ''; $BQ = ''; } elseif ('R' == $piece) { if ($colFrom == $origARookPos) { // a-side moved $WQ = ''; } elseif ($colFrom == $origHRookPos) { // h-side moved $WK = ''; } } elseif ('r' == $piece) { if ($colFrom == $origARookPos) { // a-side moved $BQ = ''; } elseif ($colFrom == $origHRookPos) { // h-side moved $BK = ''; } } } // check for en passant capture colrow2til($colTo, $rowTo, $tilTo); if ($tilTo == $EP && 'P' == strtoupper($piece)) { // get the idx of the captured pawn colrow2idx($colTo, $rowFrom, $idxCapt); // and remove the captured pawn FENplace($xFEN, $idxCapt, '0'); } $FENbit = packFEN($xFEN); // search for ambiguous castle notation //-------------------------------------------- // remove any extra information from the current castle notations if ('' != $WK) { $WK = 'K'; } if ('' != $WQ) { $WQ = 'Q'; } if ('' != $BK) { $BK = 'k'; } if ('' != $BQ) { $BQ = 'q'; } // get current position of main pieces $whiteBackRank = substr($xFEN, -8); $blackBackRank = substr($xFEN, 0, 8); // search the ends of the back ranks for rooks // and add unambiguous notation if needed if (strrpos($whiteBackRank, 'R') > $origHRookPos && '' != $WK) { $WK = $WK . substr($COLS, $origHRookPos, 1); } if (strpos($whiteBackRank, 'R') < $origARookPos && '' != $WQ) { $WQ = $WQ . substr($COLS, $origARookPos, 1); } if (strrpos($blackBackRank, 'r') > $origHRookPos && '' != $BK) { $BK = $BK . substr($COLS, $origHRookPos, 1); } if (strpos($blackBackRank, 'r') < $origARookPos && '' != $BQ) { $BQ = $BQ . substr($COLS, $origARookPos, 1); } $castlingAvail = $WK . $WQ . $BK . $BQ; if ('' == $castlingAvail) { $castlingAvail = '-'; } // increase the move number (if needed) $MN = "w" == $CM ? $MN : ++$MN; // make sure to use the pre-increment (++var) here // toggle the current move $CM = "w" == $CM ? "b" : "w"; // put the whole thing together and return return "{$FENbit} {$CM} {$castlingAvail} {$newEP} {$PN} {$MN}"; }
/** protected function _save * Saves the setup data to the database * * @param string [optional] reflection type (Origin, Long, Short) * @action saves the setup data * @return void */ protected function _save($reflection = 'Origin') { call(__METHOD__); $Mysql = Mysql::get_instance(); try { $this->validate($reflection); } catch (MyException $e) { throw $e; } // DON'T sanitize the data // it gets sani'd in the MySQL->insert method // translate (filter/sanitize) the data $data['name'] = $this->name; $data['board'] = packFEN($this->board); $data['reflection'] = self::_get_reflection($this->board); $data['has_horus'] = self::has_horus($this->board); $data['has_sphynx'] = self::has_sphynx($this->board); $data['has_tower'] = self::has_tower($this->board); $data['created_by'] = (int) $this->creator; call($data); // create the setup $required = array('name', 'board'); $key_list = array_merge($required, array('reflection', 'has_horus', 'has_sphynx', 'has_tower', 'created_by')); try { $_DATA = array_clean($data, $key_list, $required); } catch (MyException $e) { throw $e; } $_DATA['created '] = 'NOW( )'; // note the trailing space in the field name, this is not a typo // grab the original setup data $query = "\n\t\t\tSELECT *\n\t\t\tFROM " . self::SETUP_TABLE . "\n\t\t\tWHERE setup_id = '{$this->id}'\n\t\t"; $setup = $Mysql->fetch_assoc($query); call($setup); if (!empty($this->id) && !$setup) { // we must have deleted the setup, just stop return false; } if (!$setup) { $this->id = $Mysql->insert(self::SETUP_TABLE, $_DATA); if (empty($this->id)) { throw new MyException(__METHOD__ . ': Setup could not be created'); } return $this->id; } $update_setup = false; // don't change the creator // in case of admin edits unset($_DATA['created_by']); foreach ($setup as $key => $value) { if (empty($_DATA[$key])) { continue; } if ($_DATA[$key] != $value) { $update_setup[$key] = $_DATA[$key]; } } call($update_setup); if ($update_setup) { $Mysql->insert(self::SETUP_TABLE, $update_setup, " WHERE setup_id = '{$this->id}' "); return true; } return false; }