Смекни!
smekni.com

Логическая игра Морской бой (стр. 5 из 7)

Ships2[sh]->ColCount = 1;

Ships2[sh]->RowCount = count+1; break;

}

for (int i = 0; i < count + 1; i++)

{

field2[coor_y][coor_x] = 1;

switch (dir)

{

case 0: coor_x--; break;

case 1: coor_y--; break;

case 2: coor_x++; break;

case 3: coor_y++; break;

}

}

//Заполнение границ вокруг корабля недоступными значениями

//с учетом границ поля боя и выбранного направления

int bord1 = 0, bord2 = 0, bord3 = 0, bord4 = 0;

switch (dir)

{

case 0: if (!(coor_x + 1))

bord1 = 1;

else

if (coor_x + count + 1 == 9)

bord3 = 1;

if (!coor_y)

bord2 = 1;

else

if (coor_y == 9)

bord4 = 1;

for (int u = -1 + bord2; u < 2 - bord4; u++)

for (int v = -1*(count + 1) + bord1; v < 2 - bord3; v++)

arr[xc+u*10+v] = -1;

break;

case 1: if (!coor_x)

bord1 = 1;

else

if (coor_x == 9)

bord3 = 1;

if (!(coor_y + 1))

bord2 = 1;

else

if (coor_y + count + 1 == 9)

bord4 = 1;

for (int u = -1*(count + 1) + bord2; u < 2 - bord4; u++)

for (int v = -1 + bord1; v < 2 - bord3; v++)

arr[xc+u*10+v] = -1;

break;

case 2: if (!(coor_x - count - 1))

bord1 = 1;

else

if (coor_x - 1 == 9)

bord3 = 1;

if (!coor_y)

bord2 = 1;

else

if (coor_y == 9)

bord4 = 1;

for (int u = -1 + bord2; u < 2 - bord4; u++)

for (int v = -1 + bord1; v < count + 2 - bord3; v++)

arr[xc+u*10+v] = -1;

break;

case 3: if (!coor_x)

bord1 = 1;

else

if (coor_x == 9)

bord3 = 1;

if (!(coor_y - count - 1))

bord2 = 1;

else

if (coor_y - 1 == 9)

bord4 = 1;

for (int u = -1 + bord2; u < count + 2 - bord4; u++)

for (int v = -1 + bord1; v < 2 - bord3; v++)

arr[xc+u*10+v] = -1;

break;

}

}

}

//Перетаскивание кораблей над полем

void __fastcall TSeaButForm::GridField1DragOver(TObject *Sender,

TObject *Source, int X, int Y, TDragState State, bool &Accept)

{

Accept = Source->ClassNameIs("TDrawGrid");

TDrawGrid *S = (TDrawGrid *) Source;

S->DragCursor = (Controls::TCursor)5; //Изменение курсора

//Изменение координат корабля в соответствии с положением указателя мыши

S->Top = Y - Y%29;

S->Left = X - X%29;

//Проверка границ поля

if (S->Left + S->Width > 300)

switch ((int)S->Tag/100)

{

case 4: S->Left = 174; break;

case 3: S->Left = 203; break;

case 2: S->Left = 232; break;

case 1: S->Left = 261; break;

}

if (S->Top + S->Height > 300)

switch ((int)S->Tag/100)

{

case 4: S->Top = 174; break;

case 3: S->Top = 203; break;

case 2: S->Top = 232; break;

case 1: S->Top = 261; break;

}

}

//Возможность перетаскивания при положении курсора над кораблем

void __fastcall TSeaButForm::ShipsDragOver(TObject *Sender, TObject *Source,

int X, int Y, TDragState State, bool &Accept)

{

TDrawGrid *S = (TDrawGrid *) Source;

Accept = Source->ClassNameIs("TDrawGrid");

S->DragCursor = (Controls::TCursor)5; //Изменение курсора

}

//При перетаскивании корабля над формой

void __fastcall TSeaButForm::FormDragOver(TObject *Sender, TObject *Source,

int X, int Y, TDragState State, bool &Accept)

{

TDrawGrid *S = (TDrawGrid *)Source;

S->DragCursor = (Controls::TCursor)7; //Изменение курсора

}

//Изменение положения корабля при нажатии правой кнопки мыши

void __fastcall TSeaButForm::ShipsMouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y)

{

TDrawGrid *S = (TDrawGrid *) Sender;

//Проверка нажатой кнопки

if (Button == mbRight)

{

PlaySound("Sounds&bsol;SOUNPLAS.WAV", 0, SND_ASYNC);

//Определение положения и замена на противоположное

if (S->Width > 29)

{

S->Height = S->Width;

S->Width = 29;

S->RowCount = S->ColCount;

S->ColCount = 1;

}

else

{

S->Width = S->Height;

S->Height = 29;

S->ColCount = S->RowCount;

S->RowCount = 1;

}

}

//Проверка границ поля

if (S->Left + S->Width > 300)

switch ((int)S->Tag/100)

{

case 4: S->Left = 174; break;

case 3: S->Left = 203; break;

case 2: S->Left = 232; break;

case 1: S->Left = 261; break;

}

if (S->Top + S->Height > 300)

switch ((int)S->Tag/100)

{

case 4: S->Top = 174; break;

case 3: S->Top = 203; break;

case 2: S->Top = 232; break;

case 1: S->Top = 261; break;

}

}

//О программе

void __fastcall TSeaButForm::AboutClick(TObject *Sender)

{

//Запоминание изображения канвы

SaveBM (1);

SaveBM (2);

//Показать окно

AboutProg->Position = poMainFormCenter;

AboutProg->Visible = Enabled;

}

//Интерфейс игры с компьютером

void __fastcall TSeaButForm::CompClick(TObject *Sender)

{

//Если выбран интерфейс игры с человеком

if (Human->Checked)

{

PlaySound("Sounds&bsol;SOUNREST.WAV", 0, SND_ASYNC);

//Активизация элементов интерфейса и удаление кораблей

Field2->Enabled = false;

DelShips (2);

Comp->Checked = !Comp->Checked;

Human->Checked = !Human->Checked;

Fight->Enabled = true;

FrameReady1->Visible = false;

FrameReady2->Visible = false;

FIGHT->FlashEnabled = true;

FrameAgain->Enabled = true;

RichEdit2->ReadOnly = true;

RichEdit2->Lines->Strings[0] = "Machine";

}

}

//Интерфейс игры с человеком

void __fastcall TSeaButForm::HumanClick(TObject *Sender)

{

//Если выбран интерфейс игры с компьютером

if (Comp->Checked)

{

PlaySound("Sounds&bsol;SOUNREST.WAV", 0, SND_ASYNC);

//Активизация элементов интерфейса и создание кораблей

Field2->Enabled = true;

NewShips (2);

Human->Checked = !Human->Checked;

Comp->Checked = !Comp->Checked;

Fight->Enabled = false;

FrameReady1->Visible = true;

FrameReady2->Visible = true;

Ready1->Enabled = true;

Ready2->Enabled = false;

FrameReady1->Enabled = true;

FrameReady2->Enabled = false;

Field2->Enabled = false;

FIGHT->FlashEnabled = false;

FrameAgain->Enabled = false;

RichEdit2->ReadOnly = false;

RichEdit2->Lines->Strings[0] = "Player 2";

}

}

//Выбор начала боя

void __fastcall TSeaButForm::FightClick(TObject *Sender)

{

//Определение интерфейса

if (Comp->Checked)

{

boolAllRight = CheckShips (1); //Проверить расположение кораблей

//Если все в порядке

if (AllRight)

{

//Звук и смена курсоров на боевые

PlaySound("Sounds&bsol;SOUNREST.WAV", 0, SND_ASYNC);

GridField1->Cursor = (Controls::TCursor)6;

GridField2->Cursor = (Controls::TCursor)6;

//Активизация элементов

Field2->Enabled = true;

Field1->Enabled = false;

CreateShips (); //Случайное создание кораблей

//Скрытие кораблей 1 поля

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

Ships1[i]->Visible = false;

//Сохранение изображения канв

SaveBM (1);

SaveBM (2);

Choise->Enabled = false;

Fight->Enabled = false;

//Переход к режиму боя

GridField2->OnMouseDown = GridField1MouseDown;

FIGHT->FlashEnabled = false;

FrameAgain->Enabled = false;

RichEdit1->ReadOnly = true;

RichEdit1->Color = clRed;

}

}

else

{

//Звук и смена курсоров на боевые

PlaySound("Sounds&bsol;SOUNREST.WAV", 0, SND_ASYNC);

GridField1->Cursor = (Controls::TCursor)6;

GridField2->Cursor = (Controls::TCursor)6;

//Сохранение изображения канв

SaveBM (1);

SaveBM (2);

//Активизация элементов

FrameReady1->Visible = false;

FrameReady2->Visible = false;

Fight->Enabled = false;

//Переход к режиму боя

GridField1->OnMouseDown = GridField1MouseDown;

GridField2->OnMouseDown = GridField1MouseDown;

FIGHT->FlashEnabled = false;

FrameAgain->Enabled = false;

RichEdit1->Color = clRed;

}

}

//Создать новую игру

void __fastcall TSeaButForm::NewGameClick(TObject *Sender)

{

//Звук и смена курсоров на начальные

PlaySound("Sounds&bsol;SOUNOPEN.WAV", 0, SND_ASYNC);

GridField1->Cursor = (Controls::TCursor)1;

GridField2->Cursor = (Controls::TCursor)1;

//Обнуление данных

Count1Destr = 0;

Count2Destr = 0;

Shoots1->Caption = "0";

Shoots2->Caption = "0";

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

{

Ships1Destr[i] = 0;

Ships2Destr[i] = 0;

}

GridField1->OnMouseDown = NULL;

GridField2->OnMouseDown = NULL;

//Активизация элементов

Choise->Enabled = true;

Field1->Enabled = true;

Field2->Enabled = false;

RichEdit1->Color = clNavy;

RichEdit2->Color = clNavy;

NewShips (1);

Delfield (1);

Delfield (2);

//Удаление изображений канвы

DelBM (1);

DelBM (2);

if (Comp->Checked) //Режим игры с компьютером

{

NullCpu ();

DelShips (2);

FIGHT->FlashEnabled = true;

FIGHT->OnClick = FightClick;

FrameAgain->OnClick = FightClick;

FrameAgain->Enabled = true;

Fight->Enabled = true;

RichEdit1->ReadOnly = false;

//Очистка канвы 2 поля

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

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

GridField2->Canvas->FillRect(GridField2->CellRect(i,j));

}

else //Режим игры с человеком

{

//Активизация элементов

FIGHT->OnClick = FightClick;

FrameAgain->OnClick = FightClick;

FIGHT->FlashEnabled = false;

FrameAgain->Enabled = false;

Ready1->Enabled = true;

Ready2->Enabled = false;

FrameReady1->Enabled = true;

FrameReady2->Enabled = false;

FrameReady1->Visible = true;

FrameReady2->Visible = true;

RichEdit1->ReadOnly = false;

RichEdit2->ReadOnly = false;

NewShips (2);

}

}

//Готовность 1го игрока

void __fastcall TSeaButForm::Ready1Click(TObject *Sender)

{

bool AllRight = CheckShips (1); //Проверка кораблей 1го поля

if (AllRight) //Если все в порядке

{

PlaySound("Sounds&bsol;SOUNREST.WAV", 0, SND_ASYNC);

//Активизация 2 поля

//Скрытие кораблей 1 поля

for (inti = 0; i < 10; i++)

Ships1[i]->Visible = false;

Field1->Enabled = false;

Field2->Enabled = true;

Ready1->Enabled = false;

Ready2->Enabled = true;

FrameReady1->Enabled = false;

FrameReady2->Enabled = true;

Choise->Enabled = false;

RichEdit1->ReadOnly = true;

}

}

//Готовность 2го игрока

void __fastcall TSeaButForm::Ready2Click(TObject *Sender)

{

bool AllRight = CheckShips (2); //Проверка кораблей 2го поля

if (AllRight) //Если все в порядке

{

PlaySound("Sounds&bsol;SOUNREST.WAV", 0, SND_ASYNC);

//Скрытие кораблей 1 поля

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

Ships2[i]->Visible = false;

Ready2->Enabled = false;

FrameReady2->Enabled = false;

Fight->Enabled = true;

FIGHT->FlashEnabled = true;

FrameAgain->Enabled = true;

RichEdit2->ReadOnly = true;

}

}

//Метод выстрела

void __fastcall TSeaButForm::GridField1MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y)

{

//Переменная для дальнейшего опредления поля

TDrawGrid *Field = (TDrawGrid *) Sender;

//Координаты выстрела

intxp = (int)(X/29), yp = (int)(Y/29);

//Производить при нажатии левой кнопки

if (Button == mbLeft)

{

//При выстреле не допускать сворачивание и перекрывание окна

//для сохранения изображения

SetWindow (0);

//Проверка поля

if (Field->Tag == 1)

{

//Если произошло попадание

if (field1[yp][xp] == 1)

{

//Звук и увеличение количества выстрелов

PlaySound("Sounds&bsol;SOUNBROK.WAV", 0, SND_ASYNC);

Shoots2->Caption = IntToStr(StrToInt(Shoots2->Caption)+1);

field1[yp][xp] = 3; //На месте выстрела поставить метку 3

//Графически показать попадание

SeaDraw (1,xp,yp,true);

linex = xp*29 + 24;

liney = yp*29 + 3;

Timer1->Enabled = true;

//Переменные для определения границ, направления и необходимые для

//определения убитого корабля и выставления "мимо" вокруг него

int dir = 0, temp = 0, count = 0;

bool bord1 = !xp, bord2 = !yp, bord3 = !(9-xp), bord4 = !(9-yp);

//Определение вспомогательных переменных

if (!bord1)

if ((field1[yp][xp-1] == 3))

{

dir = 1;

temp = xp;

goto M1;

}

if (!bord2)

if ((field1[yp-1][xp] == 3))

{

dir = 2;

temp = yp;

goto M1;

}

if (!bord3)

if ((field1[yp][xp+1] == 3))

{

dir = 1;

temp = xp;

goto M1;

}

if (!bord4)

if ((field1[yp+1][xp] == 3))

{

dir = 2;

temp = yp;

gotoM1;

}

//Логическая переменная для обозначения, убит ли корабль

M1: boolemp = false;

//Условие на направление корабля, если влево

if (dir == 1)

{

//Условие на приграничность корабля

if (!bord1)

//Переходим к самому левому раненому полю

while (field1[yp][temp]==3)

{

//Если дошли до границы

if (!temp)

{

bord1;

break;

}

//Если дошли до нераненного поля

if (field1[yp][temp--]==1)

{

emp = true;

break;

}

};

//В случае, если ушли от корабля влево, увеличиваем temp

if ((field1[yp][temp]==0)||(field1[yp][temp]==2)) temp++;

//Если не было нераненных полей

if (!emp)

//Теперь идем до конца корабля вправо

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

{

//Определение границы справа

if (temp+i == 10)

{

bord3 = true;

break;

}

//Если ранен, то идем дальше, увеличиваем