ADD file via upload

master
p9kujf483 2 years ago
parent 542931f452
commit 29bc97ddb2

@ -0,0 +1,235 @@
# -*- 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.val<min else min
return min
#********** End **********#
def get_value(self, node):
'''计算某棋盘状态中执x棋子的评估值1表示胜利-1表示失败0表示平局
参数:
node - GameNode 博弈树结点
返回值:
clf - int 执x棋子的评估值1表示胜利-1表示失败0表示平局
'''
#请在这里补充代码,完成本关任务
#********** Begin **********#
l=node.map
isEndI=1
isEndJ=1
##判断行列上是否存在直线
for i in range(3):
isEndI=0 if l[i][0]=='_' else 1
isEndJ=0 if l[0][i]=='_' else 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>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 **********#
Loading…
Cancel
Save