143 lines
3.1 KiB
Python
143 lines
3.1 KiB
Python
import random
|
|
import game
|
|
|
|
|
|
def chooseRandomMove(board, moves):
|
|
possible_move = []
|
|
for move in moves:
|
|
if game.validMove(board, move):
|
|
possible_move.append(move)
|
|
|
|
if possible_move:
|
|
return random.choice(possible_move)
|
|
|
|
return False
|
|
|
|
|
|
def cornerMove(board):
|
|
return chooseRandomMove(board, [1, 3, 7, 9])
|
|
|
|
|
|
def edgeMove(board):
|
|
return chooseRandomMove(board, [2, 4, 6, 8])
|
|
|
|
|
|
def randomFirstMove(board):
|
|
move = random.randint(1, 3)
|
|
|
|
if move == 1:
|
|
return edgeMove(board)
|
|
|
|
if move == 2:
|
|
return cornerMove(board)
|
|
|
|
if move == 3:
|
|
return 5
|
|
|
|
|
|
def getBoardCopy(board):
|
|
return board[:]
|
|
|
|
|
|
def whichTurn(board):
|
|
turn_count = 0
|
|
for space in board:
|
|
if space == "X" or space == "O":
|
|
turn_count += 1
|
|
|
|
return turn_count + 1
|
|
|
|
|
|
def wentFirst(board):
|
|
x_count = 0
|
|
o_count = 0
|
|
|
|
for space in board:
|
|
if space == "X":
|
|
x_count += 1
|
|
if space == "O":
|
|
o_count += 1
|
|
|
|
if x_count == o_count:
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def testCanWin(board, player, move):
|
|
board_copy = getBoardCopy(board)
|
|
game.makeMove(board_copy, player, move)
|
|
if game.hasWon(board_copy, player):
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def testCanFork(board, player, move):
|
|
board_copy = getBoardCopy(board)
|
|
board_copy[move - 1] = player
|
|
winning_moves = 0
|
|
for i in range(1, 10):
|
|
if game.validMove(board_copy, i) and testCanWin(board_copy, player, i):
|
|
winning_moves += 1
|
|
|
|
return winning_moves >= 2
|
|
|
|
|
|
def getComputerMove(board, player):
|
|
if player == "X":
|
|
opponent = "O"
|
|
else:
|
|
opponent = "X"
|
|
# If Ai goes first, play certain moves
|
|
if whichTurn(board) == 1:
|
|
return randomFirstMove(board)
|
|
|
|
# Check if AI can win with the next move
|
|
for i in range(1, 10):
|
|
if game.validMove(board, i) and testCanWin(board, player, i):
|
|
return i
|
|
|
|
# Check if Player can win with next move, so we can block them
|
|
for i in range(1, 10):
|
|
if game.validMove(board, i) and testCanWin(board, opponent, i):
|
|
return i
|
|
|
|
# Check AI fork moves
|
|
for i in range(1, 10):
|
|
if game.validMove(board, i) and testCanFork(board, player, i):
|
|
return i
|
|
|
|
# Check Player fork moves
|
|
opponent_forks = 0
|
|
for i in range(1, 10):
|
|
if game.validMove(board, i) and testCanFork(board, opponent, i):
|
|
opponent_forks += 1
|
|
temp_move = i
|
|
|
|
if opponent_forks == 1:
|
|
return temp_move
|
|
|
|
if opponent_forks == 2 and wentFirst(board):
|
|
|
|
if board[2 - 1] == player or board[8 - 1] == player:
|
|
return chooseRandomMove(board, [4, 6])
|
|
|
|
if board[4 - 1] == player or board[6 - 1] == player:
|
|
return chooseRandomMove(board, [2, 8])
|
|
|
|
if opponent_forks == 2:
|
|
return edgeMove(board)
|
|
|
|
# Take the center if free
|
|
if game.validMove(board, 5):
|
|
return 5
|
|
|
|
# Take a corner if free
|
|
move = cornerMove(board)
|
|
if move is not False:
|
|
return move
|
|
|
|
# Take a side
|
|
return edgeMove(board)
|