Можно ли играть в морской бой втроем. Морской бой
Практически каждый, кто когда-то был школьником знает игру «Морской бой», играя в которую можно замечательно провести время в поездке или перерыве. В игру «морской бой» играют двое. Для игры в «морской бой» подойдет обычный лист в клеточку, который можно скачать и распечатать на нашем сайте.
Однако специально для игры «морской бой» на этой странице можно распечатать таблицу для двух игроков. В игру «морской бой» могут играть только два человека или две команды. Сначала игроки рисуют на своем поле флот кораблей. Флот состоит из: один корабль — ряд из четырех клеток — «четырёхпалубный», два корабля — ряд из 3 клеток — «трёхбалубные», три корабля — ряд из двух клеток — «двухпалубные» и четыре корабля — ряд из одной клетотки — «однопалубые». Внизу таблиц для игры в «морской бой», которые можно скачать и рапечатать ниже, приведено какие корабли и в каком количестве есть у игрока. При рисовании корабли не могут касаться друг друга углами и не могут располагаться по диагонали.
После того как корабли расставлены, игроки бросают жребий, кто начинает первым. После этого каждый из игроков по очереди называет координаты кораблей на карте противника, например, «Д-2». Приведенные ниже таблицы для игры в «морской бой» уже содержат таблицы 10 на 10 для двух игроков с пронумерованными ячейками. Если на указанных координатах игрок находится корабль противника, то весь корабль или его часть считается поврежденный. Игрок, сделавший результативный ход, вправе сделать ещё один без очереди.
Распечатать таблицу для игры «морской бой» на А4 или скачать
Вы можете распечатать таблицу для игры «морской бой» на листе А4 в формате PDF или Word. Файл PDF для печати и RTF с возможностью редактирования можно найти по ссылкам ниже.
Файл содержит один лист формата А4 с таблицами для двух игроков.Также на нашем сайте в разделе разлинованные листы есть возможность просто распечатать лист в клетку или линейку.
Пару дней назад я с удивлением узнал, что некоторые мои знакомые не умеют играть в морской бой. Т.е. правила они, конечно, знают, но вот играют как-то бессистемно и в итоге часто проигрывают. В этой записи я постараюсь изложить основные идеи, которые помогут повысить уровень вашей игры.
Правила игры
Существует множество вариантов морского боя, но мы с вами рассмотрим наиболее распространённый вариант со следующим набором кораблей:
Все перечисленные корабли должны быть размещены на квадратном поле 10 на 10 клеток, при этом корабли не могут соприкасаться ни углами, ни сторонами. Самое игровое поле нумеруется сверху вниз, а вертикали помечаются русскими буквами от «А» до «К» (при этом буквы «Ё» и «Й» пропускают).
Рядом рисуется вражеское поле аналогичного размера. При удачном выстреле по кораблю противника на соответствующей клетке вражеского поля ставится крестик и производится повторный выстрел, при неудачном выстреле в соответствующей клетке ставится точка, и ход переходит к противнику.
Оптимальная стратегия
В игре морской бой всегда есть элемент случайности, но его можно свести к минимуму. Прежде чем переходить непосредственно к поиску оптимальной стратегии, необходимо озвучить одну очевидную вещь: вероятность попасть по кораблю противника тем выше, чем меньше непроверенных клеток осталось на его поле, аналогично вероятность попадания по вашим кораблям тем ниже, чем больше непровереных клеток осталось на вашем поле. Т.о. для эффективной игры нужно научиться сразу двум вещам: оптимальной стрельбе по противнику и оптимальному своих размещению кораблей.
В дальнейшем объяснении будут использоваться следующие обозначения:
Оптимальная стрельба
Первым и самым очевидным правилом оптимальной стрельбы является следующее правило: не стрелять по клеткам непосредственно окружающим уничтоженный корабль противника.
В соответствии с принятыми выше обозначениями, на рисунке жёлтым отмечены те клетки, по которым уже были произведены безуспешные выстрелы, красным отмечены клетки, выстрелы по которым закончились попаданием, а зелёным отмечены клетки, стрельба по которым не производилась, но можно гарантировано утверждать, что кораблей в них нет (кораблей там быть не может, т.к. по правилам игры корабли не могут соприкасаться).
Из первого правила сразу вытекает второе: если вам удалось подбить вражеский корабль, необходимо сразу же его добить, чтобы как можно раньше получить список гарантировано свободных клеток.
Третье правило вытекает из первых двух: необходимо в первую очередь пытаться подбить самые крупные корабли противника. Возможно, для вас это правило не очевидно, но если немного подумать, то можно легко заметить, что уничтожив вражеский линкор, мы в лучшем случае получим информацию сразу о 14 гарантировано свободных клетках, а уничтожив крейсер, всего о 12.
Т. о. оптимальную стратегию стрельбы можно свести к целенаправленному поиску и уничтожению самых крупных кораблей противника. К сожалению, сформулировать стратегию мало, необходимо предложить способ её реализации.
Для начала давайте рассмотрим участок игрового поля размером 4 на 4 клетки. Если в рассматриваемом участке есть вражеский линкор, то его гарантировано можно подбить не более чем за 4 выстрела. Для этого надо стрелять так, чтобы на каждой горизонтали и вертикали было ровно по одной проверенной клетке. ниже представлены все варианты такой стрельбы (без учёта отражений и поворотов).Среди всех этих вариантов, оптимальными на поле 10 на 10 клеток являются только первые два варианта, гарантирующие попадание в линкор максимум за 24 выстрела.
После того, как уничтожен вражеский линкор, необходимо начинать поиск крейсеров, а затем и эсминцев. При этом, как вы уже догадались, можно воспользоваться аналогичной методикой. Только теперь необходимо разбивать поле на квадраты со стороной в 3 и 2 клетки соответственно.
Если при поиске линкора вы использовали вторую стратегию, то для поиска крейсеров и эсминцев вам необходимо стрелять по следующим полям (зелёным отмечены поля, по которым вы уже стреляли при поиске линкора):
Для поиска катеров оптимальной стратегии не существует, поэтому в конце игры приходится опираться в основном на удачу.
Оптимальное размещение кораблей
Оптимальная стратегия размещения кораблей в некотором смысле обратна оптимальной стратегии стрельбы. При стрельбе, мы пытались найти самые крупные корабли, чтобы сократить количество клеток, которые нужно проверять, за счёт гарантировано свободных клеток. Значит, при размещении корабли надо ставить таким образом, чтобы в случае их потери минимизировать количество гарантировано свободных клеток. Как вы помните, линкор в центре поля открывает для противника сразу 14 полей, но линкор, стоящий в углу, открывает для противника всего 6 полей:
Аналогично, крейсер, стоящий в углу, вместо 12 полей открывает всего 6.
Т.о., разместив крупные корабли вдоль границы поля, вы оставляете больший простор для катеров. Т.к. стратегии для поиска катеров нет, противнику придётся стрелять наугад, и чем больше свободных полей у вас останется к моменту ловли катеров, тем тяжелее будет выиграть противнику.Ниже представлено три способа размещения крупных кораблей, которые оставляют большой простор для катеров (отмечено синим):
Каждая из приведённых расстановок оставляет для катеров ровно 60 свободных клеток, а это значит, что вероятность случайно попасть в катер составляет 0,066. Для сравнения стоит привести случайную расстановку кораблей:
При такой расстановке для катеров остаётся всего 21 клетка, а это значит, что вероятность попадания по катеру составляет уже 0,19, т.е. почти в 3 раза выше.
В заключение хочу сказать, что не стоит проводить уж слишком много времени, играя в морской бой. Особенно хочу предостеречь вас от игры на лекциях. Когда я сидел в Ваби-Саби и играл в морской бой со своей девушкой, мимо прошла официантка и сказала, что она весьма неплохо играет, т.
P.S. В комментариях абсолютно верно указывают, что на хабре уже были похожие публикации, было бы неверно не поставить ссылки на них.
Игра «Морской бой» помогает людям скоротать время на уроках, лекциях, обеденных перерывах или просто холодными зимними вечерами уже более 80-ти лет. За это время сменилось немало поколений, но игра по-прежнему остаётся актуальной. Хоть она и вытесняется более современными и динамичными компьютерными играми, сегодня практически нереально найти школьника, который не знает, как играть в морской бой и что это вообще такое. Я расскажу вам о правилах игры, а также опишу выигрышную тактику. Рассмотрим, как играть в морской бой.
Правила игры
Игровое поле каждого игрока представляет собой квадрат 10х10, на котором размещаются корабли. Поле обязательно содержит числовые и буквенные координаты (по вертикали числа 1-10, а по горизонтали буквы от а до к). Для классической игры используются четыре одноклеточных корабля (подлодки), три двухклеточных (эсминцы), два трёхклеточных (крейсеры) и один четырёхклеточный корабль (линкор). Их рисуют внутри квадрата. По правилам, корабли не должны соприкасаться. Играть лучше всего на листке в клеточку, потому что чертеж кораблей представляет собой обведение клеточек. Одна палуба — одна клеточка. Размещать корабли можно как горизонтально, так и вертикально. Рядом со своим квадратом игрок чертит второй, на котором отмечает «выстрелы» по противнику. При попадании в корабль соперника, на чужом поле ставится крестик. Попавший игрок делает ещё один выстрел.
Нарушения
- Количество кораблей не соответствует правилам
- Корабли расположены вплотную друг к другу
- Изменён размер поля
- Указаны неправильные координаты
Процесс игры
- Игроки решают, кто будет ходить первым
- Игрок, выполняющий ход, называет координату, на которой, по его мнению, располагается корабль соперника. Например, квадрат А1.
- При промахе соперник должен сказать «Мимо!», при попадании «Попал», «Ранил» или «Убил», в зависимости от размера корабля.
- Игра продолжается до потопления всех кораблей одного из игроков.
Как выиграть в морской бой
Данная стратегия является одним из множества вариантов построения боя. Её суть заключается в том, что все большие корабли (от двух до четырёх клеток) располагаются в одном углу поля и как можно более компактно. А вот одноклеточные корабли разбрасываются по оставшейся части поля. В итоге, ваш соперник довольно быстро найдёт зону группировки больших кораблей довольно быстро и начнёт нещадно уничтожать их. В этот момент он почувствует себя настоящим гением, но мы-то знаем, в чём подвох. За время, которое соперник затратит на поиски маленьких кораблей вы с большой вероятностью успеете понять его тактику и уничтожить большинство кораблей, тем самым заставив его понервничать. Остальное – уже дело техники. В данной статье было рассказано о правилах, процессе игры и приведены примеры выигрышной тактики, как выиграть в морской бой.
Дети настолько увлечены различными гаджетами, что зачастую не только читать, но даже играть не в виртуале не хотят. Это тревожит и специалистов, и родителей. В одной из серий мультфильма «Барбоскины» Дедушка как раз предлагает способ вернуть детей в реальный мир при помощи игры всей семьей в обычный «Морской бой» на бумаге.
Для этого он отключает в доме электричество, и внуки вынуждены освоить игру, не требующих никаких особых условий. Он показал, что интересно провести время можно без всякого интернета, вооружившись лишь ручкой и собственным разумом.
Хотя эта настольная игра Морской бой сегодня существует и в компьютерном варианте, но традиционная версия по уничтожению кораблей на листочке в клеточку имеет перед виртуальной одно несомненное преимущество.
Играть с живым человеком интересней, чем с компьютером, бой получается намного веселей и азартней. Да и полезней, ведь в таком случае у ребенка развивается не только логика и стратегическое мышление, но и интуиция, умение «просчитывать» и читать эмоции другого человека.
Ещё один плюс и причина долгой популярности игры – простота её организации. Для того чтобы повести корабли в бой не нужен интернет, электричество, большое помещение или какой-то особый антураж. Достаточно бумаги, ручки и знать морской бой на бумаге для двоих.
Учимся играть в морской бой
Правила в морской бой для двоих человек довольно просты. На бумаге каждый игрок должен нарисовать квадрат 10х10 клеточек, которые обозначают с одной стороны буквами от А до К (без Ё и Й), с другой цифрами от 1 до 10. В этом поле нужно расставить свои корабли.
Рядом рисуется второй такой же квадрат с аналогичным обозначением полей. На нем в процессе боя игрок фиксирует свои выстрелы.
- Совершая «выстрел» игрок называет координаты цели, например, Б8.
- Противник отвечает «мимо», если в клеточке ничего нет; «ранен», если в его корабль попали; «убит», когда корабль уничтожен.
- Попадание в чужой корабль обозначается крестиком. В этом случае правила дают право на следующий выстрел.
- При промахе право на выстрел переходит ко второму игроку. Побеждает тот, кто первый уничтожит все корабли противника.
- По окончании игры участник может потребовать у противника предъявить его игровое поле и сверить записи ходов.
Правила игры Морской бой оговаривают не только сколько и какие по величине корабли участвуют в бое, но и их расположение.
- Состав кораблей: 4 подлодки из одной клеточки, 3 эсминца, состоящие из двух клеток, 2 крейсера из трех клеток и один четырехклеточный линкор.
- Рисовать корабли надо так, чтобы они ни в коем случае не касались друг друга. Между ними должно быть расстояние не меньше одной клетки.
- Располагать корабли можно и по горизонтали, и по вертикали, и у края игрового поля.
Чего делать нельзя
Оговаривают правила и определенные ограничения.
- Нельзя изменять состав кораблей.
- В некоторых правилах говорится, что один корабль может иметь только линейную форму, в некоторых вариантах допускается форма буквы Г. Этот момент нужно оговорить заранее. Но во всех вариантах нельзя рисовать и располагать корабли по диагонали.
- Нельзя изменять величину поля.
- Нельзя искажать координаты и скрывать попадание.
Стратегии
Не только простые правила и условия организации игры объясняют популярность игры Морской бой, но и то, что выигрыш в ней определяется не только везением, но и верной стратегией и тактикой. Это игра двоих людей, а значит, к логике присоединяются эмоции и хитрости. Поэтому выигрышная стратегия предполагает:
- Соперник ни в коем случае не должен иметь возможности увидеть ваше игровое поле.
- Учитывайте мастерство и способ игры соперника. Например, если ваш противник начинающий игрок, то не стоит располагать свои корабли в углах поля. Неопытные зачастую начинают именно с них, особенно с хода А1. Если с вами будет играть опытный и давний соперник, который уже знает, что в углах ваших кораблей быть не может, то стоит сломать шаблон и спрятать парочку именно там.
- Продумайте расположение своих кораблей. Одной из выигрышных стратегий считается расположение крупных кораблей компактно в одном месте, а одноклеточных вразброс подальше друг от друга. Тогда игрок, быстро найдя крупные корабли, потратит много времени на поиск маленьких подлодок. Это даст вам время и шанс отыграться.
Выигрышная тактика
К правильной тактике игры относятся несколько простых приемов.
Обязательно фиксировать на своем поле ходы соперника, и все свои ходы на втором игровом поле. Обозначаются не только попадания, но и промахи. Кто-то делает это точками, кто-то крестиками. Это позволит избежать повторного обстреливания пустых квадратов и конфликтов, в случае каких-либо ошибок.
Если корабль соперника «убит» в морском бою, то окружающие его клетки отмечаем как пустые сразу. Ведь мы знаем, что правила запрещают размещение в них кораблей. Это экономит ваше время. В этом случае самый выгодный выстрел по линкору. Его уничтожение открывает сразу восемнадцать клеточек, почти пятую часть поля.
Тактика стрельбы у игроков также может быть различной. Можно стрелять, делая ходы по диагонали. Так больше шансов зацепить крупные корабли. Можно, в поисках выгодного линкора, стрелять через три клеточки на четвертую. После первых попаданий выбор ходов определяете исходя из того, что начинает проглядывать на вражеском игровом поле.
Тактика борьбы с популярным мошенничеством, когда соперник выставляет последний однопалубный корабль уже в процессе игры в последнюю свободную клетку. Для того, чтобы такой обман был невозможен, поле и корабли рисуют одним цветом, а выстрелы обозначают другой ручкой или карандашом.
Сегодня игра Морской бой существует и в виде настольного фабричного набора, и в виде компьютерной игры, но играть на простом листочке в клеточку по-прежнему увлекательно.
Играем в «Морской Бой»
Вы играете в морской бой, но не всегда выигрываете? Тогда вам наверняка интересно узнать, как существенно повысить свои шансы на выигрыш, как правильно расставить корабли, как быстро уничтожить корабли противника и, конечно же, как выиграть в игре Морской бой !
Правила игры «Морской Бой»
Существует множество вариантов морского боя, но мы с вами рассмотрим наиболее распространённый вариант со следующим набором кораблей:
Все перечисленные корабли должны быть размещены на квадратном поле 10 на 10 клеток, при этом корабли не могут соприкасаться ни углами, ни сторонами. Самое игровое поле нумеруется сверху вниз, а вертикали помечаются русскими буквами от «А» до «К» (при этом буквы «Ё» и «Й» пропускают).
Рядом рисуется вражеское поле аналогичного размера. При удачном выстреле по кораблю противника на соответствующей клетке вражеского поля ставится крестик и производится повторный выстрел, при неудачном выстреле в соответствующей клетке ставится точка, и ход переходит к противнику. Оптимальная стратегия
Как выиграть в игре Морской Бой
В игре морской бой всегда есть элемент случайности, но его можно свести к минимуму. Прежде чем переходить непосредственно к поиску оптимальной стратегии, необходимо озвучить одну очевидную вещь: вероятность попасть по кораблю противника тем выше, чем меньше непроверенных клеток осталось на его поле, аналогично вероятность попадания по вашим кораблям тем ниже, чем больше непроверенных клеток осталось на вашем поле. Таким образом, для эффективной игры нужно научиться сразу двум вещам: оптимальной стрельбе по противнику и оптимальному своих размещению кораблей.
В дальнейшем объяснении будут использоваться следующие обозначения:
Как стрелять по кораблям противника
Первым и самым очевидным правилом оптимальной стрельбы является следующее правило: не стрелять по клеткам непосредственно окружающим уничтоженный корабль противника.
В соответствии с принятыми выше обозначениями, на рисунке жёлтым отмечены те клетки, по которым уже были произведены безуспешные выстрелы, красным отмечены клетки, выстрелы по которым закончились попаданием, а зелёным отмечены клетки, стрельба по которым не производилась, но можно гарантировано утверждать, что кораблей в них нет (кораблей там быть не может, т. к. по правилам игры корабли не могут соприкасаться).
Из первого правила сразу вытекает второе: если вам удалось подбить вражеский корабль, необходимо сразу же его добить, чтобы как можно раньше получить список гарантировано свободных клеток.
Третье правило вытекает из первых двух: необходимо в первую очередь пытаться подбить самые крупные корабли противника. Возможно, для вас это правило не очевидно, но если немного подумать, то можно легко заметить, что уничтожив вражеский линкор, мы в лучшем случае получим информацию сразу о 14 гарантировано свободных клетках, а уничтожив крейсер, всего о 12.
Оптимальная стратегия стрельбы
Т.о. оптимальную стратегию стрельбы можно свести к целенаправленному поиску и уничтожению самых крупных кораблей противника. К сожалению, сформулировать стратегию мало, необходимо предложить способ её реализации.
Для начала давайте рассмотрим участок игрового поля размером 4 на 4 клетки. Если в рассматриваемом участке есть вражеский линкор, то его гарантировано можно подбить не более чем за 4 выстрела. Для этого надо стрелять так, чтобы на каждой горизонтали и вертикали было ровно по одной проверенной клетке. ниже представлены все варианты такой стрельбы (без учёта отражений и поворотов).
Среди всех этих вариантов, оптимальными на поле 10 на 10 клеток являются только первые два варианта, гарантирующие попадание в линкор максимум за 24 выстрела.
После того, как уничтожен вражеский линкор, необходимо начинать поиск крейсеров, а затем и эсминцев. При этом, как вы уже догадались, можно воспользоваться аналогичной методикой. Только теперь необходимо разбивать поле на квадраты со стороной в 3 и 2 клетки соответственно.
Python. Напишем морской бой с достойным соперником-ИИ — Офтоп на DTF
Всем привет! В предыдущей статье мы написали игру в спички с ИИ. Как оказалось некоторые из вас даже открывали эту сатью, а некоторые из тех кто открывал даже поставили лайк. Спасибо! Сегодня будем писать морской бой в таком же «терминальном» стиле. На этот раз игра будет больше, а алгоритм стоящий за ходом противника — сложнее.
23 183 просмотров
Ознакомиться с полным кодом приложения и запустить прямо в браузере можно как всегда в конце статьи по ссылке.
Вот предыдущая статья про спички если кому-то интересно:
Прошлое приложение заняло 130 строк кода и я таки умудрился расписать его целиком в рамках поста, а вот морской бой уже получился на все 470+ строк. Всё расписать не получится. Будут расширеные комментарии внутри самого кода по ссылке. Как всегда начнём с самого морского боя, а ИИ (я буду называть это ИИ) оставим на вторую половину.
Морской бой
Сама игра не такая уж и сложная, но в ней хватает нюансов и если писать всё более-менее аккуратно, то получается много кода. В основном это связано с различными проверками при расстановке кораблей, доступности хода, проверками целости кораблей и прочее.
Начнём пожалуй с описания основных классов, которые нам понадобятся для реализации:
Game — сама игра. Этот класс будет группировать и манипулировать остальными классами.
Player — игрок. Будет иметь своё поле, будет совершать ходы.
Field — поле. Будет состоять из двух частей: основная карта и радар. Поле будет проверять возможность расположения кораблей, расставлять корабли, уничтожать их.
Ship — корабль. Можно было обойтись без него на самом деле, но с ним проще. В основном корабль будет хранить координаты и свои HP.
Кроме основных классов так же были написаны вспомогательные FieldPart — чтобы было проще обращаться к конкретной части поля (карта/радар). Color — чтобы было проще и нагляднее задавать цвет элементам. Cell — чтобы описать все возможные состояния клетки поля в одном месте (пустая, сыграная, корабль, уничтоженый корабль, поврежденный корабль).
Class Game(object)
class Game(object): letters = («A», «B», «C», «D», «E», «F», «G», «H», «I», «J») ships_rules = [1, 1, 1, 1, 2, 2, 2, 3, 3, 4] field_size = len(letters) def __init__(self): self. players = [] self.current_player = None self.next_player = None self.status = ‘prepare’ # просто названия функций входящих в Game # сами функции с детальным описанием можно найти в полном коде def start_game(self) def status_check(self) def add_player(self, player) def ships_setup(self, player) def draw(self) def switch_players(self) def clear_screen()
В классе Game мы опишем буквы используемые для отображения координат. Понятное дело внутри самой игры всё задаётся исключительно цифровыми координатами [0][4], [5][1] … но игрок должен во-первых видеть буквы на поле, а во-вторых делать свои ходы используя буквенные обозначения. Поэтому без букв никак. ships_rules — в эту переменную поместим «правила» по кораблям, какие корабли игрок должен выставить до начала боя (здесь можно немного поэкспериментировать при желании: ). field_size — величина поля. Сделаем зависимость от величины списка letters. Поле ведь квадратное, а значит сколько букв — такие и габариты.
Игра будет хранить игроков в cписке players. Но зачем мучиться с коэффициентами при обращении к игрокам, если можно завести две переменные current_player и next_player,которые ссылаются на элементы списка players. Так мы всегда понимает как обратиться к текущему и следующему игроку. А в конце хода мы просто меняем значения этих переменных местами. Ну и я решил добавить такое понятие как status. У игры не то чтобы много статусов, но таким образом можно организовать более наглядный переход из одного состояния в другое в самом игровом цикле. Статусы будут примерно такие: prepare, in_game, game_over.
Функции у игры следующие:
start_game — просто объявляем текущего игрока и следующего.
status_check — игра каждый ход проверяет статусы и меняет их при достижении условий.
add_player — функция используется когда у игры статус prepare для добавления игроков и назначени им полей.
ship_setup — так же используется на старте игры. Передаём в функцию ссылку на игрока и игра просит его расставить корабли или расставляет автоматически. draw — рисует каждый ход поле и доп.инфу. switch_players — просто переключает текущего игрока и следующего, юзается в конце хода. clear_screen — чистит экран.
Class Player(object)
class Player(object): def __init__(self, name, is_ai, skill): self.name = name self.is_ai = is_ai self.auto_ship_setup = True self.skill = skill self.message = [] self.ships = [] self.enemy_ships = [] self.field = None # просто названия функций входящих в Player # сами функции с детальным описанием можно найти в полном коде def get_input(self, input_type) def make_shot(self, target_player) def receive_shot(self, shot)
Кратенько по игроку. name — просто имя. is_ai — является игрок ИИ или нет, в зависимости от этого меняет некоторая логика хода. auto_ship_setup — автоматически расставлять корабли для игрока или вручную. Опция для нетерпеливых. skill — относится к ИИ пока пропустим описание. ships наполняется имеющимися у игрока кораблями. enemy_ships — здесь будем считать какие корабли остались у противника — человек конечно и сам может посчитать, но для ИИ очень полезно. field — поле игрока (поле будет описано ниже)
Функции у игрока: get_input — запросить ввод. здесь мы передаем тип инпута либо ‘ship_setup’ либо ‘shot’. Всё зависит от статуса игры. Много логики внутри, тут лучше почитать код с комментами. make_shot — делаем выстрел по указанному игроку. В этой функции как раз и вызывается get_input с параметром ‘shot’. receive_shot — соответственно игрок принимает выстрел по координатам. На самом деле если чётко расписать действия игроков на бумаге и чем они оперируют в ходе игры всё становится гораздо очевиднее. receive_shot возвращает на выходе либо ‘miss’ (прмах) либо ‘get’ (ранил) либо ссылку на объект Ship (убил). Если убил логично вернуть весь корабль т. к. тогда проще закрасить на радаре клетки вокруг. Да, это конечно дерзко возвращать данные разных типов, но что поделать.
Class Field(object)
class Field(object): def __init__(self, size): self.size = size self.map = [[Cell.empty_cell for _ in range(size)] for _ in range(size)] self.radar = [[Cell.empty_cell for _ in range(size)] for _ in range(size)] self.weight = [[1 for _ in range(size)] for _ in range(size)] # просто названия функций входящих в Field # сами функции с детальным описанием можно найти в полном коде def draw_field(self, element) def check_ship_fits(self, ship, element) def mark_destroyed_ship(self, ship, element) def add_ship_to_field(self, ship, element) def get_max_weight_cells(self) def recalculate_weight_map(self, available_ships)
С полем всё просто: size — размер поля. map — основная карта поля по факту просто список списков изначально заполняемый пустыми клетками (Cell.empty_cell). radar — так же. weight уже по интереснее. Это относится к ИИ, поэтому обсудим чуть ниже.
Функции. draw_field — отрисовка поля. Здесь и далее параемтр element это часть поля с которой необходимо работать. либо Map либо Radar либо Weight. Check_ship_fits — прверяем что корабль помещается на ту или иную позицию. Используется при расстановке кораблей а так же для некоторых манипуляций с ИИ. mark_destroyed_ship — помечаем что корабль уничтожен. Ставим на нем кресты, вокруг — точки. add_ship_to_field — добавление корабля. тут все понятно. get_max_weight_cells и recalculate_weight_map относится к ИИ, это рассмотрим чуть ниже.
Class Ship(object)
class Ship: def __init__(self, size, x, y, rotation): self.size = size self.hp = size self.x = x self.y = y self.rotation = rotation
Тут вообще всё до безобразия просто: x, y — координаты начала корабля. size — размер. rotation — в какую сторону повёрнут (от 0 до 4). hp — текущее хп корабля. Конкретные поврежденные клетки не отслеживаются т.к. по факту за контроль отрисовки поля отвечает класс Field.
Последнее что мы рассмотрим перед написанием ИИ это основной цикл игры:
if __name__ == ‘__main__’: players = [] players.append(Player(name=’Username’, is_ai=False, auto_ship=True, skill=1)) players.append(Player(name=’IQ180′, is_ai=True, auto_ship=True, skill=1)) game = Game() while True: game.status_check() if game.status == ‘prepare’: game.add_player(players.pop(0)) if game.status == ‘in game’: Game.clear_screen() game.current_player.message.append(«Ждём приказа: «) game.draw() game.current_player.message.clear() shot_result = game.current_player.make_shot(game.next_player) if shot_result == ‘miss’: game.next_player.message. append(‘На этот раз {}, промахнулся! ‘.format(game.current_player.name)) game.next_player.message.append(‘Ваш ход {}!’.format(game.next_player.name)) game.switch_players() continue elif shot_result == ‘retry’: game.current_player.message.append(‘Попробуйте еще раз!’) continue elif shot_result == ‘get’: game.current_player.message.append(‘Отличный выстрел, продолжайте!’) game.next_player.message.append(‘Наш корабль попал под обстрел!’) continue elif shot_result == ‘kill’: game.current_player.message.append(‘Корабль противника уничтожен!’) game.next_player.message.append(‘Плохие новости, наш корабль был уничтожен :(‘) continue if game.status == ‘game over’: Game.clear_screen() game.next_player.field.draw_field(FieldPart.main) game.current_player. field.draw_field(FieldPart.main) print(‘It was the last ship of {}’.format(game.next_player.name)) print(‘{} win the match! Congrats!’.format(game.current_player.name)) break print(‘Thanks for playing!’) input(»)
Все достаточно просто. В цикле бесконечно проверяется статус игры и в зависимости от этого выполняются те либо иные действия. В статусе ‘in game’ происходят основные события игры. Получение данных о выстреле игрока, добавление подходящего сообщения для обоих игроков, передача хода другому игроку при промахе и прочее.
Если наступает статус ‘game over’ — выводим основные поля обоих игроков. Пишем кто выиграл, кто проиграл.
Алгоритм поведения ИИ
Как всегда я сел и стал прикидывать какой логикой оперирует человек при игре в морской бой.
- Первый ход случайный.
- Если попал и убил — обрисовал точками вокруг
- Если попал и не убил — стреляем в клетки сверху/снизу/слева/справа
- По диагоналям от клетки «попал» не может быть кораблей
- Прикидываем если остались только большие корабли — затираем мелкие скопления пустых клеток
Более глубокой логики поведения человека я придумать не смог. Дальше начал думать как перенести всё это на какие-то условия. Надо бы держать в уме предыдущий ход, а еще лучше предыдущий удачный ход. И если ты «попал», то следующий выстрел по сторонам. Если второй выстрел не попал, то вернуться к предыдущему ходу и выстрел в другую сторону рядом. Но дальше начинаютя сложности. Так как нужно понимать, что корабль прямой. Значит надо, чтобы ИИ понимал направление корабля и ходил после повторного попадания уже не по четырём направлениям, а в общем-то по одному. И опять-таки приходим к тому, что нужно помнить откуда начался этот корабль. Но это всё просто по сравнению с последним пунктом. Дойдя до него я понял: прежде чем стрелять по клетке — проверь, а помещается ли какой-нибудь корабль хоть как-то в нее.
И тут рассуждения увели меня чуть в сторону и стала вырисовываться идея коэффициентов: назначаем клеткам коэффициенты и стреляем по наиболее весомой. Если корабль помещается в какие-то клетки — прибавляем им коэффициенты. Если нет — коэффициент останется нулевым. Функция check_ship_fits уже была готова т.к. использовалась для расстановки кораблей до начала игры. Отлично.
Я начал развивать идею с коэффициентами. Решил так: изначально каждую клетку поля проверяем на возможность начала с нее корабля. Причем в любую из четырёх сторон. Итого клетка за каждый корабль может получить 4 балла. Естественно речь про поле-радар, единственно доступная информация о кораблях противника расположена на нем. Со временем поле будет заполнятья убитыми кораблями и промахами а коэффициенты этих клеток будут автоматически иметь 0.
Далее в систему коэффициентов нужно как-то вписать все пункты алгоритма:
«Первый ход случайный» — с введением коэффициентов это понятие немного изменится. Теперь каждый ход будет набираться список клеток с самым высоким коэффицентом, а уже из него будет случайным образом выбираться точка обстрела. Зачастую будет получатья так, что список будет состоять из одной единственной клетки которая методом подсчета получила максимальный коэффициент. Так что в целом становитя не важно первый это ход или нет.
«Если попал и убил» — тоже просто. В таких случаях клетке сразу ставится коэффициент 0 как и всем клеткам вокруг нее.
здесь и далее приведен небольшой кусочек поля
«Если попал и не убил» — мы усиливаем вес клеток по всем четырём направлениям т.к. корабль может иметь продолжение только в 4 стороны. По диагоналям от попадения — нули. Тут есть хитрость. Мы не просто выставляем коэффицинет всем вокруг мы умножаем имеющийся, а значит защищаем себя от возможности случайно увеличить нулевой кэффициент
первое попадание. увеличиваем коэффициенты
второе попадание
Ну и последний пункт — если остались только большие корабли — затираем мелкие скопления пустых клеток. Это будет выполняться на основе начального вычисления коэффициентов. Для каждой клетки будут браться оставшиеся корабли и будет совершаться попытка их вписать. Пример:
остался только трехпалубный корабль и как бы мы ни старались он не может проходить через клетку с «?» значит эта клетка не получит увеличения коэффицинета. И как результат коэффициент там будет 0. То же справедливо и для двух незанятых клеток чуть ниже.
Теперь осталось всего лишь написать это:
# пересчет веса клеток def recalculate_weight_map(self, available_ships): # Для начала мы выставляем всем клеткам 1. # нам не обязательно знать какой вес был у клетки в предыдущий раз: # эффект веса не накапливается от хода к ходу. self.weight = [[1 for _ in range(self.size)] for _ in range(self.size)] # Пробегаем по всем полю. # Если находим раненый корабль — ставим клеткам выше ниже и по бокам # коэффициенты умноженые на 50 т.к. логично что корабль имеет продолжение в одну из сторон. # По диагоналям от раненой клетки ничего не может быть — туда вписываем нули for x in range(self.size): for y in range(self.size): if self. radar[x][y] == Cell.damaged_ship: self.weight[x][y] = 0 if x — 1 >= 0: if y — 1 >= 0: self.weight[x — 1][y — 1] = 0 self.weight[x — 1][y] *= 50 if y + 1 < self.size: self.weight[x — 1][y + 1] = 0 if y — 1 >= 0: self.weight[x][y — 1] *= 50 if y + 1 < self.size: self.weight[x][y + 1] *= 50 if x + 1 < self.size: if y — 1 >= 0: self.weight[x + 1][y — 1] = 0 self.weight[x + 1][y] *= 50 if y + 1 < self.size: self.weight[x + 1][y + 1] = 0 # Перебираем все корабли оставшиеся у противника. # Это открытая инафа исходя из правил игры. Проходим по каждой клетке поля. # Если там уничтоженый корабль, задамаженый или клетка с промахом — # ставим туда коэффициент 0. Больше делать нечего — переходим следующей клетке. # Иначе прикидываем может ли этот корабль с этой клетки начинаться в какую-либо сторону # и если он помещается прбавляем клетке коэф 1. for ship_size in available_ships: ship = Ship(ship_size, 1, 1, 0) # вот тут бегаем по всем клеткам поля for x in range(self.size): for y in range(self.size): if self.radar[x][y] in (Cell.destroyed_ship, Cell.damaged_ship, Cell.miss_cell) \ or self.weight[x][y] == 0: self.weight[x][y] = 0 continue # вот здесь ворочаем корабль и проверяем помещается ли он for rotation in range(0, 4): ship.set_position(x, y, rotation) if self.check_ship_fits(ship, FieldPart.radar): self.weight[x][y] += 1
У нас есть поле с выставленными коэффициентами. Надо бы дописать функцию get_max_weight_cells которая будет возвращать список координат с максимальным коэффициентом.
def get_max_weight_cells(self): weights = {} max_weight = 0 for x in range(self.size): for y in range(self.size): if self.weight[x][y] > max_weight: max_weight = self.weight[x][y] weights.setdefault(self.weight[x][y], []).append((x, y)) return weights[max_weight]
Занесем координаты всех клеток в словарь weights. Ключом будет вес клеток. Значением — список содержащий пары координат.
Пробегаем по всем клеткам и заносим их в словарь. Заодно запоминаем максимальное значение веса. Далее просто берём из словаря список координат с ключом максимальным заначением веса: weights[max_weight]
Всё что осталось сделать ИИ, для совершения адекватного хода, это из полученного списка координат выбрать случайную:
x, y = choice(self.field.get_max_weight_cells())
Вот вроде бы и всё. Здесь не описал многие детали реализации, но, как я писал выше, комментарии есть еще в коде.
Строку 335 можно раскомментировать, чтобы получить доступ к отладочному полю с коэффициентами и видеть их распределение.
Вы можете опробовать морской бой прямо здесь, а так же прочитать дополнительные комментарии
Если хотите еще статью похожей тематики — ставьте лайк и предлагайте идеи.
В следующих раз можем попробовать написать например телеграмм-бот тамагочи: )
Sea Battle Game — Etsy Australia
Etsy больше не поддерживает старые версии вашего веб-браузера, чтобы обеспечить безопасность пользовательских данных. Пожалуйста, обновите до последней версии.
Воспользуйтесь всеми преимуществами нашего сайта, включив JavaScript.
Найдите что-нибудь памятное, присоединяйтесь к сообществу, делающему добро.
( 160 релевантных результатов, с рекламой Продавцы, желающие расширить свой бизнес и привлечь больше заинтересованных покупателей, могут использовать рекламную платформу Etsy для продвижения своих товаров. Вы увидите результаты объявлений, основанные на таких факторах, как релевантность и сумма, которую продавцы платят за клик. Узнать больше. )
Морской бой 2 в App Store
Описание
«Морской бой 2» — любимая всеми с детства настольная игра с новыми способностями и расширенным арсеналом! В эту игру играют миллионы людей по всему миру. В вашем распоряжении будут линкоры, самолеты, подводные лодки, мины и радары — и это еще не все. Размещайте свои линкоры на поле боя и атакуйте поле противника. Используйте различные виды оружия, чтобы потопить военно-морской флот противника и выиграть битву.
Сражайтесь с игроками со всего мира онлайн в режиме реального времени! Выстраивайте свою стратегию игры, улучшайте тактику и не дайте соперникам ни единого шанса! Повысь свой ранг и стань адмиралом своего флота!
Построй свой портовый город и получай награды! Побеждайте на эпических аренах и открывайте новые здания. Стройте военные базы, верфи, фабрики, небоскребы, достопримечательности и многое другое!
Особенности игры:
• ОНЛАЙН-БОИ
Сражайтесь с игроками со всего мира через Интернет!
• ИГРА С ДРУЗЬЯМИ ПО ИНТЕРНЕТУ
Отправляй приглашения и играй по сети с друзьями
• ЗВАНИЯ
Побеждай в битвах, чтобы повысить свой ранг и звание от моряка до адмирала!
• АРЕНЫ
Участвуйте в боях на эпических аренах, открывайте новые и получайте награды!
• ПОРТОВЫЙ ГОРОД
Станьте героем в собственном городе, который вы проектируете и строите!
• ИГРАТЬ ПО BLUETOOTH
Устраивайте сражения с друзьями, коллегами или просто знакомыми по Bluetooth.
• ИГРАТЬ С ДРУГОМ
Играйте с друзьями на одном телефоне (планшете), по очереди расставляйте корабли, выбирайте арсенал и сражайтесь!
• ПОЕЗД С БОТОМ
Выберите подходящий уровень сложности и попытайтесь победить ИИ (искусственный интеллект).
• ПЕРСОНАЛИЗАЦИЯ
Настройте свой военный флот и арсенал и разблокируйте различные скины от эпохи Первой мировой войны до наших дней. Выберите себе грозное имя, крутую аватарку и флаг своего флота.
• ЧАТ
Общайтесь с игроками во время боя с помощью чата и эмодзи.
• НЕСКОЛЬКО РЕЖИМОВ ИГРЫ
Выберите расширенный или классический режим без дополнительного оружия.
• ТУРНИРЫ И ТРОФЕИ
Участвуйте в турнирах и выигрывайте трофеи. Заполните свою комнату трофеев!
• ГЛОБАЛЬНЫЕ ТАБЛИЦЫ ЛИДЕРОВ
Повысь свой рейтинг и стань лучшим игроком в глобальных таблицах лидеров по количеству побед!
Морской бой 2 — игра с красивой графикой в стиле тетради и эффектами, придающими игре оригинальность и незабываемую атмосферу.
Морской бой 2 — бесплатная игра, но некоторые игровые элементы можно приобрести за реальные деньги.
*****
Пришло время узнать, кто сильнейший в морском бою!
Нравится Морской бой 2? Узнать больше!
Инстаграм: https://www.instagram.com/byril_games/
Версия 2.9.1
• Исправлены ошибки
Рейтинги и обзоры
3,8 тыс. оценок
Лучшая игра, в которую я когда-либо играл с папой и друзьями
Да, это, безусловно, лучшая игра, в которую я когда-либо играл со своей семьей и друзьями. Я выигрывал буквально каждый раз, когда играл в нее, и я получил эту игру вчера, и я играл в нее около 30 раз, я хочу каждый раз, так что да, я буду если вам не нравится убивать лодки или вы находитесь на лодке, то я рекомендую эту игру для вас и ваших друзей и семьи, скажите всем, что это самая лучшая игра на свете, и если вам она не нравится, вы многое упускаете. так много всего, и это все для меня пока
Отличная игра, дерьмовый ИИ
Не поймите меня неправильно, мне нравится эта игра. Проблема в том, что прогресс занимает так много времени из-за стремления смотреть рекламу денег/нефти. Однако это не было бы проблемой, если бы это была игра, основанная на навыках. К сожалению, это не так. Каждый раз, когда я играю против ИИ, я в конечном итоге уничтожаю все, кроме одного или двух патрульных катеров, в которых требуется более 20 ходов, чтобы найти и выследить их. Это не было бы такой проблемой; У меня часто есть отличная информация о том, где нет вражеских кораблей. Но, к сожалению, плохо сделанный ИИ гарантирует попадание после каждых двух ходов, что делает почти невозможным выиграть против него какие-либо длительные игры. Я буду иметь более половины своих пространств неоткрытыми с огромными патчами, и ИИ всегда проверяет точный угол или край или где бы ни находился мой корабль, из-за чего я теряю как нефть, так и монеты и замедляю свой прогресс (который я могу частично восстановить после просмотра куча рекламы). Очень грустно, так как я ценю стиль игры, а в остальном играть весело.
Вниманию разработчиков!!!q!
Я переустановил игру и потерял прогресс. «Ледяной океан» (второй уровень карты) заблокирован и показывает, что мне нужно построить «-4» здания, чтобы открыть его. У меня 6 уже построено. Игра застревает на первом уровне и не продвигается вперед. Я зарабатываю золото за бои, но не могу ничего ни построить, ни улучшить. Пожалуйста, исправьте эту ошибку. Спасибо
Разработчик, ООО «БИРИЛ», указал, что политика конфиденциальности приложения может включать обработку данных, как описано ниже. Для получения дополнительной информации см. политику конфиденциальности разработчика.
Данные, используемые для отслеживания вас
Следующие данные могут использоваться для отслеживания вас в приложениях и на веб-сайтах, принадлежащих другим компаниям:
- Расположение
- Идентификаторы
- Данные об использовании
Данные, связанные с вами
Следующие данные могут быть собраны и связаны с вашей личностью:
- Расположение
- Идентификаторы
- Данные об использовании
Данные, не связанные с вами
Могут быть собраны следующие данные, но они не связаны с вашей личностью:
- Покупки
- Данные об использовании
- Диагностика
Методы обеспечения конфиденциальности могут различаться, например, в зависимости от используемых вами функций или вашего возраста.