-
Notifications
You must be signed in to change notification settings - Fork 0
/
Group-18.py
154 lines (137 loc) · 5.49 KB
/
Group-18.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
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
'''
File name: Group-18.py
Author: Utkarsh Kunwar, Utkrisht Dhankar
Email: [email protected]
Date created: 22 Oct 2017
Date last modified: 22 Oct 2017
'''
import copy
from framework import Board, Player, Piece
class MyPlayer(Player):
def __init__(self):
pass
def get_move(self,board):
'''
:param board: Board object
:return: (piece,new_position,BoardLeavingMove)
'''
return self.alphabeta(board)[1]
# Returns the evaluation value of the board configuration
def evaluate(self, board):
def lane_blocked(board):
board_matrix = board.get_board_config()[0]
h_value = 0
for row in xrange(0, board.size):
for col in xrange(0, board.size):
if board_matrix[row][col] == 1:
for down in xrange(row, board.size - 1):
if board_matrix[down][col] == 2:
h_value = h_value + 2 / (down - row + 1)
for right in xrange(col, board.size - 1):
if board_matrix[row][right] == 2:
h_value = h_value - 2 / (right - col + 1)
return h_value
def finish_distance(board):
h_value = 0
for piece in board.player_1_pieces:
if piece.dead:
h_value = h_value + 1
h_value = h_value + (2 / (board.size - piece.pos[1] + 2 ))
for piece in board.player_2_pieces:
if piece.dead:
h_value = h_value - 1
h_value = h_value - (2 / (piece.pos[0] + 2))
return h_value
def blocks(board):
h_value = 0
for piece1 in board.player_1_pieces:
for piece2 in board.player_2_pieces:
# Direct Block
if (piece1.pos[0] == piece2.pos[0]) and (piece1.pos[1] + 1 == piece2.pos[1]):
if board.turn == 2:
h_value = h_value - 2
else:
h_value = h_value + 2
# Diagonal Ahead
if (piece1.pos[0] - 1 == piece2.pos[0]) and (piece1.pos[1] + 1 == piece2.pos[1]):
if board.turn == 2:
h_value = h_value + 2
else:
h_value = h_value - 2
# Diagonal Block
if (piece1.pos[0] + 1 == piece2.pos[0]) and (piece1.pos[1] + 1 == piece2.pos[1]):
if board.turn == 2:
h_value = h_value + 5
else:
h_value = h_value - 5
return h_value
return lane_blocked(board) + finish_distance(board) + blocks(board)
# Uses the MiniMax Algorithm with AlphaBeta pruning to get the MiniMax value.
def alphabeta(self, board, alpha=float('-inf'), beta=float('inf'), depth=4):
# Terminal node
if depth is 0 or not board.get_valid_moves():
return self.evaluate(board), None
moves = board.get_valid_moves()
# For MAX
if board.turn == 1:
best_val = float('-inf')
best_move = ()
for move in moves:
board_copy = copy.deepcopy(board)
board_copy = self.try_move(board_copy, move)
val = self.alphabeta(board_copy, alpha=alpha, beta=beta, depth=depth-1)[0]
if val > alpha:
alpha = val
if val > best_val:
best_val = val
best_move = move
if alpha > beta:
break
return alpha, best_move
# For MIN
else:
best_val = float('inf')
best_move = ()
for move in moves:
board_copy = copy.deepcopy(board)
board_copy = self.try_move(board_copy, move)
val = self.alphabeta(board_copy, alpha=alpha, beta=beta, depth=depth-1)[0]
if val < beta:
beta = val
if val < best_val:
best_val = val
best_move = move
if alpha > beta:
break
return beta, best_move
# Just to do the move without the prints in the 'framework/Board.py'
# and return the modified board along it as well.
def try_move(self, board, move):
if move not in board.get_valid_moves():
return board
if board.turn == 1:
for piece in board.player_1_pieces:
if piece == move[0]:
piece.pos = move[1]
if move[2] == True:
piece.dead = True
board.turn = 2
return board
elif board.turn == 2:
for piece in board.player_2_pieces:
if piece == move[0]:
piece.pos = move[1]
if move[2] == True:
piece.dead = True
board.turn = 1
return board
if len(board.get_valid_moves()) == 0:
# Other oppoment is blocked by this move
if board.turn == 1:
# Opposite loses
board.turn = 2
return board
elif board.turn == 2:
# Opposite loses
board.turn = 1
return board