tests
This commit is contained in:
parent
bd87ed86d0
commit
dbd18b603f
76
board.py
76
board.py
|
@ -33,29 +33,69 @@ class Board:
|
||||||
# TODO: Allow not doing anything if and only if no alternatives
|
# TODO: Allow not doing anything if and only if no alternatives
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_move_valid(board, player, face_value, move):
|
def is_move_valid(board, player, face_value, move):
|
||||||
board = list(board)
|
def sign(a):
|
||||||
|
return (a > 0) - (a < 0)
|
||||||
|
|
||||||
from_idx = move[0]
|
from_idx = move[0]
|
||||||
to_idx = move[1]
|
to_idx = move[1]
|
||||||
to_state = board[to_idx]
|
to_state = None
|
||||||
from_state = board[from_idx]
|
from_state = board[from_idx]
|
||||||
|
delta = to_idx - from_idx
|
||||||
|
direction = sign(delta)
|
||||||
|
bearing_off = None
|
||||||
|
|
||||||
if from_idx == 26:
|
if to_idx >= 1 and to_idx <= 24:
|
||||||
from_idx = 1
|
to_state = board[to_idx]
|
||||||
face_value -= 1
|
bearing_off = False
|
||||||
elif from_idx == 27:
|
else: # Bearing off
|
||||||
from_idx = 24
|
to_state = 0
|
||||||
face_value -= 1
|
bearing_off = True
|
||||||
|
|
||||||
if not (1 <= from_idx <= 24 and
|
# print("_"*20)
|
||||||
1 <= to_idx <= 24):
|
# print("board:", board)
|
||||||
return False
|
# print("to_idx:", to_idx, "board[to_idx]:", board[to_idx], "to_state:", to_state)
|
||||||
elif ( abs( from_idx - to_idx ) != face_value ):
|
# print("+"*20)
|
||||||
return False
|
|
||||||
elif (from_state * player >= 1 and # Is moving player's own checker?
|
def is_forward_move():
|
||||||
(to_state * player >= 0 or # Is 'to' empty or has player's own checkers?
|
return direction == player
|
||||||
to_state * -player == 1)): # Can opponent checker be hit?
|
|
||||||
|
def face_value_match_move_length():
|
||||||
|
return abs(delta) == face_value
|
||||||
|
|
||||||
|
def bear_in_if_checker_on_bar():
|
||||||
|
if player == 1:
|
||||||
|
bar = 0
|
||||||
|
else:
|
||||||
|
bar = 25
|
||||||
|
|
||||||
|
bar_state = board[bar]
|
||||||
|
|
||||||
|
if bar_state != 0:
|
||||||
|
return from_idx == bar
|
||||||
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def checkers_at_from_idx():
|
||||||
|
return sign(from_state) == player
|
||||||
|
|
||||||
|
def no_block_at_to_idx():
|
||||||
|
if -sign(to_state) == player:
|
||||||
|
return abs(to_state) == 1
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def can_bear_off():
|
||||||
|
# TODO
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
return all([ is_forward_move(),
|
||||||
|
face_value_match_move_length(),
|
||||||
|
bear_in_if_checker_on_bar(),
|
||||||
|
checkers_at_from_idx(),
|
||||||
|
no_block_at_to_idx(),
|
||||||
|
can_bear_off() if bearing_off else True])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_winner(board, player):
|
def is_winner(board, player):
|
||||||
for i in range(1,25):
|
for i in range(1,25):
|
||||||
|
@ -69,6 +109,10 @@ class Board:
|
||||||
# Iterate through each index and check if it's a possible move given the roll
|
# Iterate through each index and check if it's a possible move given the roll
|
||||||
# If player is O, then check for idx + roll
|
# If player is O, then check for idx + roll
|
||||||
# If player is X, then check for idx - roll
|
# If player is X, then check for idx - roll
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: make sure that it is not possible to do nothing on first part of
|
||||||
|
# turn and then do something with the second die
|
||||||
print("Find legal moves: ",roll,"-"*20)
|
print("Find legal moves: ",roll,"-"*20)
|
||||||
|
|
||||||
def idxs_with_checkers_of_current_player(board):
|
def idxs_with_checkers_of_current_player(board):
|
||||||
|
|
94
test.py
Normal file
94
test.py
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
import unittest
|
||||||
|
from board import Board
|
||||||
|
|
||||||
|
class TestIsMoveValid(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_simple_movement(self):
|
||||||
|
board = Board.initial_state
|
||||||
|
self.assertEqual(Board.is_move_valid(board, 1, 2, (1, 3)), True) # White
|
||||||
|
self.assertEqual(Board.is_move_valid(board, -1, 3, (24, 21)), True) # Black
|
||||||
|
|
||||||
|
def test_backwards_movement_invalid(self):
|
||||||
|
board = Board.initial_state
|
||||||
|
self.assertEqual(Board.is_move_valid(board, 1, 2, (12, 10)), False)
|
||||||
|
self.assertEqual(Board.is_move_valid(board, -1, 3, (8, 11)), False)
|
||||||
|
|
||||||
|
def test_face_value_match_move_length(self):
|
||||||
|
board = Board.initial_state
|
||||||
|
self.assertEqual(Board.is_move_valid(board, 1, 2, (1, 3)), True)
|
||||||
|
self.assertEqual(Board.is_move_valid(board, 1, 2, (1, 4)), False)
|
||||||
|
|
||||||
|
def test_bear_in(self):
|
||||||
|
board = [ 1,
|
||||||
|
1, 0, 0, 0, 0, -5,
|
||||||
|
0, -3, 0, 0, 0, 5,
|
||||||
|
-5, 0, 0, 0, 3, 0,
|
||||||
|
5, 0, 0, 0, 0, -2,
|
||||||
|
0 ]
|
||||||
|
self.assertEqual(Board.is_move_valid(board, 1, 2, (0, 2)), True)
|
||||||
|
|
||||||
|
board = [ 0,
|
||||||
|
2, 0, 0, 0, 0, -5,
|
||||||
|
0, -3, 0, 0, 0, 5,
|
||||||
|
-5, 0, 0, 0, 3, 0,
|
||||||
|
5, 0, 0, 0, 0, -1,
|
||||||
|
-1 ]
|
||||||
|
self.assertEqual(Board.is_move_valid(board, -1, 2, (25, 23)), True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_force_bear_in(self):
|
||||||
|
board = [ 1,
|
||||||
|
1, 0, 0, 0, 0, -5,
|
||||||
|
0, -3, 0, 0, 0, 5,
|
||||||
|
-5, 0, 0, 0, 3, 0,
|
||||||
|
5, 0, 0, 0, 0, -2,
|
||||||
|
0 ]
|
||||||
|
self.assertEqual(Board.is_move_valid(board, 1, 2, (1, 3)), False)
|
||||||
|
self.assertEqual(Board.is_move_valid(board, -1, 3, (24, 21)), True)
|
||||||
|
|
||||||
|
board = [ 0,
|
||||||
|
2, 0, 0, 0, 0, -5,
|
||||||
|
0, -3, 0, 0, 0, 5,
|
||||||
|
-5, 0, 0, 0, 3, 0,
|
||||||
|
5, 0, 0, 0, 0, -1,
|
||||||
|
-1 ]
|
||||||
|
self.assertEqual(Board.is_move_valid(board, -1, 2, (24, 22)), False)
|
||||||
|
self.assertEqual(Board.is_move_valid(board, 1, 2, (1, 3)), True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_owned_checker_at_from(self):
|
||||||
|
board = Board.initial_state
|
||||||
|
self.assertEqual(Board.is_move_valid(board, 1, 2, (3, 5)), False) # No checkers
|
||||||
|
self.assertEqual(Board.is_move_valid(board, -1, 2, (23, 21)), False) # No checkers
|
||||||
|
self.assertEqual(Board.is_move_valid(board, 1, 2, (8, 10)), False) # Opponent checkers
|
||||||
|
self.assertEqual(Board.is_move_valid(board, -1, 2, (1, 3)), False) # Opponent checkers
|
||||||
|
|
||||||
|
def test_no_block_at_to(self):
|
||||||
|
board = Board.initial_state
|
||||||
|
self.assertEqual(Board.is_move_valid(board, 1, 5, (1, 6)), False)
|
||||||
|
self.assertEqual(Board.is_move_valid(board, -1, 5, (24, 19)), False)
|
||||||
|
|
||||||
|
def test_able_to_hit_opponent_checkers(self):
|
||||||
|
board = [ 0,
|
||||||
|
2, 0, 0, -1, 0, -4,
|
||||||
|
0, -3, 0, 0, 0, 5,
|
||||||
|
-5, 0, 0, 0, 3, 0,
|
||||||
|
4, 0, 1, 0, 0, -2,
|
||||||
|
0 ]
|
||||||
|
self.assertEqual(Board.is_move_valid(board, 1, 3, (1, 4)), True)
|
||||||
|
self.assertEqual(Board.is_move_valid(board, -1, 3, (24, 21)), True)
|
||||||
|
|
||||||
|
def test_bear_off_simple(self):
|
||||||
|
board = [ 0,
|
||||||
|
0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 1,
|
||||||
|
0 ]
|
||||||
|
self.assertEqual(Board.is_move_valid(board, 1, 2, (24, 26)), True)
|
||||||
|
self.assertEqual(Board.is_move_valid(board, 1, 1, (24, 25)), True)
|
||||||
|
|
||||||
|
# TODO: More tests for bearing off are needed
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
Reference in New Issue
Block a user