Головоломки Flash

         

Другие возможности



Другие возможности

В более сложных игровых автоматах в одном окне могут находиться сразу несколько символов. В некоторых автоматах символы отображаются также и по вертикали, так что игрок может выиграть, если совпадут символы по трем горизонтальным линиям и двум диагоналям. Иногда игрок может выбирать, сколько монет (от одной до пяти) "вставить" в автомат, чтобы определить потенциальный выигрыш (он будет зависеть от величины ставки).
Так как Flash-ролик - не игра на деньги, а просто развлечение, то более важно предусмотреть возможность изменения графики для соответствия различным темам Web-сайтов. Например, для детского сайта можно сделать картинки с конфетами. Изменяя внешний вид автомата и картинки, одну и ту же программу можно использовать для оформления разных сайтов.



Другие возможности



Другие возможности

Суммы, указанные в функции winnings, я выбрал, руководствуясь обычными правилами покера. Однако вы можете указать другие числа в зависимости от той суммы, которую хотите переводить на счет виртуального казино или игрока.
Можно сделать и так: когда на счету игрока не остается денег, переходить, например, к кадру game over.
Еше одна вариация игры - позволить игроку ставить от одного до пяти долларов за игру. Таким образом, игрок ставит меньшую сумму, когда чувствует, что ему не везет, и большую - в других случаях.



Другие возможности



Другие возможности

Эта игра очень хороша для изучения языка ActionScript, но она разочарует игроков в двадцать одно, играющих на деньги. Поэтому для хороших ActionScript-профаммистов далее представлено руководство, как добавить некоторые возможности этой игры, которые были опущены.
Легче всего добавить возможность раздачи только двух карт. Для этого нужно создать кнопку Double (Удваивание ставки) в кадре с меткой "Player". Когда игрок щелкнет по ней, ему дадут еще одну карту, ставка еще раз будет вычтена из суммы наличных денег, и игра перейдет к раздающему. Однако прежде следует убедиться, что игрок не взял какие-либо дополнительные карты, поскольку такая раздача возможна только тогда, когда у игрока на руках первые две карты.
Возможность страхования создать немного сложнее, так как при этом надо написать еше одну "ветвь" программы. Страхование возникает тогда, когда раздающему показывается туз. В этом случае игрок может застраховаться от того, что у раздающего будет 21, на сумму, обычно равную ставке. Если было взято страхование, и у раздающего 21 очко, игра заканчивается. Игрок теряет исходную ставку, но получает страховую сумму.
Разделение - сложное дополнение к игре. Если у игрока две карты одного достоинства, например две девятки, тогда ему может быть разрешено разделить карты на два расклада, каждый из которых будет начинаться с девятки. Следовательно, чтобы можно было хранить карты игрока в одном массиве playerHand, вы должны создать массив из массивов. В большинстве случаев в таком массиве playerHand содержится один массив, который отражает расклад на одной руке. Если игрок разделит карты, то в массиве будут содержаться два массива. Игроку обычно позволяется разделять карты несколько раз, таким образом, в массиве playerHand может содержаться три, четыре и более массивов. Затем нужно сыграть с каждым раскладом игрока. Вы понимаете, насколько это усложняет каждую часть игры. Игрок может выиграть, проиграть или сыграть в ничью по нескольким или всем своим раскладам.



Другие возможности



Другие возможности

Игру можно сделать значительно проще, если вы разрешите игроку переворачивать колоду уже открытых карт и смотреть карты столько раз, сколько он захочет. Вы можете сделать это, опознавая, когда массив deck пуст, и помещая каждую карту из массива stack обратно в массив deck.
Кроме этого пасьянса вы можете создать много других. В моей коллекции более 200 вариантов подобных игр. Большинство из них требует вытаскивания карт и перекладывания из стопки в стопку. Это делает код гораздо более сложным, но не невозможным для опытного программиста.



Игра в очко, или двадцать одно





Игра в очко, или двадцать одно

Исходный файл:

Двадцать одно - еще одна популярная карточная игра в казино, которую легко можно перенести на компьютер. Раздающий карты следуют определенному набору правил, следовательно, можно написать программу, которая будет имитировать действия раздающего.



Игровой автомат



Игровой автомат

Исходный файл:

Игровой автомат - игра функционально простая, но с довольно сложным интерфейсом. Игрок просто щелкает по рычагу игрового автомата и ждет результата. Автомат сам выполняет всю оставшуюся работу.
На Рисунок 15.1 показан фрагмент ролика Slotmachine.fla. Рычаг справа единственный элемент, который будет реагировать на действия игрока. Когда игровой автомат останавливается, в трех окошках отображаются картинки.



Эти кадры анимаиии создают эффект крутящегося барабана при быстром воспроизведении



Рисунок 15.2 Эти кадры анимаиии создают эффект крутящегося барабана при быстром воспроизведении


В каждом из трех окон будет отображаться копия клипа spin. Когда придет время вращения барабана, всем трем клипам будет сообщаться о воспроизведении, а также передаваться точное число вращений. Эти значения будут различными для каждого клипа, так что барабаны будут останавливаться не одновременно.
Просмотрите ролик Slotmachine.fla, чтобы увидеть, как крутятся барабаны и как они последовательно останавливаются.



К сведению



К сведению

Если вы посмотрите на ролик, который приводится в качестве примера, то увидите, что фон игрового автомата на самом деле располагается на переднем плане. Три окна - это "дырки" в изображении, сквозь них видно, как проигрывается анимация вращения, а также видны символы на барабанах.
Вы можете указать действия, которые будут совершаться, если деньги на счету игрока закончатся. Можно проверять это условие и, если оно оказывается истинным, переходить к другому кадру. Можно сообщить игроку, что игра окончена, либо предоставить еще 100 долларов, чтобы игрок сыграл еще раз.



К сведению



К сведению

К каждой кнопке Hold/Draw прикреплен собственный фрагмент кода. Для первой кнопки он выглядит следующим образом:

on (press) { holdDraw(0);}

Цифра 0 сообщает функции holdDraw, что действие производится с нулевой картой, для остальных четырех кнопок вместо нуля стоят числа от 1 до 4.
Хотя первый кадр ролика сразу же вызывает функцию startGame (см. раздел "Создание кода"), второй кадр должен вызывать функцию startDeal. Просмотрите ролик, приведенный в качестве примера, чтобы самостоятельно изучить, как это реализовано.



К сведению



К сведению

Основная временная шкала этого ролика - самая сложная из всех игр, рассмотренных в этой книге. Поэтому важно просмотреть ролик на Web-сайте, чтобы получить четкое представление о том, что и где расположено.
Также необходимо создать текстовые поля, в которых будут отображаться сумма очков игрока и раздающего, ставка, сумма наличных и результат.



К сведению



К сведению

Кнопка New на экране имеет простой сценарий и сначала вызывает clearGame, а потом startGame. Это перезапускает игру в любой удобный пользователю момент.

on (press) {

clearGame();

startGame();

}



Пасьянс "Пирамида"



Пасьянс "Пирамида"

Исходный файл:

Пасьянс "Пирамида" не так популярен, как обычный пасьянс, и не так сложен; однако, ему легко научиться и он очень затягивает. На Рисунок 15.7 . представлено начало игры.

Рисунок 15.7 В пасьянс "Пирамида" играют с помощью пирамиды из 28 карт и остальной колоды

Играть можно любой полностью открытой картой. Если часть карты закрыта другой картой пирамиды, играть этой картой можно только в том случае, если закрывающую ее карту удалить. Удалить карту игрок может только в том случае, если найдет подходящую ей другую карту, чтобы сумма их значений равнялась бы 13. Например, 10 и 3 или 6 и 7 могут составить пару. Туз имеет значение 1, валет значение 11, дама 12 и король 13. Это значит, что только король может быть выбран сам по себе, без второй карты.
Цель, естественно, в том, чтобы убрать из пирамиды все карты. Оставшиеся 24 карты колоды помешены под пирамидой, и за один ход можно перевернуть одну карту. Любая перевернутая карта может быть выбрана вместе с картой из пирамиды так, чтобы составить в сумме число 13.
Попробуйте поиграть в этот пасьянс. Вам придется отложить книгу, поскольку понадобится потратить какое-то время, чтобы окончить игру.



Подготовка ролика



Подготовка ролика

В этом ролике используются три ключевых библиотечных эталона, все остальное - элементы фона. Первый эталон - рычаг, в его первом кадре находится кнопка, по которой может щелкнуть игрок. Остальная часть клипа - анимация рычага, показывающая, как нажали рычаг.
Клип "spin" начинается с пустого кадра, где он "ждет", пока игрок не щелкнет по рычагу. Кадр прозрачный, так что сквозь него виден клип "symbols".
В остальных кадрах клипа "spin" находится размытая анимация. За изображениями, показанными на Рисунок 15.2, расположен белый непрозрачный фон, закрывающий клип "symbols" во время вращения колес.
В клипе "symbols" находятся семь кадров, во всех содержатся разные символы. В ролике Slotmachine.fla это изображения желудя, яблока, листа, бревна, луны, солнца и лисы.



Подготовка ролика



Подготовка ролика

Основной библиотечный элемент в данной игре - колода карт, то есть клип с 54 кадрами. Первый кадр отображает пустой контур карты. Во втором кадре содержится рубашка карты. Кадры 3-54 показывают различные карты колоды. Каждый кадр имеет такое же имя, какое используется в коде для идентификации карт. Например, "c1" - туз треф и "h11" -валет червей.
Просмотрите ролик Videopoker.fla и вы увидите, что для клипа "deck" выделена целая папка библиотеки, заполненная графическими изображениями. Это упрощает повторное использование элементов для разных карт.
Ролик составлен из пяти экземпляров клипа "deck" (колода), которые называются "card0", "card1", "card2", "card3" и "card4". В первом кадре
нужна только кнопка "Deal" (Раздать), которая отображается также и в третьем кадре.
Во втором кадре находится кнопка "Draw" (Выигрыш), а под каждой картой - кнопка "Hold/Replace" (Оставить/Поменять).



Подготовка ролика



Подготовка ролика

В отличие от видеопокера на руках может быть от двух до 11 карт. Для каждого расклада создаются 11 экземпляров клипов, имена которых изменяются от "player0" до "player10" и от "dealer0" до "dealer10". Кадры клипа "deck" - пусты. Следовательно, когда вы поместите клип на рабочее поле, вы не увидите ничего, кроме меток, которые устанавливаются программой Flash для клипов по умолчанию. На Рисунок 15.5 показаны все 22 метки.



Подготовка ролика



Подготовка ролика

Ролик содержит в библиотеке такой же клип "deck", как в игре "Двадцать одно". Ему необходимо присвоить имя в панели Linkage Properties,чтобы он экспортировался вместе с роликом. То же относится и к клипу "outline". ' В игре присутствует только два кадра: кадр "Play" и кадр "Game over". Последний будет использоваться только в редком случае выигрыша. Оба кадра должны содержать кнопку New, чтобы пересдавать карты в любой удобный игроку момент.



Подход



Подход

Единственной сложной частью кода в игре является вращение. Осуществить это можно следующим образом: сделать так, чтобы различные картинки прокручивались в окошке снизу вверх. Проблема заключается в том, что картинки должны вертеться так же быстро, как крутятся барабаны в реальном игровом автомате. На большинстве компьютеров программа Flash не может проигрывать ролик с такой скоростью. Вместо этого можно воспользоваться размытой анимацией вращения, которая представляет собой клип, состоящий из нескольких "размытых" кадров. На Рисунок 15.2 показаны несколько подобных кадров.



Подход



Подход

Первое, что необходимо программе, - это перетасованная колода карт, которая будет представлять собой массив с символьными данными, например "h7", что означает семерка червей. Четыре масти представлены буквами "с", "d", "h" и "s". Туз обозначен "1", то есть «c1" означает туз треф, а валет, дама и король обозначены цифрами "И", "12" и "13" соответственно.
Создать упорядоченную колоду карт просто, совсем другое дело - создание перетасованной колоды. Для этого вы берете упорядоченный массив и, выбирая из него случайным образом элементы, один за другим помешаете их в новый массив.
Затем первые пять карт в массиве отображаются на экране. Под каждой картой располагается кнопка. Один щелчок мыши по ней переворачивает карту, так что будет видна рубашка карты. Второй щелчок возвращает карту в исходное положение на тот случай, если игрок передумал.
Когда игрок будет удовлетворен своим выбором, он щелкает по кнопке Draw (Поменять). Те карты, которые были выбраны длят замены, замешаются следующими картами из перетасованной колоды.
Самый сложный фрагмент программного кода нужен для конечной фазы игры. Окончательный массив из пяти карт должен быль оценен с точки зрения покера. Вот список возможных вариантов:

• младшая пара - пара карт одного достоинства (десятка или ниже);

• старшая пара - пара валетов, дам, королей или тузов;

• тройка - три карты одного достоинства;

• стрит - пять карт, ранг каждой из которых на единицу превышает ранг предыдущей карты, например восьмерка, девятка, десятка, валет и дама. Туз может располагаться как перед двойкой, так и послекороля;

• флэш - пять карт одной масти;

• фул хаус - пара и три карты одного достоинства;

• каре - четыре карты одного достоинства;

• стрейт флэш - пять карт одной масти, ранг каждой из которых на единицу превышает ранг предыдущей карт;

• роял флэш - стрейт флэш с десяткой, валетом, дамой, королем и тузом.

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



Подход



Подход

Как и в видеопокере, здесь есть массив deck, в котором содержится перетасованная колода карт. Разница заключается в том, что в этой игре в массиве находятся шесть колод. В игре в очко такой массив называется shoe.
Как для игрока, так и для раздающего создается массив, в котором представлены карты, имеющиеся на руках. Вам нужно будет подумать насчет первой карты раздающего, так как она не должна быть видна до тех пор, пока игрок не закончит набирать карты.
В отличие от видеопокера оценка расклада в этой игре проста. Единственная сложность: туз может стоить как одно, так и 11 очков. Однако, так как два туза дадут 22 очка, второй туз никак не может стоить 11. То есть все, что нужно, - определить, есть ли на руках туз, подсчитать, что он равен единице, а затем добавить 10, если при этом на руках не будет перебора. Например, расклад с тройкой, девяткой и тузом рассматривается как 13 очков, потому что если считать, что туз стоит 11, то на руках окажется 23 очка, то есть перебор.



Подход



Подход

Мы используем такую же колоду, как и в игре "Двадцать одно". Игра начинается с тасовки карт и выстраивания пирамиды. Остальные карты помешаются стопкой мастью вниз внизу экрана. Игрок может щелкнуть, по верхней карте в стопке, и карта отобразится мастью вверх в соседней стопке карт, которая изначально была пустой. Каждый щелчок по стопке карт, лежащих мастью вниз, добавляет одну карту к стопке карт, лежащих мастью вверх.
Игрок может выбрать любую незакрытую карту из пирамиды или из стопки карт с открытой мастью. Выбранная карта выделяется рамкой.
Когда игрок щелкает по следующей карте, она сравнивается с первой, чтобы узнать, составит ли она с ней вместе 13 очков. Если да, обе карты удаляются. Если при этом одна из карт находится в стопке карт мастью вверх, то лежащая под ней карта открывается.
Определить, открыта ли какая-то карта в пирамиде, можно, пройдя циклом по всем картам в пирамиде и выясняя, присутствует ли на месте одна
из двух карт, которые должны закрывать данную. Например, вторая карта в третьем ряду должна быть закрыта второй и третьей картой в четвертом ряду. Если какая-нибудь из них на месте, карта не может быть выбрана. Когда карта удаляется из стопки открытых карт, становится видна предыдущая открытая карта. Это означает, что вам нужно следить за стопкой открытых карт, помещая их в массив, как только они оказываются перевернутыми.
Особым случаем является король. Выбранный король немедленно удаляется как из колоды карт с открытой мастью, так и из пирамиды, если, конечно, выбранный король был открыт.



Простой игровой автомат с рычагом и тремя окошками



Рисунок 15.1 Простой игровой автомат с рычагом и тремя окошками


выигрыша, этот предельно прост. Игрок щелкает по рычагу, чтобы привести его в действие. Затем барабаны в трех окнах начинают крутиться. Один за другим они будут останавливаться, показывая произвольный элемент (картинку).
Когда все три барабана останавливаются, картинки, оказавшиеся в них, и определяют результат. Выигрыш соответствует тем суммам, которые показаны внизу игрового автомата (см. Рисунок 15.1).



Расклад, когда раздающий выиграл, так как у него 21, а у игрока только 18 очков



Рисунок 15.4 Расклад, когда раздающий выиграл, так как у него 21, а у игрока только 18 очков


Если с первыми двумя картами у игрока 21 очко, он сразу же выигрывает и получает дополнительно 50% суммы выигрыша. Если у раздающего получается 21, игра сразу же приостанавливается. Если же так не случилось, то выигрывает тот, у кого на руках большее количество очков, не превышающее 21.
Игрок может контролировать свои ставки (от 5 до 25 долларов), каждый раз повышая ставку на пять долларов.



Создание кода



Создание кода

Большая часть кода для этой игры находится в основной временной шкале. Однако сначала разберем те фрагменты кода, которые относятся к клипам.
В ролике Slotmachine.fla под клипом с рычагом размещена кнопка. К ней прикреплен простой сценарий, который вызывает функцию pull, находящуюся в основной временной шкале.

on (release) {
pull();
}

В клипе "spin" содержатся два небольших сценария. Команда stop () находится в первом .кадре. Сценарий, который уменьшает значение счетчика numTimes на единицу, располагается в последнем кадре. Если значение счетчика равно нулю, сценарий переходит к первому кадру ролика и сообщает об этом функции в основной временной шкале. В противном случае клип снова возвращается ко второму кадру.

numTimes--;

if (numTimes

gotoAndStop(l);

_root.spinDone(_name);

} else {

gotoAndPlay(2); }

Большой фрагмент программы в основной временной шкале определяет, сколько денег выиграл пользователь, если выиграл вообще. Программа начинается с того, что случайным образом выбирает кадр для трех символов и предоставляет игроку $100, на которые он может играть в этой виртуальной игре.

initGame() ;

stop();

function initGame() {

// Случайным образом выбираем кадры для трех символов,

for (i=l;i

_root["symbol"+i].gotoAndStop(randomSymbol());

}

// Начинаем со $100.

cash = 100;

showCash();

}

Вместо того чтобы отображать сумму, имеющуюся у игрока, просто цифрами, следующая функция помещает перед ней знак доллара и добавляет переменную cash в displayCash. Эта переменная связана с текстовым полем на рабочем поле.

// Отображаем сумму в долларах,
function showCash() {

cashDisplay.= "$"+cash;

}

Когда игрок щелкает по рычагу, происходит несколько событий. Сначала из суммы наличных денег игрока вычитается $1. Затем клип "arm' переходит ко второму кадру, то есть показывается, что рычаг переходит в нижнее положение. Затем все три клипа "spin" начинают проигрываться. Каждому клипу сообщаются различные значения переменной numTimes - 8,6 и 4 - то есть первая анимация будет проигрываться восемь раз, вторая - шесть и третья - четыре. Также здесь определяется результат каждого вращения, устанавливаются клипы "symbol", хотя они скрыты за непрозрачными анимациями "spin" до тех пор, пока эти анимации не будут проиграны.




// Рычаг переходит в нижнее положение,

function pull(); {

// Когда рычаг приводится в действие,
// каждый раз вычитаем один доллар.
cash--;

showCash() ;

// Воспроизводим анимацию рычага.

_root["arm"].gotoAndPlay(2);

// Воспроизводим анимацию вращения,

for (i=l; i

// Сообщаем, сколько раз нужно вращать барабан.

_root["spin"+i].numTimes = 8-i*2;

_root["spin"+i].gotoAndPlay(2); }

// Выбираем результат для каждого символа случайным образом.

for (i=l; i

_root["symbol"+i].gotoAndStop(randomSymbol());
}}

Запрограммировать случайный выбор символа непросто. Если вероятность выбора каждого из семи символов одинакова, тогда вероятность Я вывода трех совпадений одинакова для любого символа. Другими словами, три изображения желудя появляются так же часто, как и три изображения лисы. То есть не имеет смысла выплачивать различные суммы за совпадения различных картинок.

У реальных игровых автоматов необычайно сложный метод выбора символов, которые появятся в окошках. В таком методе используются сложные математические формулы, так что казино может точно рассчитать вероятность выигрыша.

Но вероятность появления одного символа должна отличаться от вероятности появления другого символа. Например, символ с бревном появляется в 29% случаев. С другой стороны, символ лисы появляется только в 3% случаев.
Это осуществляется с помощью массива, куда записывается вероятность появления того или иного символа. Затем произвольным образом выбирается число из этого массива. Если оно попадает в диапазон между нулем и вероятностью появления первого символа, выбирается первый символ. В противном случае программа переходит к следующему числу в массиве. Так происходит до тех пор, пока какой-нибудь символ не будет выбран. Просмотрите следующий код, чтобы увидеть, как работает эта схема.

// Выбираем произвольный символ в зависимости

//от вероятности его появления.

function randomSymbol() {

// Задаем вероятность появления каждого символа.

chances = [29,21,16,12,9,7,6];



// Определяем сумму вероятностей.

totalChances = 0;

for (j=0; j

totalChances += chances[j];

// Выбираем случайное число.

г = int(Math.random()*totalChances);

// Определяем, какой символ это число представляет,
for (j=0; j< chances.length; j++) {

if (r < chances[j]) {

return!j+1);

} else {

r -= chances[ j ] ;
}}}

Когда анимация клипа "spin" завершается, вызывается функция spinDone, которой передается имя экземпляра клипа. Клип "spin1" представляет собой последнюю анимацию в последовательности. Когда эта анимация закончена (то есть все три барабана прекратили вращаться), вызывается функция calcwin, чтобы определить сумму выигрыша.

// Вызываем функцию после каждой анимации вращения,

function spinDone(name) {

// Определяем, последний ли это символ,

// остановились ли барабаны.
if (name == "spinl") {

// Подсчитываем сумму выигрыша,

win = calcWin();

cash += win;
showCash() ;
}}

функция calcWin определяет, совпадают ли три символа, а также подсчитывает число изображений с желудем в последовательности. Если все три символа совпадают, сумма выигрыша определяется тем, какой это символ. В противном случае игрок все равно может выиграть небольшую сумму денег, если в последовательности находятся одно или два изображения желудя.

// Определяем сумму выигрыша,

function calcWin() {

// Выясняем, сколько выпало изображений с желудем

numAcorns = 0;

for (i=l; i

if (_root["symbol"+i]._currentFrame == 2)
numAcorns++;

// Проверяем, совпадают ли три символа.

firstSymbol = _root["symboll"]._currentFrame;

threeOfAkind = true;

for(i=2; i

if (_root["symbol"+i]._currentFrame != firstSymbol)
threeOfAKind= false;

// Определяем сумму выигрыша в соответствии с типом символа.

if (threeOfAKind) {

if (firstSymbol == 1) {

win = 20;

} else

if (firstSymbol == 2) {

win = 10;

} else if (firstSymbol ==3) {

win = 30;

} else if (firstSymbol == 4) {

win = 50;

} else if (firstSymbol == 5) {

win = 80;

} else if (firstSymbol == 6) {

win = 100;

} else if (firstSymbol == 7) {

win = 1000;

// Два изображения желудя.

} else if (numAcorns ==2) {

win = 2;

// Один желудь.

} else if (numAcorns ==1) {

win = 1;

// Изображений желудя нет.

} else {

win = 0;

return(win);}


Создание кода



Создание кода

Большая часть кода содержится в первом кадре основной временной шкалы. Начинается она с того, что игроку предоставляется 100 долларов.

startGame();

stop () ;

// "Выдаем" исходную сумму,

function startGame() {

cash = 100;
}

Как и в предыдущем проекте, перед суммой наличных денег игрока отобразите знак "$".

// Отображаем сумму наличных со знаком доллара,

function showCash() {

cashDisplay = "$"+cash;

}

Раздача карт начинается с того, что у игрока изымается один доллар. Каждая раздача производится из новой колоды, состоящей из 52 карт. Функция f irstDraw берет первые пять карт, а функция showCards помешает клипы соответствующих карт на рабочее поле.

// Сдача карты,

function startDeal() {

// Уменьшаем сумму наличных денег.

cash--;

showCash();

// Перетасовываем карты и снова сдаем их.

createDeck();

f irstDraw();

showCards(); }

Создание полностью произвольной перетасованной колоды включает в себя два шага. Первый - создание упорядоченной колоды. Это осуществляется путем циклического просмотра всех мастей и всех рангов карт и для каждой комбинации добавляется соответствующий элемент массива.
Затем программа случайным образом выбирает карты из упорядоченной колоды и помещает их в другой массив. Когда массив заполняется, а предыдущий массив оказывается пустым, у вас получается перетасованная колода карт.

// Создаем перетасованную колоду,

function createDeckO {

// Создаем упорядоченную колоду,

suits = ["с","d","s","h"];

temp = new Array();

for(suit=0; suit

for (num=l; num

temp.push(suits[suit]+num);

}

// Случайным образом выбираем карты,

// пока колода не будет полностью перетасована.

deck = new Array();

while (temp.length > 0) {

r = int(Math.random()*temp.length),

deck.push(temp[r]);

temp.splice(r,1); }

Функция firstDraw берет пять карт из колоды и помешает их в массив cards, а также создает небольшой массив hold, в котором хранятся имена тех карт, которые игрок хочет оставить.




// Сдаем первые пять карт.

function firstDraw() {

cards = new Array();

for (i=0; i

cards.push(deck.pop());

}

// Допускаем, что игрок оставляет все карты,

hold = [true, true, true, true, true];

showCards();
}

Для того чтобы преобразовать содержимое массива cards в то, что игрок видит на экране, функция showCards на рабочем поле устанавливает кадры для каждого из пяти экземпляров клипа. Кадры должны соответствовать символьной строке, расположенной в массиве hand.

// Определяем вид клипов карт, сданных игроку. function showCards() {

for (i=0; i

_root["card"+i].gotoAndStop(cards[i]) ;

}}

После того как все карты будут показаны игроку, он должен решить, что делать дальше. Кнопка "Hold/Draw" под каждой картой вызывает функцию holdDraw и передает ей число от 0 до 4.
Первый раз, когда щелкают по кнопке, программа изменяет экземпляр клипа так, что отображается рубашка карты. Если игрок щелкает по ней еще раз, карта возвращается в исходное состояние. Игрок может сколько угодно переворачивать карты, прежде чем щелкнуть по кнопке Draw.
В массиве hold будет находиться значение true, если игрок хочет оставить соответствующую карту, и false, если хочет ее заменить.

// Переворачиваем карту, предназначенную для замены,

function holdDraw(cardNum) {

// Переворачиваем карту, которая находится среди тех,
// которые игрок хочет оставить,

if (hold[cardNum]) {

_root["card"+cardNum].gotoAndStop("back");

hold[cardNum] = false;

// Если карта перевернута еще раз, оставляем ее.

} else {

_root["card"+cardNum].gotoAndStop(cards[cardNum]);

hold[cardNum] = true;

}}

Когда игрок щелкает по кнопке "Draw", функция secondDraw заменяет те карты, для которых в массиве hold значения были равны false. Затем вызывается функция showCards, чтобы изменения были отражены на экране.
Затем программа с помощью функции handvalue определяет, какой расклад имеется у игрока. Ценность расклада передается функции winning, которая рассчитывает, какую сумму следует добавить к величине cash (сумме наличных). Переменная resultsDisplay используется для отображения этих значений на экране.



// Заменяем карты и определяем выигрыш,

function secondDraw() {

// Заменяем карты, for (i=0; i

if (!hold[i]> { cards[i] = deck.pop();

showCards();

// Определяем, что на руках у игрока.

handVal = handValue(cards);

// Расчитываем сумму выигрыша.

winAmt = winning(handVal);

resultsDisplay = handVal + ": " + winAmt;

// Добавляем сумму выигрыша к имеющейся сумме наличных,

cash += winAmt;

showCash();

gotoAndPlay("done");

}

Прежде чем перейти к рассмотрению функции handvalue, необходимо создать функцию compareHands. Функция handvalue сортирует карты на руках у игрока по возрастанию. Программа Flash ничего не знает о колоде игральных карт, так что вам придется "научить" ее распознавать сочетания покера.
Функция compareHands берет две карты и сравнивает их. Для каждой карты из символьной строки она выбирает первый и второй символы, то есть игнорирует нулевой символ. Таким образом, карта "с7" становится "7", а "с13" - "13".
Затем функция возвращает один из трех вариантов ответов: -1 - первая карта меньше по достоинству второй карты, 0 - карты одинакового достоинства, и 1 - ранг первой карты на единицу больше ранга второй.
Эта функция необходима для команды sort, использующейся в функции handvalue. Если для сортировки не будет специальной функции, программа попытается отсортировать массив hand по алфавиту, то есть все трефы будут расположены перед бубнами, так как трефовая масть начинается с буквы "с", а бубновая - с "d". А вам нужно, чтобы карты были отсортированы в соответствии с их рангом.

// Эта функция используется командой сортировки для определения,
// какие карты идут первыми,

function compareHands(a,b) {

// Получаем ранг карты.

numa = Number(a.substr(1,2));

numb = Number (b. subs t r (1,2) ) ;

// Возвращаем -1, 0 или 1 в зависимости

//от результата сравнения,

if (numa < numb) return(-1);

if (numa == numb) return(O);

if (numa > numb) return(1);}



Следующая функция handvalue начинается с того, что копирует массив cards и помешает его в массив hand. Затем она сортирует полученный массив с использованием функции compareHands (1).
Например, если на руках у игрока имеются карты ["h4", "d5", "c2", "s3", "h6"], после сортировки массив будет выглядеть следующим образом: ["с2", "s3", "h4", "d5", "h6"]. Так гораздо проще узнать, находится ли на руках у игрока "стрит".
"Стрит" определяется путем просмотра каждой карты и выяснением, больше ли ранг этой карты на единицу ранга карты предыдущей (2). Если такое условие выполняется для всего массива, то тогда на руках у игрока "стрит".
Таким образом будет определен не только "стрит": когда "стрит" начинается с десятки и заканчивается тузом, то это "флэш стрит". Произошло ли так или нет, можно определить с помощью простого теста (3).
Затем вы проверяете, одной ли масти карты (4). Для этого все карты, кроме первой, сравниваются с первой. Если масть всех карт совпадает с мастью первой карты, значит, все карты одной масти.
На следующем шаге создается массив counts, в котором будет храниться число карт одинакового достоинства (5). В этом массиве находится 14 элементов, каждый из которых будет отвечать за число карт определенного ранга, имеющихся у ифока. Первый элемент массива не используется, так как нет карт с нулевым рангом.

Некоторые люди думают, что стритом можно считать и такой набор карт, в котором задействован туз. Например, дама, король, туз, двойка и тройка. Это не стрит, а всего лишь его дополнительная вариация, используемая в любительских играх в покер. Туз может быть использован и как первая карта стрита (туз, двойка, тройка, четверка, пятерка), и как последняя (десять, валет, дама, король, туз), но только не в середине.

Например, если на руках туз, две тройки, четверка и валет, массив будет выглялеть следующим образом: [0,1,0,2,1,0,0,0,0,0,0,1,0,0].
Теперь, наконец, программа может начать определение расклада на руках у игрока. Просматривается массив counts и отмечаются все значения пары, тройки или четверки (6). Если один раз встречаются две карты одного достоинства, то у игрока пара. Если один раз встречается три карты одного достоинства, то у игрока тройка; если один раз встречается четыре карты одного достоинства, то - каре. Также можно дважды обнаружить две карты одного достоинства или пару и тройку. В первом случае будет две пары, а втором - фул хаус.
Затем проверяется, есть ли на руках пары с валетом или картами высшего достоинства (7). Обычно видеопокер отмечает только такие пары.
Следующий тест проверяет, есть ли в раскладе туз (8). Это будет нужно для определения флэш стрита. Если у ифока флэш стрит, и одна из карт - туз, то у него самый высший тип флэш стрита - флэш роял.
Теперь у функции есть весь набор значений логических переменных: straight, flush, hasAce, fourOfAKind, threeOfAKind, twoPair, pair, fullHouse и jackOrHigher. С их помощью определяется действительная ценность расклада, и возвращается символьная строка (9).



// Определяем расклад,

function handValue() {

// Копируем и сортируем карты игрока.

hand = cards.slice();

(1) hand, sort (compareHands) ;

// Создаем массив мастей и рангов для более легкого доступа

//к ним.

suits = new Array();

nums = new Array();

for (i=0; i

suits.push(hand[i].substr(0,1));

nums.push(Number(hand[i].substr(1,2)));

(2)// Проверяем, расположены ли они по возрастанию,

straight = true;

for (i=0; i

if (nums[i]+l != num[i+l]) straight = false;

(3)// Ищем десятку, валета, даму, короля и туза,

if (nums[0] == 1) and (nums[l] == 10) and (nums[2]) == 11)

and (nums[3] == 12) and (nums[4] == 13)) straight = true;

(4)// Выясняем, одной ли масти карты,

flush = true;

for (i=l; i

if (suits[i] != suitstO]) flush = false;

// Создаем массив для подсчета, сколько карт одного

(5)// достоинства находится в раскладе,

counts = new Array ();

for (i=0; i

for (i=0; i

(6)// Используя массив counts, ищем совпадения,

pair = false;

twoPair = false;

threeOfAKind = false;

fourOfAKind = false;

for (i=l; i

// Найдена пара.

if (counts[i] == 2) {

// Найдена вторая пара.

if (pair) {

twoPair = true;

// Найдена только одна пара.

} else {

pair = true;

// Три карты одного достоинства.

} else if (counts[i] == 3) {

threeOfAKind .= true;

// Четыре карты одного достоинства.

} else if (countsfi] == 4) {

fourOfAKind = true;

// Проверяем, есть ли среди совпадающих карт валеты или

(7)// карты более высокого ранга.

jackOrHigher = false;

for (i=l; i

if (((i==l) or (i>10) and (counts[i]>=2)) {

jackOtHigher = true;

(8) // Выясняем, является ли карта более высокого ранга тузом.

hasAce = false; if (counts[1] > 0) hasAce = true;

(9)// Делаем вывод, какой расклад на руках у игрока.
if (straight and flush and hasAce) {

return("Royal Flush");

} else if (straight and flush) {

return("Straight Flush");

} else if (fourOfAKind) {

return("Four-Of-A-Kind");

} else if (pair and threeOfAKind) {

return ("Full House");



} else if (flush) {

return("Flush");

} else if (straight) {

return("Straight");

} else if (threeOfAKind) {

return("Three-Of-A-Kind");

} else if (twoPair) {

return("Two Pair");

} else if (pair and jaskOrHigher) {

return!"High Pair"); } else if (pair) {

return("Low Pair");

} else {

return("Nothing");

И последняя оставшаяся функция - winning, которой передается строчка, сгенерированная функцией handvalue и которая определяет соответствующую сумму выигрыша.

//Исходя из типа расклада возвращаем сумму выиграша

function winnings(handVal) {

if (handVal == "Royal Flush") return(800);

if (handVal == "Straight Flush") return(50);

if (handVal == "Four-Of-A-Kind") return(25);

if (handVal == "Full House") return(8);

if (handVal == "Flush") return(5);

if (handVal == "Straight") return(4);

if (handVal == "Three-Of-A-Kind") return(3);

if (handVal == "Two Pair") return(2);

if (handVal == "High Pair") return(1);

if (handVal == "Low Pair") return(0);

if (handVal == "Nothing") return(0);

}


Создание кода



Создание кода

Первый кадр вызывает функцию initGame , но после нее не идет команда stop (), так как указатель должен двигаться и перейти к кадру "shuffle".

initGame();

Функция initGame определяет исходную сумму наличных денег игрока.

function initGame() {

cash = 100;

showCash();

}

Функция createDeck похожа на одноименную функцию, используемую в видеопокере, но здесь она шесть раз добавляет каждую карту, чтобы создать шесть колод карт.
Один из недостатков использования шести колод состоит в том, что программе требуется время для, их перетасовки. Следовательно, кадр "shuffle" появляется перед ключевым кадром, вызывающим функцию createDeck. Поэтому слово "shuffle" (Идет перетасовка колоды) появится на экране прежде, чем код начнет тасовать карты. Следовательно, игрок не должен удивляться, почему его компьютер вдруг "завис".

// Создаем перетасованную колоду карт,

function createDeck() {

// Создаем упорядоченную колоду.

suits = ["с", "d", "s", "h"];

temp = new Array();

for (i=0; i

for (suit=0; suit

for (num=1; num temp.push(suits[suit]+num);

}}}

// Карты выбираются случайным образом до тех пор, пока

// колода не будет перемешана,
deck = new Array();

while (temp.length>0) {

r = int(Math.random()*temp.length) ;

deck.push(temp[r]);

temp.splice(r,1);

}}

В функции initHand создаются массивы playerHand и dealerHand. Переменной showDealerFirstCard присваивается значение false, по умолчанию делается ставка в пять долларов.

// Инициализируем массивов расклада и определяем сумму ставки,

function initHand() {

playerHand = new Array();

dealerHand = new Array();

showDealerFirstCard = false;

bet = 5;

showBet();

}

Когда игрок щелкает по кнопке Add to bet (Повысить ставку), вызывав функция addToBet, которая повышает ставку на пять долларов и не позволяет сделать ставку, превышающую 25 долларов.

// Функция увеличивает ставку игрока вплоть до 25 долларов,

function addToBet() {




bet += 5;

if (bet > 25) bet = 25;

showBet;

}

Когда игрок щелкает по кнопке Deal (Раздать), вызывается функция makeBet, которая вычитает сумму ставки из суммы наличных игрока, Затем ролик проходит по четырем кадрам от "Deal1" до "Deal4".

// Вычитаем сумму ставки из суммы наличных денег игрока.

function makeBet() {

cash -= bet;

showCash();
}

В каждом из четырех кадров вызывается функция dealCard, дважды с использованием массива playerHand и дважды - dealerHand. При выполнении этой функции по две карты раздаются игроку и раздающему. Также в каждом кадре вызывается функция showCards.

// Раздаем игроку одну карту из колоды.

function dealCard(hand) {

hand.push(deck.pop());

}

Функции showBet и showCash отображают текущую ставку и текущую сумму наличных с добавлением знака "$" впереди. Не забудьте создать, соответствующие текстовые поля для каждой из этих сумм.

// Отображаем сумму наличности со знаком "$".

function showCash() {

cashDisplay = "$" + cash;

}

// Отображаем сумму ставки со знаком "$".
function showBet() {

betDisplay = "$" + bet;

}

Функция showCards просматривает карты, имеющиеся на руках у игрока и раздающего, и помещает соответствующие клипы на рабочее поле. С помощью переменной showDealerFirstCard указывается, отображается ли первая карта раздающего или показывается всего лишь рубашка карты.

// Отображаем карты на руках у игрока и раздающего,

function showCards() {

// Отображаем первую карту раздающего, когда игроку

// все карты розданы.

if (showDealerFirstCard) {

_root["dealerO"].gotoAndStop(dealerHand[0]);

} else {

_root[“dealer0"].gotoAndStop(2);

}

// Показываем остальные карты раздающего,

for (i=1; i

_root["dealer"+i].gotoAndStop(dealerHand[i]);

}

// Показываем все карты игрока,

for (i=0; i

_root["player"+i].gotoAndStop(playerHand[i]);

}

// Отображаем сумму карт на руках.

playerValue = handValue(playerHand);



dealerValue = handValue(dealerHand);

}

После того как были розданы первые две карты, существует вероятность того, что у кого-то уже двадцать одно очко. Если у игрока, то он сразу же выигрывает, сумма выигрыша составляет 150% от ставки. Если же у раздающего, то игрок проигрывает.

// Проверяем, есть ли 21 очко,

function checkForBlackjack() {

// Если двадцать одно у игрока,

// выигрыш составляет 150% ставки.

if (playerHand.length == 2) and (playerValue == 21)) {

cash += bet*2.5;

showCash();

result = "Blackjack!";

gotoAndPlay("Done");

// Если у раздающего двадцать одно, игрок проиграл.

} else if ((dealeerHand.length == 2) and (dealerHand == 21)) {

result = "Dealer has blackjack!";

gotoAndPlay("Done");
}}

После того как были розданы первые четыре карты, ролик переходит в режим ожидания, к кадру "Player". В этом кадре находятся две кнопки: «Hit” (Еще) и "Stay" (Хватит). Игрок может щелкнуть по кнопке Hit" и запросить еще одну карту, при этом вызывается функция hit. Если с новой картой у игрока 21 очко или больше, игра автоматически переходит дальше к кадру выигрыша или проигрыша соответственно.

// Игрок берет еще одну карту.

function hit() {

dealCard(playeerHand);

showCards();

playerValue = handValue(playerHand);

// Если у игрока 21 очко или больше, выясняем,

// сколько очков у раздающего.

if (playerValue >= 21) startDealer();
}

Когда игрок закончит набирать карты, очередь переходит к раздающему. Функция startDealer начинается с того, что переменной showDealerFirstCard присваивается значение true. Когда снова вызывается функция showCards, отображается первая карта раздающего. Затем игра переходит к кадру "Dealer".

// Отображаем первую карту раздающего,

// теперь он может набирать себе карты.

function startDealer() {

showDealerFirstCard = true;

showCards(0);

gotoAndPlay("Dealer");

}

Кадр "Dealer" проигрывается снова и снова, каждый раз вызывается функция dealerMove, проверяется сумма очков раздающего, больше ли она 17 или нет. Правилами казино определено, что раздающий берет еще одну карту до тех пор, пока сумма очков не превысила 16. Когда раздающий закончил набирать карты, вызывается функция decideWinner.



// Раздающий берет еще одну карту до тех пор,

// пока сумма очков меньше 17.

function dealerMove() {

if (handValue(dealerHand) < 17) {

dealCard(dealerHand);

shoCards();

gotoAndPlay("Dealer");

// Раздающий закончил набирать карты.

} else {

decidewinner();

}}

Функция handValue используется во многих ранее рассмотренных функциях для того, чтобы определить сумму очков на руках. Ранг каждой карты добавляется к сумме очков, при этом туз равен одному очку. Если на руках находится туз и добавление 10 очков не приведет к перебору, тогда к обшей сумме прибавляется 10 очков.

// Подсчитываем очки,

function handValue(hand) {

total = 0;

асе = false;

for (i=0; i

// Добавляем ранг карты.

val = Number(hand[i].substr(1,2));

11 За валета, даму и короля начисляем 10 очков,
if (val > 10) val = 10;

total += val;

// Запоминаем, если был найден туз.

if (val == 1) асе = true;

}

// Туз может стоить 11 очков, если у игрока не будет перебора.

if ((асе) and (total

return(total);
}

С помощью набора правил, следующая функция определяет победителя. В случае выигрыша игрока не только корректируется сумма наличных, но и определяется значение переменной result, которая затем отображается на рабочем поле в кадре с меткой "Done".

// Определяем победителя или случай игры в ничью,

function decideWinner() {

showCash();

if (playerValue > 21) {

result = "You Busted!";

} else if (dealerValue > 21) {

cash += bet*2;

result = "Dealer Busts. You Win!";

} else if (dealerValue > playerValue) {

result = "You Lose!";

} else if (dealerValue == playerValue) {

cash += bet;

result = "Tie!";

} else if (dealerValue < playerValue) {

cash += bet*2;

result = "You Win!";

}

showCash(); gotoAndPlay("Done");

}

В кадре Done находится кнопка Next Hand (Сыграть еще раз), которая вызывает следующую функцию, проверяющую, осталось ли в колоде 26 карт. Если в колоде карт меньше, заново создается перетасованная колода. Если осталось достаточное количество карт, вызывается функция initHand, и игра возвращается к кадру "Bet". В любом случае вызывается функция resetCards, которая устанавливает все находящиеся на рабочем поле клипы "deck" в первый кадр, благодаря чему карты не остаются на экране.

// Начинаем следующую раздачи карт.

function newDeaK) { resetCards();

// Если в колоде менее 26 карт,

// Создаем новую перетасованную колоду,

if (deck.length < 26) {

gotoAndPlay("shuffle");

} else {

initHand();

gotoAndPlay("Bet");

}}

// Удаляем карты со стола.

function resetCards() {

for (i=0; i

_root["dealer"+i.gotoAndStop(1);

} for (i=0; i

_root t"player"+i].gotoAndStop(1);

}}


Создание кода



Создание кода

Практически весь код находится в главной временной шкале. Он начинается с функции "startGame". После того как создана новая, перетасованная, колода, создается семь рядов карт (10). Первый ряд содержит» одну карту, второй - две и т.д.
Каждая карта помешается на свое место в соответствии с рядом и местом в ряду (11). К тому же масштаб каждой карты уменьшен на 50%, поскольку колода, использованная в игре "Двадцать одно", в два раза больше по размеру той, что необходима для этой игры (12).
Значение карты берется из массива deck (13). Оно соответствует метке кадра внутри клипа "deck". Это значение сохраняется в свойстве value клипа, после чего клип отправляется в соответствующий кадр. В свойствах клипа row и col хранится позиция клипа в пирамиде (14).
Затем вы создаете клипы для стопок карт мастью вниз и мастью вверх (15). Клип для карт мастью вниз отправляется в кадр "back", показывающий изображение рубашки карты. Другая стопка остается в первом кадре, который пуст.
Переменная firstcard установлена как undefined (16). Эта переменная содержит значение первой карты в паре, выбираемой самим игроком. Массив stack используется для слежения за судьбой карт из стопки мастью вверх. В случае, когда карта из этой стопки используется, должно быть отыскано значение предыдущей выбранной карты.
В заключение должен быть создан экземпляр клипа рамки (17). В начальный момент он помешается за пределами видимости.

startGame();

stop();

function startGame() {

// Тасуем колоду.

createDeck();

(10)// Выстраиваем карты в пирамиду,

level = 0;

for(row=0;row

for(i=0;i

// Создаем новый клип.

mc = _root.attachMovie("Deck","card"+level,level);

(11)// Задаем его расположение.

mc._x = i*60-row*30 + 275;

mc. _у = row*30 + 50;

(12)// Задаем масштаб.

mc._xscale = 50;

mc.__yscale = 50;

(13)// Устанавливаем знчение карты,

mc. value = deck.pop();

mc.gotoAndStop(mc.value);

(14)// Запоминаем позицию карты,

mc.row = row;




mc.col = i;

level++;
}}

(15)// Размещаем клипы открытой и закрытой колод,

for(i = 0 ; i

me = _root.attachMovie("Deck","stack"+i,level)

mc._x = i*60+100;

mc._y = 340;

mc._xscale =50;

mc._yscale = 50;

level++;}

// Показываем "рубашку" для закрытой колоды.

_root["stackO"].gotoAndStop("back");

(16) // Задаем значение первой выбранной карты и массив для

// открытой колоды.

firstCard = undefined;

stack = new Array();

(17) // Создаем и размещаем рамку.

outline = _root.attachMovie("outline","outline",1000);

outline._xscale = 50;

outline._yscale = 50;

outline._x = -1000;

}

Функция createDeck такая же, как в игре "Двадцать одно". Однако теперь вы сортируете только одну колоду. Результат представляется в виде глобальной переменной deck.

// Создаем перетасованную колоду.

function createDeck() {

// Создаем упорядоченную колоду.
suits = ["с","d","s","h"];

temp = new Array();

for(suit=0;suit

for(num=l;num

temp.pushfsuits[suit]+num);

}}

// Выбираем случайные карты, пока не создадим перетасованную

// колоду.

deck = new Array();

while (temp.length > 0) {

r = int(Math.random()*temp.length);

deck.push(tempt[r]);

temp.splice(r, 1) ;
}}

Вместо того, чтобы использовать сценарий клипа или кнопку для обнаружения щелчков мыши, я определю функцию для обработки события onMouseDown.
Сначала она совершает цикл по всем картам в пирамиде и определяет, не совершен ли щелчок по одной из них. (18). Цикл начинается с 28 и совершает обратный отсчет. Таким образом, карты наверху рассматриваются сначала, а карты внизу - потом.
Далее мы проверяем, если по карте был совершен щелчок, то программа определяет, закрывают ли данную карту другие карты пирамиды (19). Для этого вызывается функция cardPresent вместе со значениями ряда и колонки двух карт, которые могли бы закрывать карту, по которой был совершен щелчок.
Если локальная переменная card все еще не определена, значит, ни одна карта не была выбрана. Нужно еще проверить, не выбрал ли игрок карту из стопки карт с открытой мастью. Эту колоду представляет клип "stack1" (20).
Если карта была выбрана, а глобальная переменная firstcard все еще не определена, значит, не выбрана никакая другая карта. Ссылка на выбранную карту помещается в firstcard (21).
Если другая карта уже выбрана, значения старой и новой карт складываются. Функция cardValue используется для хранения численных значений карт (22). Если сумма равна 13, обе карты удаляются при помощи функции removeCard.
Если, с другой стороны, значение firstcard равно 13, значит, это король, и он может быть удален сам по себе (23).
Если по клипу "stack0" был совершен щелчок, это значит, что игрок решил перенести карту из закрытой колоды в открытую. В этом случае берется последнее значение в массиве deck и используется для изменения кадра клипа "stack1" (24). Массив stack используется для отслеживания карт, которые перемешаются между стопками. Чтобы выделить выбранную карту, клип "outline" перемешается в то же положение, что и выбранная карта (25).
И наконец, проверяется первая карта пирамиды (26). Если она отсутствует, значит, игрок ее удалил и выиграл игру.



_root.onMouseDown = function() {

var card = undefined;

(18) // Смотрим, был ли щелчок по одной из карт пирамиды.

for(var i=27;i>=0;i--) {

if (_root["card"+i].hitTest(_xmouse,_ymouse)) {

var card = _root["card"+i];

break;

}}

(19)// Если был, закрывают ли эту карту другие карты?

if (card != undefined) {

if (cardPresent(card.row+l,card.col) or cardPresent(card.row+1,card.col+l)) {

card = undefined;

}}

(20)// Был ли щелчок по стопке карт, лежащих мастью вверх?

if (card == undefined) {

if (stackl.hitTest(_xmouse,_ymouse)) {

card = stack1;

}}

// Проверяем, выбрана ли еще одна карта,

if (card != undefined) {

(21)// Первая выбранная карта,

if (firstCard == undefined) {

firstCard = card;

// Игнорируем второй щелчок по той же карте.

} else if (firstCard == card) {

(22)// Если выбраны две карты и их сумма равна 13.

} else if (cardValueffirstCard) + cardValue(card) == 13) {

// Удаляем обе карты.

removeCard(card);

removeCard(firstCard);

firstCard = undefined;

// В противном случае считаем, что это первая выбранная

// карта.

} else {

firstCard = card;

}}

(23)// Если выбрана одна карта, и это "король"

if (cardValueffirstCard) ==13) {

removeCardffirstcard);

firstCard = undefined;

}}

(24)// Если щелкнули по колоде закрытых карт, переворачиваем

// очередную карту.

if (stackO.hitTest(_xmouse,_ymouse)) {

stackl.value = deck.pop();

stackl.gotoAndStop(stackl.value);

stack.push(stackl.value);

// Когда закрытая колода кончается, удаляем ее.

if (deck.length == 0) {

stackO.removeMovieClip();

}}

(25)// Помещаем рамку около выделенной карты,

if (firstCard != undefined) {

outline._x = firstCard._x;

outline._y = firstCard._y;

} else {

outline._x = -1000;}

(26)// Если удалена первая карта в пирамиде, значит игрок

// выиграл.

if (_root["card0"] == undefined) {

gotoAndStop("game over");

}}

Осталось рассмотреть несколько полезных функций. Первая, removeCard, удаляет карту из колоды открытых карт или из пирамиды. Чтобы удалить карту из открытой колоды , она должна просто отправить клип "stack1" к кадру, который представляет предыдущую карту. Именно в этом месте оказывается полезным массив stack. Каждая карта, положенная мастью вверх, добавляется к stack. Чтобы достать карту опять, вам нужно удалить последнюю карту из массива stack и затем обратиться к последнему члену этого массива. Если карта оказалась из пирамиды, то клип просто удаляется.



function rernoveCard(thisCard) {

if (thisCard == stackl) {

// Удаляем карту из открытой колоды,

stack1.gotoAndStop(1);

stack.pop();

stackl.value = stack[stack.length-l];

stack1.gotoAndStop(stackl.value);

} else {

// Удаляем карту из пирамиды.

thisCard.removeMovieClip();
}}

Следующая функция, cardPresent, проверяет в цикле все карты, чтобы определить, существует ли карта в позиции, определенной аргументам вызова данной функции.

function cardPresent(row, col) {

// Проверяем, существует ли в пирамиде данная карта.

for(var i=0;i

thisCard = _root["card"+i] ;

if ((thisCard.row == row) and(thisCard.col == col)) {

return (true);

}}

return(false);

}

Функция cardvalue берет свойство value клипа карты, отбрасывает первый символ и возвращает численное значение. Например, если значение value карты равно с9, возвращается число 9.

function cardValue(card) {

// Удаляем первый символ из значения value.

n = card.value;

n = parselnt(n.substr(1,2));

return(n);
}

Последняя функция проходит в цикле по всем картам пирамиды и удаляет все оставшиеся карты. Также она удаляет "stack0" и "stackl". Это очищает рабочее поле для подготовки к следующему раунду.

function clearGame() {

// Удаляем карты из пирамиды.

for(var i=0;i

_root["card"+i].removeMovieClip();

}

// Удаляем обе колоды
stack0.removeMovieClip();

stack1.removeMovieClip();

}


В сложной основной временной шкале игры в очко для каждого шага существует помеченный кадр



Рисунок 15.6 В сложной основной временной шкале игры в очко для каждого шага существует помеченный кадр


В процессе игры указатель текущего кадра передвигается вдоль основной временной шкалы. Каждый ключевой кадр содержит различные функции. Сам код расположен в первом ключевом кадре.
Обязательно просмотрите ролик Blackjack.fla, чтобы самому увидеть, где расположены ключевые кадры и какие функции они вызывают.



Видеопокер



Видеопокер

Исходный файл:

В казино автоматы с видеопокером располагаются рядом с игровыми автоматами. По существу, они представляют собой то же самое: вы вставляете монету и можете выиграть некоторую сумму денег. Единственное различие состоит в том, что в течение игры вы должны совершать некоторые действия, чтобы повлиять на результат, а автомат будет на них реагировать.
Не ошибитесь: казино всегда выигрывает. Но так как игрок может заменять некоторые карты в течение игры, ему кажется, что у него появляется больше шансов на выигрыш. Такая возможность усложняет написание программы.



Видеопокер показывает игроку пять карт



Рисунок 15.3 Видеопокер показывает игроку пять карт



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



Все карты представлены в виде



Рисунок 15.5 Все карты представлены в виде маленьких кружочков, меток клипа, так как на данный момент-карты не видны


В этом ролике сложная основная временная шкала. Каждая метка представляет собой различный этап игры. На Рисунок 15.6 показана шкала в момент, когда видна большая часть меток.





Задача проекта

В отличие от многих игровых автоматов, в которых используются интересные, но сложные способы для определения ставок и получения



Задача проекта

Эта игра состоит из трех шагов. Первый шаг - игра ждет, пока игрок попросит сдать карты. На втором шаге игрок смотрит на пять карт, которые ему раздали, и решает, какие оставить, а какие - поменять. И последний шаг - раздаются новые карты, и подсчитывается сумма выигрыша. После чего осуществляется переход к первому шагу.
Игра должна представить игроку набор из пяти карт, выбранных случайным образом из перемешанной колоды (Рисунок 15.3).



Задача проекта

Наша цель - создать базисный вариант игры в очко, не стремясь реализовать полный набор функций. Некоторые правила в этой игре редко используются, например удваивание ставки, страхование и разделение, но если вы захотите включить их в свою игру, написание кода окажется очень сложной задачей. Оценить наличие таких правил смогут только избранные, поэтому здесь они опущены, чтобы не перегружать книгу лишней информацией.
На Рисунок 15.4 показан кадр ролика Blackjack.fla. Вы видите, что игрок взял пять карт, которые в сумме дали 18 очков. А раздающий карты взял три карты, их сумма составляет 21.
В этой простой игре игроку и раздающему дается по две карты. Первая карта раздающего остается лежать рубашкой вверх до тех пор, пока игрок не закончит набирать карты. Игрок может брать карты до тех пор, пока у него не окажется двадцать одно очко или более. Затем компьютер "выдает" карты раздающему, пока у того не будет минимум 17 очков.



Задача проекта

Цель этого проекта - создание полной версии игры в пасьянс "Пирамида". Программа должна узнавать даже тот редкий случай, когда игрок выигрывает, удаляя все карты из пирамиды. Если игрок чувствует себя в безвыходном положении или текущая партия представляется неплодотворной, он может нажать кнопку и в любое время пересдать карты.