头歌平台-人工智能导论实验(博弈中的搜索)

极大极小法

 

# -*- 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 **********#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值