First we try, then we trust

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

完整的程序代码可以从http://www2.cnblogs.com/Files/zhenyulu/HRD.rar下载

九、 代码设计

在看完了解题过程后,下面来看一看具体的代码设计方案:

我们首先从Core开始,在Core.dll里面定义了系统所需的最基本的数据类型以及相关的接口。其中枚举ChessmanType与MoveMethod分别定义了棋子的类型以及棋子移动的方法。

public enum ChessmanType
{
  Blank 
= 0,
  Solider 
= 1,
  VChessman 
= 2,
  HChessman 
= 3,
  General 
= 99
}


public enum MoveMethod
{
  Up, 
  Down, 
  Left, 
  Right, 
  Up2, 
  Down2, 
  Left2, 
  Right2, 
  Turning,
  Nothingness    
//没有任何移动
}

ChessStep定义了棋局中的"一步"棋。包括当前棋盘布局的整数表示、移动了哪一个棋子以及如何移动。当华容道自动解题程序完成后,将返回一个ChessStep[]数组,记录每一步的走法。我们可以通过实现IResultHandler接口的"HandleResult (ChessStep[] steps)"方法来达到这一目的。IResultHandler接口将在后面加以介绍。

public struct ChessStep
{
  
public short chessmanNum;
  
public MoveMethod moveMethod;
  
public int layout;
}

Position与BlankPosition是两个结构"structure",用来记录棋子的位置以及某一棋盘上空格的位置。BlankPosition中有一IsBlank(int x, int y)方法,用来判断坐标为(x,y)的点是否是空格。

public struct Position
{
  
public int x;
  
public int y;

  
public Position(int x, int y)
  
{
    
this.x = x;
    
this.y = y;
  }

}


public struct BlankPosition
{
  
public Position Pos1;
  
public Position Pos2;
    
  
public BlankPosition(Position pos1, Position pos2)
  
{
    
this.Pos1 = pos1;
    
this.Pos2 = pos2;
  }


  
public bool IsBlank(int x, int y)
  
{
    
if( x == Pos1.x && y == Pos1.y)
      
return true;
    
if( x == Pos2.x && y == Pos2.y)
      
return true;
      
return false;
  }

}

之所以选择使用结构而不是类是因为struct是值类型的,而class是引用类型。在本程序中,struct要比class更有效率。关于struct与class的区别在这里就不再详细讨论了。我们看下面一段程序:

Position P1 = new Position(0,0);
Position P2;
P2 
= P1;

P2经过赋值后,P2.x与P2.y都与P1相同,并且这种赋值不是"引用"赋值,修改P2中x、y的值并不会影响P1中x、y的值。

HRD.Core命名空间下除了这些基本类型的定义外,还定义了一系列接口,主要是用来达到解耦目的。在上篇文章中,我们看到了TreeLinkedList、CircularLinkedList以及AVLTree之间如何协作工作,但在实际代码设计中,这将带来严重的耦合问题。组件与组件之间联系过于紧密,造成无法有效的剥离。为此,程序在设计时引入了"中介者"模式,设计了一个Mediator,所有组件仅与Mediator打交道,这样耦合便被"松动"了。

Mediator的定义如下:

public class Mediator
{
  
private IAVLTree _avlTree;
  
private ICircularList _circleList;
  
private ITreeList _treeList;
  
private IResultHandler _resultHandler;
  
  …………

}

其中IAVLTree、ICircularList、ITreeList便是参与运算的三种数据结构。其具体定义可以参考具体的程序源代码。(可以参考http://www2.cnblogs.com/zhenyulu/archive/2005/02/03/101426.html里面的代码,但不是最终版本,可能会与本文有所出入)。

这里还有一个接口定义,就是IResultHandler接口。刚才已经提到过。我们可以将一个实现了该接口的对象传递给Mediator对象,这样,当系统运算完成后便会调用IResultHandler中的特定方法,将结果回传。

public interface IResultHandler
{
  
void HandleResult(ChessStep[] steps);
  
void HandleInfo(int currentStep);
}

IResultHandler定义了两个方法HandleResult与HandleInfo。HandleResult用来处理程序产生的结果,结果以ChessStep数组的形式传入。HandleInfo可以被用来处理程序运算过程中的一些中间信息。这里我只提供了一个信息,那就是当前搜索层次是什么。它通过currentStep参数传入。如果需要,用户可以重新定义该接口以获取更多的信息(例如搜索了多少个节点等)。IResultHandler接口的具体使用方法可以参考源代码中WinHRD或ConsoleHRD中的实现。

HRD.Core命名空间下还定义了Layout以及Chessman,此外还有一个CallBackDelegate的定义,这些将在后续的文章中再加以介绍。

posted on 2005-02-04 16:23  吕震宇  阅读(3711)  评论(2编辑  收藏  举报