#!/usr/local/bin/perl
#$HOST = 'anemone.daimi.aau.dk';
$HOST = 'ics.uoknor.edu';
$PORT = 5000;
#unpack unsigned char
#gethostbyname returns hostname, alias, addresstype, addresslength, address.
@hostent = gethostbyname($HOST);
@addr = unpack("C4", $hostent[4]);
#pack unsigned short, short network, signed char(4), null(8).
$server = pack("Snc4x8", 2, $PORT, @addr);
#socket domain, type, protocol
#internet, stream, tcp
die "socket: $!\n" if (!socket(SOCKET, 2, 1, 6));
die "connect: $!\n" if (!connect(SOCKET, $server));
#unbuffer socket.
$oldfh = select(STDOUT); $| = 1; select($oldfh);
$oldfh = select(STDIN); $| = 1; select($oldfh);
$oldfh = select(SOCKET); $| = 1; select($oldfh);
#telnet protocol control characters
$IAC  = "\xff";
$DONT = "\xfe";
$DO   = "\xfd";
$WONT = "\xfc";
$WILL = "\xfb";

open(MSGLOG, ">msg.log");
$oldfh = select(MSGLOG); $| = 1; select($oldfh);
sub getstring
{
	$BUFFER = '';
	while(read(SOCKET, $CHAR, 1))
	{
		if ($CHAR eq $IAC)
		{
			read(SOCKET, $VERB, 1);
			read(SOCKET, $OPTION, 1);
			if ($VERB eq $DO)
			{
				$temp = unpack("C", $OPTION);
				print("DO: $temp\n");
				print(SOCKET $IAC . $WONT);
			}
			elsif ($VERB eq $DONT)
			{
				$temp = unpack("C", $OPTION);
				print("DONT: $temp\n");
				print(SOCKET $IAC . $WONT);
			}
			elsif ($VERB eq $WILL)
			{
				$temp = unpack("C", $OPTION);
				print("WILL: $temp\n");
				print(SOCKET $IAC . $DONT);
			}
			elsif ($VERB eq $WONT)
			{
				$temp = unpack("C", $OPTION);
				print("WONT: $temp\n");
				print(SOCKET $IAC . $DONT);
			}
			else
			{
				$temp = unpack("C", $VERB);
				print("unknown: $temp\n");
			}
		}
		else
		{
			$BUFFER .= $CHAR;
			if ($BUFFER =~ /$_[0]/)
			{
				print(MSGLOG "$BUFFER\n");
				return;
			}
			if ($CHAR eq "\n")
			{
				print(MSGLOG "$BUFFER\n");
				$BUFFER = '';
			}
		}
	}
	print("Connection closed!\n");
	exit(0);
}

do getstring("Enter Login:$");
print(SOCKET "zzzzzz\n\n");
print(SOCKET "set shout 0\nset bell 0\nset style 12\n\nset open 1\n");
open(LOG, ">ics.log");
$oldfh = select(LOG); $| = 1; select($oldfh);
$LOAD = 1;
while(TRUE)
{
	do getstring('.*\n');
	if ($BUFFER =~ /You may accept this with "accept (\w+)"/)
	{
		print(LOG "accepting $+\n");
		print(SOCKET "accept $+\n");
		@TIME = localtime(time);
		$KEY = join('.', "game",
			$TIME[5],$TIME[4],$TIME[3],$TIME[2],$TIME[1],$TIME[0]);
		open(GAME, ">$KEY");
		close(GAME);
	}
	elsif ($BUFFER =~ /Your opponent requests that the game be aborted/)
	{
		print(LOG "aborting\n");
		print(SOCKET "abort\n");
	}
	elsif ($BUFFER =~ /<12>.*\n/)
	{
		@INFO = split(' ', $BUFFER);
		if ($INFO[19] == 1)
		{
			$COLOUR = $INFO[9];
			$INITTIME = $INFO[20] * 60;
			$INCTIME = $INFO[21];
			if ($COLOUR eq "W")
			{
				$REMTIME = $INFO[24];
			}
			else
			{
				$REMTIME = $INFO[25];
			}
			$MOVENR = $INFO[26];
			$MOVE = $INFO[29];
			if ($MOVE ne "none")
			{	
				if (($MOVE eq "0-0-0") || ($MOVE eq "O-O-O"))
				{
					$MOVE = "o-o-o";
				}
				elsif (($MOVE eq "0-0") || ($MOVE eq "O-O"))
				{
					$MOVE = "o-o";
				}
				open(GAME, ">>$KEY");
				print(GAME  "$MOVE\n");
				close(GAME);
			}
			if ($INCTIME > 0)
			{
				if ($MOVENR > 60)
				{
					$ALLOCTIME = $INCTIME - 2;
				}
				else
				{
					$ALLOCTIME = $REMTIME / (61 - $MOVENR) + $INCTIME - 2;
				}
			}
			else
			{
				if ($MOVENR > 60)
				{
					$ALLOCTIME = 10;
				}
				else
				{
					$ALLOCTIME = $REMTIME / (61 - $MOVENR);
				}
			}
			if ($ALLOCTIME > $REMTIME)
			{
				$ALLOCTIME = $REMTIME;
			}
			if ($ALLOCTIME < 1)
			{
				$ALLOCTIME = 2;
			}
			$ALLOCTIME /= $LOAD;
			print(LOG "$MOVENR init=$INITTIME inc=$INCTIME rem=$REMTIME alloc=$ALLOCTIME load=$LOAD\n");
			$TIME1 = time;
			system("a.out -TimeLimit $ALLOCTIME batch $KEY");
			$TIME2 = time;
			$USEDTIME = $TIME2 - $TIME1;
			if ($USEDTIME == 0)
			{
				$LOAD = 1;
			}
			else
			{
				$LOAD = $USEDTIME/$ALLOCTIME;
				if ($LOAD < 1) 
				{
					$LOAD = 1;
				}
				print(LOG "alloc=$ALLOCTIME used=$USEDTIME load=$LOAD\n");
			}
			$LINE = `tail -1 $KEY`;
			($MOVE, @REST) = split(' ', "$LINE");
			$MOVE =~ s/#//;
			print(SOCKET "$MOVE\n");
		}
	}
}
