编写“线围棋”程序-2-可开局
棋盘有了,怎么支持在上面落子呢?
只要解决下面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-可开局相关推荐
- C语言字符串围棋盘放麦粒,围棋高手(民间)用C编写的围棋程序。
围棋高手(民间)用C编写的围棋程序. #include void main() { int n,m,x,y,temp,j=0,i=0 ; printf("输入棋盘的横格数,竖格数:\n&qu ...
- 围棋程序=围棋数据结构+围棋算法
围棋程序=围棋数据结构+围棋算法 e.g. 各种典型的棋局或对弈程序=棋盘的数据结构(19X19 二维数组)+各种典型的下棋步骤即记录棋局对弈过程的一系列具体的算法 晓辉是这样想的: 如果所有可能的布 ...
- 【转】独家教程:用PHP编写Android应用程序
Google的开源Android移动操作系统正在席卷全球智能手机市场,和苹果不一样,它对那些想将应用程序提交到iPhone App Store的开发人员有着严格的指导方针和要求,Google的Andr ...
- 编写运行java的步骤,【简答题】编写运行Java程序需要经过哪些主要步骤? (30.0分)...
[简答题]编写运行Java程序需要经过哪些主要步骤? (30.0分) 更多相关问题 电子商务的()个支撑点是框架结构得以存在并能应用的基础.A.1B.2C.3 电子商务总体框架包括()个层次.A.2B ...
- python只能运行在windows平台上吗_在Windows平台上编写的Python程序无法在Unix平台运行。...
问题:在Windows平台上编写的Python程序无法在Unix平台运行. 更多相关问题 Because plants cannot move or talk, most people believe ...
- VC++实现双人对决的围棋程序,附源码
可以双人对决的VC++围棋程序,送给我梦中的情人.虽然程序不很复杂,但毕竟是我自己亲手写的,而且还得到了女朋友夸奖,通过编写这个小程序,让我对VC++有了更深层的了解,想要的下载.游戏打开后可以选择适 ...
- python可以在多种平台运行、体现了_在Windows平台上编写的Python程序无法在Unix平台运行。...
问题:在Windows平台上编写的Python程序无法在Unix平台运行. 更多相关问题 某船公司2003年2月,建造了两艘航行于武汉-南京的2000吨油船,双壳结构形式,至今使用良好,为公司创 肾病 ...
- 电脑围棋竞赛朝鲜最强-KCC围棋程序九战全胜夺冠
电脑围棋竞赛朝鲜最强-KCC围棋程序九战全胜夺冠 2005.11.30 <script type="text/javascript"> </script> ...
- Linux环境下编写一个shell程序,此程序的功能:随机生成一个1-100的数(答案)让用户猜
题目:编写一个shell程序,此程序的功能:随机生成一个1-100的数(答案)让用户猜,如果用户猜的数大于答案,则提示大了,如果用户猜的数小于答案,则提示小了.当用户猜对时提示:猜对了. #! /bi ...
最新文章
- 快速幂 + 矩阵快速幂
- python二分查找
- python打印出指定目录下的所有文件夹和文件名(递归实现)
- Sublime Text3 高亮显示Jade语法 (Windows 环境)
- 前端学习(1991)vue之电商管理系统电商系统之实现商品的分页功能
- vue 组件 - 非单文件组件
- 7系统启动到一半停止_扛不住了!可口可乐巨震:500个品牌砍一半,裁员4000人.........
- energy in transition课文翻译_思迪软件科技 招聘 字幕翻译(远程兼职)
- 集成学习—决策树(CART)
- c++ 设计一个立方体的类,求出立方体的面积和体积
- 非华为电脑安装华为电脑管家,实现与手机平板的多屏协同
- revit二次开发 材质类别分析
- leetcode4568
- 【 微软 2023校园招聘倒计时3天】
- 使用grep命令抓取报: memory exhausted(内存耗尽)
- linux 查看文件最后几行
- Ubuntu 14.04 安装配置 JDK8
- HCIA的基础知识(1)
- 原创科幻短篇《腿控》
- 用UltraISO制作镜像以RAW格式写入到U盘后,无法识别的解决办法
热门文章
- React开发(228):ant design table根据宽度自动忽略
- 前端学习(3249):总结生命周期
- react学习(68)--ant design inputNumber
- 前端学习(3177):react-hello-react之利用github搜索组件
- 前端学习(3132):react-hello-react之react中事件处理
- 前端学习(3054):vue+element今日头条管理-状态展示处理
- [vue] 说说你对MVC、MVP、MVVM模式的理解
- [css] 使用css3实现一个斑马线的效果
- 工作312:uni-时间戳处理
- 工作275:表单验证层级添加