Читать книгу Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 2: Программирование на Visual C# искусственного интеллекта (продолжение 1) - Валерий Алексеевич Карданов, Дарья Андреевна Самсонова, Наталья Сергеевна Кузьмина - Страница 10

Введение
12.4. Код программы

Оглавление

Открываем файл Form1.cs (например, по схеме: File, Open, File) и в классе Form1 записываем следующие переменные и метод.


Листинг 12.1. Переменные и метод.

public int cx = 15;

public int cy = 70;

public int Level = 3;

public Connect4Board b = new Connect4Board ();


public void Draw (Graphics g)

{

Pen p = new Pen (Color. Black);

g. DrawRectangle (p, 15, 70, 210, 180);

int q = 0;

int w = 5;

for (int y = cy; y <cy +180; y += 30)

{

for (int x = cx; x <cx +210; x += 30)

{

if (b.arr [q, w] == 0)

g.FillEllipse (new SolidBrush (Color. White),

x +3, y +3, 27, 27);

if (b.arr [q, w] == 1)

g.FillEllipse (new SolidBrush (Color. Yellow),

x +3, y +3, 27, 27);

if (b.arr [q, w] == 2)

g.FillEllipse (new SolidBrush(Color.Red),

x +3, y +3, 27, 27);

g. DrawEllipse (p, x +3, y +3, 27, 27);

q++;

}

q = 0;

w – ;


}

}


В панели Properties (для Form1) на вкладке Events дважды щёлкаем по имени события Paint. Появившийся шаблон метода Form1_Paint после записи нашего кода принимает следующий вид. Напомним, что другие варианты вывода изображения, например, на элемент управления PictureBox и после щелчка по какому-либо элементу управления уже приводились ранее.


Листинг 12.2. Метод для рисования изображений.

private void Form1_Paint (object sender, PaintEventArgs e)

{

e.Graphics.FillRectangle (new SolidBrush(Color.RoyalBlue),

15, 70, 210, 180);

Draw(e.Graphics);

}


В панели Properties (для Form1) на вкладке Events дважды щёлкаем по имени события MouseDown. Появившийся шаблон метода Form1_MouseDown после записи нашего кода принимает следующий вид.


Листинг 12.3. Метод для обработки щелчка экрана мышью.

private void Form1_MouseDown (object sender, MouseEventArgs e)

{

Microsoft.VisualBasic.Interaction.Beep ();

if (b. endt == 0)

{

if ((e.X> cx) && (e.X <cx +210))

{

if ((e.Y> cy) && (e.Y <cy +180))

{

int selection = (e.X – cx) / 30;

if ((selection> = 0) && (selection <7))

{

if (b.add (selection, b.plr) == 0)

{

Draw(this.CreateGraphics ());

b. turncheck ();

b. turn = b. cpu;

if (b. endt == 0)

{

int ck;

b.col = b.Think ();

ck = b.add(b.col, b. cpu);

if (ck == 0)

{

b.lin = 6 – b.tops[b.col];

b. turn = b.plr;

}

}

Draw(this.CreateGraphics ());

b. turncheck ();


}

}

}

}

}

}


Дважды щёлкаем по команде Begins the player (Начинает игрок) для элемента управления MenuStrip (или в панели Properties на вкладке Events выбираем событие Click). Появляется шаблон метода, который после записи нашего кода принимает следующий вид.


Листинг 12.4. Метод-обработчик выбора команды.

private void playerFirstToolStripMenuItem_Click (

object sender, EventArgs e)

{

//Player First

b = new Connect4Board ();

b.rec = Level;

Invalidate ();


}


Дважды щёлкаем по команде Begins the computer (Начинает компьютер) для элемента управления MenuStrip. Появляется шаблон метода, который после записи нашего кода принимает следующий вид.


Листинг 12.5. Метод-обработчик выбора команды.

private void computerFirstToolStripMenuItem_Click (

object sender, EventArgs e)

{

//CPU First

b = new Connect4Board ();

b.rec = Level;

Draw(this.CreateGraphics ());

b. turn = b. cpu;

if (b. endt == 0)

{

int ck;

b.col = b.Think ();

ck = b.add(b.col, b. cpu);

if (ck == 0)

{

b.lin = 6 – b.tops[b.col];

b. turn = b.plr;

}

}

Draw(this.CreateGraphics ());

b. turncheck ();


}


