Валерий Жарков - Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 3: Программирование на Visual C# искусственного интеллекта (продолжение 2)
- Название:Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 3: Программирование на Visual C# искусственного интеллекта (продолжение 2)
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:9785005910844
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Валерий Жарков - Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 3: Программирование на Visual C# искусственного интеллекта (продолжение 2) краткое содержание
Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 3: Программирование на Visual C# искусственного интеллекта (продолжение 2) - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
void doDown ()
{
switch (mode)
{
case GameMode.PlacingBets:
pot.DoDecreaseBet ();
showPot ();
this.Invalidate ();
break;
}
}
void showHelp ()
{
helpForm.ShowDialog ();
}
В панели Properties (для Form1) на вкладке Events дважды щёлкаем по имени события Load. Появившийся шаблон метода Form1_Load после записи нашего кода принимает следующий вид.
Листинг 1.2.Метод для загрузки файлов объектов.
private void Form1_Load (object sender, EventArgs e)
{
//We load the game objects:
init ();
startGame ();
}
В панели Properties (для Form1) на вкладке Events дважды щёлкаем по имени события Paint. Появившийся шаблон метода Form1_Paint после записи нашего кода принимает следующий вид. Напомним, что другие варианты вывода изображения, например, на элемент управления PictureBox и после щелчка по какому-либо элементу управления уже приводились ранее.
Листинг 1.3.Метод для рисования изображений.
private void Form1_Paint (object sender, PaintEventArgs e)
{
paintForm(e.Graphics);
}
Для задания режимов и управления игрой воспользуемся каким-либо элементом управления или компонентом. Как и выше, с панели инструментов Toolbox переносим на форму компонент MenuStrip и щёлкаем по нему (ниже формы в режиме проектирования). На форме Form1 появляются окна с надписью Type Here, в которые записываем команды (по второму варианту, можно записывать в панели Properties в свойстве Text): Stay, Menu, Exit, HitMe, BetPlus, BetMinus, Sound, Help, рис. 1.30. Для команды, слева от которой поставлен флажок, в панели Properties для этой команды значение Checked следует задать как True.

