Я должен написать хорошую игру «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; } }
Изменение этого для проверки положительных диагоналей остается как упражнение.
Вы можете проверить диагональ на два отдельных цикла:
$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'; }