类内递归,Python

类内递归,Python,python,oop,recursion,tic-tac-toe,Python,Oop,Recursion,Tic Tac Toe,我正在尝试创建一个类,该类从游戏Tic-Tac-Toe为棋盘生成决策树。我使用用户“ssoler”在帖子上的评论作为该课程的基础,但我认为该课程不起作用。首先,我不能看到所有的输出,因为idle使用“…”来缩写它们。此外,我过去对类和递归的使用也很差。我的目标是对类输出的树应用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

我正在尝试创建一个类,该类从游戏Tic-Tac-Toe为棋盘生成决策树。我使用用户“ssoler”在帖子上的评论作为该课程的基础,但我认为该课程不起作用。首先,我不能看到所有的输出,因为idle使用“…”来缩写它们。此外,我过去对类和递归的使用也很差。我的目标是对类输出的树应用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())

我猜这个程序的简化会产生你想要的,所有可能的电路板都是一棵树。现在,您可以使用您的获胜组合列表在生成分支时对其进行大幅修剪:

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())

关键是不要在你的对象中存储你想临时改变的东西,以观察可能发生的事情(例如,董事会和轮到谁了)——制作这些局部变量。另外,您可用的_moves()方法的True和False是相反的。

我猜您的程序的这种简化会生成您想要的,所有可能的电路板都是一棵树。现在,您可以使用您的获胜组合列表在生成分支时对其进行大幅修剪:

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())

关键是不要在你的对象中存储你想临时改变的东西,以观察可能发生的事情(例如,董事会和轮到谁了)——制作这些局部变量。另外,您可用的\u moves()方法的正确和错误被颠倒了。

谢谢您提供的解决方案,您能帮我多一点吗,因为我目前正在添加一个模块,该模块可以确定用户是否赢了。但是,当我尝试访问赢的组合时,我发现了错误“AttributeError:'list'对象没有带有'check_if_won'的属性[检查谁赢了或是否是平局的模块]“@Faisal148991,我建议你结束这个问题,发布一个新的问题,包括你遇到问题的方法、它正在处理的数据示例以及你希望返回的内容。您可以包含一个返回到此问题的链接,以获取有关您问题的其他背景信息。感谢您提供的解决方案,您是否可以帮助我多一点,因为我目前正在添加一个模块,该模块可以确定用户是否已赢,但当我尝试访问获胜组合时,我会发现错误“AttributeError:'list'对象没有带有'check_if_won'的属性[检查谁赢了或是否是平局的模块]“@Faisal148991,我建议你结束这个问题,发布一个新的问题,包括你遇到问题的方法、它正在处理的数据示例以及你希望返回的内容。您可以包含一个返回到此问题的链接,以获取有关问题的其他背景信息。
“…”
输出可能是尝试打印递归数据结构的结果。(我怀疑
self.c_g_s
self.child_节点
,尽管我还没有真正研究过它。)由于打印包含自身的结构会花费很长时间,Python的标准类型使用
“…”
作为占位符来表示“此处更多相同的内容”。decorator允许您将自己的
\uuuu repr\uuu
函数标记为可能的递归函数,以避免在自己的容器类型中出现此问题。
'…'
输出可能是尝试打印递归数据结构的结果。(我怀疑
self.c_g_s
self.child_节点
,尽管我还没有真正研究过它。)由于打印包含自身的结构会花费很长时间,Python的标准类型使用
“…”
作为占位符来表示“此处更多相同的内容”。decorator允许您将自己的
\uuu repr\uu
函数标记为可能的递归函数,以避免在自己的容器类型中出现此问题。