Мне нужно создать минимаксную функцию (без использования альфа-бета-обрезки) для платы Connect 4. Функция должна принимать параметры поля и глубины в качестве параметров и возвращать лучший ход и результат в виде кортежа. Моему алгоритму также необходимо точно идентифицировать позиции терминала и назначить им соответствующие значения констант.
Вот код моей эвристики:
P1_WIN_SCORE = 15
P2_WIN_SCORE = -15
DRAW_SCORE = 0
def heuristic(self, board):
cnt1 = 0 #p1 score counter
cnt2 = 0 #p2 score counter
for column in range(board.WIDTH):
for row in range(board.HEIGHT):
# horizontal checks
# 3 in a row checks
try:
if board.board[column][row] == board.board[column][row+1] == board.board[column][row+2]:
if [column][row] == 0:
cnt1 += 3
if [column][row] == 1:
cnt2 -= 3
except IndexError:
pass
# 2 in a row checks
try:
if board.board[column][row] == board.board[column][row+1]:
if [column][row] == 0:
cnt1 += 2
if [column][row] == 1:
cnt2 -= 2
except IndexError:
pass
# 1 in a row checks (works for every direction)
try:
if board.board[column][row] == 0:
cnt1 += 1
elif board.board[column][row] == 1:
cnt2 -= 1
except IndexError:
pass
# vertical checks
# 3 in a row checks
try:
if board.board[column][row] == board.board[column+1][row] == board.board[column+2][row]:
if [column][row] == 0:
cnt1 += 3
if [column][row] == 1:
cnt2 -= 3
except IndexError:
pass
# 2 in a row checks
try:
if board.board[column][row] == board.board[column+1][row]:
if [column][row] == 0:
cnt1 += 2
if [column][row] == 1:
cnt2 -= 2
except IndexError:
pass
# right diagonal up
# 3 in a row checks
try:
if board.board[column][row] == board.board[column+1][row+1] == board.board[column+2][row+2]:
if [column][row] == 0:
cnt1 += 3
if [column][row] == 1:
cnt2 -= 3
except IndexError:
pass
# 2 in a row checks
try:
if board.board[column][row] == board.board[column+1][row+1]:
if [column][row] == 0:
cnt1 += 2
if [column][row] == 1:
cnt2 -= 2
except IndexError:
pass
# right diagonal down
# 3 in a row
try:
if row >= 3 and board.board[column][row] == board.board[column+1][row-1] == board.board[column+2][row-2]:
if [column][row] == 0:
cnt1 += 3
if [column][row] == 1:
cnt2 -= 3
except IndexError:
pass
# 2 in a row
try:
if row >= 3 and board.board[column][row] == board.board[column+1][row-1]:
if [column][row] == 0:
cnt1 += 2
if [column][row] == 1:
cnt2 -= 2
except IndexError:
pass
return cnt1 + cnt2
Вот моя функция, которая находит клеммные колодки:
def isTerminal(self):
for column in range(self.WIDTH):
for row in range(self.HEIGHT):
try: #horizontal checks
if self.board[column][row] == self.board[column][row+1] == self.board[column][row+2] == self.board[column][row+3]:
return self.board[column][row]
except IndexError:
pass
try: #vertical checks
if self.board[column][row] == self.board[column+1][row] == self.board[column+2][row] == self.board[column+3][row]:
return self.board[column][row]
except IndexError:
pass
try: #right diagonal up
if self.board[column][row] == self.board[column+1][row+1] == self.board[column+2][row+2] == self.board[column+3][row+3]:
return self.board[column][row]
except IndexError:
pass
try: #right diagonal down
if row >= 3 and self.board[column][row] == self.board[column+1][row-1] == self.board[column+2][row-2] == self.board[column+3][row-3]:
return self.board[column][row]
except IndexError:
pass
if self.isFull():
return -1
return None
Вот код, который у меня есть до сих пор, я знаю, что мне нужен способ определить лучший столбец для выбора игрока, и я не уверен, как это реализовать ...
def minimax(self, board, depth):
b = board
#score = 0
#move = depth
while depth > 0:
if board.isTerminal() == True or depth == 0:
return heurisitic(b)
else:
if BasePlayer.heuristic(self, b) > score:
score == BasePlayer.heuristic(self, b)
depth -= 1
self.minimax(board, depth)
return (move, score)