ОГЛАВЛЕНИЕ
- Постановка задачи..................................................3
- Описание структур данных и методов доступа.........................3
- Укруплённый алгоритм...............................................4
- Инструкция по пользованию..........................................6
- Комментированный листинг...........................................8
ПОСТАНОВКА ЗАДАЧИ
Разработать игру “Крестики и нолики” для двух игроков.
Размер поля 20 на 20.
Выигрывает игрок, первым поставивший 5 символов в ряд (по вертикали, горизонтали или диагонали).
ОПИСАНИЕ СТРУКТУРЫДАННЫХ И МЕТОДОВ ДОСТУПА
В программе используются массивы, как одномерные, так и двумерные.
Массив, это именованный набор однотипных переменных, расположенных в памяти непосредственно друг за другом, доступ к которым осуществляется по адресу. Он имеет следующую структуру:
Тип_данных_массива Имя_массива [индекс_элемента_массива]
Тип данных указывает на то, какого типа будут элементы массива, имя и индекс массива позволяют обращаться к конкретному элементу массива. К примеру:
int massive[10];
massive[3]=7;
printf(”%d”,massive[3]); // он выведет число 7.
Отсчёт индексов в массиве ведётся с 0, то есть в моём примере, чтобы обратиться к первому элементу, надо написать (massive[0]). Вот так осуществляется доступ и обращение в одномерном массиве.
В случае двумерного массива (int massive[10][10];) структура массива такова: первый индекс указывает одни из, в данном случае, десяти одномерных массивов, второй индекс указывает на элемент в этих массивах.
УКРУПЛЁННЫЙ АЛГОРИТМ
| |||||||||||
| ||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
| |||||
|
ИНСТРУКЦИЯ ПО ИСПОЛЬЗОВАНИЮ
Кре́стики-но́лики — логическая игра между двумя противниками на квадратном поле 3 на 3 клетки или бо́льшего размера (в частном случае 20 на 20). Один из игроков играет «крестиками», второй — «ноликами».
Правила игры.
Игроки по очереди ставят на свободные клетки поля 20х20 знаки (один всегда крестики, другой всегда нолики). Первый, выстроивший в ряд 5 своих фигур по вертикали, горизонтали или диагонали, выигрывает. Первый ход делает игрок, ставящий крестики.
После запуска программы перед вами появится окно такого типа:
Слева вы видите поле (20x20) и крестик в середине. Так же справа снизу присутствует таймер (если он остановился, значит программа зависла).
У каждого игрока есть 5 клавиш для управления:
- ШАГ ВВЕРХ стрелка вверх (для крестиков) W \ Ц (для ноликов)
- ШАГ ВНИЗ стрелка вниз (для крестиков) S \ Ы(для ноликов)
- ШАГ ВЛЕВО стрелка влево (для крестиков) A \ Ф (для ноликов)
- ШАГ ВПРАВО стрелка вправо (для крестиков) D \ В (для ноликов)
- СДЕЛАТЬ ХОД ENTER (для крестиков) SPASE (для ноликов)
Победит тот, кто первым поставит фигуры в ряд:
В случае, если все клетки закончатся (жуткая игра должна быть), вам выведется сообщение:
Приятной Игры!
КОММЕНТИРОВАННЫЙ ЛИСТИНГ
#include <stdafx.h>
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <process.h>
//Постоянные
#define X_MOVE 1
#define O_MOVE 0
#define UP_X 72
#define DOWN_X 80
#define LEFT_X 75
#define RIGHT_X 77
#define UP_O 119
#define DOWN_O 115
#define LEFT_O 97
#define RIGHT_O 100
#define ENTER 13
#define ESC 27
#define PROBEL 32
#define DRAW 401
#define START_POLE 0
#define END_POLE 21
#define VICTORY_NEEDS 5
void SetColor(int text, int background) //Цвет
{
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdOut, (WORD)((background << 4) | text));
}
void gotoxy(int xpos, int ypos) //Расположение курсора
{
COORD scrn;
HANDLE hOuput = GetStdHandle(STD_OUTPUT_HANDLE);
scrn.X = xpos; scrn.Y = ypos;
SetConsoleCursorPosition(hOuput,scrn);
}
void __cdecl timer(void* pParam) //Таймер в нижней правой части экрана
{
int h1=0,h2=0,m1=0,m2=0,s1=0,s2=0;
gotoxy(68,21);
SetColor(12,0);
printf("TIMER");
for(;;)
{
Sleep(1000);
gotoxy(65,23);
SetColor(12,0);
printf("%d%d: %d%d: %d%d",h1,h2,m1,m2,s1,s2);
if(s2++==9) {s2=0;s1++;}
if(s1==6) {s1=0;m2++;}
if(m2==9) {m2=0;m1++;}
if(m1==6) {m1=0;h2++;}
if(h2==9) {h2=0;h1++;}
if(h1==2) {h1=h2=m1=m2=s1=s2=6;goto end;}
}
end: Sleep(1000);
gotoxy(75,23);
SetColor(12,0);
printf("%d%d: %d%d: %d%d",h1,h2,m1,m2,s1,s2);
}
void Victory_X () //Вывод сообщение в случае победы крестиков
{
int i,j;
char victory_X [5][5]={'\0'};
MessageBeep(MB_ICONEXCLAMATION);
gotoxy(40,10);
SetColor(14, 0);
for(i=0; i<5; i++)
{
victory_X [i][i]='*';
victory_X [i][4-i]='*';
}
for(int i=0,j=0;j!=5;i++)
{
printf("%c",victory_X [i][j]);
if(i==4)
{ j++;i=-1;gotoxy(40,10-j); }
}
gotoxy(50,15);
printf("Hope you enjoy it =)");
getch();
exit(1);
}
void Victory_O () //Вывод сообщения в случае победы ноликов
{
int i,j;
char victory_O [5][5]={'\0'};
MessageBeep(MB_ICONEXCLAMATION);
gotoxy(40,10);
SetColor(14, 0);
for(i=1; i<4; i++)
{
victory_O [i][0]=victory_O [i][4]='*';
victory_O [0][i]=victory_O [4][i]='*';
}
for(int i=0,j=0;j!=5;i++)
{
printf("%c",victory_O [i][j]);
if(i==4)
{ j++;i=-1;gotoxy(40,10-j); }
}
gotoxy(50,15);
printf("Hope you enjoy it =)");
getch();
exit(1);
}
void draw_XO() //Вывод сообщения в случае ничьи
{
int i,j;
char draw_O [5] [5]={'\0'};
char draw_l [5] [5]={'\0'};
MessageBeep(MB_ICONEXCLAMATION);
SetColor(14, 0);
for(i=1; i<4; i++)
{
draw_O [i][0]=draw_O [i][4]='*';
draw_O [0][i]=draw_O [4][i]='*';
}
for(i=0; i<5; i++)
draw_l[i][4-i]='*';
gotoxy(40,10);
for(int i=0,j=0;j!=5;i++)
{
printf("%c",draw_O [i][j]);
if(i==4)
{ j++;i=-1;gotoxy(40,10-j); }
}
gotoxy(46,10);
for(int i=0,j=0;j!=5;i++)
{
printf("%c",draw_l [i][j]);
if(i==4)
{ j++;i=-1;gotoxy(46,10-j); }
}
gotoxy(52,10);
for(int i=0,j=0;j!=5;i++)
{
printf("%c",draw_O [i][j]);
if(i==4)
{ j++;i=-1;gotoxy(52,10-j); }
}
gotoxy(50,15);
printf("Hope you enjoy it =)");
getch();
exit(1);
}
void main()
{
//Начальная заставка
MessageBeep(MB_ICONEXCLAMATION);
Sleep(500);
MessageBeep(MB_ICONEXCLAMATION);
Sleep(500);
MessageBeep(MB_ICONEXCLAMATION);
SetColor(12, 0);
gotoxy(50,1);
printf("Greeting my Lord!");
gotoxy(0,1);
int i, j, step=1, x=11, y=11, count;
char move=26, buf;
char pole[22][22]={'\0'};
for(i=0; i!=22; i++) //Заполнение массива pole (что является Игровым полем^^)
{
pole[0][i]=pole[21][i]='-';
pole[i][0]=pole[i][21]='|';
}
pole[0][0]=pole[0][21]=pole[21][0]=pole[21][21]='*';
gotoxy(1,1);
SetColor(14, 0);
for(i=0, j=0; (j!=22); i++) //Вывод поля на экран
{
printf("%c",pole[j][i]);
if(i==21)
printf("\n ",j++,i=-1);
}
_beginthread(timer, 0, 0);
Sleep(500);
//----------------------------------------------------------------------------------------------------
while(move!=ESC) //Условие выхода их игры, кнопка ESC
{
//----------------------------------------------------------------------------------------------------
if(step%2 == X_MOVE)// Проверка, ходят ли сейчас крестики
{
gotoxy(x+1,y+1);
SetColor(9, 0);
buf=pole[y][x];
printf("X");
gotoxy(-1,-1);
move=getch();
if(move==UP_X||move==DOWN_X||move==RIGHT_X||move==LEFT_X) /*В случае, если будет нажата одна из кнопок вверх, вниз, вправо, влево*/
{
if(buf=='X')
SetColor(12, 0);
if(buf=='O')
SetColor(10, 0);
gotoxy(x+1,y+1);
printf("%c",buf);
if(move==UP_X && y-1!=START_POLE)
y--;
if(move==DOWN_X && y+1!=END_POLE)
y++;
if(move==RIGHT_X && x+1!=END_POLE)
x++;
if(move==LEFT_X && x-1!=START_POLE)
x--;
}
if(move==ENTER && pole[y][x]=='\0') //В случае, если будет нажата кнопка ENTER
{
step++;
pole[y][x]='X';
//up-down Проверка на условие победы
for(count=1,i=1;pole[y+i][x]=='X';i++)
count++;
for(i=1;pole[y-i][x]=='X';i++)
count++;
if(count>=VICTORY_NEEDS) Victory_X ();
//left-right Проверка на условие победы for(count=1,i=1;pole[y][x+i]=='X';i++)
count++;
for(i=1;pole[y][x-i]=='X';i++)
count++;
if(count>=VICTORY_NEEDS) Victory_X ();
//diagonal '/' Проверка на условие победы
for(count=1,i=1;pole[y-i][x+i]=='X';i++)
count++;
for(i=1;pole[y+i][x-i]=='X';i++)
count++;
if(count>=VICTORY_NEEDS) Victory_X ();
//diagonal '\' Проверка на условие победы
for(count=1,i=1;pole[y+i][x+i]=='X';i++)
count++;
for(i=1;pole[y-i][x-i]=='X';i++)
count++;
if(count>=VICTORY_NEEDS) Victory_X ();
}
}
//----------------------------------------------------------------------------------------------------
if(step%2 == O_MOVE) // Проверка, ходят ли сейчас нолики
{
gotoxy(x+1,y+1);
SetColor(9, 0);
buf=pole[y][x];
printf("O");
move=getch();
if(move==UP_O||move==DOWN_O||move==RIGHT_O||move==LEFT_O||move==UP_O 32||move==DOWN_O-32||move==RIGHT_O-32||move==LEFT_O-32) /*В случае, если будет нажата одна из кнопок вверх, вниз, вправо, влево*/
{
if(buf=='X')
SetColor(12, 0);
if(buf=='O')
SetColor(10, 0);
gotoxy(x+1,y+1);
printf("%c",buf);
if((move==UP_O || move==UP_O-32) && y-1!=START_POLE)
y--;
if((move==DOWN_O || move==DOWN_O-32) && y+1!=END_POLE)
y++;
if((move==RIGHT_O || move==RIGHT_O-32) && x+1!=END_POLE)
x++;
if((move==LEFT_O || move==LEFT_O-32) && x-1!=START_POLE)
x--;
}
if(move==PROBEL && pole[y][x]=='\0') //В случае, если будет нажата кнопка ENTER
{
step++;
pole[y][x]='O';
//up-down Проверка на условие победы
for(count=1,i=1;pole[y+i][x]=='O';i++)
count++;
for(i=1;pole[y-i][x]=='O';i++)
count++;
if(count>=VICTORY_NEEDS) Victory_O ();
//left-right Проверка на условие победы
for(count=1,i=1;pole[y][x+i]=='O';i++)
count++;
for(i=1;pole[y][x-i]=='O';i++)
count++;
if(count>=VICTORY_NEEDS) Victory_O ();
//diagonal '/' Проверка на условие победы for(count=1,i=1;pole[y-i][x+i]=='O';i++)
count++;
for(i=1;pole[y+i][x-i]=='O';i++)
count++;
if(count>=VICTORY_NEEDS) Victory_O ();
//diagonal '\' Проверка на условие победы
for(count=1,i=1;pole[y+i][x+i]=='O';i++)
count++;
for(i=1;pole[y-i][x-i]=='O';i++)
count++;
if(count>=VICTORY_NEEDS) Victory_O ();
}
}
//----------------------------------------------------------------------------------------------------
if(step == DRAW) //В случае ничьей
draw_XO();
}
//----------------------------------------------------------------------------------------------------
gotoxy(60,15);
SetColor(14,0);
printf("Buy! Buy!"); //Пока! Пока!
getch();
}