質問編集履歴
3
タイトルの変更
test
CHANGED
@@ -1 +1 @@
|
|
1
|
-
アルファベータ法のAIを作ったが,
|
1
|
+
アルファベータ法のAIを作ったが,MiniMax法と同じ動作ををしてくれない
|
test
CHANGED
File without changes
|
2
タグ追加
test
CHANGED
File without changes
|
test
CHANGED
File without changes
|
1
プログラムをターミナル上で実行可能にしました.
test
CHANGED
File without changes
|
test
CHANGED
@@ -58,8 +58,11 @@
|
|
58
58
|
## AlphaBeta(該当のソースコード)
|
59
59
|
```Python
|
60
60
|
def alphabeta(board, player, depth, alpha, beta):
|
61
|
+
# print("depth = ",depth)
|
61
62
|
maximize_player = 0
|
62
63
|
minimize_player = 1
|
64
|
+
|
65
|
+
# print(depth)
|
63
66
|
|
64
67
|
if board.is_win(maximize_player):
|
65
68
|
return (1, None)
|
@@ -72,25 +75,18 @@
|
|
72
75
|
opp = 1 if player == 0 else 0
|
73
76
|
|
74
77
|
if player == maximize_player:
|
75
|
-
max_score = float('-inf')
|
76
|
-
max_idx = None
|
77
78
|
for put in board.valid_puts():
|
78
79
|
score, next_idx = alphabeta(board.board_result(put), opp, depth-1, alpha, beta)
|
79
80
|
alpha = max(alpha, score)
|
80
81
|
if alpha >= beta:
|
81
|
-
|
82
82
|
break
|
83
83
|
next_idx = put
|
84
84
|
return alpha, next_idx
|
85
85
|
|
86
86
|
else:
|
87
87
|
for put in board.valid_puts():
|
88
|
-
min_score = float('inf')
|
89
|
-
min_idx = None
|
90
|
-
# print(put, len(board.valid_puts()))################
|
91
88
|
score, next_idx = alphabeta(board.board_result(put), opp, depth-1, alpha, beta)
|
92
89
|
beta = min(beta, score)
|
93
|
-
# print(beta, next_idx) #############
|
94
90
|
if alpha <= beta:
|
95
91
|
break
|
96
92
|
next_idx = put
|
@@ -104,8 +100,19 @@
|
|
104
100
|
self.state = [-1] * 9 #置かれている種類(O or X)
|
105
101
|
self.count = 0
|
106
102
|
|
107
|
-
def
|
103
|
+
def render(self):
|
104
|
+
MARKS = {0: 'X', 1: 'O'}
|
105
|
+
text = """
|
106
|
+
0|1|2
|
107
|
+
-----
|
108
|
+
3|4|5
|
109
|
+
-----
|
110
|
+
6|7|8
|
111
|
+
"""
|
108
|
-
|
112
|
+
for idx, x in enumerate(self.state):
|
113
|
+
if x is not -1:
|
114
|
+
text = text.replace(str(idx), MARKS[x]) # 4 -> X
|
115
|
+
print(text)
|
109
116
|
|
110
117
|
def put(self, player, idx):
|
111
118
|
if self.state[idx] != -1 or (not(0 <= idx <= 8)):
|
@@ -185,10 +192,95 @@
|
|
185
192
|
|
186
193
|
## NPCクラス
|
187
194
|
```Python
|
195
|
+
|
196
|
+
def minimax(board, player):
|
197
|
+
maximize_player = 0
|
198
|
+
minimize_player = 1
|
199
|
+
|
200
|
+
if board.is_win(maximize_player):
|
201
|
+
return (1, None)
|
202
|
+
elif board.is_win(minimize_player):
|
203
|
+
return (-1, None)
|
204
|
+
elif board.is_end():
|
205
|
+
return (0, None)
|
206
|
+
|
207
|
+
opp = 1 if player == 0 else 0
|
208
|
+
|
209
|
+
if player == maximize_player:
|
210
|
+
max_score = float('-inf')
|
211
|
+
max_idx = None
|
212
|
+
|
213
|
+
for idx in board.valid_puts():
|
214
|
+
board.put(player, idx)
|
215
|
+
score, next_idx = minimax(board, opp)
|
216
|
+
if max_score < score:
|
217
|
+
max_score = score
|
218
|
+
max_idx = idx
|
219
|
+
board.take(idx)
|
220
|
+
|
221
|
+
return (max_score, max_idx)
|
222
|
+
else:
|
223
|
+
min_score = float('inf')
|
224
|
+
min_idx = None
|
225
|
+
|
226
|
+
for idx in board.valid_puts():
|
227
|
+
board.put(player, idx)
|
228
|
+
score, next_idx = minimax(board, opp)
|
229
|
+
if min_score > score:
|
230
|
+
min_score = score
|
231
|
+
min_idx = idx
|
232
|
+
board.take(idx)
|
233
|
+
|
234
|
+
return (min_score, min_idx)
|
235
|
+
|
236
|
+
def alphabeta(board, player, depth, alpha, beta):
|
237
|
+
# print("depth = ",depth)
|
238
|
+
maximize_player = 0
|
239
|
+
minimize_player = 1
|
240
|
+
|
241
|
+
# print(depth)
|
242
|
+
|
243
|
+
if board.is_win(maximize_player):
|
244
|
+
return (1, None)
|
245
|
+
elif board.is_win(minimize_player):
|
246
|
+
return (-1, None)
|
247
|
+
elif board.is_end() or depth == 0:
|
248
|
+
return (0, None)
|
249
|
+
|
250
|
+
|
251
|
+
opp = 1 if player == 0 else 0
|
252
|
+
|
253
|
+
if player == maximize_player:
|
254
|
+
for put in board.valid_puts():
|
255
|
+
score, next_idx = alphabeta(board.board_result(put), opp, depth-1, alpha, beta)
|
256
|
+
alpha = max(alpha, score)
|
257
|
+
if alpha >= beta:
|
258
|
+
break
|
259
|
+
next_idx = put
|
260
|
+
return alpha, next_idx
|
261
|
+
|
262
|
+
else:
|
263
|
+
for put in board.valid_puts():
|
264
|
+
score, next_idx = alphabeta(board.board_result(put), opp, depth-1, alpha, beta)
|
265
|
+
beta = min(beta, score)
|
266
|
+
if alpha <= beta:
|
267
|
+
break
|
268
|
+
next_idx = put
|
269
|
+
return beta, next_idx
|
270
|
+
|
271
|
+
class MiniMax:
|
272
|
+
def __init__(self, player):
|
273
|
+
self.player = player
|
274
|
+
|
275
|
+
def play(self, board):
|
276
|
+
score, idx = minimax(board, self.player, )
|
277
|
+
return board.put(self.player,idx), idx
|
278
|
+
|
188
279
|
class AplhaBeta:
|
189
280
|
def __init__(self , player):
|
190
281
|
self.player = player
|
282
|
+
self.depth = float('inf')
|
191
|
-
self.depth = 5
|
283
|
+
# self.depth = 5
|
192
284
|
|
193
285
|
def play(self, board):
|
194
286
|
score ,idx = alphabeta(board, self.player, self.depth, float('-inf'), float('inf'))
|
@@ -198,12 +290,47 @@
|
|
198
290
|
|
199
291
|
## Playerクラス
|
200
292
|
```Python
|
201
|
-
class Player:
|
293
|
+
class HumanPlayer:
|
202
294
|
def __init__(self, player):
|
203
295
|
self.player = player
|
204
|
-
|
296
|
+
|
205
297
|
def play(self, board):
|
298
|
+
while True:
|
299
|
+
print('0~8の数字を入力してください:', end="")
|
206
|
-
idx = input()
|
300
|
+
idx = input()
|
301
|
+
|
302
|
+
try:
|
303
|
+
idx = int(idx)
|
207
|
-
|
304
|
+
success = board.put(self.player, idx)
|
305
|
+
if success:
|
306
|
+
break
|
307
|
+
else:
|
308
|
+
print("適切な数字を入力してください")
|
309
|
+
except ValueError:
|
310
|
+
pass
|
208
|
-
```
|
311
|
+
```
|
312
|
+
|
209
|
-
|
313
|
+
## Main
|
314
|
+
```Python
|
315
|
+
import Board
|
316
|
+
import NPC
|
317
|
+
import PLAYER
|
318
|
+
|
319
|
+
board = Board()
|
320
|
+
players = [NPC.AplhaBeta(0), PLAYER.HumanPlayer(1)]
|
321
|
+
player = 0 # 0 or 1
|
322
|
+
|
323
|
+
while True:
|
324
|
+
p = players[player]
|
325
|
+
p.play(board)
|
326
|
+
board.render()
|
327
|
+
|
328
|
+
if board.is_win(player):
|
329
|
+
break
|
330
|
+
elif board.is_end():
|
331
|
+
print("引き分け")
|
332
|
+
break
|
333
|
+
|
334
|
+
player = 1 if player == 0 else 0
|
335
|
+
```
|
336
|
+
|