棋盘有了,怎么支持在上面落子呢?

只要解决下面3个问题就可以了:

1.响应鼠标点击事件,获得“下棋子”的动作源。

2.修改和记录棋局状态。

3.在棋盘上显示棋局的状态。

为此,直接增加一个“棋局类“,也就是对“一盘棋“对象的实现。

先把已经编好的棋盘类移到一个新的单元里,不再放到窗体单元中,我喜欢这样把成熟的程序逐渐移到新单元内存放。

棋盘单元如下:

unit UnitBoardView;

interface

uses
  Windows, Messages, SysUtils, Variants, Types, Classes, Graphics;

Type
 TStringGoBoard = Class(TObject)     //线棋盘类
   Private
     FMaxP : Integer;                  //棋盘最大点树
     FRect : TRect;                    //棋盘区域位置
     Function GetDD : Integer;         //相邻交叉点间隔距离
     Function GetBX0 : Integer;        //棋盘起画点X
     Function GetBY0 : Integer;        //棋盘起画点Y
   Protected
     Procedure SetMaxP(AMaxP : Integer);
     Property DD : Integer Read GetDD;     //相邻交叉点间隔距离
     Property BX0 : Integer Read GetBX0;   //棋盘起画点X
     Property BY0 : Integer Read GetBY0;   //棋盘起画点Y
   Public
     Procedure Drawto(ACanvas : TCanvas);  //画到一个画布上
     Procedure DrawMove(ACanvas : TCanvas; APos : Integer; AStatus : Integer); //画一步棋
     Function Position(X,Y : Integer) : Integer;         //找一个下棋位置
     Property MaxP : Integer Read FMaxP Write SetMaxP;
     Property Rect : TRect Read FRect Write FRect;
   End;

implementation

{TStringGoBoard}
Function TStringGoBoard.GetDD : Integer;     //相邻交叉点间隔距离
  begin
    Result := ((Rect.Right - Rect.Left) - 20) div MaxP; //宽度两边各留10个像素
  end;

Function TStringGoBoard.GetBX0 : Integer;        //棋盘起画点X
  begin
    Result := Rect.Left + 10;
  end;

Function TStringGoBoard.GetBY0 : Integer;        //棋盘起画点Y
  begin
    Result := Rect.Top + (Rect.Bottom - Rect.Top) div 2;
  end;

Procedure TStringGoBoard.SetMaxP(AMaxP : Integer);
  begin
    FMaxP := (AMaxP Div 2) * 2; //N必须是偶数,也就是必须得到奇数个交叉点;
  end;

Procedure TStringGoBoard.Drawto(ACanvas : TCanvas); //画到一个画布上
var
  i,M: Integer;
  X0,Y0,BDD,CDD : Integer;
begin
  M := MaxP div 2;
  with ACanvas do
    begin
      Pen.Width := 1;
      X0 := BX0;          //动态计算画棋盘位置
      Y0 := BY0;
      BDD := DD;
      CDD := BDD div 2;
      moveto(X0,Y0);
      LineTo(X0 + MaxP * BDD, Y0);
      For i := 0 to MaxP do
        begin
          if (i = 0) or (i = MaxP) then
             Pen.Width := 3           //画两端的粗线
            else
             Pen.Width := 1;          //画中间的细线
          moveto(X0 + i * BDD,Y0 - CDD);
          Lineto(X0 + i * BDD,Y0 + CDD);
          if i = M then               //在中点画一个星(天元,呵呵!)
            begin
              Brush.Color := ClBlack;
              Brush.Style := bsSolid;
              Ellipse(X0 - 2 + i * BDD, Y0 -2, X0 +2 + i * BDD, Y0 +2);
            end;
        end;
    end;
end;

Procedure TStringGoBoard.DrawMove(ACanvas : TCanvas; APos : Integer; AStatus : Integer); //画一步棋
var
  X0,Y0,BDD,CDD : Integer;
begin
  with ACanvas do
    begin
      X0 := BX0;
      Y0 := BY0;
      BDD := DD;
      CDD := BDD div 2;
      if AStatus = 1 then
         Brush.Color := ClBlack
        else
         Brush.Color := ClWhite;
      Pen.Width := 1;
      Pen.Color := Brush.Color;
      Brush.Style := bsSolid;
      Ellipse(X0 - CDD + APos * BDD, Y0 - CDD, X0 + CDD + APos * BDD, Y0 + CDD);
    end;
end;

