如何检测“对角线获胜”;一行5个”;游戏(PHP)


How to detect diagonal win in "5 in a row" game (PHP)

我必须写一个漂亮的"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。这有点棘手或破解,但我们可以将这样的数组用作长字符串,并找到子字符串,如XXXXX00000(用于行检查)、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';
}