1

我有我认为可能只是这个 Python 代码中的一个同步问题。该代码旨在将极小极大算法应用于井字游戏,通过并行进程而不是单个进程来实现,一一探索所有可能的移动。在将其标记为一个非常糟糕的主意之前,我被要求这样做。

假设未知方法确实与他们的名字所暗示的完全一致,并假设它们可以正常工作(它们已经过手动测试)。我不能 100% 确定的唯一方法是这个,这里是代码:

def q_elems(queue):
    li = []
    while not queue.empty(): li.append(queue.get())
    return li

游戏板用一个简单的Board类(扩展list类)表示。 SimpleQueueProcess类是从multiprocessingPython 模块导入的。 H函数是我实现的启发式函数:它返回对玩家 MAX 有利的棋盘正值,对 MIN 返回负值,对平局返回 0。这是算法代码:

def minimax(board: Board, depth: int, turn: int, queue: SimpleQueue) -> int:
     queue.put(10000)

     if is_winning(board) or is_tie(board) or depth == 0:
         queue.put(H(board))
         return

     local_queue = SimpleQueue()

     prcs_list = []
     for child_brd in possible_moves(board, MAX if turn == TURN_MAX else MIN):
         p = Process(target=minimax, args=(
             Board(child_brd),                               # board
             depth - 1,                                      # depth
             TURN_MIN if turn == TURN_MAX else TURN_MAX,     # turn
             local_queue)                                    # queue
             )

         prcs_list.append(p)

     [p.start() for p in prcs_list]
     [p.join() for p in prcs_list]

     # turn was MAX
     if turn == TURN_MAX:
         queue.put(max(q_elems(local_queue)))
         return
     # turn was MIN
     else:
         queue.put(min(q_elems(local_queue)))
         return

主要方法很简单:

k = SimpleQueue()
minimax(b, MINIMAX_DEPTH, turn=TURN_MAX, queue=k)

我经常遇到这种错误:

Traceback (most recent call last):
  File "game.py", line 202, in <module>
    minimax(b, MINIMAX_DEPTH, turn=TURN_MAX, queue=k)
  File "game.py", line 182, in minimax
    queue.put(max(q_elems(local_queue)))
ValueError: max() arg is an empty sequence

但不总是。递归方法有错误吗?我实在想不通。

我的想法是为每一回合建立一个本地队列,然后从该队列中提取最大/最小值,将其带到“上”队列,即前一回合的队列。

4

2 回答 2

1

我怀疑你们中的任何人都在问自己这里的问题出在哪里,但对于未来可能的读者:该方法在传递给它的队列上q_elems执行一个方法,该方法实际上从队列中弹出元素,返回它们但也删除它们从队列中。get

问题解决了。

于 2013-01-26T16:12:50.573 回答
0

因此,从该消息中,听起来 q_elems(local_queue) 正在返回 [],这意味着 local_queue 中没有任何内容。

possible_moves() 是否会返回一个空列表(例如,在棋盘上进行了所有动作之后)?如果 possible_moves 没有产生任何东西,那么您的本地队列中不会有任何东西。

于 2013-01-26T00:03:45.273 回答