Рис. 1.30.Команды элемента управления MenuStrip.
В режиме редактирования дважды щёлкаем по левой команде Stay (для приостановки игры). Появившийся шаблон метода после записи строки принимает следующий вид.
Листинг 1.4.Метод для приостановки игры.
private void StayToolStripMenuItem_Click (object sender, EventArgs e)
{
doLeftMenuKey ();
}
Аналогично дважды щёлкаем по команде Exit. Появившийся шаблон метода после записи нашего кода принимает следующий вид.
Листинг 1.5.Метод для окончания игры.
private void ExitToolStripMenuItem_Click (object sender, EventArgs e)
{
Application. Exit ();
}
Аналогично дважды щёлкаем по команде «Hit Me». Появившийся шаблон метода после записи нашего кода принимает следующий вид.
Листинг 1.6.Метод для выдачи карты игроку.
private void HitMeToolStripMenuItem_Click (object sender, EventArgs e)
{
playerHits ();
}
Аналогично дважды щёлкаем по команде «BetPlus». Появившийся шаблон метода после записи нашего кода принимает следующий вид.
Листинг 1.7.Метод для увеличения Ставки.
private void BetPlusToolStripMenuItem_Click (object sender, EventArgs e)
{
doUp ();
}
Аналогично дважды щёлкаем по команде «Ставка -” (Bet -). Появившийся шаблон метода после записи нашего кода принимает следующий вид.
Листинг 1.8.Метод для уменьшения Ставки.
private void BetMinusToolStripMenuItem1_Click (object sender, EventArgs e)
{
doDown ();
}
Методика приостановки и возобновления звука при помощи установки и удаления флажка в команде Звук (Sound) была описана выше. В данной игре, звук включён постоянно.
Аналогично дважды щёлкаем по команде Help. Появившийся шаблон метода после записи нашего кода принимает следующий вид.
Листинг 1.9.Метод для вывода справочной формы.
private void HelpToolStripMenuItem_Click (object sender, EventArgs e)
{
showHelp ();
}
Теперь программа должна управлять карточной игрой, используя любые клавиши, например, верхнюю (Up) и нижнюю (Down), левую (Left) и правую (Right) клавиши со стрелками, а также клавишу Enter (для начальной сдачи карт игроку и Банкомёту и последующей сдачи по одной карте игроку). В панели Properties (для формы Form1) на вкладке Events дважды щёлкаем по имени события KeyDown. Появившийся шаблон обработки нажатий всех клавиш после записи нашего кода для нажатий только трех клавиш (относящимся к тематике данной главы) принимает следующий вид.
Листинг 1.10.Метод для обработки нажатий клавиш.
private void Form1_KeyDown (object sender, KeyEventArgs e)
{
if ((e.KeyCode == System.Windows.Forms.Keys. Up))
{
doUp ();
e. Handled = true;
}
if ((e.KeyCode == System.Windows.Forms.Keys.Down))
{
doDown ();
e. Handled = true;
}
if ((e.KeyCode == System.Windows.Forms.Keys. Enter))
{
//Набираем себе карты:
doEnter ();
}
}
Мы закончили написание программы в главный класс Form1 (для формы Form1 с пользовательским интерфейсом игры). В этом проекте движок игры (Engine Game) находится не в файле Form1.cs (как обычно бывает), а в следующем файле CardEngine. cs.
Теперь в наш проект добавляем новые файлы (для программирования соответствующих игровых действий) по следующей схеме.
В панели Solution Explorer выполняем правый щелчок по имени проекта и в контекстном меню выбираем Add, New Item. В панели Add New Item выделяем шаблон Code File, в окне Name записываем имя нового файла с расширением *.cs и щёлкаем кнопку Add. В проект (и в панель Solution Explorer) добавляется этот файл, открывается пустое окно редактирования кода, в которое записываем следующий код.
Листинг 1.11.Новый файл CardEngine. cs.
using System;
using System.Collections;
using System. Drawing;
namespace PocketJack
{
///
/// Provides the behaviours required to manage and draw cards
///
public class Card
{
///
/// The number of the card, in the range 1 to 52
///
public byte CardNo;
///
/// Indicates if the card is to be drawn face up.
/// True by default.
///
public bool FaceUp = true;
///
/// The images of the cards. Stored for all the cards.
/// The image with number 0 is the
/// back pattern of the card
///
static private Image [] cardImages = new Bitmap [53];
///
/// The attribute to be used when drawing the card
/// to implement transpancy
///
static public System.Drawing.Imaging.ImageAttributes
cardAttributes;
///
/// Used when loading card images prior to drawing
///
static private System.Reflection.Assembly execAssem;
///
/// Sets up the color and attribute values.
///
static Card ()
{
cardAttributes =
new System.Drawing.Imaging.ImageAttributes ();
cardAttributes.SetColorKey(Color.Green, Color.Green);
execAssem =
System.Reflection.Assembly.GetExecutingAssembly ();
}
///
/// Scores for each of the cards in a suit
///
static private byte [] scores =
new byte [] {11, //ace
2,3,4,5,6,7,8,9,10, //spot cards
10,10,10}; //jack, queen, king
///
/// Picture information for each card in a suit
///
static private bool [] isPicture =
new bool [] {false, //ace
false, false, false, false, false, false,
false, false, false, //spot cards
true, true, true}; //jack, queen, king
///
/// Names of the suits, in the order that of the suits
/// in the number sequence
///
static private string [] suitNames =
new string [] {«club», «diamond», «heart», «spade»};
///
/// Names of individual cards, in the order of the cards
/// in a suit
///
static private string [] valueNames =
new string [] {«Ace», «Deuce», «Three», «Four», «Five», «Six»,
«Seven», «Eight», «Nine», «Ten», «Jack», «Queen», «King»};
///
/// Returns the value in points of a given card,
/// according to BlackJack rules
///
public int BlackJackScore
{
get
{
return scores [(CardNo – 1) % 13];
}
}
///
/// Returns true if the card is a picture
/// (i.e. jack, queen or king)
///
public bool IsPicture
{
get
{
return isPicture [(CardNo – 1) % 13];
}
}
///
/// Returns text of the suit of this card
///
public string Suit
{
get
{
return suitNames [(CardNo – 1) / 13];
}
}
///
/// Returns the text of the value of this card
///
public string ValueName
{
get
{
return valueNames [(CardNo – 1) % 13];
}
}
///
/// Returns true if this is a red card
///
public bool Red
{
get
{
int suit = (CardNo – 1) / 13;
return ((suit == 1) || (suit == 2));
}
}
///
/// Returns true if this is a black card
///
public bool Black
{
get
{
return! Red;
}
}
///
/// Returns an image which can be used to draw this card
///
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];
}
}
///
/// Constructs a card with a partiuclar number
///
/// number of the card
/// in the range 1 to 52
/// true if the card
/// is to be drawn face up
public Card (byte cardNo, bool faceUp)
{
CardNo = cardNo;
FaceUp = faceUp;
}
///
/// Constructs a face up card with that number
///
///
public Card (byte cardNo)
: this (cardNo, true)
{
}
///
/// String description of the card
///
/// the name and suit of the card
public override string ToString ()
{
return ValueName + " of " + Suit;
}
}
///
/// Provides a container for a number of cards.
/// May be used to draw the cards and compute their score.
///
public class CardHand: ArrayList
{
///
/// Used as a destination of teh draw action
///
private static Rectangle drawRect;
///
/// Draws the hand on the graphics.
///
/// graphics to draw with
/// left edge of first card
/// top of first card
/// x gap between each card
/// y gap between each card
public void DrawHand (Graphics g, int startx, int starty,
int gapx, int gapy)
{
drawRect. X = startx;
drawRect. Y = starty;
foreach (Card card in this)
{
drawRect. Width = card.CardImage. Width;
drawRect. Height = card.CardImage. Height;
g. DrawImage (
card.CardImage, // Image
drawRect, // destination rectange
0, // srcX
0, // srcY
card.CardImage. Width, // srcWidth
card.CardImage. Height, // srcHeight
GraphicsUnit. Pixel, // srcUnit
Card.cardAttributes); // ImageAttributes
drawRect. X += gapx;
drawRect. Y += gapy;
}
}
///
/// Computes the score of the hand
///
/// the value of the score
public int BlackJackScoreHand ()
{
int score = 0;
int aces = 0;
foreach (Card card in this)
{
score += card. BlackJackScore;
if (card. BlackJackScore == 11)
{
aces++;
}
}
while ((score> 21) && (aces> 0))
{
score -= 10;
aces – ;
}
return score;
}
}
///
/// Contains a number of card decks
/// which can be dealt one at a time.
///
public class CardShoe
{
private int noOfDecks = 1;
private byte [] decks;
private int nextCard;
private bool testShoe = false;
///
/// True if the deck is «stacked»,
/// i.e. was created from a byte array
///
public bool TestShoe
{
get
{
return testShoe;
}
}
private void makeShoe ()
{
decks = new byte [noOfDecks * 52];
int cardPos = 0;
for (int i = 0; i
{
for (byte j = 1; j <53; j++)
{
decks [cardPos] = j;
cardPos++;
}
}
nextCard = 0;
}
private void shuffleShoe ()
{
if (!testShoe)
{
System. Random rand = new Random ();
byte swap;
int p1, p2;
for (int i = 0; i
{
p1 = rand.Next (decks. Length);
p2 = rand.Next (decks. Length);
swap = decks [p1];
decks [p1] = decks [p2];
decks [p2] = swap;
}
}
nextCard = 0;
}
///
/// Gets the next card number from the deck
///
/// The number of the next card
public byte NextCardNo ()
{
if (nextCard == decks. Length)
{
shuffleShoe ();
}
return decks [nextCard++];
}
///
/// Gets the next card from the deck.
///
/// A new instance of the card
public Card DealCard ()
{
return new Card (NextCardNo ());
}
///
/// Constructs a shoe containing a number of decks
///
///
public CardShoe (int noOfDecks)
{
this.noOfDecks = noOfDecks;
makeShoe ();
shuffleShoe ();
testShoe = false;
}
///
/// Constructs a shoe containing a single deck
///
public CardShoe ()
: this (1)
{
}
///
Интервал:
Закладка: