1
2set_time_limit(0);
3
4define('MAXNUM', 81); //单元格数
5define('SHOWWAIT', 200000); //显示停顿时间,单位微秒
6
7/**
8* 统计指定单元格所在行、列、块已添数字
9* 如发现现违规输入则中断运行
10* 参数
11* $i 数值,单元格所在行
12* $j 数值,单元格所在列
13* 返回 数组,分别为单元格所在行、列、块已添数字
14**/
15function load($i, $j) {
16global $dw;
17$row = array();
18$col = array();
19$block = array();
20foreach($dw[$i] as $v) {
21if(! empty($v)) $row[] = $v;
22}
23if(count(array_count_values($row)) != count($row))
24message("第 $i 行输入错误");
25foreach($dw as $v) {
26if(! empty($v[$j])) $col[] = $v[$j];
27}
28if(count(array_count_values($col)) != count($col))
29message("第 $j 列输入错误");
30$di = floor($i/3)*3;
31$dj = floor($j/3)*3;
32for($i=$di; $i<$di+3;$i++) {
33for($j=$dj; $j<$dj+3;$j++) {
34$v = $dw[$i][$j];
35if(! empty($v)) $block[] = $v;
36}
37}
38if(count(array_count_values($block)) != count($block))
39message('第 '.($di/3).','.($dj/3).' 块输入错误');
40$ar = array($row, $col, $block);
41return $ar;
42}
43
44/**
45* 记录成功排列的“九宫格”数据
46* 参数 无
47* 返回 无
48**/
49function save() {
50global $dw;
51$val = '';
52foreach($dw as $v) {
53$val .= join('', $v);
54}
55$val = str_replace(' ', '', $val);
56if(strlen($val) != MAXNUM) return;
57if(! search($val)) {
58$fp = fopen('data.txt', 'a+');
59fwrite($fp, "$val\r\n");
60fclose($fp);
61}
62}
63
64/**
65* 检查传入的数据是否已被保存
66* 参数
67* $val 字符串,待检查的数据
68* 返回 逻辑值,在 true,不在 false
69**/
70function search($val) {
71if(! is_file('data.txt')) return false;
72$fp = fopen('data.txt', 'r');
73while(! feof($fp)) {
74$s = trim(fgets($fp, 100));
75if($s == $val) {
76fclose($fp);
77return true;
78}
79}
80fclose($fp);
81return false;
82}
83
84/**
85* 暂停当前程序,等待若干时间后继续
86* 参数
87* $t 数值,等待的时间,单位 微秒
88* 返回 无
89**/
90function wait($t=0) {
91list($usec, $sec) = explode(" ",microtime());
92$t1 = (float)$usec + (float)$sec;
93do {
94list($usec, $sec) = explode(" ",microtime());
95$t2 = (float)$usec + (float)$sec;
96}while($t2 - $t1 < $t/1000000);
97}
98
99/**
100* 消息发布
101* 参数
102* $str 字符串,待发布的信息
103* 返回 无
104* 说明 执行后将终止当前程序的运行
105**/
106function message($str) {
107echo "
<script>document.getElementById('view').innerHTML = '$str'</script>
1\n";
2exit;
3}
4
5/**
6* 在记录文件中检索是否存在符合当前样本的记录
7* 参数
8* $ar 数组,输入的样本
9* 返回 逻辑值,存在 true,不存在 false
10* 说明 当检索成功时全局变量中将保存有成功的案例
11**/
12function find($ar) {
13global $dw;
14$type = false;
15$p = '';
16foreach($ar as $v) {
17$p .= empty($v) ? '.' : $v;
18}
19if(! ($fp = fopen('data.txt', 'r'))) return false;
20while(! feof($fp)) {
21$buf = trim(fgets($fp, 100));
22if(ereg($p, $buf)) {
23$type = true;
24break;
25}
26}
27fclose($fp);
28if($type) {
29$dw = array_chunk(split(',', chunk_split($buf, 1, ',')),9);
30}
31return $type;
32}
33
34/**
35* 填写“九宫格”函数
36* 使用递归算法遍历单元格
37* 参数
38* $pos 数值,指定待处理的单元格编号
39* 返回 逻辑值,成功 true,失败 false
40**/
41function check($pos) {
42global $dw, $d;
43if($pos == MAXNUM) return true;
44while($pos < MAXNUM) {
45$i = floor($pos/9);
46$j = floor($pos%9);
47$value = $dw[$i][$j];
48list($row, $col, $block) = load($i, $j);
49if(empty($value)) {
50shuffle($d);
51$t = array_diff($d, $row, $col, $block);
52foreach($t as $v) {
53$dw[$i][$j] = $v;
54echo "
<script>document.getElementById('j$i$j').value=$v</script>
1\n";
2flush();
3wait(SHOWWAIT);
4if(check($pos+1)) return true;
5$dw[$i][$j] = '';
6echo "
<script>document.getElementById('j$i$j').value=''</script>
1\n";
2flush();
3wait(SHOWWAIT);
4}
5return false;
6}
7$pos++;
8}
9return true;
10}
11
12$start = false;
13if(!empty($_POST['submit'])) {
14$_POST['dw'] = array_map('trim', $_POST['dw']);
15$inp = $_POST['dw'];
16if(!find($inp)) {
17$dw = array_chunk($_POST['dw'], 9); //按行分割提交的数据
18$start = true;
19}
20}else {
21$dw = array_chunk(array_fill(0, 81, ''), 9);
22}
1<html>
2<head>
3<title>九 宫 格</title>
4</head>
5<body>
6<table align="center" width="80%">
7<tr>
8<td valign="top" width="300">游戏规则:<br/>
9<ol type="1">
10<li>将1到9填入此表格中</li>
11<li>在9×9的格子每行每列,只能且必须填1到9这9个数字 (9个数字都必须出现)</li>
12<li>在3×3的每个大格子中的9个数必须是1到9这9个数字(9个数字都必须出现)</li>
13</ol>
14<b>注意:当你发现在数字总是一个区间内重复时,可能预示按输入的样本将无法完成“九宫格”排列。
15如不想等待,请单击“停止”(stop)终止当前的程序</b>
16</td>
17<td>
18<h2 align="center">输入数字</h2>
19<table align="center" border="2" cellpadding="1" cellspacing="0" width="225">
20<form method="POST">
$color = array(
array('red', 'orange', 'yellow'),
array('orange', 'yellow', 'green'),
array('yellow', 'green', 'blue'),
);
for($i=0; $i<9; $i++) {
echo "<tr>\n";
for($j=0,$p='A'; $j<9; $j++,$p++) {
$c = $color[floor($i/3)][floor($j/3)];
$cc = empty($inp[$i*9+$j]) ? '#000000' : '#FF0088';
$v = $dw[$i][$j];
echo "<td bgcolor="$c" bordercolor="$c" width="25">";
echo "<input id="j$i$j" maxlength="1" name="dw[]" size="1" style="color:$cc" type="text" value="$v"/></td>\n";
}
echo "</tr>\n";
}
1<tr>
2<td align="center" colspan="9">
3<input name="submit" type="submit" value="提交"/>
4<input name="reset" type="submit" value="清空"/>
5</td>
6</tr>
7</form>
8</table>
9</td></tr>
10<tr><td></td><td align="center" id="view" style="color:red"></td></tr></table>
11</body>
12</html>
1
2if($start) {
3$d = array(1,2,3,4,5,6,7,8,9);
4shuffle($d);
5if(check(0)) {
6save();
7}else {
8message('无法完成排列');
9}
10}