В моей предыдущей статье о массивах PHP я предложил несколько вещей, которые являются таблицами и, следовательно, также могут быть выражены в виде массивов. В этой статье я буду использовать набор игральных карт для изучения некоторых встроенных функций массива, наиболее часто используемых программистами PHP.
Чтобы осветить некоторые функции обработки массивов, которые предлагает PHP, я буду использовать некоторые компоненты Buraco — игры, очень популярной в моей части мира и очень похожей на Рамми. В реальном Бурако играют две колоды (104 карты) плюс две карты Джокера. В нем также есть колода карт, в которой хранятся все карты, которые не сдаются игрокам, но я не буду здесь их использовать, поэтому вам не нужно о них беспокоиться.
Представление колоды карт
Карты датируются, возможно, девятым веком, временем, когда листы бумаги впервые начали использоваться в Китае. Они пошли по пути других изобретений с Востока — сначала в арабский мир, откуда они были затем увезены в Европу, а затем в Новый Свет. В своей самой популярной на данный момент форме, французской колоде, колода игральных карт состоит из 52 карт, разделенных на четыре масти: булавы (♣), бриллианты (♦), червы (♥) и пики (♠). У каждой масти по 13 карт или лиц: A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q и K.
Вы можете написать массивы для хранения как костюмов, так и лиц:
<?php $suits = array ("clubs", "diamonds", "hearts", "spades"); $faces = array (1 => "A", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13");
Оба являются числовыми индексированными массивами, то есть имеют целочисленные ключи. Поскольку я явно не давал никаких ключей при определении $suits
, PHP автоматически присваивает им ключи, начиная с 0. Итак, значение $suits[0]
равно «club», а $suits[3]
— «spades». Однако я предоставил ключ к первому элементу $ Faces. PHP назначает каждый новый ключ, беря максимальный целочисленный индекс и добавляя к нему 1. $faces[1]
— это «A», $faces[2]
— это «02», $faces[3]
— это «03» и так далее. Вы заметите, что я заставил PHP начать индексирование $faces
с 1, чтобы числовые лица карты были идентичны их соответствующим ключам.
Вы можете использовать два цикла foreach
для создания мастер-массива из всех 52 карт, каждая из которых представлена в виде строки в формате face | suit , например:
<?php $deck = array(); foreach ($suits as $suit) { foreach ($faces as $face) { $deck[] = $face . "|" . $suit; } }
Результат приведенного выше кода такой же, как если бы вы заполнили $deck
вручную:
<?php $deck = array("A|clubs", "02|clubs", "03|clubs", "04|clubs", ... "Q|spades", "K|spades");
Некоторые из более опытных читателей могут спросить, почему бы не использовать вложенный массив в отличие от строк, например:
<?php $deck = array(); $deck["A"] = array("clubs", "diamonds", "hearts", "spades"); $deck["02"] = array("clubs", "diamonds", "hearts", "spades"); $deck["03"] = array("clubs", "diamonds", "hearts", "spades"); ...
В этом-то и прелесть: строки иногда можно рассматривать как неассоциативные одноуровневые массивы, но, тем не менее, массивы! Фактически, та же функция, используемая для подсчета количества элементов в массиве — count()
— также может использоваться для подсчета количества символов в строке! Позже вы увидите, как конвертировать строки в массивы.
Дело рук
Давайте начнем с перетасовки колоды и раздачи руки из 11 случайных карт. Для этого вы можете использовать функцию array_rand()
. Возвращает массив ключей, взятых случайным образом из оригинала. Функция была разработана для возврата ключей, а не значений, поэтому она может работать с вложенными массивами так же эффективно, как и с одноуровневыми массивами, и вы всегда можете получить значения, если знаете ключ.
<?php $myKeys = array_rand($deck, 11); $myHand = array(); foreach ($myKeys as $key) { $myHand[] = $deck[$key]; unset($deck[$key]); }
с<?php $myKeys = array_rand($deck, 11); $myHand = array(); foreach ($myKeys as $key) { $myHand[] = $deck[$key]; unset($deck[$key]); }
Первоначально $myKeys
временный массив $myKeys
, значения которого равны 11 случайным ключам, найденным в $deck
. Затем цикл foreach
использует значение $myKeys
чтобы получить соответствующее значение из $deck
в $myHand
. Конечно, это не удаляет элементы из оригинальной колоды. Если бы вам пришлось снова вызывать array_rand()
, вполне возможно, что вы могли бы получить несколько ключей, индексирующих снова некоторые карты, которые уже были извлечены! Чтобы этого не произошло, вызывается unset()
чтобы удалить элемент из $deck
чтобы убедиться, что его нельзя использовать повторно.
Чтобы выяснить, находится ли карта, скажем «06 | hearts» (6 ♥), в раздаче, вы можете использовать функцию in_array()
. Сначала он принимает иглу , желаемое значение для поиска, а затем стог сена , массив для поиска.
<?php if (in_array("06|hearts", $myHand)) { echo "I found it!"; }
В качестве примечания о иголках и стогах сена евангелисты других языков любят находить ошибки в PHP (и, конечно, верно и обратное!). Единственная критика, которую я никогда не мог опровергнуть, это раздражающий противоречивый порядок параметров в PHP между похожими функциями. Некоторые функции, такие как in_array()
, сначала принимают иглу, в то время как другие функции сначала принимают стог сена. Я знаю давних разработчиков PHP, которые до сих пор не могут вспомнить, какой порядок используют некоторые функции, так что не отчаивайтесь, если вам всегда нужно проверять онлайн-документацию.
in_array()
возвращает только то, было ли найдено что-то в массиве, а не ключ значения. В большинстве случаев этого достаточно. Но если вам также необходимо знать ключ, рассмотрите возможность использования array_search()
.
Хорошее ведение домашнего хозяйства важно, и благодаря манере « лицо | масть» , в которой представлены карточки, сортировать их так же просто, как и использовать sort()
. Эта функция упорядочивает элементы массива в возрастающем алфавитном и числовом порядке:
<?php sort($myHand);
Функция sort()
отличается тем, что работает со своим собственным аргументом! Если вы хотите сохранить исходный порядок $myHand
вам придется скопировать его в другую переменную перед сортировкой:
<?php $preservedHand = $myHand; sort($myHand);
Melds и Discards
Buraco, как и Rummy, — это игра в бега — последовательности, установленные на столе. Акт вытаскивания карт из руки на пробежку называется слиянием . Например, карты 9 ♦, 10 ♦, J ♦ и Q ♦, если они были в $myHand
можно объединить для запуска. Программно это означает удаление карт из $myHand
и помещение их в новый массив $myRuns
. Вы можете использовать функцию array_slice()
которая возвращает копию диапазона элементов из массива, очень похоже на то, как substr()
работает со строками. Предполагая, что последовательности занимают позиции от 0 до 3 в $myHand
:
<?php $myRuns = array(); $myRuns[] = array_slice ($myHand, 0, 4); $myHand = array_slice($myHand, 5, 7);
Первая строка создает массив $myRuns
а вторая добавляет к нему вложенный массив, состоящий из 4 элементов из $myHand
начиная с индекса 0, который является первой позицией в массиве. array_slice()
не удаляет срез из исходного массива, что является проблемой, так как вам нужно удалить карты из вашей руки, которые вы слили или сбросили. Решением здесь является использование array_slice()
во второй раз для переназначения других элементов $myHand
себе.
В начале своего хода игрок должен либо взять одну карту из колоды или все карты из колоды сброса и добавить их в свою руку. Обе опции могут быть выполнены с помощью функции array_merge()
. Функция возвращает массив, состоящий из всех элементов из указанных массивов в порядке их предоставления. Например, скажем, состояние игры выглядит так:
Рука игрока: 2 ♣, 5 ♥, 6 ♠, 6 ♥, 7 ♦, 8 ♥, K ♠
Прогон: 9 ♦, 10 ♦, J ♦, Q ♦
Сброс свай: 7 ♠, J ♠, 4 ♥, 4 ♦
Чтобы собрать все карты из колоды сброса и добавить их в руку игрока, вы можете написать:
<?php $myHand = array_merge($myHand, $discarded);
После этого $myHand
будет содержать:
массив («02 | клубы», «5 | сердечки», «06 | пики», «06 | сердечки», «07 | алмазы», «08 | червы», «13 | пики», «07 | пики», «11 | пики», «04 | сердечки», «04 | бриллианты»)
Показ руки
Было бы неплохо отобразить одну или несколько карточек в браузере. Моя стратегия состоит в том, чтобы использовать нотацию | лицо | костюм для создания ряда HTML-тегов изображения, которые будут отображать лицо и графику костюма. Хотя это вряд ли является эффективным решением для реального приложения, оно дает мне возможность показать вам одну последнюю функцию, explode()
.
<?php foreach ($myHand as $card) { $tmpArray = explode("|", $card); echo '<img src="img/face_' . $faces[$tmpArray[0]] . '.png">"; echo '<img src="img/suit_' . $suits[$tmpArray[1]] . '.png">"; echo " "; // Just a blank space for visual separation }
Каждый foreach
просматривает все карты в $myHand
и возвращает одно значение номинальной масти на каждой итерации в виде $card
. Функция explode()
берет каждое значение $card
и разбивает его на две части, используя вертикальную черту в качестве разделителя. Затем он возвращает массив с таким количеством элементов, сколько есть частей. Я использую вертикальную черту здесь, но explode()
будет работать с любым символом или последовательностью символов.
Резюме
PHP имеет более 70 функций, связанных с массивами. В этом уроке вы увидели, как использовать их всего несколько для выполнения некоторых базовых манипуляций с массивами. Эти функции являются инструментами, которые вы часто будете использовать для решения задач программирования или, как я их называю, задач. Важно наладить с ними знакомство, чтобы при планировании сценария вы могли принимать обоснованные решения на основе нужных вам результатов.
Изображение через Синди Хаггерти / Shutterstock