【问题标题】:Recursion within Class, Python类中的递归,Python
【发布时间】:2016-02-14 23:25:35
【问题描述】:

我正在尝试创建一个类,该类可以从 Game Tic-Tac-Toe 中为棋盘生成决策树。我正在使用帖子Tic-Tac-Toe: How to populate decision tree? 上用户“ssoler”的评论作为课程的基础,但我认为课程没有工作。一方面,我看不到所有输出,因为使用“...”将它们缩写为空闲。我过去对类和递归的使用也很差。我的目标是将 Minimax 算法和 alpha-beta 修剪应用于类输出的树。

win_comb=((0,1,2),(3,4,5),(6,7,8),(6,3,0),(7,4,1),(8,5,2),(6,4,2),(8,4,0))
Board = [1, 2, 3, 4, 5, 6, 7, 8, 9]
whose_move = 1
child_nodes = []

class Node():
    def __init__(self,Board,win_comb,whose_move, child_nodes):
        self.c_g_s = Board
        self.node = None
        self.new_node = None
        self.child_nodes = child_nodes
        self.win_comb = win_comb
        self.w_m = whose_move

    def create_tree(self):
        for index,each in enumerate(self.c_g_s):
            if each == index + 1:
                self.new_node = self.c_g_s
                if self.w_m == 1:
                    self.new_node[index] = "X"
                    self.w_m = 0
                else:
                    self.new_node[index] = "O"
                    self.w_m = 1
                self.new_node = tuple(self.new_node)
                if self.available_moves():
                    self.new_node = self.c_g_s
                    self.child_nodes.append(self.create_tree())
                else:
                    child_nodes.append(self.new_node)
        if self.child_nodes:
            return [self.node,self.child_nodes]
        return

    def available_moves(self):
        for index, each in enumerate(self.c_g_s):
            if index + 1 == each:
                return False
        return True

n = Node(Board,win_comb,whose_move,child_nodes)


print(n.create_tree())

【问题讨论】:

  • '...' 输出可能是尝试打印递归数据结构的结果。 (我怀疑self.c_g_sself.child_nodes,虽然我还没有真正看过它。)由于打印一个包含自身的结构需要很长时间,Python 的标准类型使用'...' 作为占位符来表示“更多相同这里”。 reprlib.recursive_repr 装饰器允许您将自己的 __repr__ 函数标记为潜在递归,以避免在您自己的容器类型中出现此问题。

标签: python oop recursion tic-tac-toe


【解决方案1】:

我猜你的程序的这种简化会产生你想要的东西,所有可能的板都是一棵树。现在,您可以使用获胜组合列表来显着修剪生成的分支:

winning_combinations = ((0,1,2), (3,4,5), (6,7,8), (6,3,0), (7,4,1), (8,5,2), (6,4,2), (8,4,0))
board = [1, 2, 3, 4, 5, 6, 7, 8, 9]
whose_move = 1

class Node():
    def __init__(self, board, whose_move):
        self.board = board
        self.whose_move = whose_move

    def create_tree(self, board=None, whose_move=None):

        if board is None:
            board = self.board
        if whose_move is None:
            whose_move = self.whose_move

        child_nodes = []

        for index, square in enumerate(board):
            if square == index + 1:  # if square not taken
                new_board = list(board)  # make a shallow copy

                if whose_move == 1:
                    new_board[index] = "X"
                    whose_move = 0
                else:
                    new_board[index] = "O"
                    whose_move = 1

                if self.available_moves(new_board):
                    child_nodes.append(self.create_tree(new_board, whose_move))
                else:
                    child_nodes.append(new_board)
        return child_nodes

    def available_moves(self, board):
        for index, square in enumerate(board):
            if square == index + 1:  # if square not taken
                return True
        return False

node = Node(board, whose_move)

print(node.create_tree())

关键是不要在你的对象中存储你想要临时变异以查看可能发生什么的东西(例如董事会以及轮到谁了)——制作那些局部变量。此外,您的 available_moves() 方法将 True 和 False 颠倒了。

【讨论】:

  • 感谢您的解决方案,您能否再帮我一些忙,因为我目前正在添加一个模块来确定用户是否赢了,但是当我尝试访问我得到的获胜组合时错误“AttributeError: 'list' object has no attribute with 'check_if_won' [检查谁获胜或是否平局的模块]”
  • @Faisal148991,我建议您关闭此问题并发布一个新问题,其中包含您遇到问题的方法、正在处理的数据示例以及您希望返回的内容。您可以包含返回此问题的链接,以获取有关您的问题的更多背景信息。
猜你喜欢
  • 1970-01-01
  • 2019-05-06
  • 2021-07-20
  • 1970-01-01
  • 1970-01-01
  • 2017-02-03
  • 2016-11-15
  • 1970-01-01
相关资源
最近更新 更多