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
|
import random
board = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
wincombs = ((0, 1, 2), (3, 4, 5), (6, 7, 8), (0, 3, 6), (1, 4, 7), (2, 5, 8), (0, 4, 8), (2, 4, 6))
player1 = 'x'
player2 = 'o'
def render(board):
print(f'''
{board[0]} │ {board[1]} │ {board[2]}
───┼───┼───
{board[3]} │ {board[4]} │ {board[5]}
───┼───┼───
{board[6]} │ {board[7]} │ {board[8]}''')
def evaluate(board):
for wincomb in wincombs:
if board[wincomb[0]] == board[wincomb[1]] == board[wincomb[2]] == player1:
return 1
if board[wincomb[0]] == board[wincomb[1]] == board[wincomb[2]] == player2:
return -1
if all(cell in {player1, player2} for cell in board):
return 0
def askmove(board):
for _ in range(3): # 3 attempts
userinput = input('\nWhere do you want to place your x? > ')
if userinput in {'1', '2', '3', '4', '5', '6', '7', '8', '9'}:
idx = int(userinput) - 1
if board[idx] not in {player1, player2}:
return idx
print('\nInvalid input')
return askmove(board)
exit(0)
def emptycells(board):
for cell in board:
if cell not in {player1, player2}:
yield cell
def checkposition(board):
eval = evaluate(board)
if eval is not None:
render(board)
if eval == 0:
print('\nDRAW\n')
if eval == 1:
print(f'\n{player1} won the game!\n')
if eval == -1:
print(f'\n{player2} won the game!\n')
exit(0)
def minimax(board, ismax, alpha = -float('inf'), beta = float('inf')):
eval = evaluate(board)
if eval is not None:
return eval
if ismax:
bestvalue = -float('inf')
for cell in emptycells(board):
idx = int(cell) - 1
board[idx] = player1
minimaxvalue = minimax(board, False, alpha, beta)
board[idx] = cell
if minimaxvalue > bestvalue:
bestvalue = minimaxvalue
alpha = max(alpha, bestvalue)
if alpha >= beta:
break
else:
bestvalue = float('inf')
for cell in emptycells(board):
idx = int(cell) - 1
board[idx] = player2
minimaxvalue = minimax(board, True, alpha, beta)
board[idx] = cell
if minimaxvalue < bestvalue:
bestvalue = minimaxvalue
beta = min(beta, bestvalue)
if alpha >= beta:
break
return bestvalue
def bestmoves(board, ismax):
bestmovelist = []
if ismax:
bestvalue = -float('inf')
for cell in emptycells(board):
idx = int(cell) - 1
board[idx] = player1
minimaxvalue = minimax(board, False)
board[idx] = cell
if minimaxvalue == bestvalue:
bestmovelist.append(cell)
elif minimaxvalue > bestvalue:
bestvalue = minimaxvalue
bestmovelist = [cell]
else:
bestvalue = float('inf')
for cell in emptycells(board):
idx = int(cell) - 1
board[idx] = player2
minimaxvalue = minimax(board, True)
board[idx] = cell
if minimaxvalue == bestvalue:
bestmovelist.append(cell)
elif minimaxvalue < bestvalue:
bestvalue = minimaxvalue
bestmovelist = [cell]
return bestmovelist
import time
if __name__ == '__main__':
while True:
starttime = time.time()
bestmoves_list = bestmoves(board, False)
computermove = random.choice(bestmoves_list)
exectime = time.time() - starttime
print('exectime >', exectime)
input()
render(board)
usermove = askmove(board)
board[usermove] = player1
checkposition(board)
bestmoves_list = bestmoves(board, False)
computermove = random.choice(bestmoves_list)
idx = int(computermove) - 1
board[idx] = player2
checkposition(board)
|