极大极小法
# -*- 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=[],child=[]):
self.map = map
self.val = val
self.deepID = deepID
self.parent = parent
self.children = children
self.child = child
class GameTree:
'''博弈树结点数据结构
成员变量:
root - GameNode 博弈树根结点
成员函数:
buildTree - 创建博弈树
'''
def __init__(self, root):
self.root = root # GameNode 博弈树根结点
def buildTree(self, root):
'''递归法创建博弈树
参数:
root - GameNode 初始为博弈树根结点
'''
# 请在这里补充代码,完成本关任务
# ********** Begin **********#
if root.deepID > 5:
return
# 精华
map = copy.deepcopy(root.map)
for i in range(0,3):
for j in range(0,3):
if(map[i][j] == '_' or map[i][j] == ' '):
if root.deepID % 2 == 0:
map[i][j] = 'x'
node = GameNode(copy.deepcopy(map),deepID=root.deepID+1,parent=root,children=[],val=0,child=[])
root.children.append(node)
self.buildTree(node)
if len(node.children) == 0:
node.val = self.get_value(node)
map[i][j] = '_'
else:
map[i][j] = 'o'
node = GameNode(copy.deepcopy(map),deepID=root.deepID+1,parent=root,children=[],val=0,child=[])
root.children.append(node)
self.buildTree(node)
if len(node.children) == 0:
node.val = self.get_value(node)
map[i][j] = '_'
# ********** End **********#
def get_value(self, node):
'''计算某棋盘状态中:执x棋子的评估值,1表示胜利,-1表示失败,0表示平局
参数:
node - GameNode 博弈树结点
返回值:
clf - int 执x棋子的评估值,1表示胜利,-1表示失败,0表示平局
'''
# 请在这里补充代码,完成本关任务
# ********** Begin **********#
for i in range(0, 3):
if node.map[i][0] == node.map[i][1] == node.map[i][2]:
if node.map[i][0] == 'x':
return 1
else:
return -1
for i in range(0, 3):
if node.map[0][i] == node.map[0][i] == node.map[0][i] == 'x':
if node.map[0][i] == 'x':
return 1
else:
return -1
if node.map[0][0] == node.map[1][1] == node.map[2][2]:
if node.map[0][0] == 'x':
return 1
else:
return -1
if node.map[2][0] == node.map[1][1] == node.map[0][2]:
if node.map[2][0] == 'x':
return 1
else:
return -1
return 0
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 **********#
if len(node.children) != 0:
for n in node.children:
self.minmax(n)
if node.deepID % 2 == 0:
node.child,node.val = self.max_value(node)
# if child != None:
# node.child.append(child.map)
# else:
# node.child = []
else:
node.child,node.val = self.min_value(node)
# if child != None:
# print(child.map)
# node.child.append(child.map)
# else:
# node.child = []
if node.deepID == 0:
# print(child.map)
ans_list = []
for n in self.game_tree.root.child:
ans_list.append(n.map)
return ans_list
# ********** End **********#
def max_value(self, node):
'''计算最大值
参数:
node - GameNode 博弈树结点
返回值:
clf - int 子结点中的最大的评估值
'''
# 请在这里补充代码,完成本关任务
# ********** Begin **********#
max = -2
max_list = []
for n in node.children:
if self.get_value(n) >= max:
max = self.get_value(n)
for n in node.children:
if n.val == max:
max_list.append(n)
return max_list,max
# ********** End **********#
def min_value(self, node):
'''计算最小值
参数:
node - GameNode 博弈树结点
返回值:
clf - int 子结点中的最小的评估值
'''
# 请在这里补充代码,完成本关任务
# ********** Begin **********#
min_list = []
min = 100000
for n in node.children:
if self.get_value(n) <= min:
min = self.get_value(n)
for n in node.children:
if n.val == min:
min_list.append(n)
return min_list,min
# ********** End **********#
def get_value(self, node):
'''计算某棋盘状态中:执x棋子的评估值,1表示胜利,-1表示失败,0表示平局
参数:
node - GameNode 博弈树结点
返回值:
clf - int 执x棋子的评估值,1表示胜利,-1表示失败,0表示平局
'''
# 请在这里补充代码,完成本关任务
# ********** Begin **********#
for i in range(0,3):
if node.map[i][0] == node.map[i][1] == node.map[i][2]:
if node.map[i][0] == 'x':
return 1
else:
return -1
for i in range(0, 3):
if node.map[0][i] == node.map[0][i] == node.map[0][i] == 'x':
if node.map[0][i] == 'x':
return 1
else:
return -1
if node.map[0][0] == node.map[1][1] == node.map[2][2]:
if node.map[0][0] == 'x':
return 1
else:
return -1
if node.map[2][0] == node.map[1][1] == node.map[0][2]:
if node.map[2][0] == 'x':
return 1
else:
return -1
return 0
# ********** End **********#
def isTerminal(self, node):
'''判断某状态是否为最终状态:无空闲棋可走(无子结点)
参数:
node - GameNode 博弈树结点
返回值:
clf - bool 是最终状态,返回True,否则返回False
'''
# 请在这里补充代码,完成本关任务
# ********** Begin **********#
for i in range(0,3):
for j in range(0,3):
if map[i][j] == '_':
return True
return False
# ********** End **********#
# -*- coding:utf-8 -*-
def printtree(list_,root, closed):
if len(list_) == 0:
return
print("----这是第{}层------".format(root.deepID))
for i in range(0,3):
for j in range(0,3):
print(root.map[i][j],end="")
print("\n")
print("\n")
list_.remove(root)
closed.append(root)
for node in root.children:
if node not in closed:
list_.append(node)
if(len(list_) != 0):
printtree(list_,list_[0],closed)
阿尔法-白塔剪枝法
import copy # 注意对象的深拷贝和浅拷贝的使用!!!
class GameNode:
'''博弈树结点数据结构
成员变量:
name - string 结点名字
val - int 结点值
children - list[GameNode] 子结点列表
'''
def __init__(self, name='', val=0):
self.name = name # char
self.val = val # int
self.children = [] # list of nodes
class GameTree:
'''博弈树结点数据结构
成员变量:
root - GameNode 博弈树根结点
成员函数:
buildTree - 创建博弈树
'''
def __init__(self):
self.root = None # GameNode 博弈树根结点
def buildTree(self, data_list, root):
'''递归法创建博弈树
参数:
data_list - list[] like this ['A', ['B', ('E', 3), ('F', 12)], ['C', ('H', 2)], ['D', ('K', 14)]]
root - GameNode
'''
#请在这里补充代码,完成本关任务
#********** Begin **********#
for i in range(1,len(data_list)):
if type(data_list[i])==list:
root.children.append(GameNode(data_list[i][0]))
self.buildTree(data_list[i],root.children[i-1])
else:
root.children.append(GameNode(data_list[i][0],data_list[i][1]))
#********** End **********#
class AlphaBeta:
'''博弈树结点数据结构
成员变量:
game_tree - GameTree 博弈树
成员函数:
minmax_with_alphabeta - 带AlphaBeta剪枝的极大极小值算法,计算最优行动
max_value - 计算最大值
min_value - 计算最小值
get_value - 返回结点的值
isTerminal - 判断某结点是否为最终结点
'''
def __init__(self, game_tree):
self.game_tree = game_tree # GameTree 博弈树
def minmax_with_alphabeta(self, node):
'''带AlphaBeta剪枝的极大极小值算法,计算最优行动
参数:
node - GameNode 博弈树结点
返回值:
clf - GameNode 最优行动的结点
'''
#请在这里补充代码,完成本关任务
#********** Begin **********#
clf=self.max_value(node,-10000,10000)
for child in node.children:
if child.val==clf:
return child;
#********** End **********#
def max_value(self, node, alpha, beta):
'''计算最大值
参数:
node - GameNode 博弈树结点
alpha - int 剪枝区间下限值
beta - int 剪枝区间上限值
返回值:
clf - int 子结点中的最大的评估值
'''
#请在这里补充代码,完成本关任务
#********** Begin **********#
if self.isTerminal(node):
return self.get_value(node)
clf=-10000
for child in node.children:
clf=max(clf,self.min_value(child,alpha,beta))
if clf>=beta:
return clf
alpha=max(alpha,clf)
node.val=clf
return clf
#********** End **********#
def min_value(self, node, alpha, beta):
'''计算最小值
参数:
node - GameNode 博弈树结点
alpha - int 剪枝区间下限值
beta - int 剪枝区间上限值
返回值:
clf - int 子结点中的最小的评估值
'''
#请在这里补充代码,完成本关任务
#********** Begin **********#
if self.isTerminal(node):
return self.get_value(node)
clf=10000
for child in node.children:
clf=min(clf,self.max_value(child,alpha,beta))
if clf<=alpha:
return clf
beta=min(clf,beta)
node.val=clf
return clf
#********** End **********#
def get_value(self, node):
'''返回结点的值
参数:
node - GameNode 博弈树结点
返回值:
clf - int 结点的值,即 node.val
'''
#请在这里补充代码,完成本关任务
#********** Begin **********#
return node.val
#********** End **********#
def isTerminal(self, node):
'''判断某结点是否为最终结点(无子结点)
参数:
node - GameNode 博弈树结点
返回值:
clf - bool 是最终状态,返回True,否则返回False
'''
#请在这里补充代码,完成本关任务
#********** Begin **********#
if node.val==0:
return False
else:
return True
#********** End **********#