Файл: Курсовая работа по объектноориентированному программированию " Крестикинолики" Студент группы.docx
Добавлен: 07.11.2023
Просмотров: 53
Скачиваний: 3
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Федеральное агентство Российской Федерации по связи и информатизации
Сибирский государственный университет телекоммуникации и информатики
Кафедра ПМиК
Курсовая работа по объектно-ориентированному программированию
“Крестики-нолики”
Выполнил:
Студент группы
ЗП-61 Немытова Анастасия
Проверил: Ситняковская Е.И.
Новосибирск 2019
Задание
Реализовать игру «крестики-нолики» в графическом режиме.
Описание иерархии объектов и методов класса
Родительским классом является класс Figura он состоит из объектов x,y – координаты, color – цвет. Он содержит два метода: Init(…), который инициализирует переменные, передавая их в класс, и Draw(…), который выделяет квадратом ячейку, на которой находится в данным момент игрок. Объекты в нем объявлены как защищенные (protected), т.е. они доступны ему и всем дочерним классам. Методы в общем доступе для всех классов. Полностью все методы и объекты наследуются дочернему классу Point. Point наследует свои методы и объекты трем классам: Field, Cross, Zero. Field содержит метод, позволяющий разлиновать игровое поле, средством рисования четырех квадратов. Метод класса Cross рисует крестик. А Zero рисует нолик.
Также в каждом классе присутствует конструктор, с помощью которого инициализируются две переменные sk – размер стороны квадрата, wd – ширина фигуры (крестика и нолика).
В данной иерархии прослеживаются все свойства объектно-ориентированного программирования. То есть, инкапсуляция, объединение полей данных и действий в одном типе данных. Наследование, наследование методов и объектов дочерним классам. Полиморфизм прослеживается в методе Draw(…), который является виртуальными, т.е. является элементом позднего связывания.
Ход работы
Игровое поле хранится в матрице размером 3 на 3, в которой нули - это пустые места, единицы - крестики
, а двойки - нолики. Игрок играет крестиками и в первой игре ему предоставляется право первого хода. Ставит крестики игрок при помощи передвигающегося с помощью клавиатуры по полю сектора, выделенного желтым цветом. Этот сектор указывает какая ячейка игрового поля сейчас выделена чтобы поставить крестик. Нажимая пробел игрок ставит крестик и сразу после этого ход переход к компьютеру. Действия алгоритма: Если свободен центр поля, то он первым делом поставит нолик туда, а иначе если есть строки где уже заняты две ячейки одинаковыми значками, то он ставит в оставшуюся свободную ячейку, чтобы выиграть или предотвратить свой проигрыш. То же самое для столбцов. Затем он, если не найдет подходящего столбца или строки начинает искать позицию на диагоналях. По такому же принципу. Ищет одну свободную позицию из двух занятых одинаковыми значками. Если же и такой позиции нет, то он поставит крестик в первую попавшуюся клетку согласно прописанному приоритету.
Затем происходит проверка игрового поля на победу одной из сторон или ничью и игра будет продолжаться снова и снов пока игрок не закроет приложение.
Код программы
#include
class Figura{
protected:
int x,y,color,sk,wd;
public:
void Init(int x,int y,int color);
void Draw(int x,int y, int color);
Figura(int sk,int wd);
};
void Figura::Init(int x, int y,int color){
this->x=x;
this->y=y;
this->color=color;
}
Figura::Figura(int sk,int wd){
this->sk=sk;
this->wd=wd;
}
void Figura::Draw(int x,int y,int color){
setcolor(color);
rectangle(x*sk,y*sk,(x+1)*sk,(y+1)*sk);
}
class Point:public Figura{
public:
Point(int sk,int wd);
};
Point::Point(int sk,int wd):Figura(sk,wd){
this->sk=sk;
this->wd=wd;
}
class Field:public Point{
public:
void Draw(int color);
Field(int sk,int wd);
};
Field::Field(int sk,int wd):Point(sk,wd){
this->sk=sk;
this->wd=wd;
}
void Field::Draw(int color){
setcolor(color);
rectangle(0,0,sk*2,sk*2);
rectangle(sk,0,sk*3,sk*2);
rectangle(0,sk,sk*2,sk*3);
rectangle(sk,sk,sk*3,sk*3);
}
class Cross:public Point{
public:
void Draw();
Cross(int sk,int wd);
};
Cross::Cross(int sk,int wd):Point(sk,wd){
this->sk=sk;
this->wd=wd;
}
void Cross::Draw(){
int x1,y1,x2,y2;
setfillstyle(1,3);
x1=x*sk+sk/2-wd/2;
y1=y*sk+1;
x2=x*sk+sk/2+wd/2;
y2=(y+1)*sk-1;
bar(x1,y1,x2,y2);
x1=x*sk+1;
y1=y*sk+sk/2-wd/2;
x2=(x+1)*sk-1;
y2=y*sk+sk/2+wd/2;
bar(x1,y1,x2,y2);
}
class Zero:public Point{
public:
void Draw();
Zero(int sk,int wd);
};
Zero::Zero(int sk,int wd):Point(sk,wd){
this->sk=sk;
this->wd=wd;
}
void Zero::Draw(){
setcolor(0);
setfillstyle(1,4);
fillellipse(x*sk+sk/2,y*sk+sk/2,sk/2-1,sk/2-1);
setfillstyle(5,0);
fillellipse(x*sk+sk/2,y*sk+sk/2,sk/2-1-wd,sk/2-1-wd);
}
#include
#include
#include
#include "class.cpp"
const int sk=200,wd=20;
int a[3][3],x,y;
bool endgame = false;
void newgame(int code);
void test();
int main() {
int i,j,xx,yy;;
Field aa(sk,wd);
Cross b(sk,wd);
Zero c(sk,wd);
Point d(sk,wd);
aa.Init(x,y,8);
d.Init(x,y,14);
for (i=0;i<3;i++)
for (j=0;j<3;j++) a[i][j]=0;
x=y=1;
initwindow(3*sk,3*sk);
while (!endgame) {
if (kbhit()) {
xx=x;
yy=y;
switch (getch()) {
case 72: {d.Draw(x,y,0);y--;} break;
case 80: {d.Draw(x,y,0);y++;} break;
case 75: {d.Draw(x,y,0);x--;} break;
case 77: {d.Draw(x,y,0);x++;} break;
case ' ': {
//--------Õ-------//
int x1,y1,x2,y2;
if (a[x][y]!=0) break;
a[x][y]=1;
b.Init(x,y,5);
b.Draw();
test();
//----------0------//
int x0,y0;
x0=y0=-1;
if (a[1][1]==0) x0=y0=1; else {
for (i=0;i<3;i++) {
if ((((a[i][0]==1)&(a[i][1]==1))|((a[i][0]==2)&(a[i][1]==2)))&(a[i][2]==0)) {
x0=i; y0=2; break;
} else
if ((((a[i][0]==1)&(a[i][2]==1))|((a[i][0]==2)&(a[i][2]==2)))&(a[i][1]==0)) {
x0=i; y0=1; break;
} else
if ((((a[i][1]==1)&(a[i][2]==1))|((a[i][1]==2)&(a[i][2]==2)))&(a[i][0]==0)) {
x0=i; y0=0; break;
} else
if ((((a[0][i]==1)&(a[1][i]==1))|((a[0][i]==2)&(a[1][i]==2)))&(a[2][i]==0)) {
x0=2; y0=i; break;
} else
if ((((a[0][i]==1)&(a[2][i]==1))|((a[0][i]==2)&(a[2][i]==2)))&(a[1][i]==0)) {
x0=1; y0=i; break;
} else
if ((((a[1][i]==1)&(a[2][i]==1))|((a[1][i]==2)&(a[2][i]==2)))&(a[0][i]==0)) {
x0=0; y0=i; break;
}
}
if (x0==-1)
if ((((a[0][0]==1)&(a[1][1]==1))|((a[0][0]==2)&(a[1][1]==2)))&(a[2][2]==0)) {x0=y0=2;} else
if ((((a[1][1]==1)&(a[2][2]==1))|((a[1][1]==2)&(a[2][2]==2)))&(a[0][0]==0)) {x0=y0=0;} else
if ((((a[2][0]==1)&(a[1][1]==1))|((a[2][0]==2)&(a[1][1]==2)))&(a[0][2]==0)) {x0=0; y0=2;} else
if ((((a[0][2]==1)&(a[1][1]==1))|((a[0][2]==2)&(a[1][1]==2)))&(a[2][0]==0)) {x0=2; y0=0;} else
if (a[0][0]==0) {x0=y0=0;} else
if (a[0][2]==0) {x0=0; y0=2;} else
if (a[2][2]==0) {x0=y0=2;} else
if (a[2][0]==0) {x0=2; y0=0;} else
if (a[1][0]==0) {x0=1; y0=0;} else
if (a[2][1]==0) {x0=2; y0=1;} else
if (a[1][2]==0) {x0=1; y0=2;} else
if (a[0][1]==0) {x0=0; y0=1;}
}
if (x0==-1) {
newgame(0); break;
}
a[x0][y0]=2;
c.Init(x0,y0,4);
c.Draw();
test();
}; break;
case 27: endgame=true; break;
}
if (x<0) {x=0;d.Draw(x*sk+sk/2,y*sk+sk/2,14);}
if (y<0) {y=0;d.Draw(x*sk+sk/2,y*sk+sk/2,14);}
if (x>2) {x=2;d.Draw(x*sk+sk/2,y*sk+sk/2,14);}
if (y>2) {y=2;d.Draw(x*sk+sk/2,y*sk+sk/2,14);}
aa.Draw(8);
d.Draw(x,y,14);
}}
closegraph();
}
void newgame(int code) {
int i,j;
setcolor(14);
if (code==0)
outtextxy(sk+sk/2,0,"Íè÷üÿ!"); else
if (code==1)
outtextxy(sk+sk/2,0,"ÏÎÁÅÄÀ!"); else
outtextxy(sk+sk/2,0,"ÏÎÐÀÆÅÍÈÅ!");
getch();
for (i=0;i<3;i++)
for (j=0;j<3;j++) a[i][j]=0;
setfillstyle(1,0);
bar(0,0,sk*3,sk*3);
}
void test() {
int i,j;
setcolor(15);
for (i=0;i<3;i++) {
if ((a[i][0]==a[i][1])&(a[i][0]==a[i][2])&(a[i][0]>0)) {
line(i*sk+sk/2,sk/2,i*sk+sk/2,sk*2+sk/2);
newgame(a[i][0]);
return;
} else
if ((a[0][i]==a[1][i])&(a[0][i]==a[2][i])&(a[0][i]>0)) {
line(sk/2,i*sk+sk/2,sk*2+sk/2,i*sk+sk/2);
newgame(a[0][i]);
return;
}
}
if ((a[0][0]==a[1][1])&(a[0][0]==a[2][2])&(a[0][0]>0)) {
line(sk/2,sk/2,2*sk+sk/2,2*sk+sk/2);
newgame(a[0][0]);
return;
} else
if ((a[2][0]==a[1][1])&(a[2][0]==a[0][2])&(a[1][1]>0)) {
line(2*sk+sk/2,sk/2,sk/2,2*sk+sk/2);
newgame(a[1][1]);
return;
}
for (i=0;i<3;i++)
for (j=0;j<3;j++) if (a[i][j]==0) return;
newgame(0);
}