Full source code ⋅ Next chapter
Battleship is a strategy type guessing game for two players. It is played on ruled grids (paper or board) on which each player’s fleet of warships are marked. The locations of the fleets are concealed from the other player. Players alternate turns calling “shots” at the other player’s ships, and the objective of the game is to destroy the opposing player’s fleet. Ships cannot touch each other horizontally, vertically or diagonally.
Writing a game from scratch, including agents, seems like a pretty daunting task. Nevertheless we could start with a tiniest prototype implementation ever possible, simplifying everything that is not necessary at the moment.
Any tile in a grid could consist any ship part:
type Tile = Unit `S` Unit
pattern Idle = This Unit
pattern Ship = That UnitBut from an oppononent point of view, we should include some information whether a damaged ship is sinking after shooting:
type Nail = Unit `S` Unit
pattern Bang i = This i
pattern Sunk i = That i
type Shot = Nail `S` Unit
pattern Nail i = This i
pattern Miss i = That iPlayers need distinguish boards to arrange their ships and track opponent ones. For the sake of simplicity we start with one dimensional area:
type Board = Nonempty List
type Personal = Board Tile
type Opponent = Board ShotWe represent all ships as lists of units:
type Ship = Board UnitBefore players arrange their boards, they both should know a set of available ships.
type Fleet = Board ShipLet’s say we have one destroyer (2-sized) and one submarine (3-sized) ships:
destroyer = Nonempty @List
`ha` Item Unit `ha` Next
`ha` Item Unit `ha` Lastsubmarine = Nonempty @List
`ha` Item Unit `ha` Next
`ha` Item Unit `ha` Next
`ha` Item Unit `ha` Lastfleet = Nonempty @List @Ship
`ha_` Item `hv` by destroyer `ha` Next
`ha_` Item `hv` by submarine `ha` LastThere is not so much we can do with it except print it out to console.
Printing a title is straightforward, we just need to specify exast datastructure behind a string literal:
title x = is @(List ASCII) x `yokl` Forth `ha` World `ha` outputPrinting out ships is more tricky, we need first to traverse a list of ships, then ships themselves, making a space break after each one:
print x = x `yokl_` Forth `ha` World `ha___` is @Ship
`ho__'yukl` Forth `ha` World `ha` output `ha` Glyph `ha` Symbol `ha` Punctuate `hv` by Hash
`ho__'yuk` World `ha` output `ha` Caret `hv` by SpaceFinally, putting it all together:
main = enter @World
`yuk__` World `hv` title "SHIPS: "
`yuk__` World `hv` print fleetHere is the result:
SHIPS: ### ##Having all this in mind, how the bot should understand where to hit? By calculating probabilities.