-
Notifications
You must be signed in to change notification settings - Fork 0
/
players.py
100 lines (91 loc) · 3.98 KB
/
players.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
import copy
from gameboard import GameBoard
class Player:
def __init__(self, val):
self.val = val
# Deprecated - make a move using the console input
def makeMoveConsole(self, board):
move = self.getInput()
move_is_valid = board.isValidMove(move[0], move[1])
while not move_is_valid:
print("Invalid input - try again")
move = self.getInput()
move_is_valid = board.isValidMove(move[0], move[1])
board.playpiece(move[0], move[1], self.val)
# Makes a move on the board using positions provided
def make_move_explicit(self, board, move):
move_is_valid = board.isValidMove(move[0], move[1])
while not move_is_valid:
print("Invalid input - try again")
return -1
board.playpiece(move[0], move[1], self.val)
# Minimax algorithm, returns a score for the best move on the board depending on if maximizer or minimizer
def minimax(self, board, depth, is_maximizer):
# If x wins
if board.check_game_won() == "X":
return -1
# If o wins
if board.check_game_won() == "O":
return 1
# If it's a tie
if not board.movesRemaining():
return 0
# If maximizing
if is_maximizer:
# Initialise best val to a low number
best_val = -10000
# For each move
for cols in range(3):
for rows in range(3):
if board.isValidMove(cols, rows):
board.playpiece(cols, rows, "O")
# Call minimax recursively
best_val = max(best_val, self.minimax(board, depth + 1, not is_maximizer))
board.playpiece(cols, rows, "")
return best_val
else: # If minimizing
# Initialise best val to a high number
best_val = 10000
# For each move
for cols in range(3):
for rows in range(3):
if board.isValidMove(cols, rows):
board.playpiece(cols, rows, "X")
# Call minimax recursively
best_val = min(best_val, self.minimax(board, depth + 1, not is_maximizer))
board.playpiece(cols, rows, "")
return best_val
# Get the ai to make a move using minimax
def make_move_ai(self, board):
best_move = -1, -1
if self.val == "O":
best_val = -1000
for cols in range(3):
for rows in range(3):
if board.isValidMove(cols, rows):
temp_board = GameBoard()
temp_board.board = copy.deepcopy(board.board)
temp_board.playpiece(cols, rows, self.val)
move_val = self.minimax(temp_board, 0, False)
if move_val > best_val:
best_val = move_val
best_move = cols, rows
else:
best_val = 1000
for cols in range(3):
for rows in range(3):
if board.isValidMove(cols, rows):
temp_board = GameBoard()
temp_board.board = copy.deepcopy(board.board)
temp_board.playpiece(cols, rows, self.val)
move_val = self.minimax(temp_board, 0, True)
if move_val < best_val:
best_val = move_val
best_move = cols, rows
print("Player " + self.val + ": Minimax Score = " + str(best_val) + " - Optimal move = " + str(best_move))
board.playpiece(best_move[0], best_move[1], self.val)
# Deprecated - Get the user input from the console
def getInput(self):
col = input("Player " + self.val + " - Enter column: ")
row = input("Player " + self.val + " - Enter row: ")
return int(col), int(row)