wly.net

五子棋程序报告

五子棋程序实验

(人工智能课程序实验,还未完成,代码稍后附上)

一.需求

       1.    基本功能

       2.    阶段实现

              1)扫描棋盘,直接做出决策

              2)搜索博弈树,做出决策

              3)不断解决新问题,改进程序

二.人工智能

       1.    问题分析:

        五子棋是一个典型的博弈问题。博弈问题一般可用极大-极小法和α-β法求解。而即便是用α-β法,五子棋的搜索空间还是相当庞大。因为每走一步对棋盘的影响并不限于所走棋子周围的位置,最优决策可能位于较远的地方。这就需要有选择的进行搜索,而选择标准就是一个重要的问题。

       2.    解决办法

        我们希望在进行搜索时有一个标准,并只对几个较优解进行搜索,下面就讨论如何实现这个目标。首先,程序应该对棋盘有所认识,也就是对对方和己方的局面有一个大致的判断,所以程序应该首先扫描棋盘,对所有空白位置按己方可构成“活三”,“死四”,“获胜”等局面进行赋值,也就是该位置对己方的重要性。

        在五子棋的口诀中有一句“以功为守,以守待功”,只看某位置对己方的重要性并不正确,我们应该在走出对己方是重要的一步棋时,占据对方重要的位置,这样的重要性是对整个棋局的重要性。这个重要性可以用双方的重要性之加权和来代替。这两个重要性可以简单地以相同的权来相加,这样做是合理的。

        有了搜索的选择标准后,就可以指定每一次搜索较优解的数量N。同时程序应指定搜索的深度D。这两个常数决定了搜索的总结点数

        另一个重要的问题是叶子节的评价值。这个值应用局面中双方最重要位置的重要性之差。这样做比较显然(后面会讲到这样做的问题)。

        综上所述,人智部分要注意区分两个概念。一个是作为选择搜索位置标准的棋局重要性值,另一个是评价一个局面的评价值。它们一个对双方重要性求和再求最大,一个是对双方生要性求最大,再作差。

三.程序结构

              应用面向对象的设计方法,将程序结构做如下设计:

1.         游戏(Game):

       这是游戏的中心部分,负责整个游戏的控制。包括开局、悔棋、设定游戏模式、创建玩家、更改棋盘、通知玩家走棋、记录出棋方等。因为整个程序只有一个游戏对象,所以使用单件模式。

2.        

玩家走棋

游戏

修改棋盘

玩家调用智能机构

计算机

玩家(Player):

       玩家类代表参与游戏的个体,一个棋局中有两个玩家,它们可以是计算机和人,也可以是两个人。计算机玩家调用智能机制构(aiAgent)来获得下一步的走法。将人和计算机抽象成玩家的好处是可以在下棋过程中随时改变游戏模式,双人或人机,而游戏(Game)不用做其它工作,除了将将玩家的类型(Type)改变即可。玩家的流程如下图所示。


3.         棋盘(ChessBoard):

       一个游戏只应有一个棋盘,所以应用单件模式。内有一个1515的二维数组存储棋盘。

4.         棋局(Situation):

       棋局通过对棋盘的扫描,记录一方在四个方向上可形成攻势的情况。比如活三、死四等。它记录在四个1515的表中。

5.         智能机构(aiAgent):

       通过搜索,对玩家(Player)提供走棋位置的决策。内有一个搜索树根节点;一个虚棋盘,在进行搜索时不断变化,记录每个搜索时的棋盘状态;两个虚棋局(Situation),记录每个搜索时双方的局面。智能机构应用单件模式。

6.         计算机构(calcAgent):

       为智能机构提供计算支持,包括评价值的计算,搜索时的最大最小计算和优选结节的计算。计算机构应用单件模式。

      

       对程序的各部分进行独立设计,主要有以下几方面考虑:

1.    算法的可扩展性:

       智能机构可以使用不同算法来代替。比如最大最小、α-β法等。而对程序的其它部分没有影响。

2.       对程序进行分布式处理:

    利用.net remoting技术可以将智能部分与其它部分分置在不同的计算机上,它可以是高性能的计算机以减少搜索时间。

 

下图是程序的结构图:


四.详细设计

       1.    扫描棋盘:

              在“人工智能”部分讲到过,程序需扫描棋盘,以对棋盘重要位置有所了解。这个工作对程序的正确性有重大的影响。

              在实验过程中,我用过两种扫描方法。它们的做法都是在遇到空位置时对前后的位置进行判断。第一种方法因为程序麻烦,有遗漏,所以用第二种方法替代。第二种方法    是以空白位置为中心,在四个方向前后各扫描五个位置,然后得到算上当前空白位置在    内的连续己方棋子数目(“有效己方”),还有前后的空白位置个数(“有效空白”),跟据这三个数判断当前空白位置是活二、活三、死四、活四、还是冲五。在扫描的时候设置两个标志位countflagemptyflag,意为“可以记录自方棋子”,和“可以记录空白位置”,它们的用法如下:

       1)扫描之前置countflag为直,emptyflag为假。

       2)遇到己方棋子,如果countflag为真,说明己方棋子是连续的,记为“有效己方”。

       3)遇到空白位置,如果countflag为真,说明己方棋子结束刚刚遇到空白,则置countflag为假,emptyflag为真,停止“有效己方”,开始记录“有效空白”。

       4)遇到对方棋子,则不都再记录,countflagemptyflag都置假。

       5)在“有效空白”后紧接着遇到的己方棋子也算在“有效空白中”。

 

       2.    极大极小搜索:

       1)在aiAgent中建立一个根结点代表当前状态,对当然局面进行分析,得到最重要N个位置,放在一个链表中。

       2)以每一个重要位置为根节点,重复上述步骤,建立一棵子树。这是一个递归的建树过程。

       3)在非叶子节点的子树建好后,用N个子节点的最小/大值结本节点赋值。

       4)最底一层节点的值就是人智部分介绍的局面评价值。

五.问题分析

 

posted on 2004-10-21 18:18  wly  阅读(3255)  评论(3)    收藏  举报

导航