예제 #1
0
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;
}
예제 #2
0
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('&amp;', '&', $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('&', '&amp;', $game_state_link);
    }
    debug_out("board_encoded = {$board_encoded}\n");
}
예제 #3
0
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