[w3m-dev 00370] w3mmine.cgi

From: Hironori Sakamoto (hsaka@mth.biglobe.ne.jp)
Date: Sat Mar 04 2000 - 10:38:15 CST


$B:dK\$G$9!#(B

$B6l<j$J$N$K!"$J$s$H$J$/:n$j$?$/$J$C$F$7$^$C$F:n$C$F$7$^$C$?!#(B
w3mmine.cgi $B$G$9!#2?$+$OJ,$+$j$^$9$h$M(B(^^)$B!#(B
$B!t(B $BK\5$$G:n$C$?$o$1$G$O$J$$$N$G%3!<%I$,1x$$$N$H%P%0$O8fMF<O$r!D!#(B
-----------------------------------
$B:dK\(B $B9@B'(B <hsaka@mth.biglobe.ne.jp>
 http://www2u.biglobe.ne.jp/~hsaka/
======================================================================
#!/usr/bin/perl

($CGI = $0) =~ s@.*/@@;
$CGI = "file:/cgi-bin/$CGI";

$Id = $X = $Y = $M = $Oid = $Cid = $PX = $PY = 0;
$New = $Change = $Start = 0;
$Type = "Open";
foreach(split(/\&/, $ENV{'QUERY_STRING'})) {
  s/([^=]*)=// || next;
  $n = $1;
  if ($n =~ /^P(\d+)x(\d+)/) {
    $PX = $1;
    $PY = $2;
  } else {
    eval "\$$n = \$_";
  }
}
if ($Change) {
  $X = ($X || 8);
  $Y = ($Y || 8);
  $M = ($M || 10);
  &print_header("W3MMINE - Change X,Y,Mine");
  &change_panel();
  &print_footer();
  exit;
}
if (! $New && $Id !~ /x/) {
  $New = 1;
  $Start = 1;
}
if ($New) {
  $X = ($X > 16) ? 16 : ($X || 8);
  $Y = ($Y > 16) ? 16 : ($Y || 8);
  $N = $X * $Y;
  $M = ($M > $N) ? $N : ($M || int($N / 6) || 1);
  srand();
  $Q = int(2**31 * rand());
  $Id = "${X}x${Y}x${M}x${Q}";
  $PX = $PY = 0;
  $Oid = $Cid = 0;
} else {
  ($X, $Y, $M, $Q) = split("x", $Id);
}

&create_mine();
&create_map();
&create_open();
&create_check();
$game_over = 0;
if ($PX && $PY) {
  if ($Type eq 'Check') {
    $Check{$PX,$PY} = 1;
  } elsif ($Type eq 'Uncheck') {
    $Check{$PX,$PY} = 0;
  } else {
    &check_open($PX, $PY);
    if ($Map{$PX,$PY} < 0) {
      $game_over = 1;
    }
  }
}
&count_check();

if ($New) {
  $Time = time();
}
if ($game_over) {
  &print_header("W3MMINE - Game over(;_;)");
  &game_over();
  &print_footer();
} elsif (&check_clear()) {
  &print_header("W3MMINE - Game clear(^o^)");
  &game_clear();
  &print_footer();
} else {
  &make_oid_cid();
  &print_header("W3MMINE");
  &game();
  &print_footer();
}

sub game {
  local($x, $y);
  local($n) = sprintf("%.2d", $M - $NC);
  local($t) = time() - $Time;
  $t = sprintf("%.2d:%.2d", $t / 60, $t % 60);

  print <<EOF;
<B>W3MMINE</B>
<P>
[ $n ] [ $t ]
<select name=Type>
EOF
  for $x ("Open", "Check", "Uncheck") {
    print "<option";
    print " selected" if ($Type eq $x);
    print ">$x\n";
  }
  print <<EOF;
</select>
<input type=submit name=New value="New game">
<input type=submit name=Change value="New game (change size)">
<input type=hidden name=Id value=$Id>
<input type=hidden name=Oid value=$Oid>
<input type=hidden name=Cid value=$Cid>
<input type=hidden name=Time value=$Time>
<table border=1>
EOF
  for $y (1 .. $Y) {
     print "<tr>";
     for $x (1 .. $X) {
        print "<td><nobr>";
        if ($Check{$x,$y}) {
          print "<input type=submit name=P${x}x$y value=\"!\">\n";
        } elsif ($Open{$x,$y}) {
          if ($Map{$x,$y}) {
            print "&nbsp;$Map{$x,$y}&nbsp;";
          } else {
            print "&nbsp; &nbsp;";
          }
        } else {
          print "<input type=submit name=P${x}x$y value=\" \">\n";
        }
     }
     print "\n"
  }
  print <<EOF;
</table>
EOF
}

sub game_over {
  local($x, $y);
  local($n) = sprintf("%.2d", $M - $NC);
  local($t) = time() - $Time;
  $t = sprintf("%.2d:%.2d", $t / 60, $t % 60);

  print <<EOF;
<B>W3MMINE - Game over(;_;)</B>
<P>
[ $n ] [ $t ]
<input type=submit name=New value="New game">
<input type=submit name=Change value="New game (change size)">
<input type=hidden name=X value=$X>
<input type=hidden name=Y value=$Y>
<input type=hidden name=M value=$M>
<table border=1>
EOF
  for $y (1 .. $Y) {
     print "<tr>";
     for $x (1 .. $X) {
        print "<td><nobr>";
        if ($Map{$x,$y} < 0) {
          if ($Open{$x,$y}) {
            print "<B>&gt;@&lt;</B>";
          } elsif ($Check{$x,$y}) {
            print "[<B>!</B>]";
          } else {
            print "&nbsp;<B>@</B>&nbsp;";
          }
        } elsif ($Open{$x,$y}) {
          if ($Map{$x,$y}) {
            print "&nbsp;$Map{$x,$y}&nbsp;";
          } else {
            print "&nbsp; &nbsp;";
          }
        } else {
          if ($Check{$x,$y}) {
            print "&nbsp;<B>X</B>&nbsp;";
          } else {
            print "[ ]";
          }
        }
     }
     print "\n"
  }
  print <<EOF;
</table>
EOF
}

sub game_clear {
  local($x, $y);
  local($n) = sprintf("%.2d", $M - $NC);
  local($t) = time() - $Time;
  $t = sprintf("%.2d:%.2d", $t / 60, $t % 60);

  print <<EOF;
<B>W3MMINE - Game clear(^o^)</B>
<P>
[ $n ] [ $t ]
<input type=submit name=New value="New game">
<input type=submit name=Change value="New game (chage size)">
<input type=hidden name=X value=$X>
<input type=hidden name=Y value=$Y>
<input type=hidden name=M value=$M>
<table border=1>
EOF
  for $y (1 .. $Y) {
     print "<tr>";
     for $x (1 .. $X) {
        print "<td><nobr>";
        if ($Map{$x,$y} < 0) {
          print "[<B>!</B>]";
        } elsif ($Open{$x,$y}) {
          if ($Map{$x,$y}) {
            print "&nbsp;$Map{$x,$y}&nbsp;";
          } else {
            print "&nbsp; &nbsp;";
          }
        }
     }
     print "\n"
  }
  print <<EOF;
</table>
EOF
}

sub change_panel {
  print <<EOF;
<B>W3MMINE - Change X,Y,Mine</B>
<P>
<table>
<tr><td><td>X<td><input type=text name=X value=$X size=4> (max = 16)
<tr><td><td>Y<td><input type=text name=Y value=$Y size=4> (max = 16)
<tr><td><td>Mine<td><input type=text name=M value=$M size=4> (0: auto)
</table>
<p>
<input type=submit name=New value="OK">
EOF
}

sub print_header {
  local($title) = @_;

  $Start || print <<EOF;
w3m-control: DELETE_PREVBUF
EOF
  print <<EOF;
Content-Type: text/html

<html>
<head>
<title>$title</title>
</head>
<body>
<form action="$CGI">

EOF
}

sub print_footer {
  print <<EOF;

</form>
</body>
</html>
EOF
}

sub create_mine {
  local($_, $x, $y);
  local($b) = $M;

  %Mine = ();

  srand($Q);

  while($b) {
    $x = int(rand($X)) + 1;
    $y = int(rand($Y)) + 1;
    if (! $Mine{$x,$y}) {
      $b--;
      $Mine{$x,$y} = 1;
    }
  }
}

sub create_map {
  local($x, $y, $i, $j);

  %Map = ();

  for $x (1 .. $X) {
  for $y (1 .. $Y) {
    if ($Mine{$x,$y}) {
      $Map{$x,$y} = -1;
      next;
    }
    $Map{$x,$y} = 0;
    for $i ($x - 1, $x, $x + 1) {
      ($i < 1 || $i > $X) && next;
    for $j ($y - 1, $y, $y + 1) {
      ($j < 1 || $j > $Y) && next;
      $Mine{$i,$j} && $Map{$x,$y}++;
    }
    }
  }
  }
}

sub create_open {
  local($o, $_);

  %Open = ();
  if ($Oid) {
    $y = 0;
    for $o (split("x", $Oid)) {
      $y++;
      $x = 1;
      for(split("", $o)) {
        $_ = hex($_);
        $Open{$x++,$y} = ($_ & 0x8) && 1;
        $Open{$x++,$y} = ($_ & 0x4) && 1;
        $Open{$x++,$y} = ($_ & 0x2) && 1;
        $Open{$x++,$y} = ($_ & 0x1) && 1;
      }
    }
  }
}

sub create_check {
  local($c, $_);

  %Check = ();
  if ($Cid) {
    $y = 0;
    for $c (split("x", $Cid)) {
      $y++;
      $x = 1;
      for(split("", $c)) {
        $_ = hex($_);
        $Check{$x++,$y} = ($_ & 0x8) && 1;
        $Check{$x++,$y} = ($_ & 0x4) && 1;
        $Check{$x++,$y} = ($_ & 0x2) && 1;
        $Check{$x++,$y} = ($_ & 0x1) && 1;
      }
    }
  }
}

sub count_check {
  local($x, $y);

  $NC = 0;
  for $y (1 .. $Y) {
  for $x (1 .. $X) {
    if ($Open{$x,$y}) {
      $Check{$x,$y} = 0;
    }
    $Check{$x,$y} && $NC++;
  }
  }
}

sub check_open {
  local($x, $y) = @_;
  local($i, $j);

  $Open{$x,$y} && return;
  $Open{$x,$y} = 1;
  $Map{$x,$y} && return;
  for $i ((($x == 1) ? 1 : ($x - 1)) .. (($x == $X) ? $x : ($x + 1))) {
  for $j ((($y == 1) ? 1 : ($y - 1)) .. (($y == $Y) ? $y : ($y + 1))) {
     &check_open($i,$j);
  }
  }
}

sub check_clear {
  local($x, $y);

  for $y (1 .. $Y) {
  for $x (1 .. $X) {
    if ($Map{$x,$y} >= 0) {
      $Open{$x,$y} || return 0;
    }
  }
  }
  $NC = $M;
  return 1;
}

sub make_oid_cid {
  local($x, $y);
  local(@o, @c);

  @o = ();
  @c = ();
  for $y (1 .. $Y) {
    $x = 1;
    $_ = "";
    while($x <= $X) {
      $_ .= sprintf("%x", $Open{$x++,$y} * 8 + $Open{$x++,$y} * 4
             + $Open{$x++,$y} * 2 + $Open{$x++,$y});
    }
    push(@o, $_);
    $x = 1;
    $_ = "";
    while($x <= $X) {
      $_ .= sprintf("%x", $Check{$x++,$y} * 8 + $Check{$x++,$y} * 4
             + $Check{$x++,$y} * 2 + $Check{$x++,$y});
    }
    push(@c, $_);
  }
  $Oid = join("x", @o);
  $Cid = join("x", @c);
}



This archive was generated by hypermail 2b29 : Wed Jul 19 2000 - 10:30:54 CDT