CS50 AI井字棋Minimax算法实现中索引类型错误求助
CS50 AI井字棋作业运行错误排查
我在完成CS50 AI课程的井字棋作业时,需要用Minimax算法实现游戏,同时编写生成可行操作及新棋盘状态的函数,但代码运行时出现以下错误:
File "c:\Users\Melisa\OneDrive\Desktop\tictactoe\tictactoe.py", line 40, in result
kopja[i][j] = player(board)
TypeError: list indices must be integers or slices, not tuple
我尝试将集合中的元组拆分作为棋盘数组的索引(i,j = action[0],action[1]),但该方案未解决问题。
我的实现代码
import copy import math X = "X" O = "O" EMPTY = None def initial_state(): return [[EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY]] def player(board): Xc= 0 Oc= 0 for i in board: for j in i: if j == X: Xc+=1 if j == O: Oc+=1 # 先手为X if Xc>Oc: return O else: return X def actions(board): possible= set() for i in range(0,len(board)): for j in range(len(board[0])): if board[i][j]== EMPTY: possible.add((i,j)) return possible def result(board, action): kopja = copy.deepcopy(board) i,j = action[0],action[1] kopja[i][j] = player(board) return kopja def winner(board): # 手动列举所有获胜情况 # 横向获胜:行索引变化,列索引固定为0、1、2 for e in range(3): if board[e][0]==board[e][1]==board[e][2] and board[e][0] != EMPTY: winneri = board[0][e] # 对角线获胜 if (board[0][0]==board[1][1]==board[2][2] or board[0][2]==board[1][1]==board[2][0])and board[1][1]!=EMPTY: winneri= board[1][1] else: winneri= None return winneri def terminal(board): if winner(board) == X or winner(board) == O: return True for i in range(3): for j in range(3): if board[i][j] == EMPTY: return False return True def utility(board): if winner(board)== X: return 1 if winner(board)== O: return -1 else: return 0 def maxval(board): if terminal(board): return utility(board) else: v = float('-inf') for action in actions(board): v = max(v,minval(result(board,action))) return v def minval(board): if terminal(board): return utility(board) else: v = float('inf') for action in actions(board): v = min(v,maxval(result(board,action))) return v def minimax(board): if terminal(board): return None else: listx=[] if player(board) == X: for action in actions(board): listx.append((minval(result(board,action)),action)) listx.reverse() listi=listx return listi[0] if player(board) == O: listo=[] for action in actions(board): listo.append((maxval(result(board,action)),action)) listo.reverse() lista=listo return lista[0]
课程提供的运行代码
import pygame import sys import time import tictactoe as ttt pygame.init() size = width, height = 600, 400 black = (0, 0, 0) white = (255, 255, 255) screen = pygame.display.set_mode(size) mediumFont = pygame.font.Font("OpenSans-Regular.ttf", 28) largeFont = pygame.font.Font("OpenSans-Regular.ttf", 40) moveFont = pygame.font.Font("OpenSans-Regular.ttf", 60) user = None board = ttt.initial_state() ai_turn = False while True: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() screen.fill(black) # 让用户选择玩家身份 if user is None: # 绘制标题 title = largeFont.render("Play Tic-Tac-Toe", True, white) titleRect = title.get_rect() titleRect.center = ((width / 2), 50) screen.blit(title, titleRect) # 绘制按钮 playXButton = pygame.Rect((width / 8), (height / 2), width / 4, 50) playX = mediumFont.render("Play as X", True, black) playXRect = playX.get_rect() playXRect.center = playXButton.center pygame.draw.rect(screen, white, playXButton) screen.blit(playX, playXRect) playOButton = pygame.Rect(5 * (width / 8), (height / 2), width / 4, 50) playO = mediumFont.render("Play as O", True, black) playORect = playO.get_rect() playORect.center = playOButton.center pygame.draw.rect(screen, white, playOButton) screen.blit(playO, playORect) # 检测按钮点击 click, _, _ = pygame.mouse.get_pressed() if click == 1: mouse = pygame.mouse.get_pos() if playXButton.collidepoint(mouse): time.sleep(0.2) user = ttt.X elif playOButton.collidepoint(mouse): time.sleep(0.2) user = ttt.O else: # 绘制游戏棋盘 tile_size = 80 tile_origin = (width / 2 - (1.5 * tile_size), height / 2 - (1.5 * tile_size)) tiles = [] for i in range(3): row = [] for j in range(3): rect = pygame.Rect( tile_origin[0] + j * tile_size, tile_origin[1] + i * tile_size, tile_size, tile_size ) pygame.draw.rect(screen, white, rect, 3) if board[i][j] != ttt.EMPTY: move = moveFont.render(board[i][j], True, white) moveRect = move.get_rect() moveRect.center = rect.center screen.blit(move, moveRect) row.append(rect) tiles.append(row) game_over = ttt.terminal(board) player = ttt.player(board) # 显示标题 if game_over: winner = ttt.winner(board) if winner is None: title = f"Game Over: Tie." else: title = f"Game Over: {winner} wins." elif user == player: title = f"Play as {user}" else: title = f"Computer thinking..." title = largeFont.render(title, True, white) titleRect = title.get_rect() titleRect.center = ((width / 2), 30) screen.blit(title, titleRect) # AI回合处理 if user != player and not game_over: if ai_turn: time.sleep(0.5) move = ttt.minimax(board) board = ttt.result(board, move) ai_turn = False else: ai_turn = True # 用户回合处理 click, _, _ = pygame.mouse.get_pressed() if click == 1 and user == player and not game_over: mouse = pygame.mouse.get_pos() for i in range(3): for j in range(3): if (board[i][j] == ttt.EMPTY and tiles[i][j].collidepoint(mouse)): board = ttt.result(board, (i, j)) # 游戏结束后显示重玩按钮 if game_over: againButton = pygame.Rect(width / 3, height - 65, width / 3, 50) again = mediumFont.render("Play Again", True, black) againRect = again.get_rect() againRect.center = againButton.center pygame.draw.rect(screen, white, againButton) screen.blit(again, againRect) click, _, _ = pygame.mouse.get_pressed() if click == 1: mouse = pygame.mouse.get_pos() if againButton.collidepoint(mouse): time.sleep(0.2) user = None board = ttt.initial_state() ai_turn = False pygame.display.flip()
内容的提问来源于stack exchange,提问作者melbel
相关产品推荐
相关产品推荐

