#!/usr/local/bin/perl # Runs tic tac toe players in ARGV[0] and ARGV[1] $player1 = $ARGV[0]; $player2 = $ARGV[1]; $globalboard = initgame(); $moves = 0; while (!($winner = gameover($globalboard))) { $globalboard = makemove($player1, $globalboard); $moves++; if (!($winner = gameover($globalboard))) { $globalboard = swapsides($globalboard); $globalboard = makemove($player2, $globalboard); $moves++; $globalboard = swapsides($globalboard); } } printboard($globalboard); print "First move: 1, Winner: $winner, Moves; $moves\n"; $globalboard = initgame(); $moves = 0; while (!($winner = gameover($globalboard))) { $globalboard = makemove($player2, $globalboard); $moves++; if (!($winner = gameover($globalboard))) { $globalboard = swapsides($globalboard); $globalboard = makemove($player1, $globalboard); $moves++; $globalboard = swapsides($globalboard); } } # Since gameover is calculated assuming player 1 plays x (goes first) if ($winner == 1) { $winner = 2; } elsif ($winner == 2) { $winner = 1; } $globalboard = swapsides($globalboard); printboard($globalboard); print "First move: 2, Winner: $winner, Moves: $moves\n"; exit(); sub initgame { return(" "); } # 1 = x wins, 2 = o wins, 3 = tie, 0 = game not over sub gameover { local($var) = @_; $_ = $var; # print ">($_)<\n"; if (/xxx....../) { return 1; } if (/...xxx.../) { return 1; } if (/......xxx/) { return 1; } if (/x..x..x../) { return 1; } if (/.x..x..x./) { return 1; } if (/..x..x..x/) { return 1; } if (/x...x...x/) { return 1; } if (/..x.x.x../) { return 1; } if (/ooo....../) { return 2; } if (/...ooo.../) { return 2; } if (/......ooo/) { return 2; } if (/o..o..o../) { return 2; } if (/.o..o..o./) { return 2; } if (/..o..o..o/) { return 2; } if (/o...o...o/) { return 2; } if (/..o.o.o../) { return 2; } if (/ /) { return 0; } return 3; } sub swapsides { local($temp) = @_; $temp =~ s/x/t/g; $temp =~ s/o/x/g; $temp =~ s/t/o/g; return($temp); } # always assumes it is x's turn # also assumes -100 is near the bottom of the eval range # loads file $player to define eval sub makemove { local($player, $board) = @_; local($i, $temp, $best, $bestscore, $score); do $player; # print "loading $player\n"; $bestscore = -100; $best = $board; for ($i = 0; $i < 9; $i++) { $temp = $board; # blank space if (substr($temp, $i, 1) eq " ") { substr($temp, $i, 1) = "x"; $score = &eval($temp); if ($score > $bestscore) { $bestscore = $score; $best = $temp; } } } return($best); } sub printboard { local($board) = @_; # print ">$board<\n"; printf "%s|%s|%s\n",substr($board,0,1),substr($board,1,1),substr($board,2,1); printf "-+-+-\n"; printf "%s|%s|%s\n",substr($board,3,1),substr($board,4,1),substr($board,5,1); printf "-+-+-\n"; printf "%s|%s|%s\n",substr($board,6,1),substr($board,7,1),substr($board,8,1); }