在 Reversi (Python) 中为计算机创建有效移动的列表



我对编程比较陌生,所以请原谅这里缺乏优雅的代码。 该程序变得有点复杂,但我已经到了想要完成它并看到结果的地步。 无论如何,在这个函数中,我正在尝试为计算机创建一个有效移动的列表。

  • 板是一个由 64 个两个项目列表组成的列表,每个项目列表代表一个位置逆转板
  • 玩家
  • 是玩家的棋子,可以是"X"或"O"(在程序的前面确定)
  • 计算机
  • 是计算机的碎片,恰恰相反

第一步是收集板上当前空白的所有点(valid_list)。 接下来,我尝试遍历每个点,看看是否有任何相邻的点是玩家的棋子。 如果是,我想收集所有点,以便在同一行(或列)中有另一台计算机。 代码对我来说似乎很有意义,但它给了我意想不到的结果。 我只是想知道是否有人能猜到导致奇怪结果的原因(valid_list1列表)。

def comp_move(board, player, computer):
    valid_list = []
    for xcoord in range(8):
        for ycoord in range(8):
            if board[xcoord][ycoord] == ' ':
                valid_list.append([xcoord, ycoord])
    copy = getCopy(board)
    num_list = [-1,0,1,-1,1,-1,0,1]
    num_list2 = [-1,-1,-1,0,0,1,1,1]
    for num in range(8):
        for i in range(len(valid_list)):
            xcoord_orig = valid_list[i][0]
            ycoord_orig = valid_list[i][1]
            xcoord1 = valid_list[i][0] + num_list[num]
            ycoord1 = valid_list[i][1] + num_list2[num]
            #test to see whether any of the surrounding spots are occupied by the player's piece
            if 0 <= xcoord1 <= 7 and 0 <= ycoord1 <= 7:
                piece = board[xcoord1][ycoord1]
                if piece == player:
                    move_list = []
                    move_list1 = []
                    move_list2 = []
                    move_list3 = [] 
                    move_list4 = []
                    move_list5 = []
                    move_list6 = []
                    move_list7 = []
                    valid_list1 = []
                    #I changed the beginning of the range to 2 because we already know that the adjacent piece is the player's piece
                    #test spots above
                    for i in range(2,8):
                        #iterate through spots above the computer's spot.
                        #create a list of all the spots above the computer's spot
                        xcoordT = xcoord_orig
                        ycoordT = ycoord_orig - i
                        if 0 <= ycoordT <= 7:
                            if board[xcoordT][ycoordT] == computer:
                                move_list.append([xcoordT, ycoordT])
                    if move_list:
                        valid_list1.append([xcoord_orig, ycoord_orig])

                    #Test spots below
                    for i in range(2,8):
                        xcoordB = xcoord_orig
                        ycoordB = ycoord_orig + i
                        if 0 <= ycoordB <= 7:
                            if board[xcoordB][ycoordB] == computer:
                                move_list1.append([xcoordB, ycoordB])
                    if move_list1:
                        valid_list1.append([xcoord_orig, ycoord_orig])
                    #Test spots to the right
                    for i in range(2,8):
                        xcoordR = xcoord_orig + i
                        ycoordR = ycoord_orig
                        if 0 <= xcoordR <= 7:                           
                            if board[xcoordR][ycoordR] == computer:
                                move_list2.append([xcoordR, ycoordR])
                    if move_list2:
                        valid_list1.append([xcoord_orig, ycoord_orig])
                    #Test spots to the left
                    for i in range(2,8):
                        xcoordL = xcoord_orig - i
                        ycoordL = ycoord_orig
                        if 0 <= xcoordL <= 7:
                            if board[xcoordL][ycoordL] == computer:
                                move_list3.append([xcoordL, ycoordL])
                    if move_list3:
                        valid_list1.append([xcoord_orig, ycoord_orig])

                    #Test upper-right diagonal spots  
                    for i in range(2,8):
                        xcoordTD = xcoord_orig + i
                        ycoordTD = ycoord_orig - i
                        if 0 <= xcoordTD <= 7 and 0 <= ycoordTD <= 7:
                            if board[xcoordTD][ycoordTD] == computer:
                                move_list4.append([xcoordTD, ycoordTD])
                    if move_list4:
                        valid_list1.append([xcoord_orig, ycoord_orig])

                    #Test lower-right diagonal spots
                    for i in range(2,8):
                        xcoordBD = xcoord_orig + i
                        ycoordBD = ycoord_orig + i
                        if 0 <= xcoordBD <= 7 and 0 <= ycoordBD <= 7:
                            if board[xcoordBD][ycoordBD] == computer:
                                move_list5.append([xcoordBD, ycoordBD])
                    if move_list5:
                        valid_list1.append([xcoord_orig, ycoord_orig])
                    #Test upper-left diagonal spots
                    for i in range(2,8):
                        xcoordTD1 = xcoord_orig - i
                        ycoordTD1 = ycoord_orig - i
                        if 0 <= xcoordTD1 <= 7 and 0 <= ycoordTD1 <= 7:
                            if board[xcoordTD1][ycoordTD1] == computer:
                                move_list6.append([xcoordTD1, ycoordTD1])
                    if move_list6:
                        valid_list1.append([xcoord_orig, ycoord_orig])
                    #Test lower-left diagal spots
                    for i in range(2,8):
                        xcoordBD1 = xcoord_orig - i
                        ycoordBD1 = ycoord_orig + i
                        if 0 <= xcoordBD1 <= 7 and 0 <= ycoordBD1 <= 7:
                            if board[xcoordBD1][ycoordBD1] == computer:
                                move_list7.append([xcoordBD1, ycoordBD1])
                    if move_list7:
                        valid_list1.append([xcoord_orig, ycoord_orig])

我无法从您的问题中完全弄清楚,但是从您的代码来看,您的valid_list1似乎将充满包含所有相同值(计算机的原始坐标)的列表。我不认为这是你想要的。

如果您将if move_listi:语句(其中 i 是move_list数)替换为 valid_list1 += move_listi

例如:

# if move_list:  -- REMOVE THESE LINES
#     valid_list1.append([xcoord_orig, ycoord_orig])
valid_list1 += move_list
...
# if move_list1: -- REMOVE THESE LINES
#     valid_list1.append([xcoord_orig, ycoord_orig])
valid_list1 += move_list1
...
# Repeat for move_list2 - move_list7

同样,我不完全确定这就是你要问的。如果不是,请告诉我。valid_list1将包含与原始计算机片段视线范围内有计算机部件的所有位置的列表。

我喜欢将 othello 板表示为 10x10,边缘周围有一排空方块。然后,不要使用 x 和 y 坐标,而是将位置表示为单个值 P=Y*10+x,其中 x 和 y 从 0 到 9。然后,您的num_list和 numlist2 变成一个方向值 dir=[-11,-10,-9,-1,1,9,10,11] 代表 8 个方向的列表。您可以通过查看电路板[p+dir[d]*距离]从位置p扫描电路板。现在 Python 没有数组,查看列表的第 N 项可能不是最有效的方法,但无论你在 2D 中做什么,在 1D 中都会变得更简单。 顺便说一句,因为你总是在扫描相邻或对角线的正方形,而你只看下一个正方形被对手的棋子或你自己的棋子占据, 循环自然会在空方块的边界处终止,你永远不必检查你是否跑出了棋盘的边缘。这并不能解决您的特定实现问题,但此实现将更容易调试:-)

import numpy
def ai_player(board, scores, turn, valid_moves):
    """
    Input:
        board: numpy array of the disks for each player, e.g.
               [[0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 1, 2, 0, 0, 0],
                [0, 0, 0, 2, 1, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0]]
               - 0 empty locations
               - 1 player 1's disks
               - 2 player 2's disks
        scores: list of score values - [0, 0]
        turn: integer turn counter (starts from 1)
        valid_moves: numpy array of valid disk locations, represented in row
                     column combinations:
                     e.g [[3, 5],   # row 3 - col 5
                          [5, 3],   # row 5 - col 3
                          [4, 2],   # etc.
                          [3, 4]]
    Return:
        disk loction index --> a numpy array or a list
                           --> a valid row - col combination to place a disk
                           --> location must be empty
                           --> location must have flanks
        e.g. if valid_moves = [[3, 5],   # row 3 - col 5
                               [5, 3],   # row 5 - col 3
                               [4, 2],   # etc.
                               [3, 4]]
             and you want to place a disk at location row 4, col 2 then you
             need to return [4, 2]
"""
您如何编程,知道

您有四个输入,或者如果您想如何在其他输入中编程以获得最佳valid_moves。

最新更新