//количество палуб корабля
if (field1[yp][temp+i]==3) count++;
else //Если есть нераненое поле, то закончить проверку
//И показать, что корабль не убит
if (field1[yp][temp+i]==1)
{
emp = true;
break;
}
//Иначе, он убит, проверка закончена
else break;
}
if (!emp)
{
PlaySound("Sounds\SOUNDESTR.WAV", 0, SND_ASYNC);
Count1Destr++; //Увеличиваем количество убитых кораблей
//Заполняем массив убитых кораблей
switch (count)
{
case 2: for (int dsh = 4; dsh < 7; dsh++)
if (!Ships1Destr[dsh])
{
Ships1Destr[dsh] = 1;
break;
} break;
case 3: for (int dsh = 7; dsh < 9; dsh++)
if (!Ships1Destr[dsh])
{
Ships1Destr[dsh] = 1;
break;
} break;
default: Ships1Destr[9] = 1;
}
//В случае игры с компьютером
if (Comp->Checked)
{
//Указываем, что корабль убит
Cpu.TarDir = false;
Cpu.Target = false;
Cpu.TarDirect = false;
Cpu.TarDestr = true;
}
//Заполняем поля вокруг корабля
for (int u = yp-1+bord2; u < yp+2-bord4; u++)
for (int v = temp - 1 + bord1; v < temp + count + 1 - bord3; v++)
if (field1[u][v] == 0)
{
field1[u][v] = 2;
SeaDraw (1,v,u,false);
}
}
}
//В случае вертикального расположения корабля
//повторяем аналогичные процессы
if (dir == 2)
{
if (!bord2)
while (field1[temp][xp]==3)
{
if (!temp)
{
bord2 = true;
break;
}
if (field1[temp--][xp]==1)
{
emp = true;
break;
}
};
if ((field1[temp][xp]==0)||(field1[temp][xp]==2)) temp++;
if (!emp)
for (int i = 0; i < 5; i++)
{
if (temp+i == 10)
{
bord4 = true;
break;
}
if (field1[temp+i][xp]==3) count++;
else
if (field1[temp+i][xp]==1)
{
emp = true;
break;
}
else break;
}
if (!emp)
{
PlaySound("Sounds\SOUNDESTR.WAV", 0, SND_ASYNC);
Count1Destr++;
switch (count)
{
case 2: for (int dsh = 4; dsh < 7; dsh++)
if (!Ships1Destr[dsh])
{
Ships1Destr[dsh] = 1;
break;
} break;
case 3: for (int dsh = 7; dsh < 9; dsh++)
if (!Ships1Destr[dsh])
{
Ships1Destr[dsh] = 1;
break;
} break;
default: Ships1Destr[9] = 1;
}
if (Comp->Checked)
{
Cpu.TarDir = false;
Cpu.Target = false;
Cpu.TarDirect = false;
Cpu.TarDestr = true;
}
for (int u = temp - 1 + bord2; u < temp + count + 1 - bord4; u++)
for (int v = xp-1+bord1; v < xp+2-bord3; v++)
if (field1[u][v] == 0)
{
field1[u][v] = 2;
SeaDraw (1,v,u,false);
}
}
}
//Если убит однопалубный корабль
//повторяем те же процессы
if ((dir == 0) && (field1[yp][xp-1+bord1]!=1) && (field1[yp-1+bord2][xp]!=1)
&& (field1[yp][xp+1-bord3]!=1) && (field1[yp+1-bord4][xp]!=1))
{
PlaySound("Sounds\SOUNDESTR.WAV", 0, SND_ASYNC);
Count1Destr++;
for (int dsh = 0; dsh < 4; dsh++)
if (!Ships1Destr[dsh])
{
Ships1Destr[dsh] = 1;
break;
}
if (Comp->Checked)
{
Cpu.TarDir = false;
Cpu.Target = false;
Cpu.TarDirect = false;
Cpu.TarDestr = true;
}
for (int u = yp - 1 + bord2; u < yp + 2 - bord4; u++)
for (int v = xp - 1 + bord1; v < xp + 2 - bord3; v++)
if (field1[u][v] == 0)
{
field1[u][v] = 2;
SeaDraw (1,v,u,false);
}
}
}
//Если произошло попадание в "молоко"
if (field1[yp][xp] == 0)
{
PlaySound("Sounds\SOUNMILK.WAV", 0, SND_ASYNC);
Shoots2->Caption = IntToStr(StrToInt(Shoots2->Caption)+1);
//Указываем компьютеру, что выбрано неправильное направление
if (Comp->Checked)
Cpu.TarDirect = false;
//Ставим метку стреленого места
field1[yp][xp] = 2;
//Указываем графически
SeaDraw (1,xp,yp,false);
//Позволяем стрелять другому игроку
Field1->Enabled = false;
Field2->Enabled = true;
RichEdit2->Color = clNavy;
RichEdit1->Color = clRed;
}
}
//Если стрельба проводится по 2му полю
//то делать то же самое для него
else
{……………
}
//Сохранить изображение канв
SaveBM (1);
SaveBM (2);
//Если стрельбу не производит компьютер
if (!Timer2->Enabled && !Timer1->Enabled)
SetWindow (1); //Восстановить первоначальные свойства окна
}
}
//Таймер для прорисовки линий и стрельбы компьютера
void __fastcall TSeaButForm::Timer1Timer(TObject *Sender)
{
//Проверка активного поля
if (Field1->Enabled)
{
//Дорисовать линию через время
GridField1->Canvas->LineTo(linex,liney);
//Выключить таймер
Timer1->Enabled = false;
//Если убиты не все корабли
if (Count1Destr != 10)
{
//Если компьютер стреляет, то указать необходимые
//ему атрибуты
if (Comp->Checked)
{
if (Cpu.Target)
{
if (Cpu.TarDir)
Cpu.TarDirect = true;
else
{
Cpu.TarDir = true;
switch (Cpu.Direction)
{
case 0: Cpu.RowDir[1] = -1; Cpu.RowDir[3] = -1; break;
case 1: Cpu.RowDir[0] = -1; Cpu.RowDir[2] = -1; break;
case 2: Cpu.RowDir[1] = -1; Cpu.RowDir[3] = -1; break;
case 3: Cpu.RowDir[0] = -1; Cpu.RowDir[2] = -1; break;
}
Cpu.TarDirect = true;
}
}
else
if (!Cpu.TarDestr)
Cpu.Target = true;
//Включить 2ой таймер
Timer2->Enabled = true;
}
elseSetWindow (1); //Если стреляет игрок восстановить окно
}
//Если убиты все корабли
else
{
//Воспроизвести разные звуки в зависимости от того
//человек или компьютер играл
if (Comp->Checked)
PlaySound("Sounds\Sounholi.wav", 0, SND_ASYNC);
else
PlaySound("Sounds\Sounhihi.wav", 0, SND_ASYNC);
//Активизация элементов
for (int i = 0; i < 10; i++)
Ships2[i]->Visible = true;
Field1->Enabled = false;
SetWindow(1);
FrameAgain->Enabled = true;
FIGHT->OnClick = NewGameClick;
FrameAgain->OnClick = NewGameClick;
SaveRes (2);
Timer3->Enabled = true;
}
//Сохранить изображение канвы1
SaveBM (1);
}
//При стрельбе по 2му полю
else
{
//Провести линию и отключить таймер
GridField2->Canvas->LineTo(linex,liney);
Timer1->Enabled = false;
//Сохранить изображение
SaveBM (2);
//восстановить окно
SetWindow (1);
//Елси убиты все корабли
if (Count2Destr == 10)
{
PlaySound("Sounds\Sounhihi.wav", 0, SND_ASYNC); //звук победы
//Активизация элементов
for (int i = 0; i < 10; i++)
Ships1[i]->Visible = true;
Field2->Enabled = false;
FrameAgain->Enabled = true; //Для быстрого начала новой игры
FIGHT->OnClick = NewGameClick;
FrameAgain->OnClick = NewGameClick;
SaveRes (1); //Сохранить результаты
Timer3->Enabled = true;
}
}
}
//Функция выстрелов компьютера
voidTSeaButForm::CompShot ()
{
boolcl = false; //Логическая переменная
intx = 0, y = 0; //Координаты выстрела
//Определение ненужных координат
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
if ((field1[i][j]!=1) && (field1[i][j]!=0))
Cpu.RowNum[10*i + j] = -1;
//Если не было попадания
if (!Cpu.Target)
{
CheckDestr (); //Проверка на необходимость стрельбы по всем полям
//Заполнение массива направлений стрельбы
for (inti = 0; i < 4; i++)
Cpu.RowDir[i] = i;
//Обнуление переменных, показывающих попадания по кораблю
Cpu.Direction = -1;
Cpu.TarDestr = false;
//Выбор случайного поля
do
{
Randomize();
Cpu.Choice = Random(100);
Choice = Cpu.Choice;
//Проверка на доступность
if (Choice == Cpu.RowNum[Choice])
{
cl = true;
Cpu.RowNum[Choice] = -1;
}
}
while (!cl);
}
//Если же было попадание
else
{
//Если неизвестно положение корабля
if (!Cpu.TarDir)
//Выбираем его случайно
do
{
Choice = Cpu.Choice;
Randomize();
Cpu.Direction = Random(4);
//Сверяем на его доступность
if (Cpu.Direction == Cpu.RowDir[Cpu.Direction])
{
cl = true;
Cpu.RowDir[Cpu.Direction] = -1; //Запоминаем его
//Проверка на границы и на доступность этого поля
//Если недоступно, то повторить выбор
switch (Cpu.Direction)
{
case 0: if (!(Choice%10))
{
cl = false; break;
}
else
if (Cpu.RowNum[Choice-1] == -1)
{
cl = false; break;
}
break;
case 1: if (!(int)(Choice/10))
{
cl = false; break;
}
else
if (Cpu.RowNum[Choice-10] == -1)
{
cl = false; break;
}
break;
case 2: if (Choice%10 == 9)
{
cl = false; break;
}
else
if (Cpu.RowNum[Choice+1] == -1)
{
cl = false; break;
}
break;
case 3: if ((int)(Choice/10) == 9)
{
cl = false; break;
}
else
if (Cpu.RowNum[Choice+10] == -1)
{
cl = false; break;
}
break;
}
}
}
while (!cl);
//Если же известно положение корабля
else
//Проверяем, верно ли выбрано было направление его
if (!Cpu.TarDirect)
{
//Если нет, тогда меняем на противоположное
M3: switch (Cpu.Direction)
{
case 0: Cpu.Direction = 2; Choice = Cpu.Choice; break;
case 1: Cpu.Direction = 3; Choice = Cpu.Choice; break;
case 2: Cpu.Direction = 0; Choice = Cpu.Choice; break;
case 3: Cpu.Direction = 1; Choice = Cpu.Choice; break;
}
Cpu.TarDirect = true;
}
}
//Определение координат для стрельбы
if (Cpu.Direction == -1) //Если производится первый выстрел
{
x = Choice%10;
y = (int)(Choice/10);
}
else
{
//Когда уже выбрано направление, проверяем на граничность
//и на доступность поля, если все в порядке, то выстрел можно выполнять
//И тогда можно подтвердить выбор
switch (Cpu.Direction)
{
case 0: if (!(Choice%10))
goto M3;
else
if (Cpu.RowNum[Choice-1] == -1)
goto M3;
Choice--; Cpu.RowNum[Choice] = -1; break;
case 1: if (!(int)(Choice/10))
goto M3;
else
if (Cpu.RowNum[Choice-10] == -1)
goto M3;
Choice-=10; Cpu.RowNum[Choice] = -1; break;
case 2: if (Choice%10 == 9)
goto M3;
else
if (Cpu.RowNum[Choice+1] == -1)
goto M3;
Choice++; Cpu.RowNum[Choice] = -1; break;
case 3: if ((int)(Choice/10) == 9)
goto M3;
else
if (Cpu.RowNum[Choice+10] == -1)
goto M3;
Choice+=10; Cpu.RowNum[Choice] = -1; break;
}
//И определяем координаты
x = Choice%10;
y = (int)(Choice/10);
}
TShiftStateShift; //Пустая переменная для передачи в функцию выстрела
//Производим выстрел
GridField1MouseDown (GridField1, mbLeft, Shift, 29*x + 1, 29*y + 1);
}
//Проверка на необходимость выстрела по каждому полю
voidTSeaButForm::CheckDestr ()
{
intlen = 0; //Переменная указывает для какого вида корабля проверяем
//Определяем все ли 1палубные убиты
for (inti = 0; i < 4; i++)
if (Ships1Destr[i])
if (i == 3)
len++;
else continue;
else break;
if (!len) return; //Если нет, то выйти из функции
//Проверяем для 1палубных
for (intd1 = 0; d1 < 100; d1++)
//Если нашли доступное поле
if (Cpu.RowNum[d1] != -1)
{
//Проверяем на то, есть ли вокруг него доступные поля
if (d1%10)
if (Cpu.RowNum[d1-1] != -1) continue;
if (d1>9)
if (Cpu.RowNum[d1-10] != -1) continue;
if (d1%10 < 9)
if (Cpu.RowNum[d1+1] != -1) continue;
if (d1<90)
if (Cpu.RowNum[d1+10] != -1) continue;
elseCpu.RowNum[d1] = -1; //Если нету, то делаем поле недоступным
elseCpu.RowNum[d1] = -1;
}
//Если 1палубные убиты, то определяем все ли 2палубные убиты
if (len)
for (int i = 4; i < 7; i++)
if (Ships1Destr[i])
if (i == 6)
len++;
else continue;
else break;
if (len == 1) return;
//Делаем аналогичную проверку, как и 1 палубных
//Только смотрим на ближайшие 2 поля вокруг выбранного
for (int d1 = 0; d1 < 100; d1++)
if (Cpu.RowNum[d1] != -1)
{
if (d1%10)
if (Cpu.RowNum[d1-1] != -1)
if (d1%10>1)
{
if (Cpu.RowNum[d1-2] != -1) continue;
else
if (d1%10<9)
if (Cpu.RowNum[d1+1] != -1) continue;
}
else
if (Cpu.RowNum[d1+1] != -1) continue;
if (d1>9)
if (Cpu.RowNum[d1-10] != -1)
if (d1>19)
{
if (Cpu.RowNum[d1-20] != -1) continue;
else
if (d1<90)
if (Cpu.RowNum[d1+10] != -1) continue;
}
else
if (Cpu.RowNum[d1+10] != -1) continue;
if (d1%10<9)
if (Cpu.RowNum[d1+1] != -1)
if (d1%10<8)
if (Cpu.RowNum[d1+2] != -1) continue;
if (d1<90)
if (Cpu.RowNum[d1+10] != -1)
if (d1<80)
if (Cpu.RowNum[d1+20] != -1) continue;
else Cpu.RowNum[d1] = -1;
else Cpu.RowNum[d1] = -1;
else Cpu.RowNum[d1] = -1;
else Cpu.RowNum[d1] = -1;
}
//Аналогично для 3 палубных
if (len == 2)
for (int i = 7; i < 9; i++)
if (Ships1Destr[i])
if (i == 8)
len++;
else continue;
else break;
if (len == 2) return;
for (int d1 = 0; d1 < 100; d1++)
if (Cpu.RowNum[d1] != -1)
{
if (d1%10)
if (Cpu.RowNum[d1-1] != -1)
{
if (d1%10>1)
{
if (Cpu.RowNum[d1-2] != -1)