Программа "Четыре в ряд"
Создание игры "Четыре в ряд", написанная на языке Си в программе Notepad++. Правила игры. Реализация программного кода с комментариями. Функции ввода данных при ходе игрока. Инструкция пользователя. Режим игры "Игра с компьютером". Код программы.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 18.02.2019 |
Размер файла | 70,3 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
[Введите текст]
Федеральное агентство железнодорожного транспорта
Омский государственный университет путей сообщения
Кафедра «Автоматика и системы управления»
Программа «четыре в ряд»
Пояснительная записка к курсовой работе по дисциплине «Программирование»
ИНМВ.400000.000 ПЗ
Омск 2017
Реферат
УДК 004.42
Пояснительная записка к курсовой работе содержит 30 страниц, 5 рисунков, 4 использованных источника.
Объектом курсовой работы является консольная игра «Четыре в ряд».
Цель курсовой работы - получение основных навыков использования языка Си, создание игры с искусственным интеллектом.
Результатом курсовой работы является игра «Четыре в ряд», написанная на языке Си в программе Notepad++.
В процессе создания игры была изучена лексика языка Си.
Пояснительная записка выполнена в текстовом редакторе Microsoft Word 2007.
Содержание
Введение
1. Правила игры
2. Реализация программного кода с комментариями
3. Инструкция пользователя
Заключение
Библиографический список
Приложения
Введение
Си - универсальный язык программирования. Он тесно связан с системой UNIX, так как был разработан в этой системе, которая как и большинство программ, работающих в ней, написаны на Си. Однако язык не привязан жестко к какой-то одной операционной системе или машине. Хотя он и назван "языком системного программирования", поскольку удобен для написания компиляторов и операционных систем, оказалось, что на нем столь же хорошо писать большие программы другого профиля.
Си - язык сравнительно "низкого уровня". Однако это вовсе не умаляет его достоинств, просто Си имеет дело с теми же объектами, что и большинство компьютеров, т. е. с символами, числами и адресами. С ними, можно оперировать при помощи арифметических и логических операций, выполняемых реальными машинами.
В Си нет прямых операций над составными объектами, такими как строки символов, множества, списки и массивы. В нем нет операций, которые бы манипулировали с целыми массивами или строками символов, хотя структуры разрешается копировать целиком как единые объекты. Все это - механизмы высокого уровня, которые в Си обеспечиваются исключительно с помощью явно вызываемых функций. Большинство реализованных Си-систем содержат в себе разумный стандартный набор этих функций.
В продолжение сказанного следует отметить, что Си предоставляет средства лишь последовательного управления ходом вычислений: механизм ветвления по условиям, циклы, составные инструкции, подпрограммы - и не содержит средств мультипрограммирования, параллельных процессов, синхронизации и организации сопрограмм.
Курсовая работа является примером использования языка Си.
1. Правила игры
Четыре в ряд (Гравитрипс) - игра для двоих, в которой игроки ходят по очереди, роняя фишки в ячейки вертикальной доски. Цель игры - расположить раньше противника подряд по горизонтали, вертикали или диагонали четыре фишки своего цвета.
2. Реализация программного кода с комментариями
В программе используются библиотеки:
#include <stdio.h> // библиотека ввода-вывода
#include <stdlib.h> // библиотека функций общего назначения
#include "string.h" //библиотека функций для работы со строками и с памятью
В начале кода игры приведены различные функции для упрощения реализации работы.
Функция, которая печатает на экран текущее состояние игрового поля:
void print_pole(int pole[8][7]){
// Функция выводит на экран игровое поле
// аргументы: int pole[8][7] - игровое поле
int i,j;
printf("|");
for(i=1;i<=7;i++)
printf(" %i |",i);
printf("\n");
for(i=0;i<8;i++){
printf("|");
for(j=0;j<7;j++){
if (pole[i][j]==2) printf(" O |");
if (pole[i][j]==0) printf(" |");
if (pole[i][j]==1) printf(" x |");
}
printf("\n");
}
}
Листинг 1 - Вывод на экран игрового поля
Функция, проверки корректных данных вводимых игроком при ходе:
int hod(){
// Функции ввода данных при ходе Игрока
int a,l;
char c[200];
while(1){
scanf(" %s",c);
l=strlen(c);
if(l==1){
a=(int)c[0]-48;
return a;
}else{
printf(" Некорректные данные, введите цифру от 1 до 7\n");
}
}
}
Листинг 2 - Функции ввода данных при ходе Игрока
Функция, которая проверяет терминальное состояние игрового поля:
int game_over(int pole[8][7]){
// функция проверки терминальное состояние игрового поля.
// int pole[8][7] - текущее значение игрового поля
// возвращает: 1 - при победе крестика; 2 - при победе нолика;
// 3 - при ничьей; иначе возвращает 0
int i,j,t,m=1,f1=56;
//Проверка по горизонтали
for(i=7;i>=0;i--){
for(j=0;j<6;j++){
if(pole[i][j]==pole[i][j+1] && pole[i][j]!=0){
m++;
if(m==4){
if(pole[i][j]==1) return 1;
if(pole[i][j]==2) return 2;
}
}
else
m=1;
}
m=1;
}
//Проверка по вертикали
for(i=0;i<7;i++){
for(j=7;j>0;j--){
if(pole[j][i]==pole[j-1][i] && pole[j][i]!=0){
m++;
if(m==4){
if(pole[j][i]==1) return 1;
if(pole[j][i]==2) return 2;
}
}
else
m=1;
}
m=1;
}
//Проверка по главной диагонали
for(i=7;i>3;i--){
for(j=3;j<7;j++){
for(t=0;t<4;t++){
if(pole[i-t][j-t]==0)
t=4;
if(pole[i-t][j-t]==pole[i-t-1][j-t-1] && pole[i-t][j-t]!=0){
m++;
if(m==4){
if(pole[i-t][j-t]==1) return 1;
if(pole[i-t][j-t]==2) return 2;
}
} else{
m=1;
}
}
m=1;
}
}
//Проверка по побочной диагонали
for(i=7;i>=3;i--){
for(j=3;j>=0;j--){
for(t=0;t<4;t++){
if(pole[i-t][j+t]==0)
t=4;
if(pole[i-t][j+t]==pole[i-t-1][j+t+1] && pole[i-t][j+t]!=0){
m++;
if(m==4){
if(pole[i-t][j+t]==1) return 1;
if(pole[i-t][j+t]==2) return 2;
}
} else{
m=1;
}
}
m=1;
}
}
//проверка на ничью
for(i=0;i<8;i++){
for(j=0;j<7;j++){
if(pole[i][j]!=0){
f1--;
}
}
}
if(f1==0) return 3;
return 0;
}
Листинг 3 - Проверка терминального состояния игрового поля
Функция, которая возвращает значения глобальных переменных в начальные значения:
void oNull(){
int i,j;
for(i=0;i<8;i++){
for(j=0;j<7;j++)
array_pole[i][j]=0;
}
N=5;
slognost=0;
}
Листинг 4 - Обнуляет глобальные значения
После описания всех вспомогательных функций приведены функции для реализации главной части программы, в которой в соответствующих местах кода вызываются описанные данные функции.
Следующий фрагмент кода позволяет игроку совершать свой ход: вводить номер столбца, в который хочет совершить ход. В этом фрагменте вызываются функция проверки терминального состояния игрового поля, проверки введенных игроком данных и функция печати игрового поля.
void hodit_X(char *name1, char *name2){
// Функция хода первого игрока (играет за крестик)
// char *name1 - имя первого игрока (крестик)
// char *name2 - имя второго игрока (нолик)
int stolb, flag=0, rezult;
rezult=game_over(array_pole); // проверка на терминальное состояние
if(rezult==3) { printf("\n Ничья"); return ; }
if(rezult==1) { printf("\n Победил %s",name1); return ; }
if(rezult==2) { printf("\n Победил %s",name2); return ; }
printf(" Ходит %s \n Выбирете столбец: ",name1);
do {
stolb=hod(); // записываем в переменную stolb номер столбца, который выбрал игрок
if(stolb<1 || stolb>7){
printf(" Некорректные данные, попробуйте снова\n");
}
if(array_pole[0][stolb-1]!=0){
printf(" Cтолбец заполнен, выбирете другой:\n");
}
} while((stolb<1 || stolb>7)||(array_pole[0][stolb-1]!=0));
int i;
// Цикл перебирает клетки в столбце снизу вверх до тех пор,
// пока не найдет пустую или не дойдет до конца столбца
for(i=7;i>=0;i--){
if (array_pole[i][stolb-1]==0 && flag==0){
array_pole[i][stolb-1]=1;
flag=1;
}
}
system("cls"); // очистка экрана
print_pole(array_pole); // выводит на экран поле после хода крестика
hodit_O(name2, name1); // вызываем функцию хода второго игрока (нолика)
}
Листинг 5 - Ход игрока
В следующем фрагменте кода приведена стратегия игры компьютера:
int minimax_X(int level, int pole[8][7], int rezult){
//Основное функции ИИ-компьютера
//int level - уровнь глубины вызова функции
//int pole[8][7] - состояние игрового поля
//int rezult - результат работы функции minimax_X при ее рекурсивном вызове
// проверка на терминальное состояние
rezult=game_over(pole);
if(level==0){
printf(" Компьютер думает\n");
if(rezult==1) { printf("\n Вы проиграли "); return ; }
if(rezult==2) { printf("\n Вы победили "); return ; }
if(rezult==3) { printf("\n Ничья"); return ; }
}
if(rezult==1) return 1;
if(rezult==2) return 2;
if(rezult==3) return 0;
int var; //хранит результаты функций poisk_max или poisk_min
int j,k,m,r=0;//переменный используемые для реализации циклов
int b[8][7]; //временный массив, для хранения состояния поля при рекурсивном вызове
struct pustay_kletka mass_index[7]; // массив структур индексов пустых ячеек
int moves_array[7]={0,0,0,0,0,0,0}; //массив возможных ходов
index_array(pole,mass_index); //вызов функции index_array
for(j=0;j<N;j=j*2+2){
for(k=0;k<7;k++){
copy_array(pole,b); // копируем текущее состояние поля во временый массив
if (mass_index[k].i!=-1 && mass_index[k].j!=-1 && b[mass_index[k].i][mass_index[k].j]==0 && k!=7){
if(level%2==0) b[mass_index[k].i][mass_index[k].j]=1;
if(level%2==1) b[mass_index[k].i][mass_index[k].j]=2;
rezult=game_over(b); // запись терминального состояния после хода
if(level<j){ // проверка на мах глубину рекурсии
level++;
moves_array[k] = minimax_X(level,b,rezult);
level--;
} else {
if(rezult==1) moves_array[k] = 1;
if(rezult==2) moves_array[k] = 2;
if(rezult==3 || rezult==0) moves_array[k] = 0;
}
}
if(moves_array[k]==1) j=10; // если найден ход, когда побеждает компьютер, то заканчиваем поиск других вариантов
}
if(j==0){ // если на нулевой глубине вызова функции minimax_X все возвожные варианты ходов приводят к поражению компьютера, то ИИ не производит углубленный поиск
for(m=0;m<7;m++)
if(moves_array[m]==2) r++;
if(r==6) j=10;
}
}
// проверка на заполнение столбецов
for(m=0;m<7;m++){
if(pole[0][m]!=0)
moves_array[m]=-1;
}
// Выполняется только на нулевой глубине вызова функции minimax_X
if(level==0){
print_array(moves_array); // Выводит состояние игрового поля
var=poisk_max(moves_array); // Поик наилучшего хода для компьютера
if(moves_array[var]!=2 && pole[0][var]==0){
if(pole[7][3]==0){ //если первая ячейка центрального столбца
pole[7][3]=1; // свободна, то компьютер ходит туда,
} else{ // иначе ходит в наилучший вариант
pole[mass_index[var].i][mass_index[var].j]=1;
}
} else{
do{ // рандомный выбор хода, если нет лучшего
srand(time(NULL));
var = rand()%7;
if(pole[0][var]==0)
pole[mass_index[var].i][mass_index[var].j]=1;
} while(pole[0][var]!=0);
}
system("cls"); // очистка экрана
print_pole(pole); // Выводит состояние игрового поля
printf("\n Компьютер походил в %i столбик\n",mass_index[var].j+1);
hodit_player_O(pole); // Вызываем функцию хода за Игрока
return ;
}
if(level%2==0)
var=poisk_max(moves_array); // Поик наилучшего хода за Компьютер
if(level%2==1)
var=poisk_min(moves_array); // Поик наилучшего хода за Игрока
return moves_array[var];
}
Листинг 6 - Ход компьютера
3. Инструкция пользователя
При запуске игры игрок попадает в главное меню. Игроку предлагают выбрать режим игры и прочитать правила.
Рисунок 1 - Главное меню игры
При выборе режима игры "Игра с компьютером" на экран выводится пустое игровое поле и начинается игра с компьютером. Случайным образом определяем право первого хода.
игра программа код правило
Рисунок 2 - Начало игры с компьютером
Игрок с компьютером ходят по очереди, стараясь составить комбинацию из 4 своих фишек по вертикали, горизонтали и диагонали.
Рисунок 3 - Игровой процесс
При достижении терминального состояния (победа игрока или компьютера или ничья) на экран выводится соответствующее сообщение
Рисунок 4 - Сообщение о конце партии
При вводе некорректных данных выводится сообщение об ошибки.
Рисунок 5 - Сообщение об ошибки
Заключение
Во время выполнения курсовой работы были изучены принципы программирования на языке Си, были освоены основные концепции и стратегии по созданию консольного приложения «Четыре в ряд», которое является результатом выполнения курсовой работы.
Библиографический список
1. Керниган Б. Язык программирования Си 2-е издание / Б. Керниган Д. Ричи М.: Издательский дом "Вильямс", 2012. 272 с.
2. Википедия. Свободная энциклопедия [Электронный ресурс] / Режим доступа: https:// ru.wikipedia.org/wiki/Четыре_в_ряд
3. Википедия. Свободная энциклопедия [Электронный ресурс] / Режим доступа: https://ru.wikipedia.org/wiki/Си_(язык_программирования)
4. Tproger. Информационный портал [Электронный ресурс] / Режим доступа: https://tproger.ru/translations/tic-tac-toe-minimax/
Приложения
Код программы
#include "stdio.h"
#include <string.h>
#include <stdlib.h>
// Структрура используется в функции index_array для хранения индексов пустных креток.
struct pustay_kletka {
int i;
int j;
};
// Двумерный массив, в котором хранится текущее состояние игрового поля
int array_pole[8][7]={ 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0 };
slognost=0,N=5; //используется при ходе компьютера
// ВСПОМОГАТЕЛЬНЫЙ ФУНКЦИИ ДЛЯ РЕАЛИЗАЦИИ ИГРЫ
void print_pole(int pole[8][7]){
// Функция выводит на экран игровое поле
// аргументы: int pole[8][7] - игровое поле
int i,j;
printf("|");
for(i=1;i<=7;i++)
printf(" %i |",i);
printf("\n");
for(i=0;i<8;i++){
printf("|");
for(j=0;j<7;j++){
if (pole[i][j]==2) printf(" O |");
if (pole[i][j]==0) printf(" |");
if (pole[i][j]==1) printf(" x |");
}
Листинг А.1, лист 1
printf("\n");
}
}
int hod(){
// Функции ввода данных при ходе Игрока
int a,l;
char c[200];
while(1){
scanf(" %s",c);
l=strlen(c);
if(l==1){
a=(int)c[0]-48;
return a;
}else{
printf(" Некорректные данные, введите цифру от 1 до 7\n");
}
}
}
int game_over(int pole[8][7]){
// функция проверки терминальное состояние игрового поля.
// int pole[8][7] - текущее значение игрового поля
// возвращает: 1 - при победе крестика; 2 - при победе нолика;
// 3 - при ничьей; иначе возвращает 0
int i,j,t,m=1,f1=56;
//Проверка по горизонтали
for(i=7;i>=0;i--){
for(j=0;j<6;j++){
if(pole[i][j]==pole[i][j+1] && pole[i][j]!=0){
m++;
//printf("Гор i=%i, j=%i, m=%i\n",i,j,m);
if(m==4){
if(pole[i][j]==1) return 1;
if(pole[i][j]==2) return 2;
}
}
else
m=1;
}
m=1;
Листинг А.1, лист 2
}
//Проверка по вертикали
for(i=0;i<7;i++){
for(j=7;j>0;j--){
if(pole[j][i]==pole[j-1][i] && pole[j][i]!=0){
m++;
//printf("%Верт %i\n",m);
if(m==4){
if(pole[j][i]==1) return 1;
if(pole[j][i]==2) return 2;
}
}
else
m=1;
}
m=1;
}
//Проверка по главной диагонали
for(i=7;i>3;i--){
for(j=3;j<7;j++){
for(t=0;t<4;t++){
if(pole[i-t][j-t]==0)
t=4;
if(pole[i-t][j-t]==pole[i-t-1][j-t-1] && pole[i-t][j-t]!=0){
m++;
//printf("Глав i=%i, j=%i, t=%i m=%i\n",i,j,t,m);
if(m==4){
if(pole[i-t][j-t]==1) return 1;
if(pole[i-t][j-t]==2) return 2;
}
} else{
m=1;
}
}
m=1;
}
}
//Проверка по побочной диагонали
for(i=7;i>=3;i--){
for(j=3;j>=0;j--){
for(t=0;t<4;t++){
Листинг А.1, лист 3
if(pole[i-t][j+t]==0)
t=4;
if(pole[i-t][j+t]==pole[i-t-1][j+t+1] && pole[i-t][j+t]!=0){
m++;
//printf("Побоч %i\n",m);
if(m==4){
if(pole[i-t][j+t]==1) return 1;
if(pole[i-t][j+t]==2) return 2;
}
} else{
m=1;
}
}
m=1;
}
}
//проверка на ничью
for(i=0;i<8;i++){
for(j=0;j<7;j++){
if(pole[i][j]!=0){
f1--;
//printf(" %i\n",f1);
}
}
}
if(f1==0) return 3;
return 0;
}
void oNull(){
// функция возвращает значения глобальных переменных в начальные значения
int i,j;
for(i=0;i<8;i++){
for(j=0;j<7;j++)
array_pole[i][j]=0;
}
N=5;
slognost=0;
}
Листинг А.1, лист 4
// ФУНКЦИИ ДЛЯ РЕАЛИЗАЦИИ РЕЖИМА ИГРЫ "ЧЕЛОВЕК С ЧЕЛОВЕКОМ"
void hodit_X(char *name1, char *name2){
// Функция хода первого игрока (играет за крестик)
// char *name1 - имя первого игрока (крестик)
// char *name2 - имя второго игрока (нолик)
int stolb, flag=0, rezult;
rezult=game_over(array_pole); // проверка на терминальное состояние
if(rezult==3) { printf("\n Ничья"); return ; }
if(rezult==1) { printf("\n Победил %s",name1); return ; }
if(rezult==2) { printf("\n Победил %s",name2); return ; }
printf(" Ходит %s \n Выбирете столбец: ",name1);
do {
stolb=hod(); // записываем в переменную stolb номер столбца, который выбрал игрок
if(stolb<1 || stolb>7){
printf(" Некорректные данные, попробуйте снова\n");
}
if(array_pole[0][stolb-1]!=0){
printf(" Cтолбец заполнен, выбирете другой:\n");
}
} while((stolb<1 || stolb>7)||(array_pole[0][stolb-1]!=0));
int i;
// Цикл перебирает клетки в столбце снизу вверх до тех пор,
// пока не найдет пустую или не дойдет до конца столбца
for(i=7;i>=0;i--){
if (array_pole[i][stolb-1]==0 && flag==0){
array_pole[i][stolb-1]=1;
flag=1;
}
}
system("cls"); // очистка экрана
print_pole(array_pole); // выводит на экран поле после хода крестика
hodit_O(name2, name1); // вызываем функцию хода второго игрока (нолика)
}
void hodit_O(char *name2, char *name1){
// Функция хода второго игрока (играет за нолик)
// char *name1 - имя первого игрока (крестик)
// char *name2 - имя второго игрока (нолик)
Листинг А.1, лист 5
int stolb, flag=0, rezult;
rezult=game_over(array_pole); // проверка на терминальное состояние
if(rezult==3) { printf("\n Ничья"); return ; }
if(rezult==1) { printf("\n Победил %s",name1); return ; }
if(rezult==2) { printf("\n Победил %s",name2); return ; }
printf(" Ходит %s \n Выбирете столбец: ",name2);
do {
stolb=hod(); // записываем в переменную stolb номер столбца, который выбрал игрок
if(stolb<1 || stolb>7){
printf(" Некорректные данные, попробуйте снова\n");
}
if(array_pole[0][stolb-1]!=0){
printf(" Cтолбец заполнен, выбирете другой:\n");
}
} while((stolb<1 || stolb>7)||(array_pole[0][stolb-1]!=0));
int i;
// Цикл перебирает клетки в столбце снизу вверх до тех пор,
// пока не найдет пустую или не дойдет до конца столбца
for(i=7;i>=0;i--){
if (array_pole[i][stolb-1]==0 && flag==0){
array_pole[i][stolb-1]=2;
flag=1;
}
}
system("cls"); // очистка экрана
print_pole(array_pole); // выводит на экран поле после хода нолика
hodit_X(name1, name2); // вызываем функцию хода первого игрока (крестик)
}
// ФУНКЦИИ ДЛЯ РЕАЛИЗАЦИИ РЕЖИМА ИГРЫ "ЧЕЛОВЕК С КОМПЬЮТЕРОМ"
void copy_array(int pole_C[8][7], int pole_V[8][7]){
//Функция используется для копирования состояние поля во временый массив
//int pole_C[8][7] - исходный массив, который копируем
//int pole_V[8][7] - массив, в который копируем значения исходного массива
int i,j;
Листинг А.1, лист 6
for(i=0;i<8;i++){
for(j=0;j<7;j++)
pole_V[i][j]=pole_C[i][j];
}
}
void index_array(int pole[8][7], struct pustay_kletka *mass){
//Функция находит индексы пустых клеток, куда можно совершить ход
//int pole[8][7] - состояние игрового поля.
//struct pustay_kletka *mass - массив для хранения индексов пустых клеток
int i,j,k=0;
for(j=0;j<7;j++){
for(i=7;i>=0;i--){
if(k<7 && pole[i][j]==0){
mass[k].i=i;
mass[k].j=j;
k++;
i=-1;
}
// проверка на заполненый столбец
// если столбец заполнен, то индексы принимают значения -1
if(pole[0][j]!=0){
mass[k].i=-1;
mass[k].j=-1;
k++;
i=-1;
}
}
}
}
int poisk_max(int *mass){
//Функция находит максимально выгодное значение индекса столбца,
//куда можно походить при ходе КРЕСТИКА
//int *mass - массив хранящий индексы пустых клеток
//Функия возвращает индекс элемента массива, где хранятся индексы пустых клеток
int i,j;
if(mass[3]==1) return 3;
if(mass[4]==1) return 4;
if(mass[2]==1) return 2;
if(mass[5]==1) return 5;
Листинг А.1, лист 7
if(mass[1]==1) return 1;
if(mass[6]==1) return 6;
if(mass[0]==1) return 0;
srand(time(NULL));
for(i=0;i<20000;i++){
j = rand()%7;
//printf(" РАНДОМ МАХ j=%i\n",j);
if(mass[j]==0) return j;
}
for(i=0;i<7;i++){
//printf(" РАНДОМ БЕЗЫСХОДНОСТИ i=%i\n",i);
if(mass[i]==2) return i;
}
}
int poisk_min(int *mass){
//Функция находит максимально выгодное значение индекса столбца,
//куда можно походить при ходе НОЛИКА
//int *mass - массив хранящий индексы пустых клеток
//Функия возвращает индекс элемента массива, где хранятся индексы пустых клеток
int i,j;
if(mass[3]==2) return 3;
if(mass[4]==2) return 4;
if(mass[2]==2) return 2;
if(mass[5]==2) return 5;
if(mass[1]==2) return 1;
if(mass[6]==2) return 6;
if(mass[0]==2) return 0;
srand(time(NULL));
for(i=0;i<20000;i++){
j = rand()%7;
//printf(" РАНДОМ МИН j=%i\n",j);
if(mass[j]==0) return j;
}
for(i=0;i<7;i++){
//printf(" РАНДОМ БЕЗЫСХОДНОСТИ i=%i\n",i);
if(mass[i]==1) return i;
}
}
int print_array(int *mass){
Листинг А.1, лист 8
//функция распечатывает отладночное сообщение
int i;
for(i=0;i<7;i++){
printf("moves_array[%i]=%i\n",i,mass[i]);;
}
}
int minimax_X(int level, int pole[8][7], int rezult){
//Основное функции ИИ-компьютера
//int level - уровнь глубины вызова функции
//int pole[8][7] - состояние игрового поля
//int rezult - результат работы функции minimax_X при ее рекурсивном вызове
// проверка на терминальное состояние
rezult=game_over(pole);
if(level==0){
printf(" Компьютер думает\n");
if(rezult==1) { printf("\n Вы проиграли "); return ; }
if(rezult==2) { printf("\n Вы победили "); return ; }
if(rezult==3) { printf("\n Ничья"); return ; }
}
if(rezult==1) return 1;
if(rezult==2) return 2;
if(rezult==3) return 0;
int var; //хранит результаты функций poisk_max или poisk_min
int j,k,m,r=0; //переменный используемые для реализации циклов
int b[8][7]; //временный массив, для хранения состояния поля при
//рекурсивном вызове
struct pustay_kletka mass_index[7]; // массив структур
// индексов пустых ячеек
int moves_array[7]={0,0,0,0,0,0,0}; //массив возможных ходов
index_array(pole,mass_index); //вызов функции index_array
for(j=0;j<N;j=j*2+2){
for(k=0;k<7;k++){
copy_array(pole,b); // копируем текущее состояние поля во
// временый массив
Листинг А.1, лист 9
if (mass_index[k].i!=-1 && mass_index[k].j!=-1 && b[mass_index[k].i][mass_index[k].j]==0 && k!=7){
if(level%2==0) b[mass_index[k].i][mass_index[k].j]=1;
if(level%2==1) b[mass_index[k].i][mass_index[k].j]=2;
rezult=game_over(b); // запись терминального состояния
// после хода
if(level<j){ // проверка на мах глубину рекурсии
level++;
moves_array[k] = minimax_X(level,b,rezult);
level--;
} else {
if(rezult==1) moves_array[k] = 1;
if(rezult==2) moves_array[k] = 2;
if(rezult==3 || rezult==0) moves_array[k] = 0;
}
}
if(moves_array[k]==1) j=10; // если найден ход, когда побеждает компьютер, то заканчиваем поиск других вариантов
}
if(j==0){ // если на нулевой глубине вызова функции minimax_X
// все возвожные варианты ходов приводят к поражению
// компьютера, то ИИ не производит углубленный поиск
for(m=0;m<7;m++)
if(moves_array[m]==2) r++;
if(r==6) j=10;
}
}
// проверка на заполнение столбецов
for(m=0;m<7;m++){
if(pole[0][m]!=0)
moves_array[m]=-1;
}
// Выполняется только на нулевой глубине вызова функции minimax_X
if(level==0){
print_array(moves_array); // Выводит состояние игрового поля
var=poisk_max(moves_array); // Поик наилучшего хода для компьютера
Листинг А.1, лист 10
if(moves_array[var]!=2 && pole[0][var]==0){
if(pole[7][3]==0){ // если первая ячейка центрального столбца
pole[7][3]=1; // свободна, то компьютер ходит туда,
} else{ // иначе ходит в наилучший вариант
pole[mass_index[var].i][mass_index[var].j]=1;
}
} else{
do{ // рандомный выбор хода, если нет лучшего
srand(time(NULL));
var = rand()%7;
if(pole[0][var]==0)
pole[mass_index[var].i][mass_index[var].j]=1;
} while(pole[0][var]!=0);
}
system("cls"); // очистка экрана
print_pole(pole); // Выводит состояние игрового поля
printf("\n Компьютер походил в %i столбик\n",mass_index[var].j+1);
hodit_player_O(pole); // Вызываем функцию хода за Игрока
return ;
}
if(level%2==0)
var=poisk_max(moves_array); // Поик наилучшего хода за Компьютер
if(level%2==1)
var=poisk_min(moves_array); // Поик наилучшего хода за Игрока
return moves_array[var];
}
void hodit_player_O(int pole[8][7]){
//Функция хода игрока (нолик)
//int pole[8][7] - состояние игрового поля
slognost++; //счетчик количества сделаных ходов игроком
if(slognost==13) N=7; //после 13-го хода игрока глубина рекурсивного вызова функции minimax_X увеличивается с 5 до 7
int stolb, flag=0, rezult;
rezult=game_over(pole);
Листинг А.1, лист 11
if(rezult==3) { printf("\nНичья "); return ; }
if(rezult==1) { printf("\n Вы проиграли. "); return ; }
if(rezult==2) { printf("\n Вы победили. "); return ; }
printf(" Ваш ход \n Выбирете столбец: ");
do {
stolb=hod(); // записываем в переменную stolb номер столбца, который выбрал игрок
if(stolb<1 || stolb>7){
printf(" Некорректные данные, попробуйте снова\n");
}
if(array_pole[0][stolb-1]!=0){
printf(" Cтолбец заполнен, выбирете другой:\n");
}
} while((stolb<1 || stolb>7)||(array_pole[0][stolb-1]!=0));
int i;
// Цикл перебирает клетки в столбце снизу вверх до тех пор,
// пока не найдет пустую или не дойдет до конца столбца
for(i=7;i>=0;i--){
if(pole[0][stolb-1]!=0){
printf(" Cтолбец заполнен, выбирете другой:\n");
hodit_player_O(pole);
return ;
}
if (pole[i][stolb-1]==0 && flag==0){
pole[i][stolb-1]=2;
flag=1;
}
}
system("cls"); // очистка экрана
print_pole(pole); // выводит на экран поле после хода нолика
minimax_X(0,pole,0); // вызываем функцию хода компьютера (крестик)
return ;
}
int main(){
int h,l,k=1,massiv[14],regim,chislo,cikl1=1;
char c[20];
char player1[21], player2[21];
printf(" Добро пожаловать в игру ЧЕТЫРЕ В РЯД \n\n");
Листинг А.1, лист 12
while(k){
printf(" Выберете режим игры:\n 1 - Игра с компьютером.\n 2 - Игрок против игрока. \n 3 - Правила.\n 4 - Выход.\n ");
cikl1=1;
while(cikl1){
scanf(" %s",c);
l=strlen(c);
if(l==1){
regim=(int)c[0]-48;
if(regim>0 && regim<5)
cikl1=0;
else printf(" Некорректные данные, введите цифру от 1 до 4\n");
}else{
printf(" Некорректные данные, введите цифру от 1 до 4\n");
}
}
if(regim==4){
k=0;
}
if(regim==1){
cikl1=1;
while(cikl1){
system("cls");
srand(time(NULL));
chislo = rand();
if(chislo%2==0){
print_pole(array_pole);
hodit_player_O(array_pole);
} else {
array_pole[7][3]=1;
print_pole(array_pole);
hodit_player_O(array_pole);
}
oNull();
printf("\n Сыграть ещё раз?\n 1 - Да!\n 2 - Нет. \n ");
scanf("%i",&cikl1);
system("cls");
Листинг А.1, лист 13
if(cikl1==2) cikl1=0;
}
}
if(regim==2){
printf("Ведите имя первого игрока: ");
scanf("%s",player1);
printf("\nВедите имя второго игрока: ");
scanf("%s",player2);
cikl1=1;
while(cikl1){
system("cls");
print_pole(array_pole);
srand(time(NULL));
chislo = rand();
if(chislo%2==0)
hodit_X(player1, player2);
else
hodit_O(player2, player1);
oNull();
printf("\n Сыграть ещё раз?\n 1 - Да!\n 2 - Нет. \n ");
scanf("%i",&cikl1);
system("cls");
if(cikl1==2) cikl1=0;
}
}
if(regim==3){
printf(" Четыре в ряд (Гравитрипс) - игра для двоих, в которой игроки ходят по очереди, роняя фишки в ячейки вертикальной доски. Цель игры - расположить раньше противника подряд по горизонтали, вертикали или диагонали четыре фишки своего цвета.\n\n");
}
}
}
Листинг А.1, лист 14
Размещено на Allbest.ru
...Подобные документы
Знакомство с интерфейсом пользователя и сценарием использования программы игры в крестики и нолики. Функциональные и нефункциональные требования для персонального компьютера. Исключительные ситуации и реакция программы. Пример кода игры и комментарии.
курсовая работа [236,5 K], добавлен 27.01.2014Игровая программа "шашки" для игры между человеком и компьютером. Разработка алгоритмов, историческая линия развития задач. Различные подходы к построению систем. Сокращенный листинг программы и описание алгоритма. Компоненты искусственного интеллекта.
курсовая работа [196,2 K], добавлен 26.03.2009Программная реализация игры, необходимость наличия файла Arcanoid.exe. Список файлов, технические требования, состав программы. Алгоритм игры. Основные достоинства данного программного продукта, системные требования и руководство пользователя.
курсовая работа [753,6 K], добавлен 28.12.2011История возникновения и происхождения игры в шашки, ее популярность. Классификация шашечных игр по размерам доски и особенностям правил, виды и варианты шашек. Правила воспроизведения сражений в "Русские шашки". Составление алгоритма и кода программы.
курсовая работа [250,3 K], добавлен 28.01.2012Разработка и создание игры "Змейка". Использование динамически-активных принципов языка Java. Графические объекты программы. Описание игры, правила, теоретические сведения. Классы приложения. Типы данных. Реализация. Метод. Объект. Блок-схема игры.
курсовая работа [12,4 K], добавлен 18.06.2008Реализация программы для решения матричных игр. Задание матрицы игры вручную и случайным образом, нахождение оптимальных стратегий игроков итерационным и методом чистых стратегий. Проектирование и листинг программного кода, сохранение матрицы игры.
контрольная работа [716,7 K], добавлен 11.06.2011Описание принципа развивающей игры в слова "Виселица". Разработка программы, реализующей задачу данной игры на языке Delphi. Обоснование выбора среды программирования, листинг файла, результаты отладки и тестирования, руководство для пользователя.
курсовая работа [572,7 K], добавлен 14.07.2012Обоснование необходимости разработки программы для игры "Тетрис". Математическая и графическая части алгоритма. Выбор языка и среды программирования. Отладка текста программы, разработка интерфейса пользователя. Тестирование, руководство пользователя.
курсовая работа [1,5 M], добавлен 17.01.2011История развития языка программирования Java. История тетриса - культовой компьютерной игры, изобретённой в СССР. Правила проведения игры, особенности начисления очков. Создание интерфейса программы, ее реализация в среде Java, кодирование, тестирование.
курсовая работа [168,1 K], добавлен 27.09.2013Создание программы "компьютерная игра "баскетбол", с упрощенным изображением баскетбольного щита и игрока, с возможностью изменять положение игрока, направление броска и его силу. Построение алгоритма, описание процедур и функций, таблица идентификаторов.
дипломная работа [72,7 K], добавлен 29.11.2011Разработка компьютерной игры "Эволюция" с помощью игрового движка Unit. Сравнение критериев игры-аналога и разрабатываемой игры. Разработка графического интерфейса пользователя. Настройки камеры в редакторе Unity. Структура файла сохранения игры.
дипломная работа [3,6 M], добавлен 11.02.2017Технические и пользовательские характеристики игры, требования к программному обеспечению и среде разработки C#. Составление блок-схемы алгоритма, uml-диаграммы и текста программы, тестирование корректности компьютерного кода и результатов его работы.
курсовая работа [1,8 M], добавлен 05.03.2013Методика и основные этапы разработки стратегической игры, ее элементы и принцип работы программы. Порядок построения информационной модели. Диаграмма потоков данных и действий. Выбор языка программирования и его обоснование. Критерии качества среды.
курсовая работа [3,5 M], добавлен 11.12.2012Разработка программы казуальной игры "Zuma Deluxe" на языке С\С++. Использование стиля древних инков и ацтеков, возможностей графического движка HGE version 1.53. Назначение основных классов игры. Руководство пользователя, содержание главного меню.
курсовая работа [8,3 M], добавлен 28.10.2014Разработка программы, моделирующей игру "Кости". Использование в программе генератора псевдослучайных чисел. Схема иерархии модулей. Описание работы программы. Регистрация игрока, окно программы. Определение языка программирования, основные операторы.
курсовая работа [3,2 M], добавлен 29.07.2010Проектирование игры "Морской бой" путем составления диаграмм UML, IDEF0, DFD, моделирующих требования к программе. Разработка программы с использованием языка C# и фреймворка.NETFramework 3.5. Тестирование белого ящика и альфа-тестирование продукта.
курсовая работа [3,9 M], добавлен 24.10.2013Приемы программирования в Delphi. Алгоритм поиска альфа-бета отсечения, преимущества. Описание программного средства. Разработка программы, реализующая алгоритм игры "реверси". Руководство пользователя. Листинг программы. Навыки реализации алгоритмов.
курсовая работа [357,1 K], добавлен 28.02.2011Особенности программирования аркадных игр в среде Python. Краткая характеристика языка программирования Python, его особенности и синтаксис. Описание компьютерной игры "Танчики" - правила игры, пояснение ключевых строк кода. Демонстрация работы программы.
курсовая работа [160,3 K], добавлен 03.12.2014Проектирование программного средства "База данных". Классификация юнитов онлайн игры "World of Tanks". Разработка диаграмм прецедентов, развертывания и деятельности. Руководство пользователя. Тестирование приложения, программа и методика испытаний.
курсовая работа [920,4 K], добавлен 17.08.2013Алгоритмическое представление и описание правил игры "Эволюция". Построение диаграммы прецедентов. Разработка графического интерфейса пользователя. Реализация интерфейса в среде Unity. Структура файла сохранения игры. Проектирование поведения компьютера.
дипломная работа [3,3 M], добавлен 18.02.2017