The programs corresponding with these exercises can be found in the appendix.
Write a filter which selects words based on their position on the line.
My program checks if the arguments are numbers and then processes the text. I stumbled upon a problem: it seems that <> assumes that arguments in @ARGV are names of input files. Therefore @ARGV should be empty before we start reading the text. Example run:
$ perl -w filter 3 2 1 this is a test of lines getting shorter and shorter ^Z a is this getting lines of and shorter shorter
Improve the tic-tac-toe program ttt so that it easily beats our version in a best-of-nine match.
The original version chooses moves at random. I have changed this behavior to make the program a little bit smarter. It will first check if it has the opportunity to win the game. If that is the fact, it will play the winning move and otherwise it will check if the opponent has a winning move. When the program finds such a move, it will block the location by playing the move itself. Otherwise it will play a random move. The program can check if a certain move results in three-in-a-row by adding the value of a move to the fields value of a player. When $computerField or $humanField contains a 3 then the player has three-in-a-row somewhere.
Here is an example game of the new version (x) playing the old (o):
o . . o . . o . x o o x x . . x x . x x o x x o . . . . . o . . o x . o o4 x6 o9 x5 o6 x3 o2 x7 x wins
Here are the results of a small tournament of the programs that have been submitted as answers for this exercise:
Matches Table -------------------- ---------------------- TTT - Erik 0-5 1. Gert 3 9 13-3 Helena - Gert 1-5 2. Erik 3 6 12-3 Erik - Helena 5-0 3. Helena 3 3 6-12 Gert - TTT 5-0 4. TTT 3 0 2-15 TTT - Helena 2-5 Gert - Erik 3-2
TTT is the original program. Matches consisted of nine games but they were stopped when one of the programs obtained five points.
# filter: select words based on their positions on the line # usage: filter [n1 n2 n3 ...] # 2000-03-27 erikt@uia.ua.ac.be use strict; my ($i,@args,@words); # ARGV must be empty for reading lines: copy it @args = @ARGV; @ARGV = (); # check arguments: should be numbers for ($i=0;$i<@args;$i++) { if ($args[$i] !~ /^[0-9]+$/) { print "argument $args[$i] is not a number\n"; exit(1); } } # process input text while (<>) { @words = split(/\s+/,$_); for ($i=0;$i<@args;$i++) { print " " if ($i > 0); if (defined($words[$args[$i]-1])) { print "$words[$args[$i]-1]"; } } print "\n"; } exit(0);
# OLD VERSION (twice) # 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]); # NEW VERSION (twice) # compute a computer move $i = 0; # can we win? while ($i < $maxMovesPlayed and ($occupied[$i] or ($computerField+$fieldValues[$i]) !~ /3/)) { $i++; } if ($i < $maxMovesPlayed) { $move = $i; } else { $i = 0; # does opponent have a winning move? while ($i < $maxMovesPlayed and ($occupied[$i] or ($humanField+$fieldValues[$i]) !~ /3/)) { $i++; } if ($i < $maxMovesPlayed) { $move = $i; } else { # pick move at random $move = $maxMovesPlayed; $move = int(rand(9)) while (not(defined($occupied[$move])) or $occupied[$move]); } }