论坛交流
首页办公自动化| 网页制作| 平面设计| 动画制作| 数据库开发| 程序设计| 全部视频教程
应用视频: Windows | Word2007 | Excel2007 | PowerPoint2007 | Dreamweaver 8 | Fireworks 8 | Flash 8 | Photoshop cs | CorelDraw 12
编程视频: C语言视频教程 | HTML | Div+Css布局 | Javascript | Access数据库 | Asp | Sql Server数据库Asp.net  | Flash AS
当前位置 > 文字教程 > C语言程序设计教程
Tag:新手,函数,指针,数据类型,对象,Turbo,入门,运算符,数组,结构,二级,,tc,游戏,试题,问答,编译,视频教程

怎样编制黑白棋(3)

文章类别:C语言程序设计 | 发表日期:2008-9-24 14:46:45

估值函数

    这是一个程序中最重要的部分,假如这个模块太弱,则就算算法再好也没有用。这里将要叙述三种不同的估值函数范例。大多数的黑白棋程序都可以归结于此。
棋格表

    这种算法的意思是,不同的棋格有不同的值,角的值大而角旁边的格子值要小。忽视对称的话,棋盘上有10个不同的位置,每个格子根据三种可能性赋值:黑棋、白棋和空。更有经验的逼近是在游戏的不同阶段对格子赋予不同的值。例如,角在开局阶段和中局开始阶段比终局阶段更重要。

    一般认为,采用这种算法的程序总是很弱,但另一方面,它很轻易实现,于是许多程序开始采用这种逼近。并且,对于许多程序设计者来说,它有能力使程序强到击败它的创造者...

基于行动力的估值

    这种更久远的接近有很强的全局观,而不像棋格表那样局部化。观察表明,许多人类玩者努力获得最大的行动力(可下棋的数目)和潜在行动力(临近对手棋子的空格,见技巧篇)。假如代码有效率的话,可以很快发现,它们提高棋力很多。和另一种人类的策略一样,许多基于行动力估值的程序同时还有一些边角配置的知识,试图在中盘早期使棋子最少。

基于模版的估值

    正如上面提及的,许多中等力量的程序经常合并一些边角判定的知识,最大行动力和潜在行动力是全局特性,但是他们可以被切割成局部配置,再加在一起。棋子最少化也是如此。 这导致了以下的概括:在估值函数中仅用局部配置(模版),通常单独计算每一行、一列、斜边和角落的模板,再线性叠加在一起来实现。并且,配置情况的值非常依靠于游戏的不同阶段。比如,一条边有3321种配置情况((3^8-3^4)/2+3^4),每种情况的分值好坏在游戏的不同阶段都不相同。分值基于强力玩者和程序的游戏结果统计,他们存于数据库中,游戏启动时自动调入。

常见的有这样一些模板:

名称 类似区域 配置数 去掉对称后的配置数
corner5x2 a1:e2 3^10=59049 (3^10-3^5)/2+3^5 = 29646
diag5 a5:e1 3^5 =243 (3^5 -3^3)/2+3^3 = 135
diag6 a6:f1 3^6 =729 (3^6 -3^3)/2+3^3 = 378
diag7 a7:g1 3^7 =2187 (3^7 -3^4)/2+3^4 = 1134
diag8 a8:h1 3^8 =6561 (3^8 -3^4)/2+3^4 = 3321
edge2x a1:h1 + b2 + g2 3^10=59049 (3^10-3^5)/2+3^5 = 29646
hor2 a2:h2 3^8 =6561 (3^8 -3^4)/2+3^4 = 3321
hor3 a3:h3 3^8 =6561 (3^8 -3^4)/2+3^4 = 3321
hor4 a4:h4 3^8 =6561 (3^8 -3^4)/2+3^4 = 3321
triangle a1:a4:d1 3^10=59049 (3^10-3^5)/2+3^5 = 29646

估值合并

    一般程序的估值基于许多的参数,如行动力、潜在行动力、余裕手、边角判定、稳定子(见技巧篇)。但是怎么样将他们合并起来得到一个估值呢?为了提高速度,一般的程序采用线性合并。设a1,a2,a3,a4为参数,则估值s:=n1*a1+n2*a2+n3*a3+n4*a4。其中n1,n2,n3,n4为常数,术语叫“权重”(weight),它决定了参数的重要性,来自于统计值。

一个基于棋格表和行动力估值的例子

function Evalution: Double;
var
  i, j: Integer;
  oppMobility, compMobility: Integer;          //双方行动力
  oppValue, compValue: Integer;                //双方棋格表值
  temp: Double;
  Final: Boolean;
begin
  oppValue := 0;
  compValue := 0;
  if Final then                                //假如是终局搜索
  begin
    for i := 1 to 8 do
      for j := 1 to 8 do
      begin
        if Board[i, j] = compColor then
          Inc(compValue);                      //电脑的棋子数
        if Board[i, j] = oppColor then
          Inc(oppValue);                       //对手的棋子数
      end;
    Result := compValue - oppValue;
    Exit;
  end;
  oppMobility := 0;
  compMobility := 0;
  changeCost;                                  //动态修正棋格表的值
  for i := 1 to 8 do
    for j := 1 to 8 do
    begin
      if (Board[i, j] = compcolor) then
        compValue := compValue + cost[i, j];   //电脑的棋格表值
      if (Board[i, j] = oppColor) then
        oppValue := oppValue + cost[i, j];     //对手的棋格表值
    end;
  for i := 1 to 8 do
    for j := 1 to 8 do
    begin
      if chessable(i, j, compColor) then       //电脑在位置[i,j]可以下棋
        inc(compMobility);                     //增加电脑的行动力
      if chessable(i, j, oppColor) then        //对手在位置[i,j]可以下棋
        inc(oppMobility);                      //增加对手的行动力
    end;
  temp := sqrt(compMobility * 100) - sqrt(oppMobility * 100);
  if compValue - oppValue >= 0 then            //估值合并,不过这里用的并不是线性合并法
    Result := round((sqrt(compValue - oppValue) * 2 + temp) * 100) / 100
  else
    Result := -round((sqrt(oppValue - compValue) * 2 - temp) * 100) / 100;
end;

上一篇:{应用}怎样编制黑白棋(2) 人气:5182
下一篇:{应用}怎样编制黑白棋(4) 人气:7013
视频教程列表
文章教程搜索
 
C语言程序设计推荐教程
C语言程序设计热门教程
看全部视频教程
购买方式/价格
购买视频教程: 咨询客服
tel:15972130058