# ttt: play tic-tac-toe # usage: ttt # 2000-03-13 erikt@uia.ua.ac.be $true = 1; $false = 0; $gamesPlayed = 0; $continue = $true; $computerScore = 0; $humanScore = 0; $computerStarts = ""; # this loop allows us to play a series of games while ($continue) { $movesPlayed = 0; $maxMovesPlayed = 9; $gameWon = $false; # The field contains nine squares which can be identified as follows: # 0..1..2 # 3..4..5 # 6..7..8 # In the move lists the value $true means that the player has occupied # the square. @computerMoves = ($false,$false,$false,$false,$false,$false,$false,$false,$false); @humanMoves = ($false,$false,$false,$false,$false,$false,$false,$false,$false); @occupied = ($false,$false,$false,$false,$false,$false,$false,$false,$false); # The field contains eight rows which can be identified as follows: # 0 1 2 3 4 row 0 contains squares 0, 4, 8 # 0..1..2 5 row 1 contains squares 0, 3, 6 # 3..4..5 6 row 2 contains squares 1, 4, 7 # 6..7..8 7 row 3 contains squares 2, 5, 8 # row 4 contains squares 2, 4, 6 # row 5 contains squares 0, 1, 2 # row 6 contains squares 3, 4, 5 # row 7 contains squares 6, 7, 8 # Each square is represented by a number in which ones and zeroes # indicate in what rows the square appears. @fieldValues = ( 11000100, 100100, 11100, 1000010,10101010, 10010, 1001001, 100001,10010001); # The numbers will be added to the field value of the player that # occupies them. As soon as one of these numbers contains a 3 then # the player has three-in-a-row $computerField = 0; $humanField = 0; # let the computer play the first move, if necessary if ($computerStarts !~ /^[01]$/) { print "Do you want to start (y/n)? "; chomp($answer = <>); $computerStarts = $answer ne "y"; } if ($computerStarts) { # compute a computer move: choose a random number until it is ok $move = $maxMovesPlayed; $move = int(rand(9)) while (not(defined($occupied[$move])) or $occupied[$move]); print "computer playes ",$move+1,"\n"; $computerMoves[$move] = $true; $occupied[$move] = $true; $computerField += $fieldValues[$move]; $movesPlayed++; # for next game $computerStarts = $false; } else { $computerStarts = $true; } # while the game has not ended, read a human move while ($movesPlayed < $maxMovesPlayed and not($gameWon)) { # print the field for ($i=0;$i<$maxMovesPlayed;$i++) { if (not($occupied[$i])) { print ". "; } elsif ($computerMoves[$i]) { print "x "; } elsif ($humanMoves[$i]) { print "o "; } else { print "cannot happen\n"; exit(1); } if ($i == 3*(int(($i+1)/3))-1) { print "\n"; } } # read a human move: accept numbers 1-9! $move = ""; while ($move !~ /^[1-9]$/ or $occupied[$move-1]) { print "Please enter a move (1-9): "; chomp($move = <>); } # go back to numbers 0-8 $move--; $humanMoves[$move] = $true; $occupied[$move] = $true; $humanField += $fieldValues[$move]; $movesPlayed++; if ($humanField =~ /3/) { print "Human wins!\n"; $humanScore++; $gameWon = $true; } # if the game has not ended, play a computer move if ($movesPlayed < $maxMovesPlayed and not($gameWon)) { $move = $maxMovesPlayed; $move = int(rand(9)) while (not(defined($occupied[$move])) or $occupied[$move]); print "computer playes ",$move+1,"\n"; $computerMoves[$move] = $true; $occupied[$move] = $true; $computerField += $fieldValues[$move]; $movesPlayed++; if ($computerField =~ /3/) { print "Computer wins!\n"; $computerScore++; $gameWon = $true; } } } # print the final field for ($i=0;$i<$maxMovesPlayed;$i++) { if (not($occupied[$i])) { print ". "; } elsif ($computerMoves[$i]) { print "x "; } elsif ($humanMoves[$i]) { print "o "; } else { print "cannot happen\n"; exit(1); } if ($i == 3*(int(($i+1)/3))-1) { print "\n"; } } if (not($gameWon)) { print "Draw.\n"; } # print results $gamesPlayed++; print "\n$gamesPlayed game"; print "s" if ($gamesPlayed != 1); print " played: Computer $computerScore - Human $humanScore\n"; print "\nContinue playing? (y/n)"; chomp($answer = <>); $continue = $false if ($answer eq "n"); } exit(0);