我必须写一个漂亮的"5连"小游戏。我已经成功地检测到像这样的行和列获胜:
对于行:
$same=0;
for($i=1;$i<=$size;$i++) for($j=1;$j<=$size;$j++){ /wins in a row
if((@$_SESSION["pos"][$i][$j] == @$_SESSION["pos"][$i][$j+1]) && @$_SESSION["pos"][$i][$j]!=0 ) ++$same; else $same=0;
if($same==4){
if($_SESSION["pos"][$i][$j]==1) $winner="First"; //will be read from DB
if($_SESSION["pos"][$i][$j]==2) $winner="Second"; //will be read from DB
print $winner.' player WON!<br />';
}
}
对于列,它是相同的,但相反,所以这很容易。现在我的问题是,如何检测对角线胜利?我试着搜索它,但找不到任何我可以使用(或理解)的东西。我只被允许使用PHP。
What is what:
$same = same symbol counter
$_SESSION["pos"][$i][$j] = the 2D array of coordinates of the board (starting from 1,1 not 0,0)
indexes are the coordinates, values can be 0 (empty space) or 1 (symbol1) or 2 (symbol2)
$size = size of the board (always N x N)
你不必用勺子给我一个完整的代码,我只需要了解一下如何做到这一点。
让我们的游戏区域宽度为5。这有点棘手或破解,但我们可以将这样的数组用作长字符串,并找到子字符串,如XXXXX
、00000
(用于行检查)、X....{5 times}
(用于列检查)或X.....{5 times}
(用于''对角线检查)和X...{5 times}
(用于/对角线检查)。
所以我们只需要用任何符号替换.
,并找到这样的模式。这个任务是我们可以使用正则表达式的时候。我们只需要将这些模式与preg_match()相匹配。
我不知道更快的方法,但它似乎是原创的(例如仅用于X
检查):
<?php
$area = array(
array('x','x','x','x','x'),
array('0','0','x','x','0'),
array('x','x','x','x','0'),
array('0','0','x','x','x'),
array('x','0','x','0','x'),
);
//get the long string of that array
$fullstring = '';
foreach($area as $string) {
$fullstring .= implode('', $string)."|";
}
//check long string for such patterns
$win_by_column = preg_match('/x.{5}x.{5}x.{5}x.{5}x/i', $fullstring); //5 game area width
$win_by_row = preg_match('/x{5}/i', $fullstring); //5 same in rows
$win_by_bs_diagonal = preg_match('/x.{6}x.{6}x.{6}x.{6}x/i', $fullstring); // ' diagonal, 5 is $area width + 1
$win_by_s_diagonal = preg_match('/x.{4}x.{4}x.{4}x.{4}x/i', $fullstring); // / diagonal, 4 is $area width - 1.
//output the results
var_dump($win_by_column);
var_dump($win_by_row);
var_dump($win_by_bs_diagonal);
var_dump($win_by_s_diagonal);
?>
如果您不熟悉正则表达式,这也是一个良好的开端;)
UPD我已经更新了代码。我在数组字符串中插入字符串分隔符。所以现在我们需要在列检查中检查5个点(任何符号),在对角线检查中检查6个点。此硬编码值相应地计算为宽度和宽度+1。为了便于阅读和理解,我不在图案中插入$area
宽度。
您可以像检测行和列一样检测对角线:只需将对角线视为倾斜的行(或列)。也就是说,不看单元[$i][$j]
,而看[$i+$j][$j]
(对于具有正倾斜的对角线)或[$i-$j][$j]
(对于负倾斜)。
例如,以下是如何检测负对角线:
$grid = $_SESSION["pos"];
for ($i = 1; $i <= $size; $i++) {
$same = 0;
$prev = 0;
for ($j = 1; $j <= $size && $i-$j >= 1; $j++) {
$cur = @$grid[$i-$j][$j];
if ($cur == $prev && $cur != 0) ++$same;
else $same = 0;
if ($same == 4) {
$winner = ($cur == 1 ? "First" : "Second"); //will be read from DB
print "$winner player WON!<br />";
}
$prev = $cur;
}
}
将其更改为检查正对角线只是一个练习。
您可以通过两个单独的for循环检查对角线:
$area = array(
array('x','x','x','x','x'),
array('0','x','x','x','0'),
array('x','x','x','x','0'),
array('0','x','x','x','x'),
array('x','0','x','0','x'),
);
$diagonal1 = 0;
for($i = 0; $i < 5; $i++){
if($area[$i][$i] == 'x'){
$diagonal1 ++;
}
}
if($diagonal1 == 5){
echo 'Diagonal win';
}
// other diagonal
$diagonal2 = 0;
for($i = 0; $i < 5; $i++){
if($area[$i][4 - $i] == 'x'){
$diagonal2 ++;
}
}
if($diagonal2 == 5){
echo 'Diagonal win';
}