编写“线围棋”程序-1-画棋盘

围棋,大家都知道是一个在平面上玩的游戏。有朋友别出心裁,提出在一条线上下围棋的想法,并取名叫做StringGo。

觉得很有意思,编个程序玩玩。

首先,要画线围棋的棋盘。顾名思义,线棋盘就是一根直线上均匀画上交叉点,就是取真正围棋盘上的一根线.

线画个看看,程序就是这样的拉 :

procedure TForm1.FormPaint(Sender: TObject);
var
  i: Integer;
begin
  with canvas do

    begin

      Pen.Width := 1; 

      moveto(10,50);
      LineTo(210,50);
      For i := 0 to 10 do
        begin
          if (i = 0) or (i = 10) then
             Pen.Width := 3           //画两端的粗线
            else
             Pen.Width := 1;          //画中间的细线
          moveto(10 + i * 20,40);
          Lineto(10 + i * 20,60);
        end;
    end;

end;

运行结果是这样的:


一个简单的StringGo的棋盘就画好了.

不过,这个棋盘有很多毛病,

1.棋盘位置是固定的,不能移动和伸缩;

2.棋盘大小也是固定的,只有11个交叉点.

3.这段程序不能随便移动重用,只能画在这个窗口的画布上,其他地方要画的画还要重写这段程序.

下面先解决问题2,让棋盘的大小(交叉点数)可以灵活设置,顺便补一个围棋盘上常见的"星位".

 程序改成这样就可以了:

procedure TForm1.FormPaint(Sender: TObject);
  begin
    DrawBoard(8);       //画9点棋盘
    //DrawBoard(15);    //画15点棋盘
  end;

Procedure TForm1.DrawBoard(N : Integer);
var
  i,M: Integer;
begin
  M := N Div 2;
  N := (M) * 2;    //N必须是偶数,也就是必须得到奇数个交叉点;
  with canvas do
    begin
      Pen.Width := 1;
      moveto(10,50);
      LineTo(10 + N * 20, 50);
      For i := 0 to N do
        begin
          if (i = 0) or (i = N) then
             Pen.Width := 3           //画两端的粗线
            else
             Pen.Width := 1;          //画中间的细线
          moveto(10 + i * 20,40);
          Lineto(10 + i * 20,60);
          if i = M then               //在中点画一个星(天元,呵呵!)
            begin
              Brush.Color := ClBlack;
              Brush.Style := bsSolid;
              Ellipse(8 + i * 20,48,12 + i * 20,52);
            end;
        end;
    end;

end;


给Form1增加了一个方法,带一个点数的参数就可以了.程序运行的效果是:

9点棋盘:

15点棋盘:

 

剩下的棋盘问题一次性解决算了,这次改动动作稍微大一点,为了很好地重用,创建了一个新类,TStringGoBoard,也就是线棋盘类了.

完整的程序如下:

unit Unit1;

interface

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

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);  //画到一个画布上
     Property MaxP : Integer Read FMaxP Write SetMaxP;
     Property Rect : TRect Read FRect Write FRect;
   End;

TForm1 = class(TForm)
    procedure FormPaint(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormResize(Sender: TObject);
  private
    FBoard : TStringGoBoard;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

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

procedure TForm1.FormPaint(Sender: TObject);
begin
  FBoard.Drawto(Canvas);             //窗口重画时画出棋盘
end;

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

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

{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;

end.

呵呵,这次的效果如下:

 

棋盘足够好用了,接下来就要编下棋的程序了.

posted on 2008-09-28 15:24  巴不得飞  阅读(588)  评论(0编辑  收藏  举报