скачать рефераты
  RSS    

Меню

Быстрый поиск

скачать рефераты

скачать рефератыКурсовая работа: Программа "Крестики-нолики 5 в ряд на неограниченном игровом поле"

for (int i=0;i<size_x;i++)

{

for (int j=0;j<size_y;j++)

{

if (fields[i][j] == 0)

{

//Расчет оценочной функции

calc_fields[i][j] = calculate(2,i,j) + calculate(1,i,j)*(float)attack_factor;

//Берем в расчет уровень (для профессионала случайности нет)

if (comp_level == 1)//Для любителя (небольшая случайность)

{

calc_fields[i][j] *= (1 + ((float)rand() / 32767)) / 2;

}

if (comp_level == 2)//Для новичка (максимальная случайность)

{

calc_fields[i][j] *= ((float)rand() / 32767);

}

if (calc_fields[i][j] == max)

{

//Еще одна клетка с максимальным значением оценочной функции

povtor_num++;

}

if (calc_fields[i][j] > max)

{

//Клетка с максимальным значением оценочной функции

max = calc_fields[i][j];

povtor_num = 0;

cur_x = i;

cur_y = j;

}

}

}

}

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

if (max == -1)

{

return;

}

//Выбираем куда сделать ход

if (povtor_num > 0)

{

//Выбираем куда ходить случайным образом из клеток с одинаковыми значениями оценочной функции

cur_povtor = rand() / (32767 / povtor_num);//Номер элемента, куда надо ходить

//Ищем его по полю

int buf_povtor = -1;

for (int i=0;i<size_x;i++)

{

for (int j=0;j<size_y;j++)

{

if (calc_fields[i][j] == max)

{

buf_povtor++;

if (buf_povtor == cur_povtor) //Клетка найдена

{

fields[i][j] = 2;//Ставим крестик

last_x = i;//Запоминаем координаты последнего хода

last_y = j;

return;

}

}

}

}

}

else

{

//Одна клетка с максимальным знаечением

fields[cur_x][cur_y] = 2;//Ставим крестик

last_x = cur_x;//Запоминаем координаты последнего хода

last_y = cur_y;

}

}

//Функция расчета оценочной функции

unsigned long CChildView::calculate(int id,int x,int y)

{

//Подсчет оценочной функции

//Ставим в массиве временно значение == id

fields[x][y] = id;

int series_length = 0;//Текущая длина ряда

unsigned long sum = 0;//Общее значение оценочной функции

///////////Расчет сверху вниз/////////

//Проход по каждой клетки, которая может входить в ряд

for (int i = 0;i<5;i++)

{

//Проверка, не вышли ли за границы поля

if ((x-4+i) < 0) continue;

if ((x+i) > (size_x - 1)) break;

//Проход по всем возможным рядам, отстоящим от клетки не более чем на 5

for (int j=0;j<5;j++)

{

if ((fields[x-4+i+j][y] != id) && (fields[x-4+i+j][y] != 0))

{

//Конец ряда

series_length = 0;

break;

}

if (fields[x-4+i+j][y] != 0) series_length++; //Ряд увеличивается

}

if (series_length == 1) series_length = 0;//Ряд из самой клетки не учитываем

if (series_length == 5) series_length = 100; //Выигрышная ситуация, ставим большое значение

//Плюсуем серию к общей сумме

unsigned long pow_st = valuation_factor;

if (series_length == 100)

{

if (id == 2)

pow_st = 10000;//Большое значение при своем выигрыше

else

pow_st = 1000; //Большое значение при выигрыше соперника, но меньшее, чем при своем

}

else

{

for (int i=0;i<series_length;i++)//Возводим оценочный коэффициент в степень длины серии

{

pow_st*=valuation_factor;

}

}

sum += pow_st;

series_length = 0;

}

///////////Расчет слева направо/////////

//Проход по каждой клетки, которая может входить в ряд

for (int i = 0;i<5;i++)

{

//Проверка, не вышли ли за границы поля

if ((y-4+i) < 0) continue;

if ((y+i) > (size_y - 1)) break;

//Проход по всем возможным рядам, отстоящим от клетки не более чем на 5

for (int j=0;j<5;j++)

{

if ((fields[x][y-4+i+j] != id) && (fields[x][y-4+i+j] != 0))

{

//Конец ряда

series_length = 0;

break;

}

if (fields[x][y-4+i+j] != 0) series_length++; //Ряд увеличивается

}

if (series_length == 1) series_length = 0; //Ряд из самой клетки не учитываем

if (series_length == 5) series_length = 100; //Выигрышная ситуация, ставим большое значение

//Плюсуем серию к общей сумме

unsigned long pow_st = valuation_factor;

if (series_length == 100)

{

if (id == 2)

pow_st = 10000;//Большое значение при своем выигрыше

else

pow_st = 1000; //Большое значение при выигрыше соперника, но меньшее, чем при своем

}

else

{

for (int i=0;i<series_length;i++)//Возводим оценочный коэффициент в степень длины серии

{

pow_st*=valuation_factor;

}

}

sum += pow_st;

series_length = 0;

}

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

//Проход по каждой клетки, которая может входить в ряд

for (int i = 0;i<5;i++)

{

//Проверка, не вышли ли за границы поля

if ((y-4+i) < 0) continue;

if ((x-4+i) < 0) continue;

if ((x+i) > (size_x - 1)) break;

if ((y+i) > (size_y - 1)) break;

//Проход по всем возможным рядам, отстоящим от клетки не более чем на 5

for (int j=0;j<5;j++)

{

if ((fields[x-4+i+j][y-4+i+j] != id) && (fields[x-4+i+j][y-4+i+j] != 0))

{

//Конец ряда

series_length = 0;

break;

}

if (fields[x-4+i+j][y-4+i+j] != 0) series_length++; //Ряд увеличивается

}

if (series_length == 1) series_length = 0; //Ряд из самой клетки не учитываем

if (series_length == 5) series_length = 100; //Выигрышная ситуация, ставим большое значение

//Плюсуем серию к общей сумме

unsigned long pow_st = valuation_factor;

if (series_length == 100)

{

if (id == 2)

pow_st = 10000;//Большое значение при своем выигрыше

else

pow_st = 1000; //Большое значение при выигрыше соперника, но меньшее, чем при своем

}

else

{

for (int i=0;i<series_length;i++)//Возводим оценочный коэффициент в степень длины серии

{

pow_st*=valuation_factor;

}

}

sum += pow_st;

series_length = 0;

}

///////////Расчет по диагонали с левого нижнего/////////

//Проход по каждой клетки, которая может входить в ряд

for (int i = 0;i<5;i++)

{

//Проверка, не вышли ли за границы поля

if ((y-4+i) < 0) continue;

if ((x+4-i) > (size_x - 1)) continue;

if ((x-i) < 0) break;

if ((y+i) > (size_y - 1)) break;

//Проход по всем возможным рядам, отстоящим от клетки не более чем на 5

for (int j=0;j<5;j++)

{

if ((fields[x+4-i-j][y-4+i+j] != id) && (fields[x+4-i-j][y-4+i+j] != 0))

{

//Конец ряда

series_length = 0;

break;

}

if (fields[x+4-i-j][y-4+i+j] != 0) series_length++; //Ряд увеличивается

}

if (series_length == 1) series_length = 0; //Ряд из самой клетки не учитываем

if (series_length == 5) series_length = 100; //Выигрышная ситуация, ставим большое значение

//Плюсуем серию к общей сумме

unsigned long pow_st = valuation_factor;

if (series_length == 100)

{

if (id == 2)

pow_st = 10000;//Большое значение при своем выигрыше

else

pow_st = 1000; //Большое значение при выигрыше соперника, но меньшее, чем при своем

}

else

{

for (int i=0;i<series_length;i++)//Возводим оценочный коэффициент в степень длины серии

{

pow_st*=valuation_factor;

}

}

sum += pow_st;

series_length = 0;

}

//Возвращаем исходное значение

fields[x][y] = 0;

return sum;

}

//В меню нажата кнопка Новая игра

void CChildView::OnNewGame()

{

new_game(); //Функция начала новой игры

this->OnPaint();

this->Invalidate();

}

//Выбрано поле 10x10

void CChildView::OnX1010()

{

//Ставим галочку в меню

switch (size_x)

{

case 19:

set_chеcked_menu(ID_X1919,ID_X1010);

break;

case 30:

set_chеcked_menu(ID_X3030,ID_X1010);

break;

case 50:

set_chеcked_menu(ID_X5050,ID_X1010);

break;

case 100:

set_chеcked_menu(ID_X100100,ID_X1010);

break;

}

size_x = 10;

size_y = 10;

//Стартуем новую игру

new_game();

//Устанавливаем новые размеры окна

resize_window();

}

//Выбрано поле 19x19

void CChildView::OnX1919()

{

//Ставим галочку в меню

switch (size_x)

{

case 10:

set_chеcked_menu(ID_X1010,ID_X1919);

break;

case 30:

set_chеcked_menu(ID_X3030,ID_X1919);

break;

case 50:

set_chеcked_menu(ID_X5050,ID_X1919);

break;

case 100:

set_chеcked_menu(ID_X100100,ID_X1919);

break;

}

size_x = 19;

size_y = 19;

//Стартуем новую игру

new_game();

//Устанавливаем новые размеры окна

resize_window();

}

//Выбрано поле 19x19

void CChildView::OnX3030()

{

//Ставим галочку в меню

switch (size_x)

{

case 10:

set_chеcked_menu(ID_X1010,ID_X3030);

break;

case 19:

set_chеcked_menu(ID_X1919,ID_X3030);

break;

case 50:

set_chеcked_menu(ID_X5050,ID_X3030);

break;

case 100:

set_chеcked_menu(ID_X100100,ID_X3030);

break;

}

size_x = 30;

size_y = 30;

//Стартуем новую игру

new_game();

//Устанавливаем новые размеры окна

resize_window();

}

//Выбрано поле 50x50

void CChildView::OnX5050()

{

//Ставим галочку в меню

switch (size_x)

{

case 10:

set_chеcked_menu(ID_X1010,ID_X5050);

break;

case 19:

set_chеcked_menu(ID_X1919,ID_X5050);

break;

case 30:

set_chеcked_menu(ID_X3030,ID_X5050);

break;

case 100:

set_chеcked_menu(ID_X100100,ID_X5050);

break;

}

size_x = 50;

size_y = 50;

//Стартуем новую игру

new_game();

//Устанавливаем новые размеры окна

resize_window();

}

//Выбрано поле 100x100

void CChildView::OnX100100()

{

//Ставим галочку в меню

switch (size_x)

{

case 10:

set_chеcked_menu(ID_X1010,ID_X100100);

break;

case 19:

set_chеcked_menu(ID_X1919,ID_X100100);

break;

case 30:

set_chеcked_menu(ID_X3030,ID_X100100);

break;

case 50:

set_chеcked_menu(ID_X5050,ID_X100100);

break;

}

size_x = 100;

size_y = 100;

//Стартуем новую игру

new_game();

//Устанавливаем новые размеры окна

resize_window();

}

//Функция начала новой игры

void CChildView::new_game()

{

if ((old_size_x != 0) || (old_size_y != 0))

{

//Освобождаем память динамических массивов

try

{

for (int i=0;i<old_size_x;i++)

{

delete fields[i];

delete calc_fields[i];

}

delete fields;

delete calc_fields;

}

catch(...)

{

this->MessageBox(CA2T("Ошибка работы с памятью"),0,0);

this->CloseWindow();

}

}

//Присваиваем старым значениям новые

old_size_x = size_x;

old_size_y = size_y;

//Выделяем память под массивы

try

{

fields = new unsigned char*[size_x];

calc_fields = new float*[size_x];

for(int i=0;i<size_x;i++)

{

fields[i] = new unsigned char[size_y];

calc_fields[i] = new float[size_y];

}

}

catch(...)

{

this->MessageBox(CA2T("Ошибка выделения памяти"),0,0);

this->CloseWindow();

}

//Обнуляем массивы

for (int i=0;i<size_x;i++)

for (int j=0;j<size_y;j++)

{

fields[i][j] = 0;

}

//Сбрасываем флаг начала игры

end_game = false;

//Проверяем, не должен ли компьютер ходить первым

if (!player_first_step)

ii();

}

//Установка новых размеров окна

void CChildView::resize_window()

{

//Устанавливаем размеры окна в соответствии с размером поля

RECT Rect;//Размеры внутренней области

RECT WindowRect;//Размеры окна

this->GetWindowRect(&Rect);

this->GetParent()->GetWindowRect(&WindowRect);

this->GetParent()->MoveWindow(WindowRect.left,WindowRect.top,

size_y*15 + 4 + (WindowRect.right - Rect.right) + (Rect.left - WindowRect.left),

size_x*15 + 4 + (WindowRect.bottom - Rect.bottom) + (Rect.top - WindowRect.top),1);

}

//Установка галочки в меню

void CChildView::set_chеcked_menu(unsigned int old_id,unsigned int new_id)

{

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

MENUITEMINFO menuItemInfo;

menuItemInfo.cbSize = sizeof(MENUITEMINFO);

menuItemInfo.fMask = MIIM_STATE;//Работа с состоянием элемента

//Получаем указатель на меню

CMenu *pMenu=this->GetParent()->GetMenu();

//Ставим галочку в новом элементе

menuItemInfo.fState = MFS_CHECKED;

pMenu->SetMenuItemInfoW(new_id,&menuItemInfo,0);

//Снимаем галочку в старом элементе

menuItemInfo.fState = MFS_UNCHECKED;

pMenu->SetMenuItemInfoW(old_id,&menuItemInfo,0);

return;

}

//Выбран первый ход человека

void CChildView::OnStepH()

{

//Ставим галочку в меню

if (player_first_step == false)

set_chеcked_menu(ID_STEP_C,ID_STEP_H);

player_first_step = true;

//Старт новой игры

new_game();

//Перерисовка окна

this->OnPaint();

this->Invalidate();

}

//Выбран первый ход компьютера

void CChildView::OnStepC()

{

//Ставим галочку в меню

if (player_first_step == true)

set_chеcked_menu(ID_STEP_H,ID_STEP_C);

player_first_step = false;

//Старт новой игры

new_game();

//Перерисовка окна

this->OnPaint();

this->Invalidate();

}

//Выбран уровень компьютера - новичок

void CChildView::OnLevelBeg()

{

//Ставим галочку в меню

if (comp_level == 0)

{

set_chеcked_menu(ID_LEVEL_PROF,ID_LEVEL_BEG);

}

else if (comp_level == 1)

{

set_chеcked_menu(ID_LEVEL_AMAT,ID_LEVEL_BEG);

}

comp_level = 2;

attack_factor = 1;

//Старт новой игры

new_game();

//Перерисовка окна

this->OnPaint();

this->Invalidate();

}

//Выбран уровень компьютера - любитель

void CChildView::OnLevelAmat()

{

//Ставим галочку в меню

if (comp_level == 2)

{

set_chеcked_menu(ID_LEVEL_BEG,ID_LEVEL_AMAT);

}

else if (comp_level == 0)

{

set_chеcked_menu(ID_LEVEL_PROF,ID_LEVEL_AMAT);

}

comp_level = 1;

attack_factor = 10;

//Старт новой игры

new_game();

//Перерисовка окна

this->OnPaint();

this->Invalidate();

}

//Выбран уровень компьютера - профессионал

void CChildView::OnLevelProf()

{

//Ставим галочку в меню

if (comp_level == 2)

{

set_chеcked_menu(ID_LEVEL_BEG,ID_LEVEL_PROF);

}

else if (comp_level == 1)

{

set_chеcked_menu(ID_LEVEL_AMAT,ID_LEVEL_PROF);

}

comp_level = 0;

attack_factor = 1;

//Старт новой игры

new_game();

//Перерисовка окна

this->OnPaint();

this->Invalidate();

}

7. Примеры выполнения программы

Примеры выполнения программы приведены на рисунках 2, 3, 4, 5.

Рисунок 2 – Вид окна программе при запуске.


Рисунок 3 – Игровая ситуация при игре на поле 30x30 на сложности любитель.

Рисунок 4 – Выигрыш компьютера при игре на сложности профессионал.


Рисунок 5 – Победа игрока при игре на сложности любитель на поле 30x30.


Выводы

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

В ходе выполнения работы удалось добиться достаточно сильного уровня игры на сложности профессионал.

Разработанный алгоритм был реализован на языке C++ на платформе Microsoft Visual Studio 2008.


Список литературы

1.         Арчер Т., Уайтчепел Э. Visual C++ .NET. Библия пользователя — Вильямс, 2007.

2.         Либерти Д., Джонс Б. Освой самостоятельно C++ за 21 день. — Вильямс, 2007.

3.         Материалы сайта http://www.firststeps.ru/mfc/steps.

4.         Подбельский В.В. Язык C++. — М.:"Финансы и статистика", 2003.


Страницы: 1, 2, 3


Новости

Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

  скачать рефераты              скачать рефераты

Новости

скачать рефераты

Обратная связь

Поиск
Обратная связь
Реклама и размещение статей на сайте
© 2010.