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

📄 xqdatat.pas

📁 象棋演播室1.6的dephi源码 作者 董世伟
💻 PAS
📖 第 1 页 / 共 4 页
字号:
      case WP of
        wpRed: if (((Da=0)and(Dy<> 1))or((Da=1)and(Yf<=4))) then Exit;
        wpBlk: if (((Da=0)and(Dy<>-1))or((Da=1)and(Yf>=5))) then Exit;
      end;

      case WP of
      wpRed:
        begin
          sRec := '兵' + sGetRedLine(Xf);

          m := 0;  n := 0;
          for i:=7 downto 1 do
          begin
            if (iGetQZIdxAtXY(Xf*10+i+2) in [12..16]) then
            begin
              m := m + 1;  if ((i+2)>=Yf) then n := n + 1;
            end;
          end;

          case m of
          2: if (n=1) then sRec:='前兵' else sRec:= '后兵';
          3: case n of
             1: sRec:='前兵';
             2: sRec:='中兵';
             3: sRec:='后兵';
             end;
          4: case n of
             1: sRec:='前兵';
             2: sRec:='二兵';
             3: sRec:='三兵';
             4: sRec:='后兵';
             end;
          5: case n of
             1: sRec:='前兵';
             2: sRec:='二兵';
             3: sRec:='三兵';
             4: sRec:='四兵';
             5: sRec:='后兵';
             end;

          end;

          case Dy of
          1 : sRec := sRec + '进' + dCREDNUM[Db];
          0 : sRec := sRec + '平' + sGetRedLine(Xt);
          end;
        end;

      wpBlk:
        begin
          sRec := '卒' + sGetBlkLine(Xf);

          m := 0;  n := 0;
          for i:=1 to 7 do
          begin
            if (iGetQZIdxAtXY(Xf*10+i-1) in [28..32]) then
            begin
              m := m + 1;  if ((i-1)<=Yf) then n := n + 1;
            end;
          end;

          case m of
          2: if (n=1) then sRec:='前卒' else sRec:= '后卒';
          3: case n of
             1: sRec:='前卒';
             2: sRec:='中卒';
             3: sRec:='后卒';
             end;
          4: case n of
             1: sRec:='前卒';
             2: sRec:='二卒';
             3: sRec:='三卒';
             4: sRec:='后卒';
             end;
          5: case n of
             1: sRec:='前卒';
             2: sRec:='二卒';
             3: sRec:='三卒';
             4: sRec:='四卒';
             5: sRec:='后卒';
             end;
          end;

          case Dy of
          -1: sRec := sRec + '进' + dCBLKNUM[Db];
          0 : sRec := sRec + '平' + sGetBlkLine(Xt);
          end;
        end;
      end;
    end;
  end; // End of Case

  for i:=1 to 32 do TempXY[i] := qzXY[i];
  if iGetQZIdxAtXY(XYt) <> 0 then qzXY[iGetQZIdxAtXY(XYt)]:=$FF;
  qzXY[iGetQZIdxAtXY(XYf)]:=XYt;

  // 如果要走子,检查将帅的安全。
  if bMove then
  begin
    // 检查走棋后将帅的安全度
    Xf := qzXY[ 5] div 10;  Yf := qzXY[ 5] mod 10;      // 红帅的位置
    Xt := qzXY[21] div 10;  Yt := qzXY[21] mod 10;      // 黑将的位置

    // 检查将帅是否照面
    if (Xf = Xt) then
    begin
      isKingSafe := False;
      for i:=(Yf+1) to (Yt-1) do if (iGetQZIdxAtXY(Xf*10+i)<>0) then
      begin
        isKingSafe := True;
      end;
      if not isKingSafe then
      begin
        for i:=1 to 32 do qzXY[i] := TempXY[i];
        Exit;
      end;
    end;

    // 检查走子后是否有子要吃掉将帅
    isKingSafe := True;
    case WP of
    wpRed:
      begin
        for i:=17 to 32 do
        begin
          if (qzXY[i] > 89) then continue;
          if sGetPlayRecStr(qzXY, qzXY[i], qzXY[5], bRL, False) <> '' then
          begin
            isKingSafe := False;
            Break;
          end;
        end;
      end;
    wpBlk:
      begin
        for i:=1 to 16 do
        begin
          if (qzXY[i] > 89) then continue;
          if sGetPlayRecStr(qzXY, qzXY[i], qzXY[21], bRL, False) <> '' then
          begin
            isKingSafe := False;
            Break;
          end;
        end;
      end;
    end;
    if not isKingSafe then
    begin
      for i:=1 to 32 do qzXY[i] := TempXY[i];
      Exit;
    end;
  end;

  // 不移动棋子,还原
  if not bMove then for i:=1 to 32 do qzXY[i] := TempXY[i];

  sGetPlayRecStr := sRec;
end;

