📄 chessboard.pas
字号:
unit ChessBoard;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, jpeg, ExtCtrls;
type
TForm_ChessBoard = class(TForm)
ChessBoard: TImage;
Chess_1: TImage;
Chess_2: TImage;
Chess_4: TImage;
Chess_6: TImage;
Chess_8: TImage;
Chess_11: TImage;
Chess_12: TImage;
Chess_17: TImage;
Chess_18: TImage;
Chess_21: TImage;
Chess_23: TImage;
Chess_25: TImage;
Chess_27: TImage;
Chess_29: TImage;
Chess_3: TImage;
Chess_5: TImage;
Chess_7: TImage;
Chess_9: TImage;
Chess_10: TImage;
Chess_16: TImage;
Chess_14: TImage;
Chess_13: TImage;
Chess_15: TImage;
Chess_19: TImage;
Chess_20: TImage;
Chess_22: TImage;
Chess_24: TImage;
Chess_26: TImage;
Chess_31: TImage;
Chess_28: TImage;
Chess_32: TImage;
Chess_30: TImage;
FirstSelected: TImage; //第一棋子选中标记
SecondSelected: TImage;
procedure ChessMoveUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure ChessBoardMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormCreate(Sender: TObject); //第二棋子选中标记
private
{ Private declarations }
public
{ Public declarations }
procedure InitChess(); //初始化棋盘布局及相关数据
procedure GetArrayCoordinate(X,Y:Integer;var i,j:Integer); //棋盘坐标转换为数组坐标
procedure ConvertArrayCoordinate(var X,Y:Integer); //把本方的数组坐标转换为对方的数组坐标
function CanMove(X1,Y1,X2,Y2:Integer):Boolean; //该步棋是否可以移到目的位置
procedure Move(X1,Y1,X2,Y2:Integer); //把棋移到目的位置
end;
var
Form_ChessBoard: TForm_ChessBoard;
ChessData:array[1..9,1..10] of Byte; //棋盘数据
First_Selected:Boolean;
FirstChess,SecondChess:TImage;
First_X,First_Y,Second_X,Second_Y:Integer;
implementation
uses Main;
{$R *.dfm}
{ TForm_ChessBoard }
procedure TForm_ChessBoard.InitChess;
var
i,j:Integer;
Chess:string;
begin
//本方棋子
ChessData[1,1]:=LocalFlag*16+8;
ChessData[2,1]:=LocalFlag*16+6;
ChessData[3,1]:=LocalFlag*16+4;
ChessData[4,1]:=LocalFlag*16+2;
ChessData[5,1]:=LocalFlag*16+1;
ChessData[6,1]:=LocalFlag*16+3;
ChessData[7,1]:=LocalFlag*16+5;
ChessData[8,1]:=LocalFlag*16+7;
ChessData[9,1]:=LocalFlag*16+9;
ChessData[2,3]:=LocalFlag*16+10;
ChessData[8,3]:=LocalFlag*16+11;
ChessData[1,4]:=LocalFlag*16+12;
ChessData[3,4]:=LocalFlag*16+13;
ChessData[5,4]:=LocalFlag*16+14;
ChessData[7,4]:=LocalFlag*16+15;
ChessData[9,4]:=LocalFlag*16+16;
//对方棋子
ChessData[1,10]:=RemoteFlag*16+9;
ChessData[2,10]:=RemoteFlag*16+7;
ChessData[3,10]:=RemoteFlag*16+5;
ChessData[4,10]:=RemoteFlag*16+3;
ChessData[5,10]:=RemoteFlag*16+1;
ChessData[6,10]:=RemoteFlag*16+2;
ChessData[7,10]:=RemoteFlag*16+4;
ChessData[8,10]:=RemoteFlag*16+6;
ChessData[9,10]:=RemoteFlag*16+8;
ChessData[2,8]:=RemoteFlag*16+11;
ChessData[8,8]:=RemoteFlag*16+10;
ChessData[1,7]:=RemoteFlag*16+16;
ChessData[3,7]:=RemoteFlag*16+15;
ChessData[5,7]:=RemoteFlag*16+14;
ChessData[7,7]:=RemoteFlag*16+13;
ChessData[9,7]:=RemoteFlag*16+12;
//放置棋子
for i:=1 to 9 do
for j:=1 to 10 do
begin
if ChessData[i,j]<>0 then
begin
Chess:='Chess_'+IntToStr(ChessData[i,j]);
with TImage(FindComponent(Chess)) do
begin
Top:=494-51*(j-1)-25;
Left:=35+51*(i-1)-25;
Visible:=TRUE;
end;
end;
end;
Form_Main.Label1.Visible := TRUE;
Form_Main.Label2.Visible := TRUE;
Form_Main.Label3.Visible := TRUE;
First_Selected := FALSE;
Over := FALSE;
end;
procedure TForm_ChessBoard.ChessMoveUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
i,j,k,PointX,PointY:Integer;
begin
if ((CurrentFlag = LocalFlag)and (not Over)) then
begin
k:= TImage(Sender).Tag;
if (((k-1) div 16) = LocalFlag) then
begin
FirstSelected.Visible:=FALSE;
SecondSelected.Visible:=FALSE; //重新选择棋子之前把原先选中的棋子取消掉
First_Selected :=TRUE;
FirstChess :=TImage(Sender);
FirstSelected.Visible:=TRUE;
FirstSelected.Top :=TImage(Sender).Top;
FirstSelected.Left:=TImage(Sender).Left;
PointX:=TImage(Sender).Left+25;
PointY:=TImage(Sender).Top+25;
GetArrayCoordinate(PointX,PointY,i,j);
if ((i<>-1) and (j<>-1)) then
begin
First_X:=i;
First_Y:=j;
end;
end;
if ((((k-1) div 16) = RemoteFlag) and First_Selected) then
begin
SecondChess:=TImage(Sender);
PointX:=TImage(Sender).Left+25;
PointY:=TImage(Sender).Top+25;
GetArrayCoordinate(PointX,PointY,i,j);
if ((i<>-1) and (j<>-1)) then
begin
Second_X:=i;
Second_Y:=j;
if CanMove(First_X,First_Y,Second_X,Second_Y) then
begin
if (ChessData[Second_X,Second_Y] = 1+RemoteFlag*16) then
begin
Over:=TRUE;
end;
SecondChess.Enabled:=FALSE;
SecondChess.Visible:=FALSE; //吃掉第二只棋
Move(First_X,First_Y,Second_X,Second_Y);
if Over then
Application.MessageBox('恭喜你赢得了比赛','恭喜');
end;
end;
end;
end;
end;
procedure TForm_ChessBoard.ChessBoardMouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
i,j:Integer;
begin
if (First_Selected and (CurrentFlag = LocalFlag) and (not Over)) then
begin
GetArrayCoordinate(X,Y,i,j);
if ((i<>-1) and (j<>-1)) then
begin
Second_X:=i;
Second_Y:=j;
if CanMove(First_X,First_Y,Second_X,Second_Y) then
begin
Move(First_X,First_Y,Second_X,Second_Y);
end;
end;
end;
end;
procedure TForm_ChessBoard.FormCreate(Sender: TObject);
var
i,j:Integer;
begin
for i:=1 to 9 do
for j:=1 to 10 do
begin
ChessData[i,j]:=0;
end;
FirstChess :=TImage.Create(Self);
SecondChess :=TImage.Create(Self);
Over:=TRUE;
end;
procedure TForm_ChessBoard.GetArrayCoordinate(X, Y: Integer; var i, j: Integer);
var
a,b:Integer;
label QuitFunc;
begin
for a:=1 to 9 do
for b:=1 to 10 do
begin
if ((abs(X-(35+51*(a-1)))<=12) and (abs(Y-(494-51*(b-1)))<=12)) then
begin
i:=a;
j:=b;
goto QuitFunc;
end
else
begin
i:=-1;
j:=-1;
end;
end;
QuitFunc:
end;
function TForm_ChessBoard.CanMove(X1, Y1, X2, Y2: Integer): Boolean;
var
i,j:Integer;
a,b:Integer;
begin
Result:=FALSE;
case (ChessData[X1,Y1]-LocalFlag*16) of
1: //选择的是主帅
begin
if ((X2>=4) and (X2<=6) and (Y2>=1) and (Y2<=3)) then //落点在米字军营
begin
if ((X1 = X2) and (abs(Y1-Y2)=1)) then //竖向走
begin
Result:=TRUE;
Exit;
end;
if ((Y1 = Y2) and (abs(X1-X2)=1)) then //横向走
begin
Result:=TRUE;
Exit;
end;
end;
if ((ChessData[X2,Y2] = (RemoteFlag*16+1)) and (X1 = X2)) then //对方是主帅
begin
j:=0;
for i:= Y1+1 to Y2-1 do
if (ChessData[X1,i]<>0) then inc(j);
if (j=0) then
begin
Result := TRUE;
Exit;
end;
end;
end;
2,3: //选择的是士
begin
if ((X2>=4) and (X2<=6) and (Y2>=1) and (Y2<=3)) then //落点在米字军营
begin
if ((abs(X1-X2) = 1) and (abs(Y1-Y2) = 1)) then
begin
Result := TRUE;
Exit;
end;
end;
end;
4,5: //选择的是象
begin
if (Y2<=5) then //象不能过河
begin
//4种可能性 象眼没棋子
if ((abs(X1-X2) = 2) and (abs(Y1-Y2) = 2) and (ChessData[(X1+X2) div 2,(Y1+Y2) div 2] = 0)) then
begin
Result := TRUE;
Exit;
end;
end;
end;
6,7: //选择的是马
begin
if ((abs(X1-X2) = 2) and (abs(Y1-Y2) = 1) and (ChessData[(X1+X2) div 2,Y1] = 0)) then
begin
Result := TRUE;
Exit;
end;
if ((abs(X1-X2) = 1) and (abs(Y1-Y2) = 2) and (ChessData[X1,(Y1+Y2) div 2] = 0)) then
begin
Result := TRUE;
Exit;
end;
end;
8,9: //选择的是车
begin
if (X1=X2) then //横坐标相同
begin
//a>b
if Y1>Y2 then
begin
a:=Y1;
b:=Y2;
end
else
begin
a:=Y2;
b:=Y1;
end;
j:=0;
for i:=b+1 to a-1 do
begin
if ChessData[X1,i]<>0 then Inc(j);
end;
if j=0 then
Result:=TRUE
else
Result:=FALSE;
Exit;
end;
if (Y1=Y2) then //纵坐标相同
begin
//a>b
if X1>X2 then
begin
a:=X1;
b:=X2;
end
else
begin
a:=X2;
b:=X1;
end;
j:=0;
for i:=b+1 to a-1 do
begin
if ChessData[i,Y1]<>0 then Inc(j);
end;
if j=0 then
Result:=TRUE
else
Result:=FALSE;
Exit;
end;
end;
10,11: //选择的是炮
begin
if (X1=X2) then //横坐标相同
begin
//a>b
if Y1>Y2 then
begin
a:=Y1;
b:=Y2;
end
else
begin
a:=Y2;
b:=Y1;
end;
j:=0;
for i:=b+1 to a-1 do
begin
if ChessData[X1,i]<>0 then Inc(j);
end;
if (((j=1) and (ChessData[X2,Y2]<>0)) or ((j=0) and (ChessData[X2,Y2]=0))) then
Result:=TRUE
else
Result:=FALSE;
Exit;
end;
if (Y1=Y2) then //纵坐标相同
begin
//a>b
if X1>X2 then
begin
a:=X1;
b:=X2;
end
else
begin
a:=X2;
b:=X1;
end;
j:=0;
for i:=b+1 to a-1 do
begin
if ChessData[i,Y1]<>0 then Inc(j);
end;
if (((j=1) and (ChessData[X2,Y2]<>0)) or ((j=0) and (ChessData[X2,Y2]=0))) then
Result:=TRUE
else
Result:=FALSE;
Exit;
end;
end;
12,13,14,15,16: //选择的是卒
begin
if (Y1<=5) then //未过河
if ((Y2 = Y1+1) and (X1 = X2)) then //只能向前
begin
Result:=TRUE;
Exit;
end;
if (Y1>5) then //已经过河
begin
if ((Y2 = Y1+1) and (X1 = X2)) then //向前
begin
Result:=TRUE;
Exit;
end;
if ((Y2 = Y1) and (abs(X1-X2)=1)) then //左右
begin
Result:=TRUE;
Exit;
end;
end;
end;
end;
end;
procedure TForm_ChessBoard.Move(X1, Y1, X2, Y2: Integer);
begin
ChessData[X2,Y2]:=ChessData[X1,Y1];
ChessData[X1,Y1]:=0;
FirstChess.Top:=494-51*(Y2-1)-25;
FirstChess.Left:=35+51*(X2-1)-25;
SecondSelected.Top:=494-51*(Y2-1)-25;
SecondSelected.Left:=35+51*(X2-1)-25;
SecondSelected.Visible:=TRUE;
ConvertArrayCoordinate(X1,Y1);
ConvertArrayCoordinate(X2,Y2);
TxLen:=5;
TxBuff[0]:=$02;
TxBuff[1]:=X1;
TxBuff[2]:=Y1;
TxBuff[3]:=X2;
TxBuff[4]:=Y2;
CurrentFlag:=RemoteFlag;
Form_Main.lblCurrent.Caption := '对方';
SendData(CommSocket,TxBuff,TxLen);
end;
procedure TForm_ChessBoard.ConvertArrayCoordinate(var X, Y: Integer);
begin
X:=10-X;
Y:=11-Y;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -