Hermit is a strategy game for two players. It is played on a board with $$n \times n$$ squares, arranged in a square grid with $$n$$ rows and $$n$$ columns. At the start of the game, the board is empty. Off the board is a supply of three dimensional blocks with dimensions of $$1 \times 1 \times 2$$ units, where a unit is about the same length as the side of a square on the board. The blocks have three different colors: red, yellow and blue.

hermit
This Hermit game board has 16 squares arranged in a square $$4 \times 4$$ grid with 4 rows and 4 columns. Both players already placed some blocks on the board and off the board is a supply of some more blocks they can place on the board. The yellow circles indicate that there are only two possibilities left to place another block in this configuration of the board: a yellow block that is placed upright at one of the two empty squares touching the left border of the grid.
start configuration
Schematic representation of a $$4 \times 4$$ Hermit board. At the start of the game, the board is empty as indicated by the white colored squares.

Each player in turn chooses a block of any color and places it either upright on the board so that it covers just one square, or on its side so that it covers two adjacent squares.

placement
The colored three dimensional blocks can be placed upright on the board so that they cover just one square (left). They can also be placed horizontally (central) or vertically (right) or on their side so that they cover two adjacent squares.

Blocks may only be placed on empty squares and can not touch a block of the same color, not even diagonally. The configuration in the diagram below has its blocks positioned as in the above picture. Yellow circles indicate the only two possibilities to place another block: a yellow block that is placed upright at position $$(1, 0)$$ or at position $$(3, 0)$$.

possible moves
The two yellow circles indicate the only two possibilities to place another block in this configuration of the board: a yellow block that is placed upright at position $$(1, 0)$$ or at position $$(3, 0)$$.

The first player who is unable to put another block on the board loses the game. Ties are not possible.

Assignment

To refer to the squares on a Hermit board, we number the rows from top to bottom and the columns from left to right, starting from zero. The position of a square on the board is then indicated by a tuple $$(r, c)$$, where $$r \in \mathbb{N}$$ (int) is the row number and $$c \in \mathbb{N}$$ (int) the column number.

The color of a block is indicated by an uppercase letter: Y (yellow), B (blue) or R (red).

The placement of a block is indicated by an uppercase letter: U (upright), H (horizontal) or V (vertical).

Define a class Hermit that can be used to simulate the progress of a Hermit game. The dimension $$n$$ (int) of the board must passed when creating a new game (Hermit). There are no blocks on the board at the start of the game.

If a game (Hermit) is passed to the built-in function str, a string representation (str) of the board must be returned in which each row of the board forms a separate line. Empty squares are represented as a dot (.) and squares covered by a block as the uppercase letter that indicates the color of the block. Representations of adjacent squares on the same row are separated from each other by a single space.

In addition, a game $$g$$ (Hermit) must at least support the following methods:

Example

>>> board = Hermit(4)
>>> print(board)
. . . .
. . . .
. . . .
. . . .
>>> board.positions((0, 0), 'H')
{(0, 0), (0, 1)}
>>> board.isvalid('R', (0, 0))
True
>>> board.isvalid('R', (0, 1))
True
>>> print(board.move('R', (0, 0), 'H'))
R R . .
. . . .
. . . .
. . . .
>>> print(board.move('R', (1, 2), 'V'))
Traceback (most recent call last):
AssertionError: invalid move
>>> print(board.move('B', (0, 2), 'U').move('Y', (1, 2), 'U'))
R R B .
. . Y .
. . . .
. . . .
>>> print(board.move('R', (3, 1), 'U').move('Y', (3, 2), 'H'))
R R B .
. . Y .
. . . .
. R Y Y
>>> print(board.move('R', (1, 3), 'V').move('B', (2, 0), 'H'))
R R B .
. . Y R
B B . R
. R Y Y
>>> board.possible_moves()
{('Y', (1, 0), 'U'), ('Y', (3, 0), 'U')}
>>> print(board.move('Y', (3, 0), 'U'))
R R B .
. . Y R
B B . R
Y R Y Y
>>> board.possible_moves()
{('Y', (1, 0), 'U')}
>>> print(board.move('Y', (1, 0), 'U'))
R R B .
Y . Y R
B B . R
Y R Y Y
>>> board.possible_moves()
set()