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

Глава 1 (продолжение 1)

Эта функция получает координаты ячейки (клетки). Если кординаты ячейки попали в корабль,
то функция сообщает убит корабль или ранен. В противном случае сообщает, что ячейка пуста.

В функцию передаются координаты курсора, который находится на одной из клеток.
Функция возвращает одно из трех значений:

SHIPKILLED - корабль убит
SHIPWOUND - корабль ранен
N_EMPTY - клетка пуста


int CField::NetStep(int x, int y) {
POINT pos;
int i, j, sumx, razx, sumy, razy, cx, cy;
int IsKilled;

pos.x = x;
pos.y = y;
if(m_Event[pos.y][pos.x] == SHIP) {

m_Event[pos.y][pos.x] = SHIPWOUND;
IsKilled = SHIPKILLED;
for(i=1; i<4; i++)
if(m_Event[pos.y][pos.x+i] != SHIPWOUND || pos.x+i==10)break;

if(m_Event[pos.y][pos.x+i] == SHIP && pos.x+i<10)
IsKilled = SHIPWOUND;

for(i=1; i<4; i++)
if(m_Event[pos.y][pos.x-i] != SHIPWOUND || pos.x-i==-1)break;

if(m_Event[pos.y][pos.x-i] == SHIP && pos.x-i>=0)
IsKilled = SHIPWOUND;

for(i=1; i<4; i++)
if(m_Event[pos.y+i][pos.x] != SHIPWOUND || pos.y+i==10)break;

if(m_Event[pos.y+i][pos.x] == SHIP && pos.y+i<10)
IsKilled = SHIPWOUND;

for(i=1; i<4; i++)
if(m_Event[pos.y-i][pos.x] != SHIPWOUND || pos.y-i==-1)break;

if(m_Event[pos.y-i][pos.x] == SHIP && pos.y-i>=0)
IsKilled = SHIPWOUND;

if(IsKilled == SHIPKILLED) {
sumx = razx = sumy = razy = 0;
for(i=1; i<4; i++) {
if(m_Event[pos.y][pos.x+i] == SHIPWOUND && pos.x+i<10) {
m_Event[pos.y][pos.x+i] = SHIPKILLED;
sumx++;
}
if(m_Event[pos.y][pos.x-i] == SHIPWOUND && pos.x-i>=0) {
m_Event[pos.y][pos.x-i] = SHIPKILLED;
razx++;
}
if(m_Event[pos.y+i][pos.x] == SHIPWOUND && pos.y+i<10) {
m_Event[pos.y+i][pos.x] = SHIPKILLED;
sumy++;
}
if(m_Event[pos.y-i][pos.x] == SHIPWOUND && pos.y-i>=0) {
m_Event[pos.y-i][pos.x] = SHIPKILLED;
razy++;
}
}
m_Event[pos.y][pos.x] = SHIPKILLED;

if(pos.x-razx-1>=0) x = pos.x-razx-1;
else x = pos.x-razx;
if(pos.x+sumx+1<10) cx = pos.x+sumx+1;
else cx = pos.x+sumx;
if(pos.y-razy-1>=0) y = pos.y-razy-1;
else y = pos.y-razy;
if(pos.y+sumy+1<10) cy = pos.y+sumy+1;
else cy = pos.y+sumy;
for(i=y; i<=cy; i++)

for(j=x; j<=cx; j++)
if(m_Event[i][j] != SHIPKILLED)
m_Event[i][j] = NEARKILLEDSHIP;

return N_SHIPKILLED;
}
else
return N_SHIPWOUND;

}
m_Event[pos.y][pos.x] = CANNOT;
return N_EMPTY;
}

Анализ:

//properties
#define EMPTY 1000
#define SHIP 1001
#define NEARSHIP 1002
#define SHIPWOUND 1003
#define SHIPKILLED 1004
#define CANNOT 1005
#define SHIPNOTKILLED 1006
#define NEARKILLEDSHIP 1007

short m_Event[10][10];

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

В функцию передаются координаты курсора, который находится на одной из клеток.
Функция возвращает одно из трех значений:

SHIPKILLED - корабль убит
SHIPWOUND - корабль ранен
N_EMPTY - клетка пуста

int CField::NetStep(int x, int y) {

POINT pos;
int i, j, sumx, razx, sumy, razy, cx, cy;
int IsKilled;

pos.x = x;
pos.y = y;

Далее проверка. Если данная клетка - корабль, то возвратить либо
корабль убит (N_SHIPKILLED), либо корабль ранен (N_SHIPWOUND):

if(m_Event[pos.y][pos.x] == SHIP) {

if{
...
return N_SHIPKILLED;
}
else
return N_SHIPWOUND;
}

Если переданная в параметр клетка не корабль, то возвратить - клетка пуста (N_EMPTY):

m_Event[pos.y][pos.x] = CANNOT;
return N_EMPTY;
}

Далее, если клетка - корабль, то присвоим этой клетке значение РАНЕН, а переменной IsKilled значение - корабль убит:

if(m_Event[pos.y][pos.x] == SHIP) {

m_Event[pos.y][pos.x] = SHIPWOUND;
IsKilled = SHIPKILLED;

Далее проверим какая у нас ситуация на соседних клетках.

В цикле проверить условие - если соседняя справа клетка не ранена
или находится вне поля боя, то прервать.
Проверить то же условие для клеток расположенных на две и на три клетки вправо.

for(i=1; i<4; i++)

if(m_Event[pos.y][pos.x+i] != SHIPWOUND || pos.x+i==10)break;

Если соседняя справа клетка - корабль и находится на поле боя,
то корабль не убит, он ранен

if(m_Event[pos.y][pos.x+i] == SHIP && pos.x+i<10)

IsKilled = SHIPWOUND;

В цикле проверить условие - если соседняя слева клетка не ранена
или находится вне поля боя, то прервать.
Проверить то же условие для клеток расположенных на две и на три клетки влево.

for(i=1; i<4; i++)

if(m_Event[pos.y][pos.x-i] != SHIPWOUND || pos.x-i==-1)break;

Если соседняя слева клетка - корабль и находится на поле боя,
то корабль не убит, он ранен

if(m_Event[pos.y][pos.x-i] == SHIP && pos.x-i>=0)

IsKilled = SHIPWOUND;

В цикле проверить условие - если соседняя снизу клетка не ранена
или находится вне поля боя, то прервать.
Проверить то же условие для клеток расположенных на две и на три клетки влево.

for(i=1; i<4; i++)

if(m_Event[pos.y+i][pos.x] != SHIPWOUND || pos.y+i==10)break;

Если соседняя снизу клетка - корабль и находится на поле боя,
то корабль не убит, он ранен

if(m_Event[pos.y+i][pos.x] == SHIP && pos.y+i<10)

IsKilled = SHIPWOUND;

В цикле проверить условие - если соседняя сверху клетка не ранена
или находится вне поля боя, то прервать.
Проверить то же условие для клеток расположенных на две и на три клетки влево.

for(i=1; i<4; i++)

if(m_Event[pos.y-i][pos.x] != SHIPWOUND || pos.y-i==-1)break;

Если соседняя сверху клетка - корабль и находится на поле боя,
то корабль не убит, он ранен

if(m_Event[pos.y-i][pos.x] == SHIP && pos.y-i>=0)

IsKilled = SHIPWOUND;

//------------------------------------
Если корабль убит, то сделаем нужные нам процедуры с клетками и вернем значение N_SHIPKILLED (корабль убит) в противном случае вернем значение N_SHIPWOUND (корабль ранен)

Итак если корабль убит, то присвоим значение УБИТ всем полям корабля.
if(IsKilled == SHIPKILLED) {

sumx = razx = sumy = razy = 0;
for(i=1; i<4; i++) {
if(m_Event[pos.y][pos.x+i] == SHIPWOUND && pos.x+i<10) {
m_Event[pos.y][pos.x+i] = SHIPKILLED;
sumx++;
}
if(m_Event[pos.y][pos.x-i] == SHIPWOUND && pos.x-i>=0) {
m_Event[pos.y][pos.x-i] = SHIPKILLED;
razx++;
}
if(m_Event[pos.y+i][pos.x] == SHIPWOUND && pos.y+i<10) {
m_Event[pos.y+i][pos.x] = SHIPKILLED;
sumy++;
}
if(m_Event[pos.y-i][pos.x] == SHIPWOUND && pos.y-i>=0) {
m_Event[pos.y-i][pos.x] = SHIPKILLED;
razy++;
}
}

m_Event[pos.y][pos.x] = SHIPKILLED;
//---------------------------------
Если корабль убит, то всем полям граничащим с кораблем
присвоим значение NEARKILLEDSHIP и возвратим значение
- N_SHIPKILLED (корабль убит).

if(pos.x-razx-1>=0) x = pos.x-razx-1;
else x = pos.x-razx;
if(pos.x+sumx+1<10) cx = pos.x+sumx+1;
else cx = pos.x+sumx;
if(pos.y-razy-1>=0) y = pos.y-razy-1;
else y = pos.y-razy;
if(pos.y+sumy+1<10) cy = pos.y+sumy+1;
else cy = pos.y+sumy;
for(i=y; i<=cy; i++)
for(j=x; j<=cx; j++)
if(m_Event[i][j] != SHIPKILLED)
m_Event[i][j] = NEARKILLEDSHIP;
return N_SHIPKILLED;

}
В противном случае - N_SHIPWOUND (корабль ранен).
else
return N_SHIPWOUND;

Эта функция получает координаты ячейки (клетки). Если кординаты ячейки попали в корабль,
то функция сообщает убит корабль или ранен. В противном случае сообщает, что ячейка пуста.


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

Hosted by uCoz