File size: 7,644 Bytes
079c32c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
import numpy as np
import pytest
from easydict import EasyDict

from connect4_env import Connect4Env
from zoo.board_games.connect4.envs.rule_bot import Connect4RuleBot


@pytest.mark.unittest
class TestConnect4RuleBot():
    """
    Overview:
        This class is used to test the Connect4RuleBot class methods.
    """

    def setup(self) -> None:
        """
        Overview:
            This method is responsible for setting up the initial configurations required for the game environment.
            It creates an instance of the Connect4Env class and Connect4RuleBot class.
        """
        cfg = EasyDict(
            battle_mode='self_play_mode',
            battle_mode_in_simulation_env='self_play_mode',
            render_mode='state_realtime_mode',
            channel_last=False,
            scale=True,
            agent_vs_human=False,
            prob_random_agent=0,
            prob_expert_agent=0,
            bot_action_type='rule',
            screen_scaling=9,
            save_replay=False,
            prob_random_action_in_bot=0
        )
        self.env = Connect4Env(cfg)
        self.player = 1
        self.bot = Connect4RuleBot(self.env, self.player)

    def test_is_winning_move(self) -> None:
        """
        Overview:
            This test method creates a game situation where the bot has three consecutive pieces in the board.
            It tests the `is_winning_move` method of the Connect4RuleBot class by asserting that the method returns True
            when a winning move is possible for the bot.
        """
        # Create a chessboard with three consecutive pieces.
        board = np.zeros((6, 7))
        board[5][3] = self.player
        board[5][4] = self.player
        board[5][5] = self.player
        self.bot.board = board
        assert self.bot.is_winning_move(2) is True  # Winning move is to place a piece in the second column.

    def test_is_winning_move_in_two_steps(self) -> None:
        board = np.zeros((6, 7))
        board[5][3] = self.player
        board[5][4] = self.player
        self.bot.board = board
        assert self.bot.is_winning_move_in_two_steps(2) is True
        board = np.zeros((6, 7))
        board[5][3] = self.player
        board[5][4] = self.player
        board[5][0] = 3 - self.player
        board[4][0] = 3 - self.player
        board[3][0] = 3 - self.player
        self.bot.board = board
        assert self.bot.is_winning_move_in_two_steps(2) is False

    def test_is_blocking_move(self) -> None:
        """
        Overview:
            This test method creates a game situation where the opponent has three consecutive pieces in the board.
            It tests the `is_blocking_move` method of the Connect4RuleBot class by asserting that the method returns True
            when a blocking move is necessary to prevent the opponent from winning.
        """
        """
        # Create a chessboard with three consecutive pieces.
        board = np.zeros((6, 7))
        opponent = 2 if self.player == 1 else 1
        board[5][3] = opponent
        board[5][4] = opponent
        board[5][5] = opponent
        self.bot.board = board
        assert self.bot.is_blocking_move(2) is True  # Placing a piece in the second column is a move to prevent the opponent from winning.
        """

        # Create a chessboard with three consecutive pieces of opponents.
        self.bot.current_player = 2
        board = np.array([[1, 0, 0, 0, 0, 0, 0],
                          [1, 0, 1, 0, 0, 0, 0],
                          [2, 0, 2, 0, 0, 0, 0],
                          [1, 1, 1, 0, 0, 0, 0],
                          [1, 2, 2, 1, 0, 0, 2],
                          [1, 2, 2, 2, 1, 0, 0]])
        self.bot.board = board
        assert self.bot.is_blocking_move(3) is True  # Placing a piece in the 4th column is a move to prevent the opponent from winning.

    def test_is_sequence_3_move(self) -> None:
        """
        Overview:
            This test method creates a game situation where the bot has two consecutive pieces in the board.
            It tests the `is_sequence_3_move` method of the Connect4RuleBot class by asserting that the method returns True
            when placing a piece next to these two consecutive pieces will create a sequence of 3 pieces.
        """
        # Create a chessboard with two consecutive pieces.
        board = np.zeros((6, 7))
        board[5][4] = self.player
        board[5][5] = self.player
        self.bot.board = board
        assert self.bot.is_sequence_3_move(3) is True  # Placing a piece in the third column should create a three-in-a-row.

    def test_is_sequence_2_move(self) -> None:
        """
        Overview:
            This test method creates a game situation where the bot has a single piece in the board.
            It tests the `is_sequence_2_move` method of the Connect4RuleBot class by asserting that the method returns True
            when placing a piece next to the single piece will create a sequence of 2 pieces.
            It also tests for situations where placing a piece will not result in a sequence of 2 pieces.
        """
        # Create a chessboard with one consecutive piece.
        board = np.zeros((6, 7))
        board[5][5] = self.player
        self.bot.board = board
        assert self.bot.is_sequence_2_move(4) is True  # Placing a move in the fourth column should create a two-in-a-row.

        # Create a chessboard with one and two consecutive pieces.
        board = np.array([[0, 0, 0, 0, 0, 0, 0],
                          [0, 0, 0, 0, 0, 0, 0],
                          [0, 0, 0, 0, 2, 0, 0],
                          [0, 0, 0, 0, 1, 0, 0],
                          [0, 0, 0, 0, 1, 0, 0],
                          [0, 0, 0, 2, 2, 0, 0]])
        self.bot.board = board
        assert self.bot.is_sequence_2_move(5) is True  # Placing a move in the 5th column should create a two-in-a-row.
        assert self.bot.is_sequence_2_move(4) is False  # Placing a move in the 5th column should not create a two-in-a-row.
        assert self.bot.is_sequence_2_move(6) is False  # Placing a move in the 6th column should not create a two-in-a-row.

    def test_get_action(self) -> None:
        """
        Overview:
            This test method creates a game situation with an empty board.
            It tests the `get_rule_bot_action` method of the Connect4RuleBot class by asserting that the method returns an action
            that is within the set of legal actions.
        """
        board = np.zeros((6, 7))
        self.bot.board = board
        action = self.bot.get_rule_bot_action(board, self.player)
        assert action in self.env.legal_actions

    def test_remove_actions(self) -> None:
        self.bot.next_player = 3 - self.player
        board = np.zeros((6, 7))
        board[5][0] = self.player
        board[5][3] = self.player
        board[5][4] = self.player
        board[5][5] = 3 - self.player
        board[4][3] = 3 - self.player
        board[4][4] = 3 - self.player
        board[4][5] = 3 - self.player
        self.bot.board = board
        self.bot.legal_actions = [i for i in range(7) if board[0][i] == 0]
        self.bot.remove_actions()
        assert self.bot.legal_actions == [0, 1, 3, 4, 5]
        board = np.zeros((6, 7))
        board[5][0] = self.player
        board[4][0] = self.player
        board[5][3] = 3 - self.player
        board[5][4] = 3 - self.player
        self.bot.board = board
        self.bot.legal_actions = [i for i in range(7) if board[0][i] == 0]
        self.bot.remove_actions()
        assert self.bot.legal_actions == [0, 2, 5]