📄 xqsystem.pas
字号:
if(not((X in [0..8])and(Y in [0..9]))) then Exit;
iIdx := iQiziIndexAtXY(XY);
case iIdx of
0 : Exit;
01..16: if (WhoPlay <> wpRed) then Exit;
17..32: if (WhoPlay <> wpBlk) then Exit;
end;
MovePosTo.Visible := False;
MovePosFrom.Visible := False;
QiziMove := Qizi[iIdx];
QiziMove.XY := XY;
QiziMoveImg.Picture := QiziMove.Picture;
QiziMoveImg.Left := BoardXY[X,Y].Left;
QiziMoveImg.Top := BoardXY[X,Y].Top;
QiziMoveImg.Visible := True;
BoardXY[X,Y].Cursor := crDefault;
BoardXY[X,Y].Picture := nil;
BoardXY[X,Y].DragMode := dmManual;
MovePosFrom.Left := BoardXY[X,Y].Left;
MovePosFrom.Top := BoardXY[X,Y].Top;
end;
//-------------------------------------------------------------------------
//
//.........................................................................
function dTXIANGQI.iQiziIndexAtXY(XY: dTBYTE): dTINT32;
var
i: dTINT32;
begin
for i:= 1 to 32 do
begin
if (XY = Qizi[i].XY) then
begin
iQiziIndexAtXY := i;
Exit;
end;
end;
iQiziIndexAtXY := 0;
end;
//-------------------------------------------------------------------------
// 变量定义
//.........................................................................
var
dCREDNUM: array [1..9] of String[3] = // 红方所用的数字系统
('一','二','三','四','五','六','七','八','九');
dCBLKNUM: array [1..9] of String[3] = // 黑方所用的数字系统
('1','2','3','4','5','6','7','8','9');
function dTXIANGQI.isMoveToValid(XY:dTBYTE; var sPlayRec:String):dTBOOLEAN;
var
i : dTINT32;
qzXY : dTXQZXY;
PN : dTXQPlayNode;
begin
isMoveToValid := False;
for i:=1 to 32 do qzXY[i] := Qizi[i].XY;
sPlayRec:=sGetPlayRecStr(qzXY, QiziMove.XY, XY, ReverseH);
if (sPlayRec='') then Exit;
if (isAddVarStep and (PlayNode.LChild<>nil)) then
begin
PN := PlayNode.LChild;
while (PN<>nil) do
begin
if ((PN.XYf=QiziMove.XY)and(PN.XYt=XY)) then
begin
Application.MessageBox(
'您刚才走的一步变着已经存在,请换一种走法作为变着。',
'系统信息 - 增加新变着',
MB_OK + MB_ICONWARNING + MB_DEFBUTTON1);
Exit;
end;
PN := PN.RChild;
end;
end;
isMoveToValid := True; ;
end;
//-------------------------------------------------------------------------
//
//.........................................................................
function dTXIANGQI.isPlayOneStepOK(XYf, XYt: dTBYTE): dTBOOLEAN;
var
iRecNo : dTINT32;
begin
iRecNo := PlayStepNo;
dStartMoveFromXY(XYf); dStopMoveAtXY(XYt);
isPlayOneStepOK := (iRecNo <> PlayStepNo);
end;
//-------------------------------------------------------------------------
//
//.........................................................................
procedure dTXIANGQI.dUndoMove;
var
X, Y: dTINT32;
begin
X := QiziMove.XY div 10; Y := QiziMove.XY mod 10;
BoardXY[X,Y].Picture := QiziMove.Picture;
BoardXY[X,Y].Cursor := crHandPoint;
BoardXY[X,Y].DragMode := dmAutomatic;
QiziMoveImg.Visible := False;
// 2001-02-15 : 解决点击走子问题。
MovePosTo.Left := BoardXY[X,Y].Left; MovePosTo.Top := BoardXY[X,Y].Top;
MovePosTo.Visible := True;
end;
//-------------------------------------------------------------------------
// 移动结束处理
//.........................................................................
procedure dTXIANGQI.dStopMoveAtXY(XY:dTBYTE);
var
i, X, Y: dTInt32;
sPlayRec : string; // 本步棋的文字记录
qzXY : dTXQZXY;
XYFrom : dTByte;
PN, PNTemp : dTXQPlayNode;
begin
if (QiziMove = nil) then Exit; // 没有棋子移动,返回
if ((PlayStepNo>(dCMaxRecNo-1))or
(not isMoveToValid(XY, sPlayRec))) then // 无效便取消移动
begin
dUndoMove;
Exit;
end;
X := XY div 10; Y := XY mod 10; // 分解X, Y
XYFrom := QiziMove.XY; // 棋子移动的起点
i := iQiziIndexAtXY(XY); // 被吃掉的棋子
if (i <> 0) then begin Qizi[i].XY := $FF; end;
// 将棋子放下
QiziMove.XY := XY; BoardXY[X,Y].Picture := QiziMove.Picture;
// 跟踪棋子的移动,放置移动指示
MovePosTo.Left := BoardXY[X,Y].Left; MovePosTo.Top := BoardXY[X,Y].Top;
MovePosTo.Visible := True;
MovePosFrom.Visible := True;
// 棋子移动的'替身'的任务结束
QiziMoveImg.Visible := False; QiziMove := nil;
dMoveMemoToRecNo(PlayStepNo); // 记录注解(移动前的注解)
PlayStepNo := PlayStepNo + 1; // 行棋记录增加一步
DispStepNo := PlayStepNo;
for i:=1 to 32 do qzXY[i] := Qizi[i].XY;
// 判断是否是增加变着状态
if not isAddVarStep then
begin
// 不是增加变着状态, 则在对弈树中增加一个左孩子节点, 并将当前节点
// 设置为该节点
PN := dTXQPlayNode.Create(PlayStepNo, sPlayRec,
XYFrom, XY, qzXY, nil, PlayNode, nil, PlayNode);
end
else
begin
// 是增加变着状态,则在对弈树中增加一个右孩子节点,并将当前节点
// 设置为该节点, 该节点应加在当前节点的最右后代
PN:= dTXQPlayNode.Create(PlayStepNo, sPlayRec,
XYFrom, XY, qzXY, nil, DispNode, nil, nil);
PNTemp := DispNode.LChild;
if (PNTemp = nil) then begin ShowMessage('Error PNTemp'); Exit; end;
// 寻找最右后代
while (PNTemp.RChild <> nil) do PNTemp := PNTemp.RChild;
PNTemp.dSetRChild(PN);
end;
dAddPlayNodeIntoPlayRec(PN);
PlayNode := PN;
DispNode := PN;
// isAddVarStep := False;
RecListBox.ItemIndex := PlayStepNo;
dDispVarStepAtRecNo(PlayStepNo);
dDispQiziAtRecNo(PlayStepNo); //??
dEnablePlayer(PlayNode);
end;
//-------------------------------------------------------------------------
//
//.........................................................................
procedure dTXIANGQI.dEnablePlayer(WP: dTWHOPLAY);
var
i, j, X, Y, m, n: dTINT32;
begin
if (WP <> wpPause) then WhoPlay := WP; m := 0; n := 0;
for i:=0 to 8 do for j:=0 to 9 do
begin
BoardXY[i,j].Cursor := crDefault;
BoardXY[i,j].DragMode := dmManual;
end;
case WP of
wpNone : Exit;
wpPause : Exit;
wpRed : begin m:=01; n:=16; end;
wpBlk : begin m:=17; n:=32; end;
end;
for i:=m to n do
begin
if (Qizi[i].XY = $FF) then Continue;
X := Qizi[i].XY div 10; Y := Qizi[i].XY mod 10;
BoardXY[X,Y].Cursor := crHandPoint;
BoardXY[X,Y].DragMode := dmAutomatic;
end;
end;
//-------------------------------------------------------------------------
//
//.........................................................................
procedure dTXIANGQI.dEnablePlayer(PN: dTXQPlayNode);
begin
if (PN=nil) then begin dEnablePlayer(wpPause); Exit; end;
if ((PN=PlayTree)and(PlayStepNo=0)and(PN.XYf=0)) then
begin
if (PN.XYt=0) then // 第0步的XYt指示了谁先行
dEnablePlayer(wpRed)
else
dEnablePlayer(wpBlk);
Exit;
end;
if (PN.StepNo<PlayStepNo) then begin dEnablePlayer(wpPause); Exit; end;
case iQiziIndexAtXY(PN.XYt) of
01..16: dEnablePlayer(wpBlk);
17..32: dEnablePlayer(wpRed);
end;
end;
//-------------------------------------------------------------------------
// 显示棋谱记录中某一步的盘面布局 (第0步为开局的盘面)
//.........................................................................
procedure dTXIANGQI.dDispQiziAtRecNo(iRec: dTINT32);
var
i, Xf, Yf, Xt, Yt, iHeight: dTINT32;
begin
if ((iRec<0)or(iRec>PlayStepNo)) then Exit; // 检查步数的有效性
MovePosFrom.Visible := False;
if (IsAutoPlaying and (DispStepNo = (iRec - 1))) then
begin
Xf := PlayRec[iRec].XYf div 10; Yf := PlayRec[iRec].XYf mod 10;
with BoardXY[Xf, Yf] do
begin
iHeight := Height;
Height := 0;
Repaint;
Sleep(333);
Height := iHeight;
Repaint;
Sleep(333);
end;
end;
MovePosTo.Visible := False; // 关掉棋子指示
for i:=1 to 32 do // 清掉无用的棋子
begin
if (Qizi[i].XY <> PlayRec[iRec].QiziXY[i]) then
begin
Xf := Qizi[i].XY div 10; Yf := Qizi[i].XY mod 10;
if (Xf < 10) then BoardXY[Xf, Yf].Picture := nil;
end;
end;
for i:=1 to 32 do // 显示不一样的棋子
begin
if (PlayRec[iRec].QiziXY[i] <> Qizi[i].XY ) then
begin
Xt := PlayRec[iRec].QiziXY[i] div 10;
Yt := PlayRec[iRec].QiziXY[i] mod 10;
if (Xt in [0..8]) then BoardXY[Xt, Yt].Picture := Qizi[i].Picture;
Qizi[i].XY := PlayRec[iRec].QiziXY[i];
end;
end;
if (iRec > 0) then // 显示棋子走动指示
begin
Xf := PlayRec[iRec].XYf div 10;
Yf := PlayRec[iRec].XYf mod 10;
MovePosFrom.Left := BoardXY[Xf,Yf].Left;
MovePosFrom.Top := BoardXY[Xf,Yf].Top;
MovePosFrom.Visible := True;
Xt := PlayRec[iRec].XYt div 10;
Yt := PlayRec[iRec].XYt mod 10;
MovePosTo.Left := BoardXY[Xt,Yt].Left;
MovePosTo.Top := BoardXY[Xt,Yt].Top;
MovePosTo.Visible := True;
end;
dMoveMemoToRecNo(DispStepNo); // 将更新的注解记录下来
dLoadMemoFromRecNo(iRec); // 显示本步棋的注解
dDispVarStepAtRecNo(iRec);
RecListBox.ItemIndex := iRec;
DispStepNo := iRec; // 设置当前显示的记录
DispNode := PlayRec[DispStepNo];
if(@PlayRecHook<>nil) then PlayRecHook;
end;
//-------------------------------------------------------------------------
// 将注解存入对局记录
//.........................................................................
procedure dTXIANGQI.dMoveMemoToRecNo(iRec:dTINT32);
var
PN : dTXQPlayNode;
begin
if (not isMemoEdit) then Exit;
if ((iRec<0)or(iRec>PlayStepNo)) then Exit; // 检查范围
PN := PlayRec[iRec];
if (PN.Remark <> nil) then // 先释放旧的记录
begin
PN.Remark.Free; PN.Remark := nil;
end;
if (RecMemo.Lines.Count>0) then // 有注解
if (not ((RecMemo.Lines.Count=1) and (RecMemo.Lines[0]=''))) then
begin
PN.Remark := TStringList.Create;
PN.Remark.Text := RecMemo.Text;
end;
RecListBox.Items[iRec] := sGetFMTRecStr(PN);
RecMemo.Lines.Clear;
end;
//-------------------------------------------------------------------------
// 将记录中的注解显示出来
//.........................................................................
procedure dTXIANGQI.dLoadMemoFromRecNo(iRec:dTINT32);
var
PN : dTXQPlayNode;
begin
RecMemo.Lines.Clear;
PN := PlayRec[iRec];
if (PN.Remark <> nil) then
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -