Назад | Начало урока | Вперед
Содержание

Глава 5

Где противник?

Продолжим писать программу "Морской бой" далее. Мы создали свое поле, научились расставлять
на поле корабли. Но в программе "Морской бой" нужно иметь поле противника, по которому
мы могли бы стрелять.

Итак, надо создать поле противника, запустить функцию, которая случайным образом
расставит на поле корабли. А мы научимся стрелять по чужому полю, и попадать в корабли.

Создадим поле противника совершенно таким же способом, как мы создали свое.
Чтобы создать поле противника требуется совсем немного кода.
В заголовке главного окна добавим три переменные типа CField:

CField m_ForeignField, m_LetterF, m_NumberF;

Теперь в функции OnInitDialog() главного окна создадим поле противника используя те же
функции, которые использовались нами для создания своего поля.

m_ForeignField.Create(NULL, WS_CHILD|WS_VISIBLE|SS_NOTIFY, CRect(260, 100, 460, 300), this);
m_ForeignField.SetMode(FOREIGN_FIELD);

m_NumberF.Create(NULL, WS_CHILD|WS_VISIBLE, CRect(260, 80, 460, 95), this);
m_NumberF.SetMode(NUMBERS);

m_LetterF.Create(NULL, WS_CHILD|WS_VISIBLE, CRect(240, 100, 255, 300), this);
m_LetterF.SetMode(LETTERS);
. . .
m_ForeignField.SetParent(this);

Теперь надо внести некоторые дополнения в сам класс Field.

В заголовочный файл класса Field добавим константу FOREIGN_FIELD,
с которой будет ассоциироваться поле противника.

#define FOREIGN_FIELD 2

Итак нам нужна функция, которая случайным образом расставит на чужом поле корабли.
Для этого нам пригодится возможность, которая есть в С++. Функция rand() случайного
числа. У нас уже есть готовая функция GenerateNumber().

int CField::GenerateNumber(int a) {

return rand()%a;
}

Надо только не забыть включить заголовочный файл:

#include "time.h"

И задействовать нужную в таком случае инструкцию:

srand(time(NULL));

Вообще-то код, необходимый нам, уже есть в функции OnLButtonDown(),
нам надо только немного его модифицировать. В этой функции
как мы помним при каждом клике левой кнопкой на поле, вызывается функция
ConvertPropertiesToMassive(), которая и располагает корабль в
этой точке, если есть такая возможность.

В нашей функции мы тоже должны вызвать функцию ConvertPropertiesToMassive()
и передать ей в параметр: координаты, число палуб и направление
корабля. Функция ConvertPropertiesToMassive() сама расположит
корабль на поле, если есть такая возможность.

Нам надо вызывать эту функцию столько раз, пока она не расположит
все корабли на поле боя.

Функция SetShip() располагает корабли на поле противника случайным образом.


void CField::SetShip() {
int n_Decks = 4;
int n_Count = 0;
POINT n_pos;
int n_dir[] = {3000,3001,3002,3003};
srand(time(NULL));

while(n_Decks!=0){

int k = 0; bool bul = 0;
int a = GenerateNumber(100);
int z = a/10;
n_pos.y = z*20;//десятки
n_pos.x = (a-(z*10))*20;//единицы

while(k < 4 && bul == 0){

if(bul = ConvertPropertiesToMassive(n_pos, n_Decks, n_dir[k])) {
n_Count++;
switch(n_Count) {
case 1:
n_Decks = 3;
break;
case 3:
n_Decks = 2;
break;
case 6:
n_Decks = 1;
break;
case 10:
n_Decks = 0;
break;
} //switch
}// if
else{
k++;
}
}//while
}//while
}

Как работает функция SetShip() понятно из ее кода. В ней происходит вызов
функции ConvertPropertiesToMassive(), и ей передаются случайные координаты
точки расположения корабля. Число палуб корабля при каждом вызове корректируется
при помощи переменной n_Count и переключателя switch. Направление выбирается
по умолчанию правое, а если в таком положении корабль не вмещается, то выбирается
положение вниз, затем влево и наконец вверх. Одно из этих положений обязательно
подойдет, чтобы разместить корабль.

Проверить как расположила функция корабли можно очень просто - нарисовать их
визуально на поле. Код для этого у нас есть в функции OnPaint в ветви if(m_Mode == OWN_FIELD).
Повторим его в ветви if(m_Mode == FOREIGN_FIELD)

Подсказка

Компьютер расположил корабли на поле справа случайным образом.
С каждым новым запуском программы получаем новое расположение кораблей
на поле противника.


Назад | Начало урока | Вверх | Вперед
Содержание

Hosted by uCoz