#!/usr/bin/perl
#
# CHESS.PL beta 1
# Copyright (C) 1997 John Watson
# email: john@watson-net.com
#
# April 9, 1997
#
# -----About-----
# Jan-97: Got the barebones program working. Only understood coordinate-coordinate
# move notation (e.g. d3-e4). Did not check for legal moves.
# Feb-97: Added code to support multiple simultaneous games. Changed loadgame(),
# savegame(), newgameform(). Added listgames(). Added additional text
# datafile of games.
# 1-Mar-97: Added code to understand algebraic notation. Also checking for legal
# moves. Implemented en-passant captures.
# 15-Mar-97: Finished code for 'lost right to castle'. Now moving a rook or king
# loses right to castle. Implemented pawn promotion (e.g. b8/Q, fxg1/R).
#
# To do: Check for check, checkmate, stalemate, draw (50 move, 3 position repetition),
# temporarily can't castle due to threat.
#
# 50 move draw: count moves since last pawn move. if 50 then draw.
# 3 position repetition: store each position in an array in FEN. After each move,
# check for 3 duplicates. If 3 dups then draw.
#
# The latest copy of this script and documentation can be obtained from
# http://www.watson-net.com/
#
# -----Distribution-----
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$DEBUG = 0;
use CGI;
$q = new CGI;
init();
# Defaults
$motd = 'chess/motd.txt';
$gamelist = 'chess/chess.txt';
$gamedir = 'chess/';
$program = 'chess.pl';
$width = 32;
$height = 30;
# Global variables
@movelist = ();
@capturelist = ();
# Pieces
%blank = ('light','chess/light.gif', 'dark','chess/dark.gif');
%wking = ('light','chess/wkl.gif', 'dark','chess/wkd.gif');
%wqueen = ('light','chess/wql.gif', 'dark','chess/wqd.gif');
%wrook = ('light','chess/wrl.gif', 'dark','chess/wrd.gif');
%wbishop = ('light','chess/wbl.gif', 'dark','chess/wbd.gif');
%wknight = ('light','chess/wnl.gif', 'dark','chess/wnd.gif');
%wpawn = ('light','chess/wpl.gif', 'dark','chess/wpd.gif');
%bking = ('light','chess/bkl.gif', 'dark','chess/bkd.gif');
%bqueen = ('light','chess/bql.gif', 'dark','chess/bqd.gif');
%brook = ('light','chess/brl.gif', 'dark','chess/brd.gif');
%bbishop = ('light','chess/bbl.gif', 'dark','chess/bbd.gif');
%bknight = ('light','chess/bnl.gif', 'dark','chess/bnd.gif');
%bpawn = ('light','chess/bpl.gif', 'dark','chess/bpd.gif');
# begin main
# get parameters
$move = $q->param('move');
$newwhite = $q->param('newwhite');
$newblack = $q->param('newblack');
$whitemail = $q->param('whitemail');
$blackmail = $q->param('blackmail');
$gamefile = $q->param('gamefile');
$password = $q->param('password');
# set takeback variable
$takeback = $q->param('takeback');
if ($takeback eq 'Takeback') { $takeback = 1; }
else { $takeback = 0; }
# set flip board variable
$flipboard = $q->param('flipboard');
$flip = $q->param('flip');
# set flip board variable
if ($flipboard eq 'Flip') {
if ($flip) { $flip = 0; }
else { $flip = 1; }
}
# print header
header();
# if $newwhite or $newblack parameters are given then start a new game
if ($newwhite || $newblack) {
init();
$whiteplayer = $newwhite;
$blackplayer = $newblack;
if ($blackplayer eq "") {
print "
You didn't enter a name for Black.
";
exit;
}
if ($whiteplayer eq "") {
print "
You didn't enter a name for White.
";
exit;
}
if ($password eq "") {
print "
You need to enter a password.
";
exit;
}
$gamefile = newgamefile();
$gamepass = $password;
savegame();
}
# if gamefile is not given then bring up new game form
if ($gamefile eq "") {
newform();
exit;
}
# load an existing game
loadgame();
# if the user enter a valid password, they are a 'player'
if ($gamepass eq $password) {
$player = 1;
} else {
$player = 0;
}
# if the game status is not 'open' then enter observation mode
if ($gamestatus ne 'open') { $player = 0; }
# do takeback
if ($takeback && $player) {
pop @movelist;
savegame();
init();
loadgame();
}
# if no names for white or black players then get the names
if ($whiteplayer eq '' || $blackplayer eq '') {
newform();
exit;
}
# if $move is legal make move and save game file
if ($move ne '' && $player) {
$movestatus = movepiece($move);
if ($movestatus == 0) { print "Illegal move.\n"; }
if ($movestatus == -1) { print "Ambiguous move.\n"; }
if ($movestatus == 1) {
savegame();
if ((tomove() eq 'w' && $whitemail ne '') ||
(tomove() eq 'b' && $blackmail ne '')) {
mailmessage();
}
}
}
# show the board
displayboard();
# print footer
footer();
exit;
sub header {
print $q->header;
print <Chessboard
Chessboard
EOT
}
sub footer {
print <
EOT
}
sub newform {
#print $q->header();
# motd
if (-e $motd) {
print "
Message of the 'Day'
";
open (FILE,"<$motd");
print ;
close(FILE);
}
# start game form
print <Existing Games