IPB
ЛогинПароль:

> Новый Морской бой
bLACK_wINGS
сообщение 8.10.2006 22:16
Сообщение #1





Группа: Пользователи
Сообщений: 9
Пол: Мужской

Репутация: -  0  +


В общем.. ига такая на логику... Весь инет облазил в поисках инфы, ничего не нашел.. попалась случайно вместе с журнальчиком 777. Суть игры:
Дано поле. По вертикали и горизонтали расположены числа 0..9. Каждое число предполагает наличие в в линии такого количества фрагментов кораблей. Набор кораблей стандартный. В общем прожка по идее должна выдать расстановку кораблей. Ваши соображения по поводу)))) smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
bLACK_wINGS
сообщение 2.11.2006 19:34
Сообщение #2





Группа: Пользователи
Сообщений: 9
Пол: Мужской

Репутация: -  0  +


Вот поразмыслил я над твоим предложением перебором сделать решение... Вот что, в принципе идея неплохая.
Скорее всего его буду использовать. Ты прав, там много на человека завязано, да и не всегда работать будет.
Только вот поподробнее вот об этом месте пожалуйста
Цитата

А теперь выбираем следующую строку/столбец, в которой количество вариантов минимально, но уже учитываем поменявшуюся обстановку на поле. Например, если в строке записана сумма 8, но уже известно, что одна (определенная) клетка там - пустая, а другая - фрагмент корабля, то здесь у нас уже не С из 10 по 8, а С из 8 по 7.

допустим клетка уже определена, ну и как её при откате распознать, что не создана она была в течение этого хода? И еще, как использовать(распознать) такую ситуацию: на первом ходе вычислили клетку, вокруг которой в СТРОКЕ!!! пустые. Ведь это может быть н-палубник по вертикали))) и как тогда?
Цитата

Перебирая варианты нужно, конечно, считать встретившиеся корабли, чтобы вовремя сделать откат противоречивого варианта.
Для удобства откатов лучше хранить не матрицу состояний (0 - не знаем, 1 - фрагмент, 2 - пусто), а матрицу целых чисел (0 - не знаем, -1 - фрагмент, K>0 - пусто, причем является результатом К выводов).
Тогда, когда мы в некоторую клетку ставим -1, мы должны просто инкрементировать всех соседей по диагонали, тем самым обозначая, что там - пусто (при этом проверяя отсутствие противоречий), а для отката достаточно будет просто декрементировать обратно, а не запоминать и восстанавливать все 8 соседей.

И вообще можешь поподробней об откате, а то вот с ним у меня будет косяк))
Уже написал действующий код, генерирующий поле автоматически.
Дааа... И еще, проблема памяти(глубины стека) возникает. Ведь функция, которая реашает задачу будет рекурсивной, или я ошибаюсь? Если ошибаюсь, то как иначе?

Сообщение отредактировано: bLACK_wINGS - 2.11.2006 19:37
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Michael_Rybak
сообщение 2.11.2006 21:08
Сообщение #3


Michael_Rybak
*****

Группа: Модераторы
Сообщений: 1 046
Пол: Мужской
Реальное имя: Michael_Rybak

Репутация: -  32  +


Цитата
И еще, проблема памяти(глубины стека) возникает. Ведь функция, которая реашает задачу будет рекурсивной, или я ошибаюсь? Если ошибаюсь, то как иначе?

Глубины более чем достаточно, потому что
1) глубина вложенности - не больше 20 (каждый уровень рекурсии соответствует одной строке/стобцу, где мы перебираем 2^x вариантов одним циклом - перебираем значения клеток, для которых ничего не известно)
2) всё поле передавать в стек не нужно; вообще в стек передавать ничего не нужно


Цитата
И еще, как использовать(распознать) такую ситуацию: на первом ходе вычислили клетку, вокруг которой в СТРОКЕ!!! пустые. Ведь это может быть н-палубник по вертикали))) и как тогда?


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

Цитата
допустим клетка уже определена, ну и как её при откате распознать, что не создана она была в течение этого хода?


Именно об этом я говорю вот здесь:

Цитата
Для удобства откатов лучше хранить не матрицу состояний (0 - не знаем, 1 - фрагмент, 2 - пусто), а матрицу целых чисел (0 - не знаем, -1 - фрагмент, K>0 - пусто, причем является результатом К выводов).
Тогда, когда мы в некоторую клетку ставим -1, мы должны просто инкрементировать всех соседей по диагонали, тем самым обозначая, что там - пусто (при этом проверяя отсутствие противоречий), а для отката достаточно будет просто декрементировать обратно, а не запоминать и восстанавливать все 8 соседей.



Итак, значения клеток у нас такие:

-1 - там корабль
0 - пока что ничего не известно
>0 - там вода

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

Выглядеть это будет так:

if (field[Ay][Ax] = 0) then // в клетке А значение неизвестно
if (field[By][Bx] >= 0) then // в клетке B не стоит корабль
begin
//делаем предположение
field[Ay][Ax] := -1; //корабль
field[By][Bx] := field[By][Bx] + 1; //увеличиваем, чтобы сказать, что там точно пусто (*)

Search(...);//рекурсивный вызов

//отменяем предположение - восстанавливаем ситуацию
field[By][Bx] := field[By][Bx] - 1; //уменьшаем, забирая только текущий вывод.
//Т.е. если там пусто из других, более
//ранних соображений, то останется
//положительное число, то же, которое было
//до вызова этого уровня рекурсии
field[Ay][Ax] := 0; //убрали корабль
end;



В строке, обозначенной "*", мы увеличиваем значение клетки, которая точно пуста. При этом мы уже и раньше могли получить эту информацию, причем не один раз, поэтому выводы о том, что клетка пуста, мы просто накапливаем в виде положительного числа, обозначающего количество выводов о ее пустоте, которые мы сделали smile.gif

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


В этом примере я не учитываю влияния изменений на соседние строки (на самом деле, изменив что-то в строке, надо пройти по ней, распознать корабли, и понаставлять вокруг них воды в соседних строках). Это просто чтоб объяснить, как откатывать.


Эта техника может быть довольно сложна для первого восприятия. Пожалуйста, попробуй как можно доскональнее понять, что я там делаю, прежде чем спрашивать дальше.

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

Сообщений в этой теме
bLACK_wINGS   Новый Морской бой   8.10.2006 22:16
Bokul   А по форуму поискать? морской бой (растановка кора...   8.10.2006 22:25
bLACK_wINGS   2Bokul: Нее.. это я уже смотрел... там чисто генер...   8.10.2006 22:32
Bokul   Да не то. Это я сначала не правильно задание по...   8.10.2006 22:41
bLACK_wINGS   2Bokul: Да набор такой: 4-однопалубников 3-двухпал...   8.10.2006 22:47
Bokul   Еще одно: Какой размер доски и может ли повторятся...   8.10.2006 23:03
Michael_Rybak   Я бы попробовал такой перебор. Рассмотрим пустую ...   9.10.2006 0:46
bLACK_wINGS   2Michael_Rybak Ё-моё.. а не будет ли много мороки ...   13.10.2006 22:15
Michael_Rybak   Давай :) EDIT: >Ё-моё.. а не будет ли много мо...   13.10.2006 23:01
bLACK_wINGS   Вот отсканенный типа алгоритм... Но как программу...   28.10.2006 10:42
Michael_Rybak   этот алгоритм вродь как лучше чем перебор Как с...   28.10.2006 13:13
bLACK_wINGS   2Michael_Rybak Да решал я эти головоломки, ну алго...   31.10.2006 20:30
Michael_Rybak   Вот оно как? Ну и замечательно! Что именн...   31.10.2006 20:43
bLACK_wINGS   Вот поразмыслил я над твоим предложением перебором...   2.11.2006 19:34
Michael_Rybak   Глубины более чем достаточно, потому что 1) глуб...   2.11.2006 21:08
bLACK_wINGS   В принципе с твоей функцией понятно. Однако у меня...   2.11.2006 22:18
Michael_Rybak   Во-первых, делаешь ты это как-то запутанно. Если...   2.11.2006 23:00
bLACK_wINGS   ВСЁЁЁ :rolleyes: :rolleyes: Дописал... Всего то ...   12.11.2006 17:06


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 14.07.2025 16:40
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"