Дважды щёлкаем по команде Usual (Обычный). Появляется шаблон метода, который после записи нашего кода принимает следующий вид.


Листинг 12.6. Метод-обработчик выбора команды.

private void easyToolStripMenuItem_Click (

object sender, EventArgs e)

{

easyToolStripMenuItem.Checked = true;

hardToolStripMenuItem.Checked = false;

normalToolStripMenuItem.Checked = false;

//Easy

Level = 3;

b = new Connect4Board ();

b.rec = Level;

Invalidate ();


}


Дважды щёлкаем по команде Normal (Нормальный). Появляется шаблон метода, который после записи нашего кода принимает следующий вид.


Листинг 12.7. Метод-обработчик выбора команды.

private void normalToolStripMenuItem_Click (

object sender, EventArgs e)

{

hardToolStripMenuItem.Checked = false;

easyToolStripMenuItem.Checked = false;

normalToolStripMenuItem.Checked = true;

//Normal

Level = 5;

b = new Connect4Board ();

b.rec = Level;

Invalidate ();


}


Дважды щёлкаем по команде Difficult (Сложный). Появляется шаблон метода, который после записи нашего кода принимает следующий вид.


Листинг 12.8. Метод-обработчик выбора команды.

private void hardToolStripMenuItem_Click (

object sender, EventArgs e)

{

hardToolStripMenuItem.Checked = true;

easyToolStripMenuItem.Checked = false;

normalToolStripMenuItem.Checked = false;

//Hard

Level = 7;

b = new Connect4Board ();

b.rec = Level;

Invalidate ();


}


Схема записи и вывода справочной информации, например, с правилами игры после выбора дополнительной команды Справка (для элемента управления MenuStrip) дана ранее и в наших книгах на сайте ZharkovPress.ru в параграфе «Методика добавления информации в справочную форму».

Мы закончили написание программы в главный класс Form1 (для формы Form1 с пользовательским интерфейсом игры).

Теперь в наш проект добавляем новый файл (для программирования соответствующих игровых действий).

Добавить в проект файл можно по двум вариантам.

По первому варианту, добавляем в проект нужный файл по обычной схеме: в панели Solution Explorer выполняем правый щелчок по имени проекта, в контекстном меню выбираем Add, Existing Item, в панели Add Existing Item в окне «Files of type» выбираем «All Files», в центральном окне находим (например, в папке компьютера файл, скопированный из Интернета), выделяем имя этого файла и щёлкаем кнопку Add (или дважды щёлкаем по имени этого файла).

По второму варианту, в панели Solution Explorer выполняем правый щелчок по имени проекта и в контекстном меню выбираем Add, New Item, в панели Add New Item выделяем шаблон Code File, в окне Name записываем имя Connect4Board. cs и щёлкаем кнопку Add. В проект (и в панель Solution Explorer) добавляется этот файл, открывается пустое окно редактирования кода, в которое записываем код со следующего листинга.


Листинг 12.9. Новый файл.

using System;

using System. Drawing;

using System.Collections;

using System.Windows.Forms;


namespace Connect4

