|
|
|
| Здравствуйте, уважаемые пользователи форума! Пишу игру "Морской бой", и у меня такой вопрос.
У меня есть двумерный массив состоящий из 0 и 1, где 0 - пустая ячейка, 1 - кораблик (или его часть). Мне необходимо реализовать проверку на PHP которая выявит хорошо ли расставлены корабли или нет по следующим критерием:
1. По количеству кораблей всего: 4 - однопалубных, 3 - двухпалубных, 2 - трёхпалубных, 1 - четырёх палубные.
2. Корабли могут находится только в вертикальном либо горизонтальном положении.
3. Корабли не должны соприкасаться друг с другом.
Я без проблемно реализовал что бы считало количество однопалубных кораблей и к ним все эти проверки выполнялись. Но не могу понять как мне обойти этот массив что бы выяснить про остальные корабли данные. Помогите пожалуйста, я в этом новичек. | |
|
|
|
|
|
|
|
для: pazha
(24.07.2012 в 18:16)
| | 0 - пустая ячейка
1 - кораблик
2 - раненый кораблик
3 - убитый кораблик
4 - недоступная ячейка | |
|
|
|
|
|
|
|
для: pazha
(24.07.2012 в 18:16)
| | Осмелюсь предположить, что потому же принципу вы могли бы сделать и для остальных кораблей.
нашли палубу -> однопалубник?
нет? -> ишем вторую палубу
нашли? -> ишем третью
нашли? -> нет
значит двухпалубник
|
Ха! Еще как вариант:
Использовать битовые операции
2 бита говорят о том какой это корабль:
00 – однопалубник
01 – двухпалубник
10 – трехпалубник
11 – четырехпалубник
1 бит указывает на ранение
Еще 2 бита говорят в каком направлении искать оставшиеся палубы
Итого всего пять бит, осталось еще три бита
1 бит говорит пустая ячейка или нет
1 бит говорит был сюда выстрел или нет
Еще бит куда то можно использовать.
А проверку делать , что б тормозить поменьше, по маске.
УПС. на направление придется использовать 3 бита, а вот бит про ранение можно совместить с битом "стреляли или нет". И последний бит говорит "убит или нет". | |
|
|
|
|
|
|
|
для: Zezst
(25.07.2012 в 01:13)
| |
$b = 2; // 01-двупалубный
$a = 80; // 001-пусть будет направо
// 0-не ранен(соответсвенно сюда не пуляли)
// 1-не пусто
// 0-не убит
$ba = $b + $a;
$korabl = 3; // 11 000000 - для того что бы выделить биты отвечаюшие за какой корабль
$pusto = 64; // 000000 1 00 - для проверки пусто или нет
if($ba //взяли ячейку
& $pusto) //выделили бит отвечающий за пусто
{ // если не пусто
$k = $ba // снова взяли ячейку
& $korabl; // выделили биты отвечающие за корабль
if($k === 0)
echo "одна палуба";
if($k === 2)
echo "две палубы";
if($k === 1)
echo "три палубы";
if($k === 3)
echo "четыре палубы";
}
|
| |
|
|
|
|
|
|
|
для: Zezst
(25.07.2012 в 02:15)
| | Сделал проверку следующим образом: двумя циклами перехожу по всем ячейкам двумерного массива, и смотрю что если у нас значение в ячейке равно 1 (это значит что это либо корабль либо его часть) то проверяем что бы в 4-х углах не было едениц.
Таким образом мы проверили на то что бы кораблики были только по вертикали и горизонтале а так же что бы не были слипшиеся два корабля. | |
|
|
|
|
|
|
|
для: pazha
(25.07.2012 в 07:54)
| | Всем спасибо. Успешно реализовал всё что хотел. Вот код, может кому понадобиться:
class NavalBattle {
# Метод: проверка правильности расстановки кораблей.
# Принимает: игровое поле в виде двумерного массива.
# Возвращает: true либо номер ошибки.
public static function CheckPlacement( &$aField ) {
# Проверка количества строк :
if( count( $aField ) != 10 )
return -1;
# Счетчик кораблей на поле :
$iShipCounter = 0;
$iSingleDeckCounter = 0;
$iDoubleDeckCounter = 0;
$iThreeDeckCounter = 0;
$iFourDeckCounter = 0;
# Перебор по строкам :
for( $iY = 0; $iY < 10; $iY++ ) {
# Проверка количества столбцов :
if( count( $aField[$iY] ) != 10 )
return -2;
# Подсчет количества кораблей по палубно :
$sTmp = str_replace( array( '[', ']' ), array( '0,', ',0' ), json_encode( $aField[$iY] ) );
$iDoubleDeckCounter += substr_count( $sTmp, '0,1,1,0' );
$iThreeDeckCounter += substr_count( $sTmp, '0,1,1,1,0' );
$iFourDeckCounter += substr_count( $sTmp, '0,1,1,1,1,0' );
# Перебор по столбцам :
for( $iX = 0; $iX < 10; $iX++ ) {
# Фильтрация значения ячейки :
$aField[$iY][$iX] = intval( $aField[$iY][$iX] );
# Проверка значения ячейки :
if( $aField[$iY][$iX] != 0 && $aField[$iY][$iX] != 1 )
return -3;
# Если это корабль :
if( $aField[$iY][$iX] == 1 ) {
# Проверяем что бы угловые ячейки содержали 0 :
if( (isset( $aField[$iY-1] ) && isset( $aField[$iY-1][$iX-1] ) && $aField[$iY-1][$iX-1] != 0) || (isset( $aField[$iY-1] ) && isset( $aField[$iY-1][$iX+1] ) && $aField[$iY-1][$iX+1] != 0) || (isset( $aField[$iY+1] ) && isset( $aField[$iY+1][$iX-1] ) && $aField[$iY+1][$iX-1] != 0) || (isset( $aField[$iY+1] ) && isset( $aField[$iY+1][$iX+1] ) && $aField[$iY+1][$iX+1] != 0) )
return -4;
# Проверяем, однопалубный ли это корабль :
if( (!isset( $aField[$iY-1] ) || $aField[$iY-1][$iX] == 0) && (!isset( $aField[$iY+1] ) || $aField[$iY+1][$iX] == 0) && (!isset( $aField[$iY][$iX-1] ) || $aField[$iY][$iX-1] == 0) && (!isset( $aField[$iY][$iX+1] ) || $aField[$iY][$iX+1] == 0) )
$iSingleDeckCounter++;
# Увеличиваем счетчик палуб кораблей :
$iShipCounter++;
}
}
}
# Проверка количества палуб на поле :
if( $iShipCounter != 20 )
return -5;
if( $iSingleDeckCounter != 4 )
return -6;
# Подсчет количества кораблей по вертикали :
for( $iX = 0; $iX < 10; $iX++ ) {
$aTmp = array();
for( $iY = 0; $iY < 10; $iY++ )
$aTmp[] = $aField[$iY][$iX];
$sTmp = str_replace( array( '[', ']' ), array( '0,', ',0' ), json_encode( $aTmp ) );
$iDoubleDeckCounter += substr_count( $sTmp, '0,1,1,0' );
$iThreeDeckCounter += substr_count( $sTmp, '0,1,1,1,0' );
$iFourDeckCounter += substr_count( $sTmp, '0,1,1,1,1,0' );
}
# Проверка количества кораблей на поле :
if( $iDoubleDeckCounter != 3 || $iThreeDeckCounter != 2 || $iFourDeckCounter != 1 )
return -6;
return true;
}
}
|
| |
|
|
|
|
|
|
|
для: pazha
(25.07.2012 в 08:07)
| | ух-ты , интересно,
надо будет поскорее закончить мои сегодняшние проекты и попробовать написать морской бой тоже))
спасибо за идею))
ток я сам попробую | |
|
|
|