<?php
$style = 1; /*设置页面风格*/
$player = $_GET["id"]; /*设置get提交的id为用户标志*/
$position = $_GET["pos"];
$file = "./five.dat"; /*设置数据存放位置*/
define("ROW","20"); /*设置棋盘大小,默认认为20x20*/
function show_head($title) {
echo "<html>";
echo "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\"/>";
echo "<head><title>$title</title></head>";
echo "<body bgcolor=black text=white>";
}
function show_foot($copyright) {
echo "<br><hr>";
echo "<div align=center>$copyright</div>";
$date = date("Y年 n月 j日");
echo "<br><div align=center>$date</div>";
echo "</body>";
echo "</html>";
}
show_head(五子棋);
game($style,$player);
function game ($style,$player) {
global $position;
global $file;
if($player == 1) $echoplayer = 2;
else $echoplayer = 1;
echo "<table border=2 width=90% height=80% align=\"center\"><tr>";
echo "<td width=60% bgcolor=teal>"; /*左边棋盘空间*/
echo "<table cellpadding=0 cellspacing=0 border=1 width=420 height=420 align=\"center\">";
/*********************main**************************/
if ($player == 0) {
init($file); /*当id没有赋值时,初始化页面*/
sidebar($player,0);
}
if ($player == 2) { /*player=2为电脑*/
writetofile($file,$position,$echoplayer); /*把玩家走棋写入文件*/
$computer_pos = five_ai($file);
$win = is_together($file,1,5);/*判断玩家是否获胜*/
echobox($file,$player,$win);
sidebar(1,$win);
if ($win == 0) {
echo "<meta http-equiv=\"refresh\" content=\"0;?id=1&pos=$computer_pos\"/>"; /*玩家未胜利时电脑走棋*/
}
}
if ($player == 1) {
writetofile($file,$position,$echoplayer); /*把前一玩家棋子写入文件*/
$win = is_together($file,2,5);/*判断是否获胜*/
echobox($file,$player,$win);
sidebar($player,$win);
}
}/*end of game function*/
function echobox($file,$player,$win)
{
$box = readfromfile($file);/*从文件中读取棋子位置,重新画图*/
for ($i=1;$i<=ROW;$i++) {
echo "<tr align=\"center\">";
for ($j=1;$j<=ROW;$j++) {
echo "<td align=\"center\">";
$id = 2;
if ($box[$i][$j] == 0 && $win == 0) echo "<a href=\"$index?id=$id&pos=$i:$j\"><img src=\"chessblank.gif\" alt=\"$nbsp\"></a></td>";
else if ($box[$i][$j] == 0 && $win == 1) echo "<img src=\"chessblank.gif\" alt=\"$nbsp\"></td>";
else if ($box[$i][$j] == 1) echo "<img src=\"chessblack.gif\" alt=\"$nbsp\"></td>";
else if ($box[$i][$j] == 2) echo "<img src=\"chesswhite.gif\" alt=\"$nbsp\"></td>";
}
}
echo "</tr>";
}
function sidebar($player,$win)
{
echo "</table>";
/*************************************************/
echo "<td width=20% valign=top bgcolor=teal>";
echo "<table height=10% align=center>";
echo "<tr><td>PHP版五子棋</td></tr>";
echo "<tr><td>作者:cocobear</td></tr>";
if ($player = 2) {
echo "<tr><td>该玩家下子"."</td></tr>";
}
else {
echo "<tr><td>该电脑下子"."</td></tr>";
}
//echo "$position";
echo "</table>";
if ($win == 1) {
if ($player == 1) echo "<table height=50% align=center><tr><td>玩家执黑子胜利</td></tr>";
if ($player == 2) echo "<table height=50% align=center><tr><td>电脑执白子胜利</td></tr>";
echo "<meta http-equiv=\"refresh\" content=5;url=./index.php>";
echo "<tr><td>5秒后自动返回</td></tr>";
echo "</table>";
}
echo "</td>";/*右边的说明表格*/
echo "<tr></table>";/*最大的表格*/
}
show_foot(本程序遵循GPL);
/*******************function************************************/
function readfromfile($file) {
$fd = file_get_contents($file);
//echo $fd;
$pieces = explode("|",$fd); /*从文件中读入棋子位置信息,然后以二维数组的方式存储在box数组中*/
for ($i=1;$i<=20;$i++) {
$m = $i-1;
//echo "<br>$pieces[$m]";
$piece = explode(":",$pieces[$m]);
for ($j=1;$j<=20;$j++) {
$n = $j-1;
//echo "<br>piece$i:$piece[$n]";
$box[$i][$j] = $piece[$n];
}
}
return $box;
}
/*********************writetofile()**************************/
function writetofile($file,$pos,$player) {
$initpos = 0;
$postion = explode(":",$pos);
if($player != 0) $state = readfromfile($file);
else $state = 0;
//print_r($state);
if(!$fp = fopen($file,"w")) echo "Can't create file!\nPlease check current dir,make sure you have write permission.";
for($i=1;$i<=ROW;$i++) {
for($j=1;$j<=ROW;$j++) {
if ($player != 0 && $state[$i][$j] != 0) fwrite($fp,$state[$i][$j]);
else if($i == $postion[0] && $j == $postion[1]) fwrite($fp,$player);
else fwrite($fp,$initpos); /*默认情况下写入0*/
if($j != ROW) fwrite($fp,":");
}
if($i != ROW) fwrite($fp,"|"); /*添加一些分隔信息*/
}
fclose($fp);
}
/*********************页面初始化*************************/
function init($file) {
$pos = "";
$player = 0;
writetofile($file,$pos,$player);
for ($i=1;$i<=ROW;$i++) {
echo "<tr align=\"center\">";
for ($j=1;$j<=ROW;$j++) {
echo "<td align=\"center\">";
echo "<a href=\"$index?id=2&pos=$i:$j\"><img src=\"chessblank.gif\" alt=\"$nbsp\"></a></td>"; /*id=1,设置用户*/
}
}/*end of function init()*/
echo "</tr>";
}
function is_together($file,$player,$num) {
$box = readfromfile($file);
for($i=1;$i<=ROW;$i++) {
for($j=1;$j<=ROW;$j++) {
$row = 0;
$col = 0;
$dia = 0;
$dia_opt = 0;
for($k=0;$k<$num;$k++) {
if($box[$i][$j+$k] == $player) $row++;
}
if($row == $num) return 1; /*横向判断*/
for($k=0;$k<$num;$k++) {
if($box[$i+$k][$j] == $player) $col++;
}
if($col == $num) return 1; /*纵向判断*/
for($k=0;$k<$num;$k++) {
if($box[$i+$k][$j-$k] == $player) $dia++;
}
if($dia == $num) return 1; /*正斜判断*/
for($k=0;$k<$num;$k++) {
if($box[$i+$k][$j+$k] == $player) $dia_opt++;
}
if($dia_opt == $num) return 1; /*反斜判断*/
}
}
return 0;/*默认返回为未胜利*/
}
/****************function is_num ***************************/
function is_num($file,$num,$player) {
$box = readfromfile($file);
$n = 0;
for($i=1;$i<=ROW;$i++) {
for($j=1;$j<=ROW;$j++) {
$row = 0;
$col = 0;
$dia = 0;
$dia_opt = 0;
for($k=0;$k<$num;$k++) {
if($box[$i][$j+$k] == $player) $row++;
}
if($row == $num) {
$top[$n][0] = $i;
$top[$n][1] = $j;
$top[$n][2] = 1; /*类型为横向*/
$add = 0;
$x = $i;
$y = $j - 1;
if( $y > 0 && $box[$x][$y] == 0) {
$top[$n][3] = 1;
$x = $i;
$y = $j + $num;
if($y <= 20 && $box[$x][$y] == 0) {
$top[$n][3] = 2;
}
else $top[$n][3] = 0;
$add = 1;
}
$x = $i;
$y = $j + $num;
if($y <= 20 && $box[$x][$y] == 0) {
if($top[$n][3] != 2) $top[$n][3] = 1;
$add = 1;
}
if($add == 1) $n++;
else $top[$n][0] = 0;/*两端都有棋子挡着则不返回有效值*/
}
/*横向判断结束*/
for($k=0;$k<$num;$k++) {
if($box[$i+$k][$j] == $player) $col++;
}
if($col == $num) {
$top[$n][0] = $i;
$top[$n][1] = $j;
$top[$n][2] = 2; /*类型为纵向*/
$add = 0;
$x = $i - 1;
$y = $j;
if( $x > 0 && $box[$x][$y] == 0) {
$top[$n][3] = 1;
$x = $i + $num;
$y = $j;
if($x <= 20 && $box[$x][$y] == 0) {
$top[$n][3] = 2;
}
else $top[$n][3] = 0;
$add = 1;
}
$x = $i + $num;
$y = $j;
if($x <= 20 && $box[$x][$y] == 0) {
if($top[$n][3] != 2) $top[$n][3] = 1;
$add = 1;
}
if($add == 1) $n++;
else $top[$n][0] = 0;
}
/***纵向判断结束*/
for($k=0;$k<$num;$k++) {
if($box[$i+$k][$j+$k] == $player) $dia++;
}
if($dia == $num) {
$top[$n][0] = $i;
$top[$n][1] = $j;
$top[$n][2] = 3; /*类型为反斜*/
$add = 0;
$x = $i - 1;
$y = $j - 1;
if( $y > 0 && $x > 0 && $box[$x][$y] == 0) {
$top[$n][3] = 1;
$x = $i + $num;
$y = $j + $num;
if($y <= 20 && $x <= 20 && $box[$x][$y] == 0) {
$top[$n][3] = 2;
}
else $top[$n][3] = 0;
$add = 1;
}
$x = $i + $num;
$y = $j + $num;
if($y <= 20 && $x <= 20 && $box[$x][$y] == 0) {
if($top[$n][3] != 2) $top[$n][3] = 1;
$add = 1;
}
if($add == 1) $n++;
else $top[$n][0] = 0;
}
/**反斜判断结束*/
for($k=0;$k<$num;$k++) {
if($box[$i+$k][$j-$k] == $player) $dia_opt++;
}
if($dia_opt == $num) {
$top[$n][0] = $i;
$top[$n][1] = $j;
$top[$n][2] = 4; /*类型为正斜*/
$add = 0;
$x = $i - 1;
$y = $j + 1;
if( $y <= 20 && $x > 0 && $box[$x][$y] == 0) {
$top[$n][3] = 1;
$x = $i + $num;
$y = $j - $num;
if($y > 0 && $x <= 20 && $box[$x][$y] == 0) {
$top[$n][3] = 2;
}
else $top[$n][3] = 0;
$add = 1;
}
$x = $i + $num;
$y = $j - $num;
if($y > 0 && $x <= 20 && $box[$x][$y] == 0) {
if($top[$n][3] != 2) $top[$n][3] = 1;
$add = 1;
}
if($add == 1) $n++;
else $top[$n][0] = 0;
}
/**正斜判断结束*/
}
}
return $top;
return 0;/*默认返回为未胜利*/
}
function five_ai($file) {
$box = readfromfile($file);
for ($i=1;$i<=ROW;$i++) {
for ($j=1;$j<=ROW;$j++) {
if ($box[$i][$j] == 1) {
$x = $i;
$y = $j;
$sum++; /*判断是否只落了一子*/
}
}
}
if ($sum == 1) {
return onedot($x,$y);
}
if (($ret = together($file,4,2,1)) != 0) return $ret;/*电脑四个连子处理*/
if (($ret = together($file,4,1,1)) != 0) return $ret;/*玩家有四个连子处理*/
if (($ret = together($file,3,1,2)) != 0) return $ret;/*玩家有三个连子且两端都为空处理*/
if (($ret = twosplit($file,1)) != 0) return $ret;/*玩家有两个子中间为空*/
if (($ret = twosplit($file,2)) != 0) return $ret;/*电脑有两个子中间为空*/
if (($ret = together($file,3,2,1)) != 0) return $ret;/*电脑三个连子,且两端都为空的处理*/
if (($ret = together($file,2,1,2)) != 0) return $ret;/*玩家有两个连子处理*/
if (($ret = together($file,2,2,2)) != 0) return $ret;/*电脑两个连子处理*/
/**/
if (($ret = together($file,3,1,1)) != 0) return $ret;/*玩家三个连子处理*/
if (($ret = together($file,2,1,1)) != 0) return $ret;/*玩家二个连子处理*/
if (($ret = together($file,2,2,1)) != 0) return $ret;/*电脑二个连子处理*/
if (($ret = together($file,1,2,2)) != 0) return $ret;
echo "<h1>Out of my expect!</h1>";
return "1:1";
}/*end of function five_ai*/
function twosplit($file,$player)
{
$box = readfromfile($file);
for ($i=1;$i<=ROW;$i++) {
for ($j=1;$j<=ROW;$j++) {
if ($box[$i][$j] == $player) {
$x = $i;
$y = $j + 1;
if ($box[$i][$j-1] == 0 && $box[$x][$y] == 0 && $box[$i][$j+2] == $player && $box[$i][$j+3] == 0) {
return "$x".":"."$y";
}
$x = $i + 1;
$y = $j;
if ($box[$i-1][$j] == 0 && $box[$x][$y] == 0 && $box[$i+2][$j] == $player && $box[$i+3][$j] == 0) {
return "$x".":"."$y";
}
$x = $i + 1;
$y = $j + 1;
if ($box[$i-1][$j-1] == 0 && $box[$x][$y] == 0 && $box[$i+2][$j+2] == $player && $box[$i+3][$j+3] == 0) {
return "$x".":"."$y";
}
$x = $i + 1;
$y = $j - 1;
if ($box[$i-1][$j+1] == 0 && $box[$x][$y] == 0 && $box[$i+2][$j-2] == $player && $box[$i+3][$j-3] == 0) {
return "$x".":"."$y";
}
}
}
}
return 0;
}
function together($file,$num,$player,$type)
{
$top = is_num($file,$num,$player);
/*返回二维数组:[0][1]为2个连子的起始坐标;[2]是连子类型1为横向2为纵向3为反斜4为正斜;[3]连子两端空闲情况:0为上边或左边空闲 1为下边或右边空闲 2为两边都空闲*/
$i = 0;
while ($top[$i][0] != 0) {
$x = $top[$i][0];
$y = $top[$i][1];
$z = $top[$i][2];
$a = $top[$i][3];
//echo "$x".":$y".":$z".":$a";
if ($type != 2) {
if ($top[$i][3] == 0) {
if ($top[$i][2] == 1) {
$x1 = $x;
$y1 = $y - 1;
return "$x1".":"."$y1";
}
if ($top[$i][2] == 2) {
$x1 = $x - 1;
$y1 = $y;
return "$x1".":"."$y1";
}
if ($top[$i][2] == 3) {
$x1 = $x - 1;
$y1 = $y - 1;
return "$x1".":"."$y1";
}
if ($top[$i][2] == 4) {
$x1 = $x - 1;
$y1 = $y + 1;
return "$x1".":"."$y1";
}
}
if ($top[$i][3] == 1) {
if ($top[$i][2] == 1) {
$x1 = $x;
$y1 = $y + $num;
return "$x1".":"."$y1";
}
if ($top[$i][2] == 2) {
$x1 = $x + $num;
$y1 = $y;
return "$x1".":"."$y1";
}
if ($top[$i][2] == 3) {
$x1 = $x + $num;
$y1 = $y + $num;
return "$x1".":"."$y1";
}
if ($top[$i][2] == 4) {
$x1 = $x + $num;
$y1 = $y - $num;
return "$x1".":"."$y1";
}
}
}
if ($top[$i][3] == 2) {
if ($top[$i][2] == 1) {
$x1 = $x;
$y1 = $y - 1;
$p1 = numof($x1,$y1);
$x2 = $x;
$y2 = $y + $num;
$p2 = numof($x2,$y2);
if ($p1 >= $p2) return "$x1".":"."$y1";
else return "$x2".":"."$y2";
}
if ($top[$i][2] == 2) {
$x1 = $x - 1;
$y1 = $y;
$p1 = numof($x1,$y1);
$x2 = $x + $num;
$y2 = $y;
$p2 = numof($x2,$y2);
if ($p1 >= $p2) return "$x1".":"."$y1";
else return "$x2".":"."$y2";
}
if ($top[$i][2] == 3) {
$x1 = $x - 1;
$y1 = $y - 1;
$p1 = numof($x1,$y1);
$x2 = $x + $num;
$y2 = $y + $num;
$p2 = numof($x2,$y2);
if ($p1 >= $p2) return "$x1".":"."$y1";
else return "$x2".":"."$y2";
}
if ($top[$i][2] == 4) {
$x1 = $x - 1;
$y1 = $y + 1;
$p1 = numof($x1,$y1);
$x2 = $x + $num;
$y2 = $y - $num;
$p2 = numof($x2,$y2);
if ($p1 >= $p2) return "$x1".":"."$y1";
else return "$x2".":"."$y2";
}
}
$i++;
}/*end of while*/
return 0;/*没有两个棋子连着*/
}
function numof($x,$y)
{
global $file;
$mini = $x - 4;
$minj = $y - 4;
$maxi = $x + 4;
$maxj = $y + 4;
$box = readfromfile($file);
for ($i = $mini;$i <= $maxi;$i++) {
for ($j = $minj;$j <= $maxj;$j++) {
if ($box[$i][$j] == 2) $count++;
}
}
//echo "count="."$count";
return $count;
}
function onedot($x,$y)
{
$x1 = $x - 1;
$y1 = $y - 1;
if ($x1 > 0 && $y1 >0) return "$x1".":$y1";
$x1 = $x - 1;
$y1 = $y;
if ($x1 > 0 && $y1 >0) return "$x1".":$y1";
$x1 = $x - 1;
$y1 = $y + 1;
if ($x1 > 0 && $y1 >0 && $y1 <= 20) return "$x1".":$y1";
$x1 = $x;
$y1 = $y - 1;
if ($x1 > 0 && $y1 >0) return "$x1".":$y1";
$x1 = $x;
$y1 = $y + 1;
if ($x1 > 0 && $y1 >0 && $y1 <= 20) return "$x1".":$y1";
$x1 = $x + 1;
$y1 = $y - 1;
if ($x1 > 0 && $x1 <= 20 && $y1 >0) return "$x1".":$y1";
$x1 = $x + 1;
$y1 = $y;
if ($x1 > 0 && $x1 <= 20 && $y1 >0) return "$x1".":$y1";
$x1 = $x + 1;
$y1 = $y + 1;
if ($x1 > 0 && $y1 >0 && $x1 <= 20 && $y1 <= 20) return "$x1".":$y1";
}
?>