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\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\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\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\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\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\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\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\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\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;
}
//Если ранен, то идем дальше, увеличиваем