日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

编写“线围棋”程序-2-可开局

發(fā)布時間:2023/12/10 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 编写“线围棋”程序-2-可开局 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

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

只要解決下面3個問題就可以了:

1.響應(yīng)鼠標點擊事件,獲得“下棋子”的動作源。

2.修改和記錄棋局狀態(tài)。

3.在棋盤上顯示棋局的狀態(tài)。

為此,直接增加一個“棋局類“,也就是對“一盤棋“對象的實現(xiàn)。

先把已經(jīng)編好的棋盤類移到一個新的單元里,不再放到窗體單元中,我喜歡這樣把成熟的程序逐漸移到新單元內(nèi)存放。

棋盤單元如下:

unit UnitBoardView;

interface

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

Type
?TStringGoBoard = Class(TObject)???? //線棋盤類
?? Private
???? FMaxP : Integer;????????????????? //棋盤最大點樹
???? FRect : TRect;??????????????????? //棋盤區(qū)域位置
???? 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必須是偶數(shù),也就是必須得到奇數(shù)個交叉點;
? 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;????????? //動態(tài)計算畫棋盤位置
????? 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.


里面已經(jīng)添加了顯示一步棋和根據(jù)鼠標位置找下棋點位置的方法了,這是支持下棋所必需要有的方法。

然后,繼續(xù)在窗體類的單元內(nèi)試驗新建的棋局類。為簡便起見,棋盤就當作棋局本身的一部分了。

新的窗體單元變成了這個樣子的:

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;????? //記錄棋子狀態(tài)的數(shù)組
??? 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;??????????? //窗口創(chuàng)建時是創(chuàng)建對局
? FGame.Board.Rect := ClientRect;?? //棋盤占整個窗口位置
? FGame.MaxP := 8;??????????????? //設(shè)為9點棋局
? //FGame.MaxP := 15;??????????????? //設(shè)為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);? //根據(jù)屏幕坐標得到下棋點坐標。
????? 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;????????? //設(shè)置棋盤大小
??? SetLength(FPosStatus, MaxP + 1 );??? //初始化記錄數(shù)組
??? For i := 0 to MaxP do
????? begin
??????? FPosStatus[i] := 0;
????? end;
? end;

end.

呵呵,我用了一個動態(tài)的整數(shù)數(shù)組來記錄棋局的狀態(tài)。

這個程序已經(jīng)可以用鼠標交替落子了,但還不能真正支持對弈,因為還不知道怎么提子。下一步就是要實現(xiàn)下棋規(guī)則了,最好支持自動提子,就可以用來玩了。

程序運行的效果如下:

?

?

?

轉(zhuǎn)載于:https://www.cnblogs.com/babituo/archive/2008/10/06/1304814.html

總結(jié)

以上是生活随笔為你收集整理的编写“线围棋”程序-2-可开局的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。