⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xqsystem.pas

📁 象棋演播室1.6的dephi源码 作者 董世伟
💻 PAS
📖 第 1 页 / 共 3 页
字号:
  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 + -