Function TStringGoBoard.Position(X,Y : Integer) : Integer;         //找一个下棋位置
  var
    i : Integer;
    X0,Y0,BDD,CDD,X1,Y1,X2,Y2 : Integer;
  begin
    Result := -1;
    X0 := BX0;
    Y0 := BY0;
    BDD := DD;
    CDD := BDD div 2;
    For i := 0 to MaxP do
      begin
        X1 := X0 - CDD + i * BDD;
        Y1 := Y0 - CDD;
        X2 := X0 + CDD + i * BDD;
        Y2 := Y0 + CDD;
        if (X >= X1) and (X <= X2) and
           (Y >= Y1) and (Y <= Y2) then
          begin
            Result := i;
            Exit;
          end;
      end;
  end;

end.

里面已经添加了显示一步棋和根据鼠标位置找下棋点位置的方法了,这是支持下棋所必需要有的方法。

然后,继续在窗体类的单元内试验新建的棋局类。为简便起见,棋盘就当作棋局本身的一部分了。

新的窗体单元变成了这个样子的:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, UnitBoardView;

type

TGame = Class(TObject)
  Private
    FBoard : TStringGoBoard;            //包含一个棋盘对象
    FPosStatus : Array of Integer;      //记录棋子状态的数组
    FCurPlayer : Integer;                   //当前行棋方,1:黑,2:白
  Protected
    Function GetMaxP : Integer;
    Procedure SetMaxP (AMaxP : Integer);
  Public
    Constructor Create;
    Destructor Destroy; Override;
    Procedure SetPos(APos : Integer);     //在位置上走一步棋
    Procedure Drawto(ACanvas : TCanvas);  //把棋局画在画布上
    Property Board : TStringGoBoard Read FBoard;
    Property MaxP : Integer Read GetMaxP Write SetMaxP;  //最大棋盘位置
  end;

