$Z= 'ox' x 5; ## Only ten characters are needed because each
## game has a maximum of nine moves
## The grid, stored as a string:
$_='1 2 3\n4 5 6\n7 8 9 ";
{ ## Start the generic loop
$C = chop $Z; ## Strip the last character from $Z ('x' or 'o')
## and store it into $C
print "\n$_=>$C"; ## Print the current grid, then the current letter
+
{ ## Begin small inner loop
<> =~ /^([\d])$/i && ## Grab input, must be a single digit...
s/$1/$C/m ## Try to replace the number the user gave ($1)
## with the current character.
or redo; ## If either of the above fails, redo this smal
+l
## inner loop.
} ## end inner loop
m/(^($C.){3})|(($C.{5}){2}$C)|(($C.{7}){2}$C)|(^.(...$C){3})/sm
## The above is a nasty regular expression that checks to see if
## the game has been won. It checks for four
## things, inside the four parenthesis above. If any are true,
## then the expression is true, and the game is won (and over).
## Here they are:
/^($C.){3})/ ## Checks for a horizontal match. Basically, it
## looks for the start of a line. Then it looks
## for the current letter followed by anything
## three times. In practice, this means it matches
## a character, a space, a character, a space,
## a character, and a newline
/($C.{5}){2}$C/ ## This checks for a vertical match. Since the grid
## is constant, we know that three vertical characters
+
## are a set distance apart. In this case, for our
## 3x3 grid, we are looking for the character,
## five anythings, the character, five anythings,
## and the character.
/($C.{7}){2}$C/ ## This checks for a diagonal match, starting from
## the upper left-hand corner. Character, 7 anything,
## character, 7 anything, then the character. Only
## this diagonal matches this pattern.
(^.(...$C){3}/ ## This checks for the opposite diagonal, starting fro
+m
## the upper right-hand corner. It has the pattern
## of three anything, then the character, all three
## times. Since this could match other places, we use
## the anchor to specify only the diagonal we want
or ++$T>8) or redo; ## Redo the outer loop *unless* one of the
## regular expressions matched *or*
## we have run 9 rounds. Anything else
## goes to the top of the generic loop
} ## end the generic loop
s/\d/-/g; print; ## We are done. Replace any numbers left in the
## grid with dashes, and re-display the grid.
Hope that helps. I did change a couple things since it was
first posted. The is not so much obfuscated code as it is
very very short code. If I were really going for obfuscation,
I would not use variables such as $T and $C. :) See Adam's
code above for the same thing a bit more obfuscated.
As far as making it a cgi, you could, but why? Nobody would
be able to see it, only interact with it - as far as they
know, it could be a 10,000 line perl script or a 1/2 Meg
executable. Still, it should be possible. It's too late
to type any more though. :)
|