質問編集履歴

3

タイトルの変更

2022/12/25 05:07

投稿

FX3XM
FX3XM

スコア0

test CHANGED
@@ -1 +1 @@
1
- アルファベータ法のAIを作ったが,うま動かない
1
+ アルファベータ法のAIを作ったが,MiniMax法と同じ動作ををしてない
test CHANGED
File without changes

2

タグ追加

2022/12/22 08:19

投稿

FX3XM
FX3XM

スコア0

test CHANGED
File without changes
test CHANGED
File without changes

1

プログラムをターミナル上で実行可能にしました.

2022/11/27 09:32

投稿

FX3XM
FX3XM

スコア0

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 board_print(self):
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
- pprint.pprint(self.state)
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
- return board.put(self.player, idx)
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
+