# -*- coding:utf-8 -*- import copy # 注意对象的深拷贝和浅拷贝的使用!!! class GameNode: '''博弈树结点数据结构 成员变量: map - list[[]] 二维列表,三子棋盘状态 val - int 该棋盘状态对执x棋子的评估值,1表示胜利,-1表示失败,0表示平局 deepID - int 博弈树的层次深度,根节点deepID=0 parent - GameNode,父结点 children - list[GameNode] 子结点列表 ''' def __init__(self, map, val=0, deepID=0, parent=None, children=[]): self.map = map self.val = val self.deepID = deepID self.parent = parent self.children = children class GameTree: '''博弈树结点数据结构 成员变量: root - GameNode 博弈树根结点 成员函数: buildTree - 创建博弈树 ''' def __init__(self, root): self.root = root # GameNode 博弈树根结点 def buildTree(self, root): '''递归法创建博弈树 参数: root - GameNode 初始为博弈树根结点 ''' #请在这里补充代码,完成本关任务 #********** Begin **********# ##创建root的子节点 ###fuc用来调用判断是否最终状态的函数 mm=MinMax(False) if mm.isTerminal(root): root.val=mm.get_value(root) return ##递归遍历创造新的节点 l=root.map val=0 for i in range(3): for j in range(3): if l[i][j]=='x' or l[i][j]=='o': continue newL=copy.deepcopy(l) newL[i][j]='o' if root.deepID%2>0 else 'x' newNode=GameNode(map=newL,parent=root,deepID=(root.deepID+1),children=[],val=0) root.children.append(newNode) self.buildTree(newNode) if root.deepID%2>0: root.val=mm.min_value(root) else: root.val=mm.max_value(root) #********** End **********# class MinMax: '''博弈树结点数据结构 成员变量: game_tree - GameTree 博弈树 成员函数: minmax - 极大极小值算法,计算最优行动 max_val - 计算最大值 min_val - 计算最小值 get_val - 计算某棋盘状态中:执x棋子的评估值,1表示胜利,-1表示失败,0表示平局 isTerminal - 判断某状态是否为最终状态:无空闲棋可走 ''' def __init__(self, game_tree): self.game_tree = game_tree # GameTree 博弈树 def minmax(self, node): '''极大极小值算法,计算最优行动 参数: node - GameNode 博弈树结点 返回值: clf - list[map] 最优行动,即x棋子的下一个棋盘状态GameNode.map 其中,map - list[[]] 二维列表,三子棋盘状态 ''' #请在这里补充代码,完成本关任务 #********** Begin **********# val=node.val result=[] if val>0: for i in node.children: if i.val==val: result.append(i.map) return result #********** End **********# def max_value(self, node): '''计算最大值 参数: node - GameNode 博弈树结点 返回值: clf - int 子结点中的最大的评估值 ''' #请在这里补充代码,完成本关任务 #********** Begin **********# l=node.children max=-1 for i in node.children: max=i.val if i.val>max else max return max #********** End **********# def min_value(self, node): '''计算最小值 参数: node - GameNode 博弈树结点 返回值: clf - int 子结点中的最小的评估值 ''' #请在这里补充代码,完成本关任务 #********** Begin **********# l=node.children min=1 for i in node.children: min=i.val if i.val0 and l[i][j]!=l[i][0]): isEndI=0 if l[j][i]=='_' or (isEndJ>0 and l[j][i]!=l[0][i]): isEndJ=0 if isEndI+isEndJ<1: break if isEndI>0: return 1 if l[i][0]=='x' else -1 if isEndJ>0: return 1 if l[0][i]=='x' else -1 ##判断斜线上是否存在直线 isEndR=0 if l[0][0]=='_' else 1 isEndL=0 if l[2][0]=='_' else 1 for i in range(3): if l[i][i]=='_' or (isEndR>0 and l[i][i]!=l[0][0]): isEndR=0 if l[2-i][i]=='_' or (isEndL>0 and l[2-i][i]!=l[2][0]): isEndL=0 if isEndR+isEndL<0: break if isEndR>0: return 1 if l[0][0]=='x' else -1 if isEndL>0: return 1 if l[2][0]=='x' else -1 return 0 #********** End **********# def isTerminal(self, node): '''判断某状态是否为最终状态:无空闲棋可走(无子结点) 参数: node - GameNode 博弈树结点 返回值: clf - bool 是最终状态,返回True,否则返回False ''' #请在这里补充代码,完成本关任务 #********** Begin **********# l=node.map ##判断是否还有空位 isFull=1 for i in range(3): for j in range(3): if l[i][j]=='_': isFull=0 break if isFull==0: break if isFull>0: return True isEndI=1 isEndJ=1 ##判断行列上是否存在直线 for i in range(3): isEndI=1 isEndJ=1 for j in range(3): if l[i][j]=='_' or (isEndI>0 and l[i][j]!=l[i][0]): isEndI=0 if l[j][i]=='_' or (isEndJ>0 and l[j][i]!=l[0][i]): isEndJ=0 if isEndI+isEndJ<1: break if isEndI+isEndJ>0: return True ##判断斜线上是否存在直线 isEndR=1 isEndL=1 for i in range(3): if l[i][i]=='_' or (isEndR>0 and l[i][i]!=l[0][0]): isEndR=0 if l[2-i][i]=='_' or (isEndL>0 and l[2-i][i]!=l[0][2]): isEndL=0 if isEndR+isEndL<0: break if isEndR+isEndL>1: return True return False #********** End **********#