//-------------------------------------------------------------------------
// 根据棋谱取得坐标的移动,棋谱采用WXF的记录方法
//.........................................................................
function wGetPlayRecXY(qzXY:dTXQZXY;wp: dTWhoPlay;sRecStr:string):dTWord;
var
  s: string;
  i, j, iCol, iRow, iNum : dTInt32;
  qzIdx   : array [1..5] of dTInt32;            // 同一个兵种可能的棋子序号
  qzCnt   : array [1..5] of dTInt32;            // 同一列上的棋子的个数
  qzOrd   : array [1..5] of dTInt32;            // 该棋子在同一列上的次序
  qzMove  : dTInt32;                            // 当前移动的棋子
  qzXYTemp: dTXQZXY;
  Xf, Yf, Xt, Yt, iDx, iDy, XYf, XYt: dTInt32;
  isPawn  : dTBoolean;
begin
  Result := $FFFF;
  if (Length(sRecStr)<>4) then Exit;
  case wp of
    wpRed: sRecStr := UpperCase(sRecStr);
    wpBlk: sRecStr := LowerCase(sRecStr);
  end;

  for i:=1 to 5 do
  begin
    qzIdx[i] := 0;  qzCnt[i] := 0;  qzOrd[i] := 0;
  end;

  // 根据兵种筛选棋子,最多可以选出5个
  isPawn := False;

  case sRecStr[1] of
    'R': begin qzIdx[1]:= 1; qzIdx[2]:= 9; end; // Red: CharRiot
    'H': begin qzIdx[1]:= 2; qzIdx[2]:= 8; end; // Red: Horse
    'E': begin qzIdx[1]:= 3; qzIdx[2]:= 7; end; // Red: Elephant
    'A': begin qzIdx[1]:= 4; qzIdx[2]:= 6; end; // Red: Adviser
    'K': begin qzIdx[1]:= 5;               end; // Red: King
    'C': begin qzIdx[1]:=10; qzIdx[2]:=11; end; // Red: Cannon
    'P': begin
           for i:=1 to 5 do qzIdx[i] := i+11;   // Red: Pawn
           isPawn := True;
         end;

    'r': begin qzIdx[1]:=17; qzIdx[2]:=25; end; // Blk: CharRiot
    'h': begin qzIdx[1]:=18; qzIdx[2]:=24; end; // Blk: Horse
    'e': begin qzIdx[1]:=19; qzIdx[2]:=23; end; // Blk: Elephant
    'a': begin qzIdx[1]:=20; qzIdx[2]:=22; end; // Blk: Adviser
    'k': begin qzIdx[1]:=21;               end; // Blk: King
    'c': begin qzIdx[1]:=26; qzIdx[2]:=27; end; // Blk: Cannon
    'p': begin
           for i:=1 to 5 do qzIdx[i] := i+27;   // Blk: Pawn
           isPawn := True;
         end;

    '+','-','1','2','3','4','5','6','7','8','9':// Red or Blk: Pawn
      begin
        isPawn := True;
        case wp of
          wpRed: for i:=1 to 5 do qzIdx[i]:=i+11;
          wpBlk: for i:=1 to 5 do qzIdx[i]:=i+27;
        end;
      end;

    else Exit;
  end;  // 筛选棋子结束,固定到某个兵种上

  // 计算同一列的棋子的个数和棋子的次序
  for i:=1 to 5 do
  begin
    if (qzIdx[i]=0) then break;
    if (qzXY[qzIdx[i]]=$FF) then continue;
    iCol := qzXY[qzIdx[i]] div 10;
    iRow := qzXY[qzIdx[i]] mod 10;
    for j:=1 to 5 do
    begin
      if (qzIdx[j]=0) then break;
      if (qzXY[qzIdx[j]]=$FF) then continue;
      if ((qzXY[qzIdx[j]] div 10)=iCol) then
      begin
        Inc(qzCnt[i]);
        case wp of
          wpRed: if ((qzXY[qzIdx[j]] mod 10)>=iRow) then Inc(qzOrd[i]);
          wpBlk: if ((qzXY[qzIdx[j]] mod 10)<=iRow) then Inc(qzOrd[i]);
        end;
      end;
    end;
  end;

  // 根据前面筛选的结果和棋谱的第二个字符,确定移动的棋子(以序号表示)
  qzMove := 0;
  case sRecStr[2] of
    '1','2','3','4','5','6','7','8','9':        // 以数字表示
      begin
        iCol := Ord(sRecStr[2]) - Ord('0');     // 取得数字的值

        // 计算绝对坐标线X
        case wp of
          wpRed: iCol := 9 - iCol;
          wpBlk: iCol := iCol - 1;
        end;
        // 此时,iCol是当前移动棋子的X坐标

        for i:=1 to 5 do                        // 从5个侯选棋子中找
        begin
          if (qzIdx[i]=0) then Exit;            // 找不到,退出
          if ((qzXY[qzIdx[i]] div 10)=iCol) then
          begin                                 // 找到
            if isPawn then                      // “兵、卒”的情况要特殊处理
            begin
              if ((qzCnt[i]=1) or               // 单兵在一条线上
                ((qzCnt[i]=3)and(qzOrd[i]=2)) or    // 三兵在一线的中间兵
                ((qzCnt[i]=5)and(qzOrd[i]=3))) then // 五兵在一线的中间兵
              begin
                qzMove := qzIdx[i];             // qzMove为当前棋子的序号
              end;
            end
            else                                // 除兵卒外的其它兵种
            begin
              case qzCnt[i] of
                1:                              // 不出现两个同样兵种在同一列上
                  begin
                    qzMove := qzIdx[i];         // qzMove为当前棋子的序号
                  end;
                2:                              // 有两个同样的兵种在同一列上
                  begin
                    qzXYTemp := qzXY;  s := sRecStr;
                    case qzOrd[i] of
                      1: s[2] := '+';
                      2: s[2] := '-';
                    end;
                    if (wGetPlayRecXY (qzXYTemp, wp, s)<>$FFFF) then qzMove := qzIdx[i];
                  end;
              end;
            end;
          end;
          if (qzMove<>0) then break;
        end;
        if (i>5) then Exit;                     // 找不到,退出
      end;

    '+', '-':                                   // 以‘前,后’表示
      begin
        if isPawn then                          // “兵、卒”的情况要特殊处理
        begin
          case sRecStr[1] of
            'P','p':
              begin
                for i:=1 to 5 do
                begin
                  case qzCnt[i] of
                    2: case sRecStr[2] of
                         '+': if (qzOrd[i]=1) then qzMove := qzIdx[i]; 
                         '-': if (qzOrd[i]=2) then qzMove := qzIdx[i]; 
                       end;

                    3: case sRecStr[2] of
                         '+': if (qzOrd[i]=1) then qzMove := qzIdx[i]; 
                         '-': if (qzOrd[i]=3) then qzMove := qzIdx[i]; 
                       end;

                    4: case sRecStr[2] of
                         '+': if (qzOrd[i]=2) then qzMove := qzIdx[i]; 
                         '-': if (qzOrd[i]=3) then qzMove := qzIdx[i]; 
                       end;

                    5: case sRecStr[2] of
                         '+': if (qzOrd[i]=2) then qzMove := qzIdx[i]; 
                         '-': if (qzOrd[i]=4) then qzMove := qzIdx[i]; 
                       end;
                  end;
                  if (qzMove<>0) then break;
                end;
              end;

            '+','-':
              begin
                if ((sRecStr[1]='+')and(sRecStr[2]='-')) then Exit;
                if ((sRecStr[1]='-')and(sRecStr[2]='+')) then Exit;

                for i:=1 to 5 do
                begin
                  case qzCnt[i] of
                    4: case sRecStr[2] of
                         '+': if (qzOrd[i]=1) then qzMove := qzIdx[i]; 
                         '-': if (qzOrd[i]=4) then qzMove := qzIdx[i]; 
                       end;

                    5: case sRecStr[2] of
                         '+': if (qzOrd[i]=1) then qzMove := qzIdx[i]; 
                         '-': if (qzOrd[i]=5) then qzMove := qzIdx[i]; 
                       end;
                  end;
                  if (qzMove<>0) then break;
                end;
              end;
            '1','2','3','4','5','6','7','8','9':
              begin
                iCol := Ord(sRecStr[1]) - Ord('0');
                for i:=1 to 5 do
                begin
                  if (qzCnt[i]<2) then continue;
                  if ((qzXY[qzIdx[i]] div 10)<>iCol) then continue;
                  case qzCnt[i] of
                    2: case sRecStr[2] of
                         '+': if (qzOrd[i]=1) then qzMove := qzIdx[i]; 
                         '-': if (qzOrd[i]=2) then qzMove := qzIdx[i]; 
                       end;

                    3: case sRecStr[2] of
                         '+': if (qzOrd[i]=1) then qzMove := qzIdx[i]; 
                         '-': if (qzOrd[i]=3) then qzMove := qzIdx[i];
                         '1','2','3','4','5','6','7','8','9':
                            if (qzOrd[i]=2) then qzMove := qzIdx[i]; 
                       end;
                  end;
                  if (qzMove<>0) then break;
                end;
              end;
          end;
        end
        else
        begin
          case sRecStr[2] of
            '+': for i:=1 to 2 do if (qzOrd[i]=1) then qzMove:=qzIdx[i];
            '-': for i:=1 to 2 do if (qzOrd[i]=2) then qzMove:=qzIdx[i];
          end;
        end;
      end;

    else Exit;
  end;

  // 此时,找到当前移动棋子的序号qzMove
  if ((qzMove<1) or (qzMove>32)) then Exit;     // 安全性检查
  if (qzXY[qzMove]=$FF) then Exit;              // 不能为“死”子
  
  Xf := qzXY[qzMove] div 10;  Xt := Xf;         // 给移动坐标赋值
  Yf := qzXY[qzMove] mod 10;  Yt := Yf;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -