本文实例讲述了php实现的生成迷宫与迷宫寻址算法。分享给大家供大家参考,具体如下:
较之前的终于有所改善。生成迷宫的算法和寻址算法其实是一样。只是一个用了遍历一个用了递归。参考了网上的Mike Gold的算法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
<?php
header( 'Content-Type: text/html; charset=utf-8' );
error_reporting (E_ALL);
//n宫格迷宫
define( 'M' , 39); //宫数
define( "S" , 20); //迷宫格大小
$_posArr = array ( array (0, -1), array (1, 0), array (0, 1), array (-1, 0)); //当前点寻址的四个xy方向 上右下左
//生成迷宫
$maze = array ();
$mazeUnit = array (1, 1, 1, 1); //上右下左
for ( $x =0; $x <=M; $x ++){
for ( $y =0; $y <=M; $y ++){
$maze [ $x ][ $y ] = $mazeUnit ;
}
}
$maze2 = array (); //破墙后的已访问格子
$mazeOrder = array (); //破墙顺序
$x = $y = 0; //初始入口
while ( count ( $maze )>0){
$tmpArr = array ();
foreach ( $_posArr as $val ){
$nx = $x + $val [0];
$ny = $y + $val [1];
if (isset( $maze [ $nx ][ $ny ])){ //未破墙过的格子
$tmpArr [] = array ( $nx , $ny );
}
}
if ( $tmpArr ){ //有未破墙的格子,随机出一个,破墙
list( $nx , $ny ) = $tmpArr [ array_rand ( $tmpArr )];
$maze2 [ $nx ][ $ny ] = $maze [ $nx ][ $ny ];
if ( empty ( $maze2 [ $x ][ $y ])) $maze2 [ $x ][ $y ] = $maze [ $x ][ $y ];
$pos = array ( $nx - $x , $ny - $y );
foreach ( $_posArr as $key => $val ){ //循环四个方向,找出需要破的墙
if ( $pos == $val ) {
$maze2 [ $x ][ $y ][ $key ] = 0; //原格子破墙
$maze2 [ $nx ][ $ny ][( $key +2)%4] = 0; //新格子破墙
}
}
//设置新的当前格后返回继续while循环
$x = $nx ;
$y = $ny ;
$mazeOrder [] = array ( $x , $y );
unset( $maze [ $x ][ $y ]); //去掉已破墙的格子
if ( empty ( $maze [ $x ])) unset( $maze [ $x ]);
} else { //当前xy周围不存在未破墙的格子,返回上一个格子继续破墙
array_pop ( $mazeOrder );
if ( $mazeOrder ) list( $x , $y ) = $mazeOrder [ count ( $mazeOrder ) - 1];
}
}
//留出出口
$maze = $maze2 ;
$maze [0][0][3] = 0;
$maze [M][M][1] = 0;
//寻址
$pathArr = findPath( $maze , 0, 0, false);
printMaze( $maze , $pathArr );
echo "<img src='maze.png'> <a href='javascript:;' onclick='location.reload();'>刷新</a>" ;
//打印迷宫和寻址结果
function printMaze( $maze , $pathArr ){
$im = ImageCreate((M + 1) * S + 1, (M + 1) * S + 1);
$bg = ImageColorAllocate( $im , 236, 233, 216);
$pathColor =ImageColorAllocate( $im , 255, 0, 0);
$exitColor =ImageColorAllocate( $im , 134, 255, 0);
$borderColor = ImageColorAllocate( $im , 0, 0, 0);
ImageRectangle( $im , 0, 0, (M + 1) * S, (M + 1) * S, $borderColor ); //包边
ImageLine( $im , 0, 0, 0, S, $bg ); //右上边开口
ImageLine( $im , (M + 1) * S, M * S, (M + 1) * S, (M + 1) * S, $bg ); //左下边开口
foreach ( $maze as $x => $xarr ){ //生成格子
foreach ( $xarr as $y => $unit ){
if ( $unit [0]) ImageLine( $im , $x * S, $y * S, ( $x + 1) * S, $y * S, $borderColor ); //上有线
if ( $unit [1]) ImageLine( $im , ( $x + 1) * S, $y * S, ( $x + 1) * S, ( $y + 1) * S, $borderColor ); //右有线
if ( $unit [2]) ImageLine( $im , $x * S, ( $y + 1) * S, ( $x + 1) * S, ( $y + 1) * S, $borderColor ); //下有线
if ( $unit [3]) ImageLine( $im , $x * S, $y * S, $x * S, ( $y + 1) * S, $borderColor ); //左有线
//if(in_array(array($x, $y), $pathArr)) ImageFilledEllipse($im, $x * S + S/2, $y * S + S/2, S, S, $pathColor);//寻址格
if (in_array( array ( $x , $y ), $pathArr )) ImageString( $im , 1, $x * S + S/5, $y * S + S/5, array_search ( array ( $x , $y ), $pathArr ), $pathColor ); //寻址格
}
}
ImagePNG( $im , 'maze.png' );
ImageDestroy( $im );
}
//寻址函数
function findPath( $maze , $x , $y , $fromxy ){
global $_posArr ;
if ( $x == M && $y == M){ //到达出口
Return array ( array ( $x , $y ));
}
foreach ( $_posArr as $key => $val ){
if ( $maze [ $x ][ $y ][ $key ]) continue ; //为1则不通
$nx = $x + $val [0];
$ny = $y + $val [1];
if (!isset( $maze [ $nx ][ $ny ]) || $fromxy == array ( $nx , $ny )) continue ; //边界超出或为来源点
if ( $pathArr = findPath( $maze , $nx , $ny , array ( $x , $y ))) {
array_unshift ( $pathArr , array ( $x , $y ));
Return $pathArr ; //能到达出口
}
}
Return false;
}
?>
|
运行结果如下:
希望本文所述对大家PHP程序设计有所帮助。
原文链接:http://www.cnblogs.com/zqifa/p/php-maze-1.html