TForm1 = class(TForm)
    procedure FormPaint(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    FGame : TGame;               //棋局对象
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
  FGame := TGame.Create;            //窗口创建时是创建对局
  FGame.Board.Rect := ClientRect;   //棋盘占整个窗口位置
  FGame.MaxP := 8;                //设为9点棋局
  //FGame.MaxP := 15;                //设为15点棋局
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  FGame.Drawto(Canvas);              //画棋局
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FGame.Free;                       //窗口销毁时销毁棋局
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  FGame.Board.Rect := ClientRect;    //窗口变化大小是变化棋盘大小
  Repaint;                           //启动重画窗口
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  Pos : Integer;
begin
  if Button = mbLeft then
    begin
      Pos := FGame.Board.Position(X,Y);  //根据屏幕坐标得到下棋点坐标。
      if Pos >= 0 then
        begin
          FGame.SetPos(Pos);          //在棋局上走一步棋
          Repaint;                    //显示棋局
        end;
    end;
end;

{TGame}
Constructor TGame.Create;
  begin
    Inherited Create;
    FCurPlayer := 1;                 //默认黑为当前下子方
    FBoard := TStringGoBoard.Create;
  end;

Destructor TGame.Destroy;
  begin
    FBoard.Free;
    Inherited Destroy;
  end;

Procedure TGame.SetPos(APos : Integer);
  begin
    FPosStatus[APos] := FCurPlayer;
    FCurPlayer := 3 - FCurPlayer;
  end;

Procedure TGame.Drawto(ACanvas : TCanvas);
  var
    i : Integer;
  begin
    FBoard.Drawto(ACanvas);           //画出棋盘
    For i := 0 to MaxP do
      begin
        if FPosStatus[i] <> 0  then
          begin
            FBoard.DrawMove(ACanvas,i,FPosStatus[i]);   //画棋子
          end;
      end;
  end;

Function TGame.GetMaxP : Integer;
  begin
    Result := FBoard.MaxP;
  end;

Procedure TGame.SetMaxP (AMaxP : Integer);
  var
    i : Integer;
  begin
    FBoard.MaxP := AMaxP;          //设置棋盘大小
    SetLength(FPosStatus, MaxP + 1 );    //初始化记录数组
    For i := 0 to MaxP do
      begin
        FPosStatus[i] := 0;
      end;
  end;

end.

呵呵,我用了一个动态的整数数组来记录棋局的状态。

这个程序已经可以用鼠标交替落子了,但还不能真正支持对弈,因为还不知道怎么提子。下一步就是要实现下棋规则了,最好支持自动提子,就可以用来玩了。

程序运行的效果如下:

转载于:https://www.cnblogs.com/babituo/archive/2008/10/06/1304814.html

编写“线围棋”程序-2-可开局相关推荐

  1. C语言字符串围棋盘放麦粒,围棋高手(民间)用C编写的围棋程序。

    围棋高手(民间)用C编写的围棋程序. #include void main() { int n,m,x,y,temp,j=0,i=0 ; printf("输入棋盘的横格数,竖格数:\n&qu ...

  2. 围棋程序=围棋数据结构+围棋算法

    围棋程序=围棋数据结构+围棋算法 e.g. 各种典型的棋局或对弈程序=棋盘的数据结构(19X19 二维数组)+各种典型的下棋步骤即记录棋局对弈过程的一系列具体的算法 晓辉是这样想的: 如果所有可能的布 ...

  3. 【转】独家教程:用PHP编写Android应用程序

    Google的开源Android移动操作系统正在席卷全球智能手机市场,和苹果不一样,它对那些想将应用程序提交到iPhone App Store的开发人员有着严格的指导方针和要求,Google的Andr ...

  4. 编写运行java的步骤,【简答题】编写运行Java程序需要经过哪些主要步骤? (30.0分)...

    [简答题]编写运行Java程序需要经过哪些主要步骤? (30.0分) 更多相关问题 电子商务的()个支撑点是框架结构得以存在并能应用的基础.A.1B.2C.3 电子商务总体框架包括()个层次.A.2B ...

  5. python只能运行在windows平台上吗_在Windows平台上编写的Python程序无法在Unix平台运行。...

    问题:在Windows平台上编写的Python程序无法在Unix平台运行. 更多相关问题 Because plants cannot move or talk, most people believe ...

  6. VC++实现双人对决的围棋程序,附源码

    可以双人对决的VC++围棋程序,送给我梦中的情人.虽然程序不很复杂,但毕竟是我自己亲手写的,而且还得到了女朋友夸奖,通过编写这个小程序,让我对VC++有了更深层的了解,想要的下载.游戏打开后可以选择适 ...

  7. python可以在多种平台运行、体现了_在Windows平台上编写的Python程序无法在Unix平台运行。...

    问题:在Windows平台上编写的Python程序无法在Unix平台运行. 更多相关问题 某船公司2003年2月,建造了两艘航行于武汉-南京的2000吨油船,双壳结构形式,至今使用良好,为公司创 肾病 ...

  8. 电脑围棋竞赛朝鲜最强-KCC围棋程序九战全胜夺冠

    电脑围棋竞赛朝鲜最强-KCC围棋程序九战全胜夺冠 2005.11.30 <script type="text/javascript"> </script> ...

  9. Linux环境下编写一个shell程序,此程序的功能:随机生成一个1-100的数(答案)让用户猜

    题目:编写一个shell程序,此程序的功能:随机生成一个1-100的数(答案)让用户猜,如果用户猜的数大于答案,则提示大了,如果用户猜的数小于答案,则提示小了.当用户猜对时提示:猜对了. #! /bi ...

最新文章

  1. 快速幂 + 矩阵快速幂
  2. python二分查找
  3. python打印出指定目录下的所有文件夹和文件名(递归实现)
  4. Sublime Text3 高亮显示Jade语法 (Windows 环境)
  5. 前端学习(1991)vue之电商管理系统电商系统之实现商品的分页功能
  6. vue 组件 - 非单文件组件
  7. 7系统启动到一半停止_扛不住了!可口可乐巨震:500个品牌砍一半,裁员4000人.........
  8. energy in transition课文翻译_思迪软件科技 招聘 字幕翻译(远程兼职)
  9. 集成学习—决策树(CART)
  10. c++ 设计一个立方体的类,求出立方体的面积和体积
  11. 非华为电脑安装华为电脑管家,实现与手机平板的多屏协同
  12. revit二次开发 材质类别分析
  13. leetcode4568
  14. 【 微软 2023校园招聘倒计时3天】
  15. 使用grep命令抓取报: memory exhausted(内存耗尽)
  16. linux 查看文件最后几行
  17. Ubuntu 14.04 安装配置 JDK8
  18. HCIA的基础知识(1)
  19. 原创科幻短篇《腿控》
  20. 用UltraISO制作镜像以RAW格式写入到U盘后,无法识别的解决办法

热门文章

  1. React开发(228):ant design table根据宽度自动忽略
  2. 前端学习(3249):总结生命周期
  3. react学习(68)--ant design inputNumber
  4. 前端学习(3177):react-hello-react之利用github搜索组件
  5. 前端学习(3132):react-hello-react之react中事件处理
  6. 前端学习(3054):vue+element今日头条管理-状态展示处理
  7. [vue] 说说你对MVC、MVP、MVVM模式的理解
  8. [css] 使用css3实现一个斑马线的效果
  9. 工作312:uni-时间戳处理
  10. 工作275:表单验证层级添加