{

public class Connect4Board

{

public Random random = new Random ();

public int [,] arr = new int [7, 6];

public int [,] thn = new int [7, 6];

public int [] tops = new int [7];

public int player, computer, endt = 0;

public int plr = 1, cpu = 2, rec = 3, turn = 1;

public int m, n, r, temp, so, ch, col, t, y;

public int plrcoin, cpucoin;

public int lin;

public Connect4Board ()

{

}

public int Think ()

{

int i;

i = rec;

return check (i, -9999999, 9999999);

}

public void turncheck ()

{

int temp;

char [] toto = new char [20];

temp = checkwin ();

if (temp == plr)

{

MessageBox.Show («You won!»);

endt = 1; return;

}

if (temp == cpu)

{

MessageBox.Show («You lost.»);

endt = 1; return;

}

if (temp == 0)

{

for (t = 0; t <= 6; t++)

if (tops [t] <6) temp = 1;

if (temp == 0)

{

//drawn ();

endt = 1;

return;

}

}

}

public int check (int i, int alpha, int beta)

{

int co, score, t, g, j = 0, p;

i – ;

if (i == -1) {score = position (); return score;}

if (i % 2 == 0)

{

int max = 0, k;

j = 0; co = 0;

for (t = 0; t <7; t++)

{

g = add (t, cpu);

if (g == 0)

{

if (checkwin () == cpu)

{

sub (t);

if (i == rec – 1)

return t;

else return 9000;

}

k = check (i, alpha, 999999);

if (k> alpha) alpha = k;

sub (t);

if (k> beta) return k;

if (co == 0) {max = k; co = 1; j = t;}

if (k == max)

{

p = (random.Next (6)) +1;

if (p> 4) j = t;

}

if (k> max) {max = k; j = t;}

}

}

score = max;

}

else

{

int min = 0, k = 0;

co = 0;

for (t = 0; t <7; t++)

{

g = add (t, plr);

if (g == 0)

{

if (checkwin () == plr)

{

sub (t);

/*if (i==rec-1) return t; else*/

return -10000;

}

k = check (i, -99999, beta);

if (k <beta) beta = k;

sub (t);

if (k <alpha) return k;

if (co == 0) {min = k; co = 1; j = t;}

if (k <min) {min = k; j = t;}

}

}

score = min;

}

if (i == rec – 1) return j;

return score;

}

public int add (int c, int coin)

{

if (tops [c] <6)

{

arr [c, tops [c]] = coin;

tops [c] ++; return 0;

}

return 1;

}

public int sub (int c)

{

tops [c] – ;

arr [c, tops [c]] = 0;

return 0;

}

public int position ()

{

int u, o, x, y, j, score;

int gh = 0, hg = 0;

score = 0;

//Empty the think array


for (x = 0; x <7; x++)

{

for (y = 0; y <6; y++)

{

thn [x, y] = 0;

}

}

//Sum the score of every opportunity to the score

for (y = 0; y <6; y++)

{

for (x = 0; x <7; x++)

{

if (arr [x, y] == 0)

score = score + checkhole (x, y);

if (y> 0)

{

if ((thn [x, y] == cpu) &&

(arr [x, y – 1]!= 0)) gh++;

if ((thn [x, y] == plr) &&

(arr [x, y – 1]!= 0))

{hg++; score = score – 4000;}

}

else

{

if (thn [x, y] == cpu) gh++;

if (thn [x, y] == plr)

{hg++; score = score – 4000;}

}

}

}

if (gh> 1) score = score + (gh – 1) * 500;

if (gh == 1) score = score – 100;

if (hg> 1) score = score – (hg – 1) * 500;

for (x = 0; x <7; x++)

{

gh = 0;

for (y = 1; y <6; y++)

{

/*if (gh==0)

if ((thn [x,y]> 0) && (arr [x,y-1] ==0)) {

gh=1;


} */

if ((thn [x, y] == cpu) &&

(thn [x, y – 1] == cpu))

{

u = 0; j = 0;

for (o = y – 1; o> -1; o – )

{

if (thn [x, o] == plr) u = 1;

if (arr [x, o] == 0) j++;

}

if (u == 0) score = score +1300 – j * 7;

if (u == 1) score = score +300;

}

if ((thn [x, y] == plr) &&

(thn [x, y – 1] == plr))

{

u = 0; j = 0;

for (o = y – 1; o> -1; o – )

{

if (thn [x, o] == cpu) u = 1;

if (arr [x, o] == 0) j++;

}

if (u == 0) score = score – 1500 + j * 7;

if (u == 1) score = score – 300;

}

if (thn [x, y] == plr)

{

u = 0;

for (o = y – 1; o> -1; o – )

{

if (thn [x, o] == cpu) u = 1;

}

if (u == 1) score = score +30;

}

if (thn [x, y] == cpu)

{

u = 0;

for (o = y – 1; o> -1; o – )

{

if (thn [x, o] == plr) u = 1;

}

if (u == 1) score = score – 30;

}

}

}

return score;

}

public int checkhole (int x, int y)

{

int score = 0;

int max, min;

int d0 = 0, d1 = 0, d2 = 0, d3 = 0;

if (((x +1) <7) && ((y – 1)> -1))

{

if (arr [x +1, y – 1] == cpu)

{

d1++;

if (((x +2) <7) && ((y – 2)> -1))

{

if (arr [x +2, y – 2] == cpu)

{

d1++;

if (((x +3) <7) && ((y – 3)> -1))

{

if (arr [x +3, y – 3] == cpu)

d1++;

}

}

}

}

}

if (((x – 1)> -1) && ((y +1) <6))

{

if (arr [x – 1, y +1] == cpu)

{

d1++;

if (((x – 2)> -1) && ((y +2) <6))

{

if (arr [x – 2, y +2] == cpu)

{

d1++;

if (((x – 3)> -1) && ((y +3) <6))

{

if (arr [x – 3, y +3] == cpu) d1++;

}

}

}

}

}

if (((x – 1)> -1) && ((y – 1)> -1))

{

if (arr [x – 1, y – 1] == cpu)

{

d2++;

if (((x – 2)> -1) && ((y – 2)> -1))

{

if (arr [x – 2, y – 2] == cpu)

{

d2++;

if (((x – 3)> -1) && ((y – 3)> -1))

{

if (arr [x – 3, y – 3] == cpu) d2++;

}

}

}

}

}

if (((x +1) <7) && ((y +1) <6))

{

if (arr [x +1, y +1] == cpu)

{

d2++;

if (((x +2) <7) && ((y +2) <6))

{

if (arr [x +2, y +2] == cpu)

{

d2++;

if (((x +3) <7) && ((y +3) <6))

{

if (arr [x +3, y +3] == cpu) d2++;

}

}

}

}

}

if ((y – 1)> -1) if (arr [x, y – 1] == cpu)

{

d0++;

if ((y – 2)> -1) if (arr [x, y – 2] == cpu)

{

d0++;

if ((y – 3)> -1)

if (arr [x, y – 3] == cpu) d0++;

}

}

if (x – 1> -1)

{

if (arr [x – 1, y] == cpu)

{

d3++;

if (x – 2> -1)

{

if (arr [x – 2, y] == cpu)

{

d3++;

if (x – 3> -1)

if (arr [x – 3, y] == cpu) d3++;

}

}

}

}

if (x +1 <7)

{

if (arr [x +1, y] == cpu)

{

d3++;

if (x +2 <7)

{

if (arr [x +2, y] == cpu)

{

d3++;

if (x +3 <7)

if (arr [x +3, y] == cpu) d3++;

}

}

}

}

max = d0;

if (d1> max) max = d1;

if (d2> max) max = d2;

if (d3> max) max = d3;

if (max == 2) score = score +5;

if (max> 2)

{

score = score +71; thn [x, y] = cpu;

if ((d1 <3) && (d2 <3) && (d3 <3))

score = score – 10;

}

if (((x +1) <7) && ((y – 1)> -1))

{

if (arr [x +1, y – 1] == plr)

{

d1++;

if (((x +2) <7) && ((y – 2)> -1))

{

if (arr [x +2, y – 2] == plr)

{

d1++;

if (((x +3) <7) && ((y – 3)> -1))

{

if (arr [x +3, y – 3] == plr) d1++;

}

}

}

}

}

if (((x – 1)> -1) && ((y +1) <6))

{

if (arr [x – 1, y +1] == plr)

{

d1++;

if (((x – 2)> -1) && ((y +2) <6))

{

if (arr [x – 2, y +2] == plr)

{

d1++;

if (((x – 3)> -1) && ((y +3) <6))

{

if (arr [x – 3, y +3] == plr) d1++;

}

}

}

}

}

if (((x – 1)> -1) && ((y – 1)> -1))

{

if (arr [x – 1, y – 1] == plr)

{

d2++;

if (((x – 2)> -1) && ((y – 2)> -1))

{

if (arr [x – 2, y – 2] == plr)

{

d2++;

if (((x – 3)> -1) && ((y – 3)> -1))

{

if (arr [x – 3, y – 3] == plr) d2++;

}

}

}

}

}

if (((x +1) <7) && ((y +1) <6))

{

if (arr [x +1, y +1] == plr)

{

d2++;

if (((x +2) <7) && ((y +2) <6))

{

if (arr [x +2, y +2] == plr)

{

d2++;

if (((x +3) <7) && ((y +3) <6))

{

if (arr [x +3, y +3] == plr) d2++;

}

}

}

}

}

if ((y – 1)> -1) if (arr [x, y – 1] == plr)

{

d0++;

if ((y – 2)> -1) if (arr [x, y – 2] == plr)

{

d0++;

if ((y – 3)> -1)

if (arr [x, y – 3] == plr) d0++;

}

}

if (x – 1> -1)

{

if (arr [x – 1, y] == plr)

{

d3++;

if (x – 2> -1)

{

if (arr [x – 2, y] == plr)

{

d3++;

if (x – 3> -1)

if (arr [x – 3, y] == plr) d3++;

}

}

}

}

if (x +1 <7)

{

if (arr [x +1, y] == plr)

{

d3++;

if (x +2 <7)

{

if (arr [x +2, y] == plr)

{

d3++;

if (x +3 <7)

if (arr [x +3, y] == plr) d3++;

}

}

}

}

min = d0;

if (d1> min) min = d1;

if (d2> min) min = d2;

if (d3> min) min = d3;

if (min == 2) score = score – 4;

if (min> 2)

{

score = score – 70; thn [x, y] = plr;

if ((d1 <3) && (d2 <3) && (d3 <3))

score = score +10;

}

return score;

}

public int checkwin ()

{

int r, x, y;

r = 0;

for (y = 2; y> -1; y – )

{

for (x = 0; x <7; x++)

{

checku (x, y, ref r);

}

}

for (y = 0; y <6; y++)

{

for (x = 0; x <4; x++)

{

check2r (x, y, ref r);

}

}

for (y = 2; y> -1; y – )

{

for (x = 0; x <4; x++)

{

checkr (x, y, ref r);

}

}

for (y = 2; y> -1; y – )

{

for (x = 3; x <7; x++)

{

checkl (x, y, ref r);

}

}

return r;

}

public void checku (int x, int y, ref int r)

{

if ((arr [x, y] == 2) && (arr [x, y +1] == 2) &&

(arr [x, y +2] == 2) &&

(arr [x, y +3] == 2)) r = 2;

if ((arr [x, y] == 1) && (arr [x, y +1] == 1) &&

(arr [x, y +2] == 1) &&

(arr [x, y +3] == 1)) r = 1;

}

public void check2r (int x, int y, ref int r)

{

if ((arr [x, y] == 2) && (arr [x +1, y] == 2) &&

(arr [x +2, y] == 2) &&

(arr [x +3, y] == 2)) r = 2;

if ((arr [x, y] == 1) && (arr [x +1, y] == 1) &&

(arr [x +2, y] == 1) &&

(arr [x +3, y] == 1)) r = 1;

}

public void checkr (int x, int y, ref int r)

{

if ((arr [x, y] == 2) && (arr [x +1, y +1] == 2) &&

(arr [x +2, y +2] == 2) &&

(arr [x +3, y +3] == 2)) r = 2;

if ((arr [x, y] == 1) && (arr [x +1, y +1] == 1) &&

(arr [x +2, y +2] == 1) &&

(arr [x +3, y +3] == 1)) r = 1;

}

public void checkl (int x, int y, ref int r)

{

if ((arr [x, y] == 2) && (arr [x – 1, y +1] == 2) &&

(arr [x – 2, y +2] == 2) &&

(arr [x – 3, y +3] == 2)) r = 2;

if ((arr [x, y] == 1) && (arr [x – 1, y +1] == 1) &&

(arr [x – 2, y +2] == 1) && (

arr [x – 3, y +3] == 1)) r = 1;


}

}

}


После этого добавления в панели Solution Explorer появляется этот файл, как показано выше. Дважды щёлкая в SE по имени файла, любой файл можно открыть, изучить и редактировать.

Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 2: Программирование на Visual C# искусственного интеллекта (продолжение 1)

Подняться наверх