-
Notifications
You must be signed in to change notification settings - Fork 0
/
heuristics.py
122 lines (84 loc) · 3.46 KB
/
heuristics.py
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
from functools import reduce
from checkers.board import Board
from checkers.piece import Piece
safe_positions = [1, 2, 3, 4, 5, 12, 13, 20, 21, 28, 29, 30, 31, 32]
central_positions = [10, 11, 14, 15, 18, 19, 22, 23]
player_promotion_line_mapping = {
1: [29, 39, 31, 32],
2: [1, 2, 3, 4]
}
def h_peices_num(board: Board, player_num):
return board.count_movable_player_pieces(player_num)
def h_kings_num(board: Board, player_num):
cnt = 0
for piece in board.pieces:
if piece.player == player_num and piece.king:
cnt += 1
return cnt
def h_safe_pieces(board: Board, player_num):
return reduce(
lambda count, piece: count + (1 if piece.player == player_num and piece.position in safe_positions else 0),
board.pieces, 0)
def h_safe_kings(board: Board, player_num):
return reduce(
lambda count, piece: count + (
1 if piece.player == player_num and piece.position in safe_positions and piece.king
else 0), board.pieces, 0)
def h_num_of_movable_pawns(board: Board, player_num):
return reduce(
(lambda count, piece: count + (1 if not piece.captured and piece.is_movable() and piece.player == player_num
and not piece.king else 0)), board.pieces, 0)
def h_num_of_movable_kings(board: Board, player_num):
return reduce \
((lambda count, piece: count + (
1 if not piece.captured and piece.is_movable() and piece.player == player_num
and piece.king else 0)), board.pieces, 0)
def h_num_of_unoccupied_cells_on_promotion_line(board: Board, player_num):
return (4 - reduce((lambda count, piece: count + (
1 if piece.position in player_promotion_line_mapping[player_num] else 0)), board.pieces, 0))
def h_num_of_centrally_positioned_pawns(board: Board, player_num):
return reduce(
lambda count, piece: count + (
1 if piece.player == player_num and not piece.captured and piece.position in central_positions else 0),
board.pieces, 0)
def h_num_of_centrally_positioned_kings(board: Board, player_num):
return reduce(
lambda count, piece: count + (
1 if piece.player == player_num and not piece.captured and piece.position in central_positions and piece.king
else 0), board.pieces, 0)
bridge = {
1: [1, 3],
2: [32, 30]
}
oreo = {
1: [2, 7, 3],
2: [30, 26, 31]
}
triangle = {
1: [1, 6, 2],
2: [32, 27, 31]
}
dog = {
1: [1, 5],
2: [32, 28]
}
def is_piece(piece: Piece, player_num: int):
return piece is not None and piece.player == player_num
def h_dog_pattern(board: Board, player_num):
if player_num == 1:
return is_piece(board.searcher.get_piece_by_position(1), 1) \
and is_piece(board.searcher.get_piece_by_position(5), 2)
else:
return is_piece(board.searcher.get_piece_by_position(32), 2) \
and is_piece(board.searcher.get_piece_by_position(28), 1)
def h_pattern(board: Board, player_num, pattern):
for pos in pattern[player_num]:
if not is_piece(board.searcher.get_piece_by_position(pos), player_num):
return -1
return 1
def h_triangle_pattern(board: Board, player_num):
return h_pattern(board, player_num, triangle)
def h_oreo_pattern(board: Board, player_num):
return h_pattern(board, player_num, oreo)
def h_bridge_pattern(board: Board, player_num):
return h_pattern(board, player_num, bridge)