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 Unit
But 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 i
Players 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 Shot
We represent all ships as lists of units:
type Ship = Board Unit
Before players arrange their boards, they both should know a set of available ships.
type Fleet = Board Ship
Let’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` Last
submarine = Nonempty @List
`ha` Item Unit `ha` Next
`ha` Item Unit `ha` Next
`ha` Item Unit `ha` Last
fleet = Nonempty @List @Ship
`ha_` Item `hv` by destroyer `ha` Next
`ha_` Item `hv` by submarine `ha` Last
There 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` output
Printing 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 Space
Finally, putting it all together:
main = enter @World
`yuk__` World `hv` title "SHIPS: "
`yuk__` World `hv` print fleet
Here is the result:
SHIPS: ### ##
Having all this in mind, how the bot should understand where to hit? By calculating probabilities.