#!/usr/local/bin/perl # # game of tic-tac-toe for mosiac 2.0//http 1.0.5 # # Jason Heirtzler # 2/10/94 # $host = "http://scv.bu.edu"; $href = "$host:5111"; # # $men = 9; #$men = 16; # $giveup = "$host/Games/puzzle"; $gohome = "

[Return to game page]

[Return to Home page]"; $newgame = "

New game?\n$gohome"; if ( $men == 9 ) { $blank = 4; $endgame = "0,1,2,3,4,5,6,7,8,9"; @valid = ( "1,3", "0,2,4", "1,5", "0,4,6", "1,3,5,7", "2,4,8", "3,7", "4,6,8", "5,7" ); } if ( $men == 16 ) { $blank = 0; $endgame = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15"; @valid = ("1,4", "0,5,2", "1,6,3", "2,7", "0,5,8", "1,4,6,9", "2,5,7,10", "3,6,11", "4,9,12", "5,8,10,13", "6,9,11,14", "7,10,15", "8,13", "9,12,14", "10,13,15", "11,14" ); } require 'getopts.pl'; # &Getopts( 'd' ); # $done = 0; $_ = <>; chop($_); # srand(time); # # initial board position is random # called as follows: # # http://lobster.bu.edu:5111/- # # for ex: GET /ooooooooo HTTP/1.0 $_ =~ s!GET /(\S+) .*!$1! unless ($opt_d); # $turn = -1; /^(\d+)-.*/ && ( $turn = $1); $turn++; /^.*-(.*)/ && ( $move = $1); # print "Content-type: text/html\n\n"; # # Print banner! # if (!$opt_d) { print "\n$men PUZZLE\n"; print "

$men Puzzle

\n"; print "\n"; } # # takes a string of the form "1,2,3" and makes it # a little harder to understand # sub recode { local( $arg ) = @_; local( @f, $x, @y ); @f = split( ',', $arg ); foreach (@f) { $x = $_ + 0; if ( $x >= 32) { $x = $x & 15; } else { $x = $x + int(rand(7))*32 + 32; } $x = $x ^6; push( @y, $x ); } return(join( ',', @y )); } # # isvalidmove( "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15", # "4,1,2,3,0,5,6,7,8,9,10,11,12,13,14,15" ); # sub isvalidmove { local( $start, $end ) = @_; local( @s, @e, $i, $j ); @s = split(/,/, $start); @e = split(/,/, $end); # for ( $i=0; $i<$men; $i++) { if (@s[$i] eq $blank) { @v = split(/,/, @valid[$i]); for ( $j=$#v; $j>=0; $j-- ) { #print "cmp ", @e[@v[$j]], " 0\n"; if (@e[@v[$j]] eq $blank ) { # print "valid\n"; return(1); } } #print "not valid\n"; return(0); } } die "no blank in start string?"; } # # randomize the board. must work backwards from # the solved board as random combinations of the # pieces may not be solvable. # sub scramble { local( @e, $b, $i, $t, $o ); # @e = split( /,/, $endgame ); # # find blank space (always first one, really) # for ( $i=length($endgame); $i>=0; $i-- ) { $b = $i if ( @e[$i] eq $blank ); } # # for ( $i=0; $i<500; $i++ ) { # # get list of valid moves @v = split(/,/, @valid[$b]); #print " from $b valid moves: ", join( ',', @v ), "($#v)\n"; #print " picking from [0..", $#v, "]\n"; # $z = int(rand($#v)+0.5); #print " taking number $z, ie ", @v[$z], "\n"; # randomly pick one of them $r = @v[$z]; # print "switch $b and $r elts\n" if ($opt_d); # now switch $b and $r elements $t = @e[$r]; @e[$r] = @e[$b]; @e[$b] = $t; # blank space has now moved $b = $r; } return(join(',',@e)); } # sub showboard { local( $what ) = @_; local( @w, $i, $j, $x, $y ); # # find the blank square # @w = split( /,/, $what ); for ( $i= $#w; $i>=0; $i-- ) { $b = $i if ( @w[$i] eq $blank ); } print "blank is $b\n" if ($opt_d); # $y = 4 if ($men == 16); $y = 3 if ($men == 9); # for ( $i = 0; $i<$y; $i++ ) { for ( $j = 0; $j<$y; $j++ ) { $x = $i*$y+$j; print " n$x " if ($opt_d); # # try switching the blank with this # square. @s = @w; $t = @s[$x]; @s[$x] = @s[$b]; @s[$b] = $t; # $t = join( ',', @s ); if (&isvalidmove( $t, $what)) { if ($opt_d) { print "+"; } else { $w = &recode( $t ); print "" unless ($done); } } else { print "-" if ($opt_d); } print "\n" unless ($opt_d); } if ($opt_d) { print "\n"; } else { print "
\n"; } } } # #print &isvalidmove( "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15", # "2,1,0,3,4,5,6,7,8,9,10,11,12,13,14,15" ); # if ($move eq "random") { $turn = 0; $move = &scramble; } else { $move = &recode($move) unless ($opt_d); } # if ($move eq "$endgame") { $done++; &showboard($move); print "

You did it!!

"; print "

Solved in $turn moves.

"; print "$newgame"; # # $MAIL = "/usr/ucb/Mail"; # $MAIL = "/usr/sbin/Mail" if ( -f "/usr/sbin/Mail" ); # # open( M, "| $MAIL -s puzzle_solved jdh" ); # print M "9-puzzle solved in $turn moves\n"; # close( M ); exit(0); } # #$move = $endgame; #print "
$move
\n"; &showboard($move); if ($turn == 0) { print "

Ready!

\n"; print "Click on a piece to move it to the black square.\n"; } else { print "

Moves: $turn

\n"; print "Click on a piece to move it to the black square.

\n"; print "Give up? Click here\n" unless ($turn == 1); } exit(0);