Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 10: Программирование на Visual C# искусственного интеллекта. Издание 3. Продолжение 1
Шрифт:
Напомним смысл игры. В игре участвуют, как минимум, два игрока: игрок и банкомёт в виде компьютера, сдающего карты. Из колоды карт банкомёт (по-английски называется dealer – дилер) сдаёт по одной карте игроку, который должен набрать количество очков, как можно ближе к 21 или равное 21 (21 – это лучший вариант – очко), но не более 21. Если игрок набрал больше 21, то это обычно называется “перебор”, и игрок считается проигравшим. Если же игрок набрал меньше 21, то он предлагает банкомёту набирать карты себе. Если банкомёт наберёт очков меньше, чем игрок, банкомёт считается проигравшим, а если больше, то победившим. При равном количестве очков в данной игре принимается,
1.2. Рисование карт на экране
Первая проблема, которую нужно решить, – показ на экране карт, которые два соревнующихся игрока, например, компьютер и игрок, держат в “руках”. Чтобы это сделать, нам нужно: 52 изображения карт в виде файлов формата, например, (.gif), одно изображение фона игры 0.gif, одно изображения банка bank.jpg и одно изображение загрузки loading.gif. Напомним, что формат (.gif) расшифровывается как Graphics Interchange Format (Формат обмена графическими данными). Все изображения в уменьшенном масштабе показаны на рис. 1.1, а в увеличенном масштабе – на рис. 1.2 – 1.5. Видно, что файлы карт имеют имена 1, 2, 3,…,52 и содержат каждую последовательность из 13 карт в четырёх мастях (последовательно сверху вниз: трефы – club, бубны – diamond, черви – heart, пики – spade). Файл с именем “0” – фон игры. Эти изображения должны быть добавлены к проекту и использованы для вывода карт на экран. Каждое изображение карты имеет приблизительно только 1 Кбайт объёма, потому что содержит только четыре цвета, чтобы не использовать много памяти.
Рис. 1.1. Карты и другие рисунки игры в уменьшенном масштабе.
Рис. 1.2. Первые семь карт в увеличенном масштабе.
Рис. 1.3. Последующие шестнадцать карт в увеличенном масштабе.
На этом рисунке закончились 13 карт 1, 2, 3, …,13 первой масти трефы – club. Первая карта любой масти – Туз (Ace – A).
Рис. 1.4. Последующие шестнадцать карт в увеличенном масштабе.
На этом рисунке закончились 13 карт 14, 15, 16, …, 26 второй масти бубны – diamond и 13 карт 27, 28, 29, …, 39 третьей масти черви – heart. И здесь первая карта масти – Туз (Ace – A).
Ниже показаны 13 карт 40, 41, 42, …, 52 последней четвертой масти пики – spade.
Рис. 1.5. Последние тринадцать карт в увеличенном масштабе.
Значения очков каждой карты следующие: Туз (Ace – A) = 1 или 11; как 1-я, 2-я или 3-я карта – Туз даёт 11 очков; с Валетом, Дамой и Королём, Туз даёт 11 очков и в сумме 10+11=21 эти две карты называются PocketJack, который бьёт карты соперника, даже набравшие 21; как 4-я и последующая карта – Туз даёт 1 очко; цифры на картах от 2 до 9 означают очки этой карты;
карта с числом 10 card with number 10, Валет (Jack – J), Дама (Queen – Q), Король (King – K) = по 10 очков.
1.3. Загрузка в проект изображений карт
Чтобы добавить имеющиеся у нас файлы карт в проект, необходимо сначала добавить в проект папку для этих файлов, затем скопировать в эту папку файлы, а затем свойства этих файлов задать как Embedded Resource, как подробно будет описано далее при создании проекта игры.
Лучший способ загрузить файлы карт в программу при её выполнении – создать массив этих карт в классе Image или Bitmap. После этого изображения могут тогда быть нарисованы на поле игры playfield, когда потребуется. Чтобы загрузить изображения карт в массив, возможны два варианта кода. По первому варианту, код имеет следующий вид:
static private Image[] cardImages = new Bitmap[53];
System.Reflection.Assembly execAssem =
System.Reflection.Assembly.GetExecutingAssembly;
for (int i=0 ; i< 53 ; i++ )
{
cardImages[i] =
new Bitmap(execAssem.GetManifestResourceStream (
@"PocketJack.cardImages."+i+@".gif"));
}
Видно, что в этом варианте проект имеет имя PocketJack, папка с файлами карт имеет имя cardImages, а в массиве cardImages все файлы карт с именами “i” должны иметь расширение (.gif).
По второму варианту, который мы применим далее в программе, код имеет следующий вид:
public Image CardImage
{
get
{
int dispNo = CardNo;
if (!FaceUp)
{
dispNo = 0;
}
if (cardImages[dispNo] == null)
{
cardImages[dispNo] = new Bitmap(
execAssem.GetManifestResourceStream(
@"PocketJack.images." + dispNo + @".gif"));
}
return cardImages[dispNo];
}
}
Видно, что в этом варианте проект имеет имя PocketJack, папка с файлами карт имеет имя images, а в массиве cardImages все файлы карт с именами “dispNo” должны иметь расширение (.gif).
1.4. Рисование изображений карт
Следующий шаг в разработке игры – процесс рисования карт. Изображение каждой карты должно иметь скруглённые углы. Когда карты прорисовываются на фоне игры, карты со скруглёнными углами выглядят более реалистично. Это – маленькая деталь, но существенная, если мы хотим спроектировать хороший пользовательский интерфейс игры. А если мы пристально посмотрим на изображения карт на экране, то можно увидеть, что углы карт нарисованы зелёным цветом, как показано на рис. 1.6.
Рис. 1.6. Углы карт нарисованы зелёным цветом.
При рисовании карт мы должны назначить этот цвет как прозрачный, чтобы был виден фон формы Form1 вокруг углов каждой карты. Мы должны использовать следующий код, чтобы создать объект класса ImageAttributes с целью задания зелёного цвета прозрачным:
static public System.Drawing.Imaging.ImageAttributes
cardAttributes;
static Card
{
cardAttributes =