Морской бой / Настольная игра
Количество игроков: двое
Дополнительно: бумага, ручки
Игроки по очереди называют координаты на неизвестной им карте соперника. Если у соперника по этим координатам имеется корабль (координаты заняты), то корабль или его часть «топится», а попавший получает право сделать ещё один ход. Цель игрока — первым поразить все корабли противника.
Игровое поле — квадрат 10х10 у каждого игрока, на котором размещается флот кораблей.
Вертикали нумеруются сверху вниз (цифры пишутся просто сбоку от квадрата — не надо чертить отдельную колонку!), а горизонтали помечаются буквами а, б, в, г, д, е, ё, ж, з, и или р, е, с, п, у, б, л, и, к, а (буквы пишутся просто над верхней стороной квадрата!).
Размещаются:
* 1 корабль — ряд из 5 клеток (авианосец, или «пятипалубный»)
* 2 корабля — ряд из 4 клеток (линкоры, или «четырёхпалубные»)
* 3 корабля — ряд из 3 клеток (крейсеры, или «трёхпалубные»)
* 4 корабля — ряд из 2 клетки (эсминцы, или «двухпалубные»)
Другой вариант названия: -трубные (напр.
![](http://xn--7-dtbea5camjj.xn--p1ai/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif)
При размещении корабли могут касаться друг друга углами (встречаются однако варианты, когда это запрещается).
Палубы кораблей можно строить «в линейку», а можно — изгибами. Главное: нельзя строить палубы одного корабля по диагонали!
Рядом со «своим» квадратом чертится «чужой» такого же размера, только пустой. Это участок моря, где плавают чужие корабли противника. При попадании в корабль противника — на чужом поле ставится крестик. Попавший стреляет ещё раз.
Перед началом боевых действий игроки бросают жребий или договариваются, кто будет ходить первым.
Игрок, выполняющий ход, совершает выстрел — называет вслух координаты клетки, в которой, по его мнению, находится корабль противника, например, «К1!» (нижняя левая клетка).
1. Если выстрел пришёлся в клетку, не занятую ни одним кораблём противника, то следует ответ «Мимо!» и стрелявший игрок ставит на чужом квадрате в этом месте точку. Право хода переходит к сопернику.
2. Если выстрел пришёлся в клетку, где находится многотрубный корабль (размером больше чем 1 клетка), то следует ответ «Ранил!» или «Попал!», кроме одного случая (см.
![](/800/600/https/konspekta.net/infopediasu/baza2/1767955512939.files/image035.png)
3. Если выстрел пришёлся в клетку, где находится однотрубный корабль или последнюю непоражённую клетку многотрубного корабля, то следует ответ «Потоплен!» или «Убит!». Оба игрока отмечают потопленный корабль на листе. Стрелявший игрок получает право на ещё один выстрел.
Победителем считается тот, кто первым потопит все 10 кораблей противника. Проигравший имеет право попросить изучить после окончания игры у соперника игровое поле.
Катерина
предыдущая | «Морской бой» | следующая
Python. Напишем морской бой с достойным соперником-ИИ — Офтоп на DTF
Всем привет! В предыдущей статье мы написали игру в спички с ИИ. Как оказалось некоторые из вас даже открывали эту сатью, а некоторые из тех кто открывал даже поставили лайк. Спасибо! Сегодня будем писать морской бой в таком же «терминальном» стиле. На этот раз игра будет больше, а алгоритм стоящий за ходом противника — сложнее.
27 774 просмотров
Ознакомиться с полным кодом приложения и запустить прямо в браузере можно как всегда в конце статьи по ссылке.
Вот предыдущая статья про спички если кому-то интересно:
Прошлое приложение заняло 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.
В классе 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 можно раскомментировать, чтобы получить доступ к отладочному полю с коэффициентами и видеть их распределение.
Вы можете опробовать морской бой прямо здесь, а так же прочитать дополнительные комментарии
Если хотите еще статью похожей тематики — ставьте лайк и предлагайте идеи.
В следующих раз можем попробовать написать например телеграмм-бот тамагочи: )
Морское сражение — YPPedia
Морское сражение (также известное как Battle Navigation или в просторечии Bnav ) происходит, когда один корабль атакует другой во время мародерства. Когда один корабль, управляемый игроком, атакует другой корабль, управляемый игроком, это называется PvP. Независимо от задействованных кораблей, морской бой разыгрывается одинаково.
Основная цель морского боя — как можно больше обстрелять другой корабль, а затем схватить его. Однако при потоплении PvP цель может заключаться в том, чтобы потопить другой корабль, а не схватиться. Кроме того, торговцы могут захотеть бежать, а не сражаться.
Морской бой состоит из трех этапов: преследование, навигация и абордаж.
Содержимое
- 1 Погоня
- 2 Навигационная ступень
- 2.1 Жетоны
- 2.1.1 Жетоны движения
- 2.1.2 Жетоны оружия
- 2.1.3 Жетоны захвата
- 2,2 витка
- 2.3 Урон
- 2.4 Конец этапа навигации
- 2.4.1 Отключение
- 2.4.2 Погружение
- 2.4.3 Посадка
- 2.1 Жетоны
- 3 Посадочный столик
- 4 Выигрыш и проигрыш
- 5 Таблица повреждений
- 6 Практика
- 7 Известные ошибки
- 8 Полный список
- 9 трофеев
- 10 Исторические заметки
- 11 Внешние/другие ссылки
Преследование
Чтобы начать морское сражение, один корабль должен преследовать другой. Любой офицер на борту своего корабля может начать преследование. Это делается путем выбора целевого корабля в открытом море и нажатия кнопки «Атака» под панелью «Судно».
На панели корабля также отображается звание экипажа (матросы, имперцы и т.д.) экипажа выбранного корабля. Ранги экипажа игроков увеличиваются за счет побед в PvP.
Одновременно можно преследовать только одно судно. Чтобы перехватить цель, два корабля должны иметь одинаковый приблизительный курс и скорость. Если корабль-цель уходит слишком далеко от атакующего, преследование автоматически прекращается. Суда, остановившиеся в точке лиги, не могут преследовать другие суда, а другие суда не могут начинать преследование против них.
Когда корабль игрока преследуется, пираты на борту этого корабля получают предупреждение вида «Вас преследует ‘<корабль>‘». Когда происходит перехват, пираты получают сообщение: «Вас перехватил <корабль>!» Подобные сообщения появляются на борту корабля игрока, преследующего цель.
После перехвата начинается этап навигации.
Навигационная платформа
Типичная боевая навигационная доска. Подсказка, показывающая время жизни жетонов движения.![](/800/600/https/slotobzor.com/wp-content/uploads/2017/05/Morskoj-boj-onlajn-4.png)
Во время навигации командир каждого корабля ведет свой корабль по доске морского боя, которая имеет 24 клетки в ширину в обоих направлениях. Навигатор планирует действия, которые должны быть выполнены на следующий ход, перетаскивая ряд жетонов на интерфейсе боевой навигации. Следующий ход разделен на четыре «фазы»: на каждой из этих фаз навигатор может запланировать жетон движения или маневра, а также один или несколько жетонов оружия или один жетон захвата. У них есть тридцать пять секунд, чтобы спланировать каждый ход. Как только таймер заканчивается, их ходы выполняются, и начинается планирование следующего хода. Во время планирования другие пираты на борту корабля работают над тем, чтобы предоставить своему командиру жетоны плавания и стрельбы. Эти жетоны используются командиром для перемещения корабля и стрельбы из орудий.
Жетоны
Все действия, которые может предпринять корабль — движение, стрельба из пушки, бросок захвата и выполнение маневра — представлены жетонами .
В неформальном использовании «жетон» часто используется для обозначения жетона маневра (и, если используется как глагол, он также может относиться к действию получения таких жетонов), тогда как «жетон движения» или просто «перемещение» относится к жетону движения. Жетон пистолета или жетон захвата часто называют «пистолетом» или «захватом» соответственно.
Жетоны движения
Моряки и такелажники производят жетона движения , которые позволяют кораблю двигаться вперед, поворачивать налево или направо. Чем выше счетчик трюма корабля, тем медленнее генерируются жетоны движения. Хотя командир может сохранять жетоны движения от хода к ходу, они в конечном итоге исчезнут, если их не использовать в течение пяти ходов. Подсказка отображается при наведении курсора мыши на каждый тип жетона в окне навигации боя. Этот совет указывает, сколько жетонов этого типа будет сброшено, если они не будут использованы за каждый ход.
Существует особый тип жетона движения, известный как маневр, доступный только для кораблей в среде с несколькими кораблями, например, в блокаде, флотилии или на поле Охоты на морских монстров. Эти жетоны требуют усилий во всех трех областях головоломки; треть этих усилий приходится на матросов и такелажников, а также на плотников и латачников и, наконец, на билджеров. Заработанные жетоны маневров позволяют кораблю совершать невероятные подвиги.
Жетоны оружия
Жетоны оружия производятся каждый раз, когда стрелок заряжает пушку. Каждый жетон оружия позволяет командиру выстрелить одним пушечным ядром во врага. Пушки можно заряжать вне боя. За каждое заряженное орудие командир получает один жетон орудия; из него можно стрелять слева или справа от корабля. В отличие от жетонов движения, срок действия этих жетонов не истекает со временем. Стрельба из пушки уменьшает количество доступных жетонов оружия на один. Все пушки имеют дальность стрельбы в три клетки.
Обратите внимание, что размещение артиллерийских станций на борту корабля не влияет на количество пушек, которые могут стрелять с каждой стороны. Например, шлюп имеет по два орудия с каждого борта (всего четыре), но может сделать четыре выстрела с правого борта за один ход.
Жетоны захвата
Существует также третий тип жетонов: жетон захвата . Он похож на жетон пистолета, который используется для стрельбы из заряженной пушки, в том смысле, что захват может быть сброшен либо с левой, либо с правой стороны корабля. Однако, в отличие от жетона оружия, крюк можно использовать только с одной стороны для каждой фазы движения. Более того, если жетон захвата размещается на одну фазу хода, жетоны оружия нельзя размещать ни с одной стороны в течение этой фазы. У навигатора неограниченный запас жетонов захвата, и их бросок не расходует ресурсы корабля.
Дальность захвата составляет одну клетку. Если он попадает во вражеский корабль, он считается «схваченным». Когда это происходит, морской бой переходит в фазу абордажа.
Размещение захвата не влияет на строку состояния над кораблем во время морского сражения, в отличие от жетонов движения и жетонов оружия. Таким образом, на корабле может быть размещено четыре захвата, и пока он не движется и не стреляет в течение этого хода, создается впечатление, что он не предпринимает никаких действий в этот ход. Например, даже если кажется, что у разбойника закончились ходы, он все еще может разместить до четырех жетонов захвата.
Обратите внимание, что жетоны захвата недоступны штурманам во время блокад, флотилий и охоты на морских монстров, поскольку игрокам не разрешается садиться на другие корабли в этих местах.
Ходы
Ход состоит из четырех фаз. На каждой фазе командир может разыграть жетон движения, выстрелить из пушек (в зависимости от размера корабля) с любой стороны корабля или попытаться схватить другой корабль. Однако от командира не требуется никаких действий. В любой данной фазе он или она может двигаться, стрелять из пушек или захватывать другой корабль, или и то, и другое, или ни то, ни другое. Жетоны стрельбы и захвата нельзя разыгрывать в одну и ту же фазу. По мере того, как командир планирует действия, полоса активности над кораблем, видимая для другого корабля, заполняется. Хороший командир разумно использует доступные ему или ей жетоны, чтобы извлечь выгоду из сложившейся ситуации, сохраняя достаточное количество в резерве для последующих ходов. Каждая фаза разыгрывается следующим образом: сначала разыгрываются все жетоны движения, запланированные на этот ход. Далее, если лодка стоит на специальном тайле моря, таком как ветер или водоворот, корабль перемещается один раз по правилам этого тайла. Если это движение помещает корабль в другую специальную клетку, оно не действует в этой фазе, но будет действовать в следующей фазе, если корабль останется там. Наконец, все пушки или захваты, которые должны были выстрелить в этом раунде, отстреливаются. Важно отметить, что некоторые корабли могут разыгрывать жетоны движения только на трех из четырех фаз любого данного хода, хотя командир лодки может выбрать, на какой фазе корабль отдыхает. Это делается путем перетаскивания восьмиугольного значка на фазу, в которой он хочет, чтобы корабль отдыхал.
Повреждения
Корабли могут получить повреждения во время морского боя четырьмя способами:
- Они могут быть поражены пушечным огнем,
- они могут попытаться переместиться на клетку доски, куда им не разрешено (а именно, на те, которые заняты камнями или за краями доски),
- они могут быть протаранены другим судном, и
- в результате регулярного износа.
Все повреждения, кроме износа, приведут к тому, что в нижней части головоломки боя на мечах экипажей во время абордажа появятся небьющиеся черные блоки или, если они сражаются с варварами, в виде серого блока в верхней части головоломки. В идеале, командир нанесет большой урон вражескому кораблю, защищая свой собственный, ставя других игроков в невыгодное положение во время боя на мечах или грохота.
Конец этапа навигации
Этап навигации может закончиться одним из трех способов: выходом из боя, затоплением или посадкой.
Отключение
Если одно судно не может нанести ущерб другому кораблю в течение некоторого периода времени, неповрежденное судно может выбрать отсоединение , вернув оба судна в плавание. Счетчик отключения начинается с десяти оборотов каждого сосуда. За каждое пушечное ядро, попавшее в корабль, к счетчику выхода из боя этого корабля добавляется два хода. Когда счетчик достигает нуля, этот корабль может выбрать выход из боя. Если счетчик на нуле, а корабль был поражен в этот ход, счетчик увеличивается, и корабль снова должен ждать, чтобы выйти из боя.
Затопление
- Основная статья: Затопление
В сражениях PvP, когда между флагами обоих кораблей существует состояние войны, или в условиях тонущей блокады, флотилии или Охоты на морских чудовищ, навигация в бою может быть прекращена, когда один Корабль получает полный урон и тонет. В этом случае тонущий корабль не просто снимается с навигационного щита, судовое дело превращается в корабль в бутылке. Все товары, восьмерки и карты потеряны вместе с кораблем. Если бутылку не восстановить до того, как она сгниет, вся мебель тоже будет потеряна.
Абордаж
Если же одному кораблю удается схватить другой, все загадки прекращаются и морское сражение переходит к этапу абордажа. Пиратам важно не переходить из одной комнаты в другую на борту корабля в промежутках между этапами, иначе из-за бага они могут не участвовать в ближнем бою.
Абордажная сцена
Во время абордажной фазы члены экипажа каждого корабля участвуют в многопользовательской битве на мечах или драке. Команды получают штрафы за повреждения в зависимости от того, сколько раз их корабль был поврежден во время фазы навигации. Кроме того, если на корабле нет рома, у экипажа будет ромовая болезнь: в бою на мечах крайний левый и крайний правый столбцы головоломки будут недоступны, заполненные кувшинами с ромом, а в грохоте прицеливание перчаток немного изменено. После того, как игрок был нокаутирован, ему или ей нечего делать, кроме как наблюдать за остальной частью схватки и болеть за своих товарищей по команде. Морское сражение заканчивается, как только все члены одной из двух команд будут нокаутированы, и битва проиграна.
Объединение в команду — важная часть боя. Командир может дать конкретные инструкции относительно целей и количества игроков, которые должны объединиться для этой цели.
Победа и поражение
Часть содержимого трюма и добычи проигравшего корабля переносится в сундук с добычей корабля-победителя. Если проигравший корабль был разбойничьим, есть шанс, что новая карта будет помещена в навигационную таблицу победившего корабля. Если оба задействованных корабля были кораблями игроков, то запись делается на странице записи морского боя каждого экипажа. Все пираты на борту обоих кораблей в конце боя получают кредит на дополнительный бой за раздел добычи, который будет представлен в виде значка корабля. Пираты должны оставаться на борту корабля до конца битвы, чтобы получить за него кредит! Разбойники и варвары забирают 10% товаров в трюме и 20% восьмерок в добыче. В сценарии PvP победитель получает 25% трюма и 50% добычи.
Таблица повреждений
Следующая таблица показывает, как нанести максимальный урон кораблю любого класса, используя выстрел определенного размера.
Название корабля | Макс. урон SF/Rumble | Полный урон | ||||
---|---|---|---|---|---|---|
Маленький | Мед | Большой | Маленький | Мед | Большой | |
Шлюп | 6 | 4 | 3 | 10 | 6,667 | 5 |
Резак | 7,5 | 5 | 3,75 | 12 | 8 | 6 |
Доу | 7,5 | 5 | 3,75 | 12 | 8 | 6 |
Фаньчуань | 7,875 | 5,225 | 3,9375 | 13.![]() | 8,75 | 6,5625 |
Драккар | 9 | 6 | 4,5 | 15 | 10 | 7,5 |
Багла | 12 | 8 | 6 | 20 | 13.333 | 10 |
Торговый бриг | 12 | 8 | 6 | 20 | 13.333 | 10 |
Хлам | 15 | 10 | 7,5 | 25 | 16,66 | 12,5 |
Военный бриг | 15 | 10 | 7,5 | 25 | 16.667 | 12,5 |
Торговый галеон | 18 | 12 | 9 | 30 | 20 | 15 |
Шебек | 21 | 14 | 10,5 | 35 | 23.333 | 17,5 |
Военный галеон | 15 | 10 | 7,5 | 25 | 16.![]() | 12,5 |
Боевой фрегат | 30 | 20 | 15 | 50 | 33.333 | 25 |
Большой фрегат | 36 | 24 | 18 | 60 | 40 | 30 |
На следующей диаграмме показано количество повреждений, наносимых кораблем тараном, в эквиваленте пушечного ядра (например, при таране торгового брига наносится такое же количество повреждений, как от одного маленького пушечного ядра). Удар по камню наносит любому кораблю урон ровно в 3 блока SF. Подробную диаграмму повреждений скальных пород см. в разделе Ramming, а подробную информацию о том, как разрешаются столкновения, см. в механике столкновений.
Название корабля | Эквивалентный номер попаданий по размеру выстрела | Размерный класс | ||
---|---|---|---|---|
Маленький | Средний | Большой | ||
Шлюп | 0,5 | 0,333 | 0,25 | Маленький |
Резак | 0,5 | 0,333 | 0,25 | Маленький |
Доу | 0,5 | 0,333 | 0,25 | Маленький |
Фаньчуань | 0,5 | 0,333 | 0,25 | Маленький |
Драккар | 0,5 | 0,333 | 0,25 | Средний |
Багла | 1 | 0,667 | 0,5 | Средний |
Торговый бриг | 1 | 0,667 | 0,5 | Средний |
Хлам | 1,5 | 1 | 0,75 | Средний |
Военный бриг | 2 | 1,333 | 1 | Средний |
Торговый галеон | 2,5 | 1,667 | 1,25 | Большой |
Шебек | 2,5 | 1,667 | 1,25 | Большой |
Боевой фрегат | 3 | 2 | 1,5 | Большой |
Большой фрегат | 4 | 2,667 | 2 | Гранд |
Попадание пушечного ядра во вражеское судно наносит два вида урона: оно повреждает лодку и пиратов на борту лодки. Повреждение лодки затрудняет управление и может привести к ее утоплению. (см. ниже) Повреждение пиратов на борту затрудняет их бой на мечах или грохот.
Чтобы потопить корабль, он должен быть полностью поврежден. Поскольку Плотники и Патчеры ремонтируют во время боя, вероятно, потребуется больше выстрелов, чем указано, для «полного повреждения». Это не влияет на «урон SF/Rumble», так как отражает то, насколько сильно пострадали пираты на борту, и, следовательно, насколько сложными будут их бои на мечах или грохот, а не то, насколько на самом деле поврежден корабль.
Во время грабежа максимальный эффект, который может нанести урон противнику, может быть нанесен в бою на мечах или в грохоте. Стрельба по кораблю больше, чем «Max SF/Rumble Damage» нанесет еще повреждений кораблю (который остается после битвы), но не повлияет на бой на мечах. Стрельба по кораблю после того, как он получил «Полное повреждение», не имеет никакого эффекта (если только не во время войны, см. Ниже), кроме предотвращения возможности ремонта противника во время боя.
Если столкновение представляет собой PvP-битву между воюющими флагами, корабль будет навсегда потоплен, если он нанесет максимальный урон.
Во время блокады корабль тонет, если он достигает максимального урона, но не теряется навсегда, если только битва не является потоплением блокады.
Практика
Игрок может практиковать боевую навигацию на флоте. Игрок должен быть подписан и иметь узкий или более опыт навигации по подписным океанам или иметь узкий или более опыт навигации по океанам-двойникам. Практика на флоте не требует от игрока покупки пушечных ядер.
Известные ошибки
- Зависание / Не позволяет игроку размещать жетоны движения. Определенного решения нет, выход и вход на станцию иногда срабатывает, http://forums.puzzlepirates.com/community/mvnforum/viewthread?thread=18981
Полный список
Лазурный | Изумруд | Лед |
---|---|---|
|
|
|
Джейд | Меридиан | Обсидиан |
|
|
|
Опал | ||
|
Трофеи
Спойлер: подробности о трофеях скрыты ниже.
Следующие трофеи связаны с боевой навигацией:
Исторические заметки
- С выпуском 28.04.2015 появилась возможность скрывать ходы навигации от всех, кто не имеет офицерских привилегий. Эта функция была запрошена игроками для решения проблемы шпионажа альтами за движением кораблей во время важных сражений.
- До выпуска 28 апреля 2004 г. механики захвата и тарана не существовало. Фаза абордажа началась, когда оба корабля заняли одну и ту же клетку на поле морского боя. Кроме того, до этого релиза края доски действовали как ветер, отбрасывающий корабли обратно на доску.
Внешние/другие ссылки
- Bnav tutorial
- Часто обсуждаемые идеи о Пушках и Морском сражении от Game Design
- Механика столкновения
- Видеогиды Dachimpy
- Официальные документы игры
- Советы по боевой навигации
- Аннотированный боевой журнал Рипачипа: показывает прогресс в репутации по сравнению с производительностью (от новичка/способного до широкого/известного
- Советы и стратегии морских сражений, описание водоворотов и течений (устарело)
Головоломки | ||
| ||
См.![]() |
Британские корабли в битве за Ютландию
Ютландское сражение, происходившее в течение двух дней с 31 мая 1916 года, было крупнейшим морским сражением Первой мировой войны. В нем участвовал 151 британский военный корабль против 99 немецких кораблей, и это был первый и единственный раз, когда два боевых флота столкнулись друг с другом. В битве принимали участие самые разные типы боевых кораблей, и каждый из них играл свою тактическую роль.
Во время боя Iron Duke обстрелял немецкие линкоры, в том числе SMS König , нанеся несколько попаданий и серьезных повреждений.
Большинство британских линкоров в ходе боя потерь не понесли. Больше всех пострадал HMS Malaya , экипаж которого 63 человека убитыми и 68 ранеными.
Три корабля были потоплены во время боя, в результате чего погибло 3320 членов экипажа — более половины погибших британцев в Ютландии.
Это HMS Лев . Во время Ютландского сражения Lion был флагманом британского флота линейных крейсеров под командованием вице-адмирала Дэвида Битти. На начальных этапах битвы флот Битти сражался с немецкими линейными крейсерами I разведывательной группы адмирала Франца фон Хиппера. В первый час боя два линейных крейсера Битти — Indefatigable и Queen Mary — были поражены немецкими снарядами, вызвавшими катастрофические взрывы, потопившие оба корабля. Lion’s bridge, Битти, как сообщается, заметил своему флагманскому капитану: «Кажется, что-то не так с нашими чертовыми кораблями сегодня».
Льву посчастливилось избежать той же участи. Когда немецкий снаряд зажег одну из башен корабля, был смертельно ранен майор морской пехоты Фрэнсис Харви. Огонь грозил перекинуться на погреб башни, в котором хранились многие тонны взрывчатки. Несмотря на свои травмы, Харви хватило присутствия духа, чтобы в качестве меры безопасности приказать залить погреб башни. Через несколько секунд он рухнул и умер. Сообразительность Харви спасла его корабль и жизни сотен его товарищей. Похороненный в море после битвы, Харви позже был посмертно награжден Крестом Виктории.
К концу Ютландской битвы Лев много раз попадал под огонь немцев. Девяносто девять членов ее экипажа были убиты, это наибольшее количество погибших среди всех британских кораблей, переживших битву и вернувшихся в порт. Еще 51 человек получили ранения.
Во время Ютландской битвы Southampton был флагманом 2-й эскадрильи легких крейсеров коммодора Уильяма Гуденаф. Плавающий с флотом линейных крейсеров Битти, Southampton был первым британским кораблем, который заметил немецкий флот в открытом море. В своих мемуарах Гуденаф вспоминал: «Мы увидели впереди себя сначала дым, затем мачты, затем [немецкие] корабли… шестнадцать линкоров с эсминцами вокруг них на каждом носу».
Гудинаф знал, что актуальная информация о немецком флоте жизненно важна. Он подвел свою эскадрилью ближе к противнику. Сосчитав немецкие корабли, заметив их строй и курс и передав эту информацию, Гуденаф повернул свою эскадру. В радиусе действия десяти немецких линкоров эскадра сразу же попала под шквальный огонь. Десятки тяжелых снарядов упали рядом с Саутгемптоном , но ни один не попал в корабль. Один офицер вспоминал: «Я могу честно сказать, что я думал, что каждый момент будет нашим последним… казалось, мы прожили заколдованную жизнь… то, как мы сбежали, поражает всех, начиная с [коммодора Гудинафа] и ниже».
Позже Саутгемптон не так повезло. Ночью корабль сражался с немецкими крейсерами в хаотичном и крайне ожесточенном бою на близкой дистанции. Хотя торпедой был потоплен немецкий крейсер, Southampton был подожжен. За считанные минуты 89 членов экипажа корабля были убиты или ранены, а большая часть экипажа верхней палубы получила увечья или обгорела. Используя ванную кочегара в качестве операционной, корабельный врач провел следующие одиннадцать часов, леча раненых.
В Ютландии Shark входил в состав 3-й эскадры линейных крейсеров, состоящей из трех линейных крейсеров, легких крейсеров Chester и Canterbury и трех других эсминцев. Во время битвы Акула ввязалась в хаотичную схватку между британцами и немцами на близком расстоянии. Акула неоднократно подвергалась ударам. Один снаряд разрушил мостик и рулевой механизм корабля, а другой вывел из строя двигатели корабля, оставив корабль дрейфовать.
Два из орудий Акулы были выведены из строя, их расчеты погибли. Покинув разрушенный мостик, раненый капитан Акулы , коммандер Лофтус Джонс, помог поднять единственное оставшееся орудие. Обстреливая близлежащие немецкие корабли, Джонс и его люди попали в немецкий эсминец V48 , выведя корабль из строя. Когда немецкие эсминцы приблизились, Джонс приказал своим людям надеть спасательные пояса. Попав под торпеду, Акула затонула. Тридцать из экипажа «Акулы» смогли сесть на плоты, но многие умерли от ран или облучения, включая Джонса. Только шестеро выжили, и поздно ночью их спас нейтральный датский пароход.
Через несколько дней тело коммандера Джонса выбросило на берег в Швеции. В 1917 году в знак признания своего лидерства Джонс был посмертно награжден Крестом Виктории
Пролетая над Северным морем, Ратленд и Тревин смогли обнаружить приближающиеся немецкие корабли. Несмотря на то, что в него стреляли, Тревин смог сообщить об их наблюдениях Энгадину . Вскоре после этого у самолета произошла механическая поломка, и Ратленд был вынужден приземлиться. Этот короткий полет, продолжавшийся немногим более получаса, был единственным вкладом авиации в Ютландское сражение. За этот подвиг Ратленд получил прозвище «Ратланд из Ютландии».
После войны самолет Ратленда хранился в Имперском военном музее. В 1941 году, во время Второй мировой войны, во время бомбардировки Германа, известной как Блиц, в музей попала немецкая бомба. Больше всего пострадала военно-морская галерея музея. Среди уничтоженных экспонатов был гидросамолет Ратленда.