Wham ...
... with this sound the heavy club touched someone's head. The body twitched and fell back. The deed was done, unheard by anyone, unseen: the perfect end, the perfect solution, the perfect story.
But, as the gnomes say, a troll is behind any misfortune.
')
sir terry prattchettThud! Of course, I could not get past this game. Not only because I really like the works of Terri Pratchet, but mainly because this game is like nothing. To begin with, it is played on an octagonal board. Gnomes fight with trolls (and the latter are much smaller). How can trolls win in the minority? Very simple - in one move a troll can take several dwarfs off the board. And the dwarves, even acting together, have to sweat to remove one troll from the board.
The board game, based on the Pratchett piece, was developed in 2002 by Trevor Truran and released for sale. From the very moment I learned about this game, I really wanted to play it. I have long and unsuccessfully searched for its computer implementation, but all I have found is the reasoning that this game is too complicated for the computer to play. Now, I have the opportunity to verify this statement.
First, let's deal with the rules of the game.
As I said earlier, the game is played on an octagonal board, in the center of which is a “Scala” occupying one cell. The game involves 8 trolls, on the one hand, and 32 gnomes (Dwarfs) on the other. The task of each side is to minimize the number of the enemy.
The game is conducted in two stages (this paragraph of the rules is essentially used in the plot of the
book of the same name). Each of the players must play for both the gnomes and the trolls. As a rule, it is not possible to remove all the enemy pieces from the board. The game ends by the agreement of the players, after which points are considered. Each remaining dwarf on the board is estimated at 1 point, a troll - 4 points. The results of the two games played are added up. Who scored the most points - he won.
Gnomes go to any number of free cells vertically, horizontally, or diagonals (like a queen in chess), but in order to remove the troll from the troll's board, the dwarf must jump on it. Several gnomes forming a line (vertically, horizontally, or diagonally) allow the extreme gnome to jump (in the opposite direction from the line) to a number of cells less than or equal to the number of gnomes in the line (provided that the troll is located at the end point of the jump). A solitary dwarf also forms a line and, thus, can jump 1 square in any direction, removing the troll (if he could manage to get close to him, of course).
Trolls can walk one square in any direction (like a king in Chess). All gnomes who are one cell away from the point where the turn is completed are removed from the board. Thus, in one move, the troll can remove from the board up to 7 dwarfs (if very lucky). In order to remove the gnome from the board, the troll must go (even if the gnome is already close to it). Trolls can also line up (although they need it to a much lesser extent than gnomes). A line of N trolls (vertically, horizontally, or diagonally) can “push” an extreme troll to N (or less) cells, provided that, as a result of this move, at least one gnome will be removed from the board.
Figures can not jump over each other or through the "Rock" in the center of the board.
You may notice that we need to count the number of figures in the "line". Since with counting anything in
ZoG everything is very difficult (most likely, I will talk about it more than once), the implementation of these rules will be, for us, in some way, a test, and at the same time, will allow us to more fully illustrate the possibilities of the language ZRF descriptions. We start, however, with a simple:
Board(define board-defs (image "images\gluk\Thud.bmp") (grid (start-rectangle 45 35 60 58) (dimensions ("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o" (35 0))
In this description, compared to what I mentioned in the previous
article , a new keyword,
kill-positions , was added. This section of the description allows you to prohibit a number of board positions, thus turning it from quadrilateral to octagonal. In the center, as I promised, is the "Rock". Figures cannot pass through it. In fact, this is not part of the playing field.
Go ahead ( define game-defs ( board (board-defs) ) ( board-setup (White (Dwarf f1 g1 i1 j1 e2 k2 d3 l3 c4 m4 b5 n5 a6 o6 a7 o7 a9 o9 a10 o10 b11 n11 c12 m12 d13 l13 e14 k14 f15 g15 i15 j15) ) (Black (Troll g7 h7 i7 g8 i8 g9 h9 i9) ) ) (loss-condition (White Black) stalemated) (draw-condition (White Black) repetition) )
Nothing new here. We place the figures, determine the conditions of loss (for each of the parties - the inability to make another move) and a draw (repetition of the position). Now, the fun begins. We need to come up with a way to count the shapes in a line.
Leap gnome ( define dwarf-3 ( mark (opposite $1) (verify friend?) (opposite $1) (verify friend?) back $1 (verify empty?) $1 (verify empty?) $1 (verify enemy?) add ) )
In order to jump a figure into 3 cells, I do the following:
- I remember the current position with the mark command
- Twice I move in the opposite direction, checking for the presence of a friendly figure on the cage.
- Returning to the original cell, the command back
- Twice moving in the direction of the turn, checking that the cell is empty.
- Move again if an enemy figure is on the target cell
- If all the conditions are met, complete the move with the add command (the enemy figure is removed from the board automatically)
Now the gnomes are able to jump into three squares (if there is a suitable line), carrying the troll from the board. In addition to the three, the gnomes could jump to a different number of cells, it is necessary to define the macros dwarf-1, dwarf-2, and so on, up to dwarf-7 inclusive. Further, the macros can not be defined, since a larger number of cells on our board cannot jump (even in order to have the opportunity to jump on 7 cells, the dwarfs should be very lucky, so most likely this macro will never be used ). This solution is somewhat verbose, but it works.
In addition to taking, gnomes should be able to make a normal move (to any number of cells in the specified direction). Everything is simple here:
Move the gnome ( define shift ( $1 ( while empty? add $1 ) ) )
We use a cycle. While the cells are empty, we move in the indicated direction, adding possible moves. This does not mean that we will go to
all these cells. We simply inform the ZoG core that these cells
can be walked on, the rest is its business.
The implementation of the troll course is somewhat complicated by the fact that at the end of the turn they can remove dwarf figures from adjacent cells from the board. Here is how the implementation of the troll's move into two cells looks like:
Troll course ( define troll-2 ( mark (opposite $1) (verify friend?) back $1 (verify empty?) $1 (verify empty?) (verify (or (enemy? n) (enemy? nw) (enemy? s) (enemy? ne) (enemy? w) (enemy? sw) (enemy? e) (enemy? se))) (if (enemy? n) (capture n)) (if (enemy? nw) (capture nw)) (if (enemy? s) (capture s)) (if (enemy? ne) (capture ne)) (if (enemy? w) (capture w)) (if (enemy? sw) (capture sw)) (if (enemy? e) (capture e)) (if (enemy? se) (capture se)) add ) )
In addition to checking for the availability of a suitable line, a check is made here that, as a result of the move, at least one dwarf will be taken. Also, before completing the turn, the addition of neighbors in all eight directions was added (provided that these are enemy figures). It should be noted that such predicates as the
enemy? or
empty? allow the form of the call with the transfer parameter of the direction that allows you to perform the test without moving to another cell. Often, it is very convenient. In the implementation of the move on one cell, simply remove the extra checks:
Troll move one square ( define troll-1 ( $1 (verify empty?) (if (enemy? n) (capture n)) (if (enemy? nw) (capture nw)) (if (enemy? s) (capture s)) (if (enemy? ne) (capture ne)) (if (enemy? w) (capture w)) (if (enemy? sw) (capture sw)) (if (enemy? e) (capture e)) (if (enemy? se) (capture se)) add ) )
It remains to put the game together and make sure that everything works:
Thud! (game (title "Thud") (description "...") (history "...") (strategy "...") (players White Black) (turn-order White Black) (game-defs) (piece (name Dwarf) (image White "images\gluk\d.bmp") (description "d") (moves (dwarf-1 n) (dwarf-1 ne) (dwarf-2 n) (dwarf-2 ne) (dwarf-1 e) (dwarf-1 nw) (dwarf-2 e) (dwarf-2 nw) (dwarf-1 s) (dwarf-1 se) (dwarf-2 s) (dwarf-2 se) (dwarf-1 w) (dwarf-1 sw) (dwarf-2 w) (dwarf-2 sw) (dwarf-3 n) (dwarf-3 ne) (dwarf-4 n) (dwarf-4 ne) (dwarf-3 e) (dwarf-3 nw) (dwarf-4 e) (dwarf-4 nw) (dwarf-3 s) (dwarf-3 se) (dwarf-4 s) (dwarf-4 se) (dwarf-3 w) (dwarf-3 sw) (dwarf-4 w) (dwarf-4 sw) (dwarf-5 n) (dwarf-5 ne) (dwarf-6 n) (dwarf-6 ne) (dwarf-5 e) (dwarf-5 nw) (dwarf-6 e) (dwarf-6 nw) (dwarf-5 s) (dwarf-5 se) (dwarf-6 s) (dwarf-6 se) (dwarf-5 w) (dwarf-5 sw) (dwarf-6 w) (dwarf-6 sw) (dwarf-7 n) (dwarf-7 ne) (shift n) (shift ne) (dwarf-7 e) (dwarf-7 nw) (shift e) (shift nw) (dwarf-7 s) (dwarf-7 se) (shift s) (shift se) (dwarf-7 w) (dwarf-7 sw) (shift w) (shift sw) ) ) (piece (name Troll) (image Black "images\gluk\T.bmp") (description "T") (moves (troll-1 n) (troll-1 ne) (troll-2 n) (troll-2 ne) (troll-1 e) (troll-1 nw) (troll-2 e) (troll-2 nw) (troll-1 s) (troll-1 se) (troll-2 s) (troll-2 se) (troll-1 w) (troll-1 sw) (troll-2 w) (troll-2 sw) (troll-3 n) (troll-3 ne) (troll-4 n) (troll-4 ne) (troll-3 e) (troll-3 nw) (troll-4 e) (troll-4 nw) (troll-3 s) (troll-3 se) (troll-4 s) (troll-4 se) (troll-3 w) (troll-3 sw) (troll-4 w) (troll-4 sw) (troll-5 n) (troll-5 ne) (troll-6 n) (troll-6 ne) (troll-5 e) (troll-5 nw) (troll-6 e) (troll-6 nw) (troll-5 s) (troll-5 se) (troll-6 s) (troll-6 se) (troll-5 w) (troll-5 sw) (troll-6 w) (troll-6 sw) (troll-7 n) (troll-7 ne) (troll-7 e) (troll-7 nw) (troll-7 s) (troll-7 se) (troll-7 w) (troll-7 sw) ) ) )
It should be noted that the trolls, in this game, turned out to be very strong figures. If the board were bigger, the gnomes would have managed to run away and gather in a compact unit, to which it would not be so easy to approach. But, on our board, thanks to the possibility of a jump, the trolls get to the gnomes already at 2-3 moves. I ran this game in computer management mode for both sides for a long time. In the end, there were 5 figures left on both sides, after which the trolls could no longer catch up with the gnomes, due to the mobility of the latter. I admit that a man could play for the gnomes better. On the other hand, playing the game for trolls, the computer with the task is certainly coping.
Sources, as always, can be picked up on
github .
Just in case, I remind you that running them on the Demo version of Zillions of Games will not work. You can not even try.