Количество палуб col_dec = 4
Количество кораблей col_ship = 1
|
col_ship < = 10
|
|
k от 0 до col_ship
|
|
i от 0 до 10
|
|
j от 0 до 10
|
|
j от 0 до col_dec
|
|
Может ли здесь находиться данная палуба?
Да Нет
|
|
новые координаты
корабля
|
col_ship = 1?
Да Нет
|
col_dec = 3
|
|
col_ship = 3?
Да Нет
|
col_dec = 2
|
|
col_ship = 6?
Да Нет
|
col_dec = 1
|
|
col_ship = col_ship + 1
|
Рис. 6.
Функция Disposition или Generation
Чтобы
проверить корректность работы программы нужно провести тестирование. Бой с
противником продолжается до полной победы, т.е. пока не будут уничтожены все 10
кораблей одного из противников.
Если первым
свои корабли потерял компьютер, игроку выводится сообщение о победе
Рис. 7.
Сообщение о победе
Если первым
свои корабли потерял игрок, ему выводится сообщение о проигрыше
Рис. 8.
Сообщение о проигрыше
В начале игры
выводится приглашение к расстановке кораблей:
Рис. 9.
Расстановка кораблей
Если игрок
выполнил недопустимое действие (например, попытался «наложить» корабль на
корабль) ему будет выведено предупреждающее сообщение о его ошибке.
Если
расстановка кораблей закончилась выводится приглашение к началу игры
Рис. 10.
Начало игры
В случае
промаха игроку выводится сообщение о промахе
Рис. 11.
Сообщение о промахе
В случае
попадания игроку выводится сообщение о попадании
Рис. 12
Сообщение о попадании
В случае
попадания в ячейку, которая уже обстреляна, игроку выводится сообщение с
предложением выстрелить ещё раз
Рис. 13.
Сообщение о выстреле в обстрелянную ячейку
Анализ работы
В процессе
выполнения данного курсового проекта были закреплены знания по использованию
классов и использованию основ объектно-ориентированного программирования.
Конец игры
предусмотрен в двух случаях: победа пользователя или победа компьютера. Также в
процессе написания программы были рассмотрены все варианты некорректной работы
программы, например: не размещает ли компьютер и пользователь корабли в
соседних клетках, не ставит ли он корабли только в углах игрового поля, не
накладываются ли корабли один на другой. Также проверяется соответствие
количества кораблей и палуб на них (1 четырехпалубный, 2 трехпалубных, 3
двухпалубных, 1 однопалубных). Все вышеописанные неполадки были обнаружены и
успешно устранены.
Во время
написания программы я получил навыки по использованию некоторых, ранее не
использованных мной, компонентов среды программирования С++ Builder 6.
Также при
написании данного курсового проекта я закрепил свои знания в области написания
объектно-ориентированных программ, содержащих взаимодействующие классы. Были
получены новые знания о создании классов и работе с ними. Благодаря работе над
программой были закреплены знания распределения обязанностей между классами.
Текст
программы состоит из следующих модулей: UShipBattle.h, UShipBattle.cpp,
ShipBattle.cpp
ShipBattle.cpp
// –
#include
<vcl.h>
#pragma
hdrstop
//
–
USEFORM
(«UShipBattle.cpp», Form1);
//
–
WINAPI
WinMain (HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->CreateForm
(__classid(TForm1), &Form1);
Application->Run();
}
catch
(Exception &exception)
{
Application->ShowException(&exception);
}
catch
(…)
{
try
{
throw
Exception(«»);
}
catch
(Exception &exception)
{
Application->ShowException(&exception);
}
}
return
0;
}
//
–
UShipBattle.cpp
// –
#include
<vcl.h>
#pragma
hdrstop
#include
«UShipBattle.h»
//
–
#pragma
package (smart_init)
#pragma
resource «*.dfm»
TForm1
*Form1;
//
–
__fastcall
TForm1:TForm1 (TComponent* Owner)
:
TForm(Owner)
{
HE
= new HandlersOfEvents (Fild1, Fild2);
}
//
–
int
Flot: GetStatus()
{
destroy
= true;
for
(j = 0; j < 10; j++)
for
(i = 0; i < ship[j].col_deck; i++)
if
(ship[j].decks[i])
{
destroy
= false;
return
1;
}
return
0;
}
//
–
int
AI: Generation (Flot *CPU, int col_ship, int col_deck)
{
int
x1, y1, k, i, j;
bool
vertical = false, regen;
do
{
randomize();
x1
= rand()% 10;
y1
= rand()% 10;
regen
= false;
for
(k = 0; k < col_deck; k++)
for
(i = 0; i < col_ship; i++)
for
(j = 0; j < CPU -> ship[i].col_deck; j++)
{
if(regen)
break;
if(!
vertical)
{
if((CPU
-> ship[i].desp_of_part[j].x == x1 + k &&
CPU
-> ship[i].desp_of_part[j].y == y1) || (x1 + k >= 10))
{
vertical
= true;
regen
= true;
continue;
}
if((CPU
-> ship[i].desp_of_part[j].x – 1 == x1 + k ||
CPU
-> ship[i].desp_of_part[j].x + 1 == x1 + k) &&
(CPU
-> ship[i].desp_of_part[j].y – 1 == y1 ||
CPU
-> ship[i].desp_of_part[j].y + 1 == y1))
{
vertical
= true;
regen
= true;
continue;
}
}
if(vertical)
{
if((CPU
-> ship[i].desp_of_part[j].x == x1 &&
CPU
-> ship[i].desp_of_part[j].y == y1 + k) ||
(y1
+ k >= 10))
{
vertical
= false;
regen
= true;
continue;
}
if((CPU
-> ship[i].desp_of_part[j].x – 1 == x1 ||
CPU
-> ship[i].desp_of_part[j].x + 1 == x1) &&
(CPU
-> ship[i].desp_of_part[j].y – 1 == y1 + k ||
CPU
-> ship[i].desp_of_part[j].y + 1 == y1 + k))
{
vertical
= true;
regen
= true;
continue;
}
}
}
} while(regen);
if(!
vertical)
for
(i = 0; i < col_deck; i++)
{
CPU
-> ship [col_ship – 1].desp_of_part[i].x = x1 + i;
CPU
-> ship [col_ship – 1].desp_of_part[i].y = y1;
}
else
for
(i = 0; i < col_deck; i++)
{
CPU
-> ship [col_ship – 1].desp_of_part[i].x = x1;
CPU
-> ship [col_ship – 1].desp_of_part[i].y = y1 + i;
}
return
0;
}
//
–
int
Referee: GoChecking (int x, int y, int n)
{
if
(n == 1)
if
(! Check(net1, x, y))
return
0;
if
(n == 2)
if
(! Check(net2, x, y))
return
0;
return
1;
}
//
–
int
Referee: Check (bool net[10] [10], int x, int y)
{
x
/= 20; y /= 20;
if
(! net[x] [y]) return 0;
}
//
–
int
Referee: GoScaning (int x, int y, int n)
{
if
(n == 1)
if
(! Scan(player, x, y))
return
0;
if
(n == 2)
if
(! Scan(CPU, x, y))
return
0;
return
1;
}
//
–
int
Referee: Scan (Flot *fl, int x, int y)
{
x
/= 20; y /= 20;
for
(i = 0; i < 10; i++)
for
(j = 0; j < fl -> ship[i].col_deck; j++)
if
(fl -> ship[i].desp_of_part[j].x == x &&
fl
-> ship[i].desp_of_part[j].y == y)
{
fl
-> ship[i].decks[j] = false;
return
0;
}
return
1;
}
//
–
int
Referee: Miss (int x, int y, int n)
{
x
/= 20; y /= 20;
if
(n == 1) net1 [x] [y] = false;
if
(n == 2) net2 [x] [y] = false;
return
1;
}
//
–
int
Referee: EndRaund (int n)
{
if
(n == 2)
Form1
-> Panel2 -> Caption = «Вы победили!»;
if
(n == 1)
Form1
-> Panel2 -> Caption = «Вы проиграли!»;
game_over
= true;
return
0;
}
//
–
int
HandlersOfEvents: Play (TImage *Im1, TImage *Im2)
{
Im1
-> Enabled = true;
Im2
-> Enabled = true;
return
0;
}
//
–
int
HandlersOfEvents: Desposition (int x, int y, TMouseButton Button)
{
if(play)
return 0;
x
/= 20; y /= 20;
for
(k = 0; k < col_deck; k++)
for
(i = 0; i < col_ship; i++)
for
(j = 0; j < player -> ship[i].col_deck; j++)
{
if
(Button == mbLeft)
{
if
(player -> ship[i].desp_of_part[j].x == x + k &&
player
-> ship[i].desp_of_part[j].y == y)
{
ShowMessage («Невозможно выполнить
действие!»);
return 0;
}
if (x + k >= 10)
{
ShowMessage («Невозможно выполнить
действие!»);
return
0;
}
if((player
-> ship[i].desp_of_part[j].x – 1 == x + k ||
player
-> ship[i].desp_of_part[j].x + 1 == x + k) &&
(player
-> ship[i].desp_of_part[j].y – 1 == y ||
player
-> ship[i].desp_of_part[j].y + 1 == y))
{
ShowMessage («Невозможно выполнить
действие!»);
return 0;
}
}
if
(Button == mbRight)
{
if
(player -> ship[i].desp_of_part[j].x == x &&
player
-> ship[i].desp_of_part[j].y == y + k)
{
ShowMessage («Невозможно выполнить
действие!»);
return 0;
}
if (y + k >= 10)
{
ShowMessage («Невозможно выполнить
действие!»);
return
0;
}
if((player
-> ship[i].desp_of_part[j].x – 1 == x ||
player
-> ship[i].desp_of_part[j].x + 1 == x) &&
(player
-> ship[i].desp_of_part[j].y – 1 == y + k ||
player
-> ship[i].desp_of_part[j].y + 1 == y + k))
{
ShowMessage («Невозможно выполнить
действие!»);
return 0;
}
}
}
if
(Button == mbLeft)
Draw
(«position_h», x*20, y*20, 1);
else
Draw
(«position_v», x*20, y*20, 1);
Generation
(CPU, col_ship, col_deck);
if
(col_ship == 1) col_deck –;
if
(col_ship == 3) col_deck –;
if
(col_ship == 6) col_deck –;
if
(col_ship == 10) play = true;
if(play)
Form1 -> Panel2 -> Caption = «Поехали»;
col_ship++;
return
0;
};
//
–
int
HandlersOfEvents: Shoot (int x, int y)
{
if
(game_over) return 0;
int
shoot_player = ShootPlayer (x, y, 2);
if
(shoot_player > 0)
do
{
x =
rand()% 200;
y
= rand()% 200;
int
shoot_cpu = ShootPlayer (x, y, 1);
if
(shoot_cpu > 0)
break;
if
(shoot_cpu < 0)
player
-> GetStatus();
if
(player -> destroy || target_CPU > 19)
{
EndRaund(1);
return
0;
}
} while(true);
else
{
if
(shoot_player < 0)
CPU
-> GetStatus();
if
(CPU -> destroy || target_player > 19)
{
EndRaund(2);
return
0;
}
}
return
0;
}
//
–
int
HandlersOfEvents: ShootPlayer (int x, int y, int n)
{
if(!
play) return 0;
if
(! GoChecking(x, y, n))
{
if
(n == 2) Form1 -> Panel2 -> Caption = «Ещё раз! Туда уже стреляли!»;
return 0;
}
else if (! GoScaning(x,
y, n))
{
Draw
(«target», x, y, n);
Miss
(x, y, n);
if
(n == 2)
{
Form1
-> Panel2 -> Caption = «Попал! Ещё раз!»;
target_player++;
}
else
target_CPU++;
return
-1;
}
Miss
(x, y, n);
if
(n == 2) Form1 -> Panel2 -> Caption = «Мимо! Ход опонента»;
Draw
(«miss», x, y, n);
return
1;
}
//
–
int
HandlersOfEvents: Draw (String key, int x, int y, int n)
{
TImage
*Im;
x
/= 20; y /= 20;
if
(n == 1) Im = Form1 -> Fild1;
if
(n == 2) Im = Form1 -> Fild2;
if
(key == «target»)
{
Im
-> Canvas -> Rectangle (x*20, y*20, x*20 + 20, y*20 + 20);
Im
-> Canvas -> Brush -> Color = clYellow;
Im
-> Canvas -> Rectangle (x*20, y*20 + 20, x*20 + 20, y*20);
Im
-> Canvas -> Brush -> Color = clWhite;
}
if
(key == «miss»)
{
Im
-> Canvas -> Ellipse (x*20, y*20, x*20 + 20, y*20 + 20);
Im
-> Canvas -> Ellipse (x*20 + 5, y*20 + 5, x*20 + 15, y*20 + 15);
}
if
(key == «position_h»)
{
for
(i = 0; i < col_deck; i++)
{
Im
-> Canvas -> Brush -> Color = clBlue;
Im
-> Canvas -> Rectangle (x*20 + i*20, y*20, x*20 + 20 + i*20, y*20 + 20);
player
-> ship [col_ship – 1].desp_of_part[i].x = x + i;
player
-> ship [col_ship – 1].desp_of_part[i].y = y;
Im
-> Canvas -> Brush -> Color = clWhite;
}
}
if
(key == «position_v»)
{
for
(i = 0; i < col_deck; i++)
{
Im
-> Canvas -> Brush -> Color = clBlue;
Im
-> Canvas -> Rectangle (x*20, y*20 + i*20, x*20 + 20, y*20 + 20 + i*20);
player
-> ship [col_ship – 1].desp_of_part[i].x = x;
player
-> ship [col_ship – 1].desp_of_part[i].y = y + i;
Im
-> Canvas -> Brush -> Color = clWhite;
}
}
return
0;
}
//
–
void
__fastcall TForm1: Fild2MouseDown (TObject *Sender,
TMouseButton
Button, TShiftState Shift, int X, int Y)
{
HE
-> Shoot (X, Y);
}
//
–
void
__fastcall TForm1: BitBtn2Click (TObject *Sender)
{
HE
-> Play (Fild1, Fild2);
BitBtn2
-> Visible = false;
BitBtn3
-> Visible = true;
Panel2
-> Caption = «Расставьте корабли»;
}
//
–
void
__fastcall TForm1: Fild1MouseDown (TObject *Sender,
TMouseButton
Button, TShiftState Shift, int X, int Y)
{
HE
-> Desposition (X, Y, Button);
}
//
–
void
__fastcall TForm1: BitBtn3Click (TObject *Sender)
{
Panel2
-> Caption = «Расставьте корабли»;
Fild1
-> Picture -> LoadFromFile («net.bmp»);
Fild2
-> Picture -> LoadFromFile («net.bmp»);
HE
= new HandlersOfEvents (Fild1, Fild2);
}
//
–
UShipBattle.h
// –
#ifndef
UShipBattleH
#define
UShipBattleH
//
–
#include
<Classes.hpp>
#include
<Controls.hpp>
#include
<StdCtrls.hpp>
#include
<Forms.hpp>
#include
<Buttons.hpp>
#include
<ExtCtrls.hpp>
#include
<Graphics.hpp>
#include
<ComCtrls.hpp>
//
–
struct
Ship
{
bool
destroy;
int
col_deck;
bool
*decks;
TPoint
*desp_of_part;
};
class
Flot
{
public:
int
i, j, n;
bool
destroy;
TImage
*Im;
Ship
ship[10];
Flot
(TImage *I)
{
destroy
= false;
Im
= I;
n
= 1;
for
(i = 0; i < 10; i++)
{
if
(i < 6) n = 2;
if
(i < 3) n = 3;
if
(i == 0) n = 4;
ship[i].destroy
= false;
ship[i].col_deck
= n;
ship[i].decks
= new bool[n];
ship[i].desp_of_part
= new TPoint[n];
}
}
int
GetStatus();
};
class
AI
{
public:
TPoint
decks_[20];
int
col_decks_;
int
Generation (Flot *CPU, int col_ship, int col_deck);
};
class
Referee: public AI
{
public:
int
i, j, target_player, target_CPU;
bool
net1 [10] [10], net2 [10] [10], game_over;
Flot
*player, *CPU;
Referee()
{
for
(i = 0; i < 10; i++)
for
(j = 0; j < 10; j++)
{
net1
[i] [j] = true;
net2
[i] [j] = true;
}
game_over
= false;
target_player
= 0;
target_CPU
= 0;
col_decks_
= 0;
}
int
GoChecking (int x, int y, int n);
int
Check (bool net[10] [10], int x, int y);
int
GoScaning (int x, int y, int n);
int
Scan (Flot *fl, int x, int y);
int
Miss (int x, int y, int n);
int
EndRaund (int n);
};
class
HandlersOfEvents: public Referee
{
public:
bool
play;
int
col_deck, col_ship, i, j, k;
HandlersOfEvents
(TImage *Im1, TImage *Im2)
{
play
= false;
col_deck
= 4; col_ship = 1;
player
= new Flot(Im1);
CPU
= new Flot(Im2);
}
int
Play (TImage *Im1, TImage *Im2);
int
Move();
int
Desposition (int x, int y, TMouseButton Button);
int
Draw (String key, int x, int y, int n);
int
ShootPlayer (int x, int y, int n);
int
Shoot (int x, int y);
};
class
TForm1: public TForm
{
__published: //
IDE-managed Components
TImage
*Fild1;
TPanel
*Panel1;
TBitBtn
*BitBtn1;
TBitBtn
*BitBtn2;
TBitBtn
*BitBtn3;
TPanel
*Panel2;
void
__fastcall Fild2MouseDown (TObject *Sender,
TMouseButton
Button, TShiftState Shift, int X, int Y);
void
__fastcall BitBtn2Click (TObject *Sender);
void
__fastcall Fild1MouseDown (TObject *Sender,
TMouseButton
Button, TShiftState Shift, int X, int Y);
void
__fastcall BitBtn3Click (TObject *Sender);
private: //
User declarations
public: //
User declarations
__fastcall
TForm1 (TComponent* Owner);
HandlersOfEvents
*HE;
};
//
–
extern
PACKAGE TForm1 *Form1;
//
–
#endif
Литература
1. А.Я. Архангельский. Программирование в C++ Builder 6. - ЗАО «Издательство
БИНОМ», Москва, 2005
2. Уильям Топп, Уильям
Форд. Структура данных в С++.-ЗАО «Издательство
БИНОМ», Москва, 2000
3. В.В. Подбельский.
Язык С, С++. «Финансы и статистика», Москва, 2003
4. Т.А. Павловская.
С/С++. «Питер», Санкт-Петербург, 2002