Смекни!
smekni.com

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

//количество палуб корабля

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&bsol;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&bsol;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&bsol;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&bsol;Sounholi.wav", 0, SND_ASYNC);

else

PlaySound("Sounds&bsol;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&bsol;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)