function chess_board_markup($base_href, $board, $clickable, $selected, $player, $flip_board) { $board_flipped = $player == WHITES_MOVE; if ($flip_board) { $board_flipped = !$board_flipped; } $pieces = get_pieces($board); $class = $player == WHITES_MOVE ? GET_WHITE : GET_BLACK; $class .= $flip_board ? ' flipped' : ''; $html = "<table class=\"{$class}\">\n"; // Create horizontal legend (A .. H) table row $legend = "<tr><th></th>"; for ($row = 0; $row < 8; $row++) { $legend .= '<th>'; if ($board_flipped) { $legend .= chr(ord('A') + $row); } else { $legend .= chr(ord('A') + (7 - $row)); } $legend .= '</th>'; } $legend .= "<th></th></tr>\n"; $html .= $legend; // Create main part of the table for ($row = 0; $row < 8; $row++) { if ($board_flipped) { $row_name = 8 - $row; } else { $row_name = $row + 1; } // Start row with left legend $html .= "<tr><th>{$row_name}</th>\n"; for ($col = 0; $col < 8; $col++) { if ($board_flipped) { $col_name = chr(ord('A') + $col); } else { $col_name = chr(ord('A') + (7 - $col)); } $field_name = $col_name . $row_name; $class = in_array($field_name, $selected) ? ' class="selected"' : ''; //$base_link $has_href = in_array($field_name, $clickable); if (get_parameter(GET_FROM) != get_parameter(GET_TO)) { $href = update_href($base_href, GET_TO, $field_name); } else { $href = update_href($base_href, GET_FROM, $field_name); } // Add TD for field $html .= "\t<td{$class}>"; if ($has_href) { $html .= "<a href=\"{$href}\">"; } $p = piece_in_field($pieces, $selected, $field_name); if ($p != '') { $html .= $p; } else { $html .= '.'; } if ($has_href) { $html .= "</a>"; } $html .= "</td>\n"; } // Right legend, finalize row $html .= "<th>{$row_name}</th></tr>\n"; } // Add second legend row and finalize $html .= "{$legend}</table>\n"; return $html; }
function main_control() { // These globals are used in the HTML template global $current_player, $history; global $heading, $name_white, $name_black; global $show_command_form, $flip_board; global $preset_from_value, $preset_to_value, $id_focus; global $chess_board_markup, $history_markup, $promotion_dialog_markup; global $board_encoded, $game_title, $turn_nr; global $history_next, $history_prev; global $href_this, $href_player, $href_flip; global $game_state_link, $hmw_home_link; // Initialize a bit $promotion_popup = false; //...NYI Show pawn promotion dialog $show_command_form = true; // Show the move input dialog $game_status = IN_PROGRESS; // The game has not ended yet $heading = ''; // "White's move" caption $game_title = ''; // Current game info for page title $game_state_link = ''; // "Send this link"-link .. $hmw_home_link = ''; // .. corrected for my stupid router //... Remember an initial double move of a pawn $get_en_passant = get_parameter(GET_EN_PASSANT); $new_en_passant = ''; // Retreive GET data $flip_board = isset($_GET[GET_FLIP_BOARD]); $history = get_parameter(GET_HISTORY); $goto = get_parameter(GET_GOTO); $name_white = get_parameter(GET_WHITE, DEFAULT_NAME_WHITE); $name_black = get_parameter(GET_BLACK, DEFAULT_NAME_BLACK); if (get_parameter(GET_PLAYER, GET_WHITE) != GET_WHITE) { // &player set, but not to "white", is taken as "black" $current_player = BLACKS_MOVE; } else { $current_player = WHITES_MOVE; } // Load base positions of pieces $base_array = decode_board(get_parameter(GET_BASE_BOARD, INITIAL_BOARD_CODED)); // Trace history (Reconstruct the current board from initial positions) //...list( $board_array, $tie_info ) = decode_history( $board_array = decode_history($base_array, $history, $goto); // Execute given command // Retreive FORM input // Move: "from" and "to" must be field names // Edit: "from" must be the code character for a piece and "to" a field $clickable = $selected = array(); $redirect_after_move = false; $cmd_piece = get_parameter(GET_FROM); $cmd_from = strtoupper(get_parameter(GET_FROM)); // Retreive commands $cmd_to = strtoupper(get_parameter(GET_TO)); if ($cmd_from == $cmd_to) { // Deselect a piece $cmd_from = $cmd_to = ''; } if ($cmd_from == '') { $cmd_to = ''; } // Never allow only TO command // Exec: Editor if (strlen($cmd_from) == 1 && valid_field_name($cmd_to)) { if (strpos(WHITE_PIECES . BLACK_PIECES, $cmd_from) !== false) { list($row, $col) = field_to_rowcol($cmd_to); if ($base_array[$row][$col] == $cmd_piece) { // Delete existing piece $base_array[$row][$col] = ''; } else { if ($base_array[$row][$col] == '') { // Add new piece $base_array[$row][$col] = $cmd_piece; } } #$base_array = $board_array; $redirect_after_move = true; } // No other commands with FROM being only one char. $cmd_from = $cmd_to = ''; } // Make sure, no invalid data is being processed as a move if (!valid_field_name($cmd_from)) { $cmd_from = ''; } if (!valid_field_name($cmd_to)) { $cmd_to = ''; } // Exec: Move if ($cmd_from != '' && $cmd_to != '') { $turn_nr = i_to_round($history); if ($turn_nr - floor($turn_nr) == 0.5) { $turn_nr = floor($turn_nr); $color = 'Black'; } else { $color = 'White'; } debug_out($_SERVER['REMOTE_ADDR'] . " - {$name_white} vs. {$name_black}, {$turn_nr}, {$color}: {$cmd_from} - {$cmd_to}\n"); list($f_row, $f_col) = field_to_rowcol($cmd_from); list($t_row, $t_col) = field_to_rowcol($cmd_to); list($clickable, $selected) = select_piece($board_array, $current_player, $cmd_from, $get_en_passant); // Check if it is our//... piece (or a piece at all) if (!in_array($cmd_from, $clickable)) { die("Error: clickable[{$f_row}][{$f_col}] empty."); } if (!in_array($cmd_to, $clickable)) { // Capturing a piece! echo "Capture! clickable = "; print_r($clickable); die; } // En passant $piece = $board_array[$f_row][$f_col]; if ($piece == 'P' && $f_row == 1 || $piece == 'p' && $f_row == 6) { if ($t_row == 3 || $t_row == 4) { $get_en_passant = chr(ord('A') + $f_col); } } if ($piece == 'P' && $t_row - $f_row == +1 || $piece == 'p' && $t_row - $f_row == -1 || $piece != 'P' && $piece != 'p') { $get_en_passant = ''; } // Promotion if ($piece == 'P' && $t_row == 7 || $piece == 'p' && $t_row == 0) { $href_this = update_href($href_this, GET_PROMOTE, chr(ord('A') + $t_col)); $promotion_popup = true; $heading = 'Promote your pawn to:'; $board_array = apply_move($board_array, $f_row, $f_col, $t_row, $t_col); } // New move applied, prepare for fresh move $clickable = $selected = array(); $cmd_from = $cmd_to = ''; // Fall through to NO COMMAND mode $current_player = !$current_player; $history .= encode_move($f_row, $f_col, $t_row, $t_col); // We changed the board, but the user's browser still shows the // move command in its address bar. An HTTP redirect is used to // update that address, but the URL is not determined yet if (!$promotion_popup) { $redirect_after_move = true; } } // Exec: Deselect, continuation of fall throughs above if ($cmd_from == '' && $cmd_to == '') { $clickable = find_movable_pieces($board_array, $current_player); // Get rid of moves with king in check afterwards $new = array(); foreach ($clickable as $from_field) { // Get two arrays (clickable, selected) $temp = select_piece($board_array, $current_player, $from_field); // Ignore moves with only one "deselection entry" if (count($temp[0]) > 1) { $new[] = $from_field; } } $clickable = $new; if (count($clickable) == 0) { if (king_in_check($board_array, $current_player)) { $heading = HEADING_CHECK_MATE; $game_status = $current_player != WHITES_MOVE ? WHITE_WINS : BLACK_WINS; } else { $heading = HEADING_STALE_MATE; $game_status = NOONE_WINS; } } } // Exec: Select piece if ($cmd_from != '' && $cmd_to == '' && $goto == '') { list($clickable, $selected) = select_piece($board_array, $current_player, $cmd_from); $heading = 'Select target'; } // Prepare move command form $preset_from_value = $cmd_from; $preset_to_value = $cmd_to; $id_focus = $preset_from_value == '' ? 'idFrom' : 'idTo'; // Generate links for main menu and board markup (pieces) $board_encoded = encode_board($base_array); // Name parameter as code for who's player's term this is $p = $current_player == WHITES_MOVE ? GET_WHITE : GET_BLACK; $href_this = update_href(); // get base link $href_this = update_href($href_this, GET_FROM, $preset_from_value); $href_this = update_href($href_this, GET_TO, $preset_to_value); $href_this = update_href($href_this, GET_PLAYER, $p); $href_this = update_href($href_this, GET_HISTORY, $history); $href_this = update_href($href_this, GET_WHITE, $name_white); $href_this = update_href($href_this, GET_BLACK, $name_black); $href_this = update_href($href_this, GET_EN_PASSANT, $get_en_passant); $href_this = update_href($href_this, GET_BASE_BOARD, $board_encoded); if ($flip_board) { $href_this = update_href($href_this, GET_FLIP_BOARD, ''); $href_flip = update_href($href_this, GET_FLIP_BOARD, REMOVE_FROM_LINK); } else { $href_flip = update_href($href_this, GET_FLIP_BOARD, ''); } if ($current_player == BLACKS_MOVE) { $href_player = update_href($href_this, GET_PLAYER, GET_WHITE); } else { $href_player = update_href($href_this, GET_PLAYER, GET_BLACK); } // HTTP redirect? if (!false && $redirect_after_move) { if (DEBUG) { #die( "Continue: <a href='$href_this'>$href_this</a>" ); } // Game state has been updated. In case of an executed move, // the browser needs to reload the page with the updated URL: header('HTTP/1.0 303 Found'); header('Location: ' . htmlspecialchars_decode($href_this)); die; } // Create HTML markup // History $history_markup = history_markup($base_array, $history, $href_this, $name_white, $name_black, $game_status); // Promotion if ($promotion_popup) { $promotion_dialog_markup = promotion_dialog_markup($href_this, $current_player, $t_row, $t_col, $history); $clickable = $selected = array(); } else { $promotion_dialog_markup = ''; } // Board if (STEADY_BOARD && $current_player == BLACKS_MOVE) { //... GET switch $flip_board = !$flip_board; } if (isset($_GET[GET_GOTO])) { $clickable = $selected = array(); } else { if ($history > '' && $cmd_from == $cmd_to) { if (substr($history, -4, 1) == '(') { // Skip promotion $selected[] = decode_field(substr($history, -3, 1)); $selected[] = decode_field(substr($history, -6, 1)); } else { // Normal move $selected[] = decode_field(substr($history, -2, 1)); $selected[] = decode_field(substr($history, -1, 1)); } } } $chess_board_markup = chess_board_markup($href_this, $board_array, $clickable, $selected, $current_player, $flip_board); // If no heading was set above, say who's next if ($goto != '') { $current_player = $goto % 2 != 0; } if ($heading == '') { $heading = $current_player ? $name_white : $name_black; $heading = ucfirst($heading) . "'"; if (substr($heading, -2, 1) != 's') { $heading .= 's'; } $heading .= ' move'; } if (king_in_check($board_array, $current_player) && strpos($heading, 'mate') === false) { $heading .= ' - <strong>Check!</strong>'; } if ($goto != '') { $turn_nr = goto_to_round($history, $goto); $heading = "Round {$turn_nr}, {$heading}"; } $heading = get_parameter(GET_COMMENT, $heading); // Game title if (isset($_GET[GET_WHITE])) { $turn_nr = i_to_round($history); $game_title = "{$name_white} vs. {$name_black} - Turn #{$turn_nr} - "; } $turn_nr = floor($turn_nr); // History links $next_goto = ($goto + 1) % (count_moves($history) + 1); $history_next = update_href($href_this, GET_GOTO, $next_goto); $next_goto = ($goto + count_moves($history)) % (count_moves($history) + 1); $history_prev = update_href($href_this, GET_GOTO, $next_goto); // Links for copy and paste if (!isset($_GET[GET_NEW_GAME]) && !isset($_GET[GET_BASE_BOARD]) && isset($_SERVER['HTTP_REFERER']) && $_SERVER['QUERY_STRING'] != '' && $cmd_from == '' && $cmd_to == '') { // Empty referer: Not reached by clicking a link in the browser $t = str_replace('&', '&', $href_this); $game_state_link = str_replace(' ', '+', $t); $home_IPs = array('192.168.14.1', '213.47.94.176', 'local.at'); foreach ($home_IPs as $ip_address) { if (strpos($game_state_link, $ip_address) !== false) { $hmw_home_link = str_replace($ip_address, 'harald.ist.org/home', $game_state_link); } } if ($hmw_home_link != '') { $game_state_link = $hmw_home_link; } $game_state_link = str_replace('flip&', '', $game_state_link); $game_state_link = str_replace('&', '&', $game_state_link); } debug_out("board_encoded = {$board_encoded}\n"); }
if ($_SERVER['QUERY_STRING'] != '') { // NOT NEW GAME ?> <h2 class="no_css">Main Menu</h2> <nav><ul> <li><a href="./" title="Enter names and start a new game">New Game</a> <li><a Xaccesskey="p" href="<?php echo $history_prev; ?> " title="History: Show previous move. Firefox: Alt+Shift+P">Back</a> <li><a Xaccesskey="n" href="<?php echo $history_next; ?> " title="History: Show next move. Firefox: Alt+Shift+N">Next</a> <li><a href="<?php echo update_href(CHESS_RIDDLE, '', ''); ?> " title="Show a chess composition for beginners">Riddle</a> <li class="js_required"><a href="javascript:return false" onclick="toggleStyle()">Style</a> </ul></nav> <?php } ?> <h3><?php echo $PROGRAM_NAME; ?> <?php echo $VERSION; ?> <br>Copy(l)eft 2015 by <a href="https://github.com/hwirth/remote_chess">hmw</a></h3> <?php