Writing Amazons in .lud Format

This tutorial provides a step-by-step walkthrough of how to implement the game Amazons, from scratch, in the .lud format.

Amazons is played on a 10x10 board. Each player has four amazons (chess queens), with other pieces used as arrows. Every turn consists of two moves. First, a player moves one of their amazons like a Chess queen, without crossing or entering a space occupied by another amazon or arrow. Second, it shoots an arrow to any space on the board that is along the unobstructed path of a queen’s move from that place. The last player able to make a move wins.

Note

For each of the following steps, the Ludii Tutorials GitHub repository contains a .lud file with the contents written in that step. They can all be loaded in Ludii and “played”, although some of them may not be particularly interesting to play!

Step 2: Defining the Pieces

In this step, we add the pieces to the equipment.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
(game "Amazons"
    (players 2)
    (equipment
        {
            (board (square 10))
            (piece "Queen" Each)
            (piece "Dot" Neutral)
        }
    )
    (rules
        (play
            (forEach Piece)
        )

        (end
            (if
                (no Moves Next)
                (result Mover Win)
            )
        )
    )
)

Line 6 defines that each player should have a piece type labelled "Queen". Ludii will automatically label these as "Queen1" and "Queen2" for players 1 and 2, respectively. Additionally, in line 7 we define a ``Dot’’ piece type, which is not owned by any player. This is the piece type that we will use in locations that players block by shooting their arrows.

Step 3: Defining the Starting Rules

We extend the game description listed above by adding start rules to place the pieces on the board:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
(game "Amazons"
    (players 2)
    (equipment
        {
            (board (square 10))
            (piece "Queen" Each)
            (piece "Dot" Neutral)
        }
    )
    (rules
        (start
            {
                (place "Queen1" {"A4" "D1" "G1" "J4"})
                (place "Queen2" {"A7" "D10" "G10" "J7"})
            }
        )
        (play
            (forEach Piece)
        )

        (end
            (if
                (no Moves Next)
                (result Mover Win)
            )
       )
    )
)

Lines 11-16 ensure that any game is started by placing objects of the two different types of queens in the correct starting locations. The labels used to specify these locations can be seen in Ludii by enabling “Show Coordinates” in Ludii’s View menu.

Step 4: Step 4: Adding the Final Rules for Amazons

To complete the game of Amazons, we need to allow players to move their queens and to shoot an arrow after moving a queen. This is implemented in the following game description:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
(game "Amazons"
    (players 2)
    (equipment
        {
            (board (square 10))
            (piece "Queen" Each (move Slide (then (moveAgain))))
            (piece "Dot" Neutral)
        }
    )
    (rules
        (start
            {
                (place "Queen1" {"A4" "D1" "G1" "J4"})
                (place "Queen2" {"A7" "D10" "G10" "J7"})
            }
        )
        (play
            (if (is Even (count Moves))
                (forEach Piece)
                (move Shoot (piece "Dot0"))
            )
        )

        (end
            (if
                (no Moves Next)
                (result Mover Win)
            )
        )
    )
)

To make the queens able to move, inside the queen pieces, we have added the following: (move Slide (then (moveAgain)))). By default, the (move Slide) ludeme defines that the piece is permitted to slide along any axis of the used board, as long as we keep moving through locations that are empty. No additional restrictions – in terms of direction or distance, for example – are required for queen moves. We have appended (then (moveAgain)) in the queen moves. This means that, after any queen move, the same player gets to make another move.

In lines 18-21, the play rules have been changed to no longer exclusively extract their moves from the pieces. Only at even move counts (0, 2, 4, etc.) do we still make a queen move (using (forEach Piece). At odd move counts, the moves are defined by (move Shoot (piece "Dot0")). This rule lets us shoot a piece of type "Dot0" into any empty position, starting from the location that we last moved to – this is the location that our last queen move ended up in. This game description implements the full game of Amazons for Ludii.

Once pieces are defined, their names are internally appended with the index of the owning player. For example, the above description defines a “Queen” piece for players 1 and 2, then the subsequent description refers to “Queen1” for “Queen” pieces belonging to Player 1 and “Queen2” for “Queen” pieces belonging to Player 2. The “Dot” piece is referred to as “Dot0”, indicating that this is a neutral piece not owned by any player. Note that pieces can also be referred to by their undecorated names in the game description, e.g. “Queen” or “Dot”, in which case the reference applies to all pieces with that name belonging to any player.

Step 5: Improving Graphics

The game description above plays correctly, but does not look appealing because it uses Ludii’s default colours for the board. This can be easily improved by adding graphics metadata:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
(game "Amazons"
    (players 2)
    (equipment
        {
            (board (square 10))
            (piece "Queen" Each (move Slide (then (moveAgain))))
            (piece "Dot" Neutral)
        }
    )
    (rules
        (start
            {
                (place "Queen1" {"A4" "D1" "G1" "J4"})
                (place "Queen2" {"A7" "D10" "G10" "J7"})
            }
        )

        (play
            (if (is Even (count Moves))
                (forEach Piece)
                (move Shoot (piece "Dot0"))
            )
        )

        (end
           (if
             (no Moves Next)
             (result Mover Win)
           )
        )
    )
)

(metadata
    (graphics
        {
            (piece Scale "Dot" 0.333)
            (board Style Chess)
        }
    )
)

Line 37 makes the “Dot” pieces smaller, and line 38 applies a Chess style to the board.