2014-11-07 2 views
4

, пытаясь сделать игру tic-tac-toe. Поэтому, если есть лучший способ, я тоже хотел бы знать! Итак, у меня есть сетка [0,8], а позиции пользователя хранятся в массиве. Отлично. Далее я хочу посмотреть, совпадают ли столбцы. Итак, допустим, первая строка (0,1,2). Мой вопрос в том, есть ли у пользователя такой массив, как array(1,5,6,0,2), поэтому он выиграл. Как я могу эффективно сопоставить это? я думал сделать что-то подобное, но не выглядит эффективным:как можно найти несколько значений сразу в массиве php

$user= array(1,5,6,0,2); 
in_array(0,$user) && in_array(1,$user) && in_array(2,$user) 

Я также думал о переключателя случае, но по-прежнему стоит вопрос, как я могу найти несколько значений одновременно.

+1

Вы можете использовать [ 'array_intersect()'] (http://php.net/manual/en/function.array-intersect.php), чтобы сравнить массив, представляющий строку '[0,1, 2] 'с массивом пользователя и проверить вывод пересечения имеет' count() == 3', что означает, что все 3 были сопоставлены. Среди обширного набора PHP [функции массива] (http://php.net/manual/en/ref.array.php) есть много способов, которые могут быть использованы так, чтобы удовлетворить ваши потребности так или иначе. Вы планируете сохранить список возможных значений, составляющих строку (простое), или вы хотите, чтобы эти алгоритмы были определены алгоритмически (немного сложнее)? –

+0

Это может быть интересно: http://www.ocf.berkeley.edu/~yosenl/extras/alphabeta/alphabeta.html –

+0

Для tic-tac-toe я бы выбрал работу с двумерной матрицей aka array , заполненное тремя возможными значениями 0 (незанятое пространство), 1 (x) и -1 (o), а затем подсчитывает суммы для строк, столбцов и диагоналей. –

ответ

1

Я согласен с тем, что с таким небольшим количеством возможных комбинаций, чтобы выиграть, решение может быть очень простым. Я бы сделал это с помощью array_diff.

function has_won($user) { 
    // returns false if the user has not won, otherwise 
    // returns the first winning combination found. 
    $wins = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]]; 
    foreach ($wins as $win) { 
     if (!array_diff($win, $user)) return $win; 
     // array_diff returns the values in the first argument 
     // not present in any subsequent arguments. So if its 
     // result is empty, the user has winning combination. 
    } 
    return false; 
} 
+0

Я думаю, что это было кратким и довольно устрашающим. – JamAndJammies

+1

Примечание для будущих читателей: использование 'empty()' непосредственно в этом контексте потребует PHP 5.5. С 5.4 и ниже это будет ошибка синтаксического анализа, так как результат 'array_diff()' не является переменной.'Array_diff()' сначала нужно сохранить в переменной, в свою очередь передать 'empty()'. 5.5 может работать только на результат выражения. –

+0

@MichaelBerkowski Отличная точка; Спасибо. Я должен упомянуть об этом в ответе. –

1

Я не буду делать требование, что это является эффективным методом наиболее, но это уменьшает количество операций, значительно по сравнению с && цепочки и нескольких in_array() вызовов.

Что мы будем делать, так это сохранить двумерный массив возможных комбинаций выигрышей: строк, столбцов, диагоналей, в качестве подматриц. Затем в цикле foreach над этим 2D-массивом проверьте текущее состояние массива пользователя на комбинацию строк с помощью array_intersect(). Если вся выигрышная комбинация присутствует в массиве пользователя, результат array_intersect() будет равен 3, которые вы можете проверить с помощью count().

Поскольку одного матча достаточно для победы, вы можете выйти из цикла в первом матче, чтобы объявить победу.

$combinations = array(
    // Rows 
    array(0,1,2), 
    array(3,4,5), 
    array(6,7,8), 
    // Columns 
    array(0,3,6), 
    array(1,4,7), 
    array(2,5,8), 
    // Diagonals 
    array(0,4,8), 
    array(2,4,6), 
); 

// Loop over the array of winners and test array_intersect() 
// If 3 values intersect, the full win combination was matched 
foreach ($combinations as $combination) { 
    if (count(array_intersect($combination, $user)) == 3) { 
     // User wins! Take whatever action necessary... 
     // Exit the loop 
     break; 
    } 
} 

Вот демонстрация, в которой 2 из 3 комплекта для $user являются победителями: http://codepad.viper-7.com/Mvu0wa

Есть алгоритмические способы получения выигрышных комбинаций, а не жесткого кодирования их, но есть только восемь возможных комбинаций так это не так сложно, и здесь нужно использовать array_intersect(), чтобы найти подмножество текущих мест размещения пользователя.

+0

+1 Умный ответ. – amphetamachine