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

📄 xqsystem.pas

📁 象棋演播室1.6的dephi源码 作者 董世伟
💻 PAS
📖 第 1 页 / 共 3 页
字号:
///////////////////////////////////////////////////////////////////////////////
//
// XQStduio Source Code (http://www.qipaile.net/xqstudio)
//
// Copyright (c) 1998-2008, DONG Shiwei (董世伟 or 过河象)
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 
//    1) Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//    2) Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer
//       in the documentation and/or other materials provided with the
//       distribution.
//    3) Neither the name of the XQStudio nor the names of its contributors
//       may be used to endorse or promote products derived from this
//       software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
//
// Note: Some characters of this file are Simplified Chinese characters 
//       encoded with GB2312/GB18030 standard
//

unit XQSystem;

//-------------------------------------------------------------------------
//
//.........................................................................
interface

//-------------------------------------------------------------------------
//
//.........................................................................
uses
  Windows, SysUtils, Classes, Graphics, Forms, Controls, Menus,
  StdCtrls, Dialogs, Buttons, Messages, ExtCtrls, ComCtrls, StdActns,
  ActnList, ToolWin, ImgList, dDelphiS, XQDataT, XQPNode, XQRecLBX;

//-------------------------------------------------------------------------
//  类型定义
//.........................................................................
type

  //-----------------------------------------------------------------------
  // 定义象棋子类
  //.......................................................................
  dTXQZ = class
    Index       : dTINT32;      // 棋子索引
    Name        : String[16];   // 棋子名称
    Picture     : TPicture;     // 棋子图像
    Arms        : 1..7;         // 兵种,依次为:车马象士将炮兵
    XYStart     : dTBYTE;       // 棋子的开局位置(指原始位置)
    XY          : dTBYTE;       // 棋子的位置(指棋子在棋盘上当前的位置)
   public
    constructor Create(iIdx:dTINT32; sName:String; pic:TPicture;
                       iArms:dTBYTE; bXYStart:dTBYTE);
  end;

  //-----------------------------------------------------------------------
  // 定义象棋计时钟
  //.......................................................................
  dTXQCLOCK = class
    Name        : String[16];
  public
    constructor Create;
    destructor Destroy; override;
  end;



  //-----------------------------------------------------------------------
  // 定义象棋类
  //.......................................................................
  dTXiangQi = class
  public
    BoardImage  : TImage;                       // 象棋盘图像
    BoardXY     : dTXQPXY;                      // 棋盘9x10个交叉点
    QiziMoveImg : TImage;                       // 移动中棋子的图像
                                                // 用来处理移动
    Qizi        : array [1..32] of dTXQZ;       // 32个象棋子
    QiziMove    : dTXQZ;                        // 被拿起移动的棋子
    MovePosFrom : TImage;                       // 最后移动过的棋子的位置
    MovePosTo   : TImage;                       //   用来显示走棋指示
    Clock       : dTXQCLOCK;                    // 计时钟
    RedPlayer   : String[32];                   // 红方棋手
    BlkPlayer   : String[32];                   // 黑方棋手
    RecListBox  : TListBox;                     // 棋谱记录列表框
    VarListBox  : TListBox;                     // 变着记录列表框
    isAddVarStep: dTBoolean;                    // 是否是加入变着状态
    RecMemo     : TMemo;                        // 注解备注
    isMemoEdit  : dTBoolean;
    PlayStepNo  : dTINT32;                      // 当前行棋的总步数
    DispStepNo  : dTINT32;                      // 当前显示的屏幕是第几步棋
    PlayNode    : dTXQPlayNode;                 // 当前最后一步棋的节点
    DispNode    : dTXQPlayNode;                 // 当前棋盘显示的棋的节点
    WhoPlay     : dTWHOPLAY;                    // 轮到谁下
    ReverseH    : Boolean;                      // 左右对换标志
    PlayRec     : array [0..dCMaxRecNo] of dTXQPlayNode; // 行棋记录(棋谱)
    PlayVar     : array [0..dCMaxVarNo] of dTXQPlayNode;
    PlayTree    : dTXQPlayNode;                 // 对弈树
    PlayRecHook : procedure;
    RefreshHook : procedure;

    //XQRecLBX    : dTXQRecListBox;
  private
    function sGetFMTRecStr(PN: dTXQPlayNode): string;

  public
    constructor Create(imgBoard: TImage; imgXY: dTXQPXY; imgQZMove: TImage;
                       imgMovePosF, imgMovePosT:TImage; picQZ:dTXQZPIC;
                       lbxRec,lbxOther:TListBox; memRec: TMemo); overload;
    constructor Create(imgBoard:TImage;imgXY:dTXQPXY;imgQZMove:TImage;
                       imgMovePosF, imgMovePosT:TImage;picQZ:dTXQZPIC;
                       lbxRec,lbxOther:TListBox;
                       memRec:TMemo;XQZXY:dTXQZXY); overload;
    destructor Destroy; override;

    procedure dStartMoveFromXY(XY:dTBYTE);      // 从XY处开始移动棋子
    procedure dStopMoveAtXY(XY:dTBYTE);         // 移动停止到XY处
    function  isMoveToValid(XY:dTBYTE; var sPlayRec:String):dTBOOLEAN;
                // 判断移动是否合乎规则, sPlayRec 记录本步棋谱

//    function  GetPlayRecStr(qzXY:dTXQZXY; WP:dTWhoPlay;
//                            XYf,XYt:dTBYTE):string;
    procedure dUndoMove;                        // 取消移动
    function  iQiziIndexAtXY(XY:dTBYTE):dTINT32;// 取XY处的棋子索引号
    function  isPlayOneStepOK(XYf, XYt: dTBYTE): dTBOOLEAN;
                // 判断从XYf移动到XYt是否合乎规则, 若合乎规则,真正执行
    procedure dEnablePlayer(WP:dTWHOPLAY); overload; // 允许一方走棋
    procedure dEnablePlayer(PN:dTXQPlayNode); overload;
    procedure dDeleteOnePlayRec(bRefresh: Boolean=True); // 删除最后一步对局记录
    procedure dDeleteOnePlayNode;               // 删除刚刚走过的一步棋的节点
    procedure dDeletePlayVar(PN:dTXQPlayNode);
    procedure dRefreshBoard(ReStart:Boolean);
                // 刷新当前棋局, Restart = True 表示从第0步开始(复位)
    procedure dDispQiziAtRecNo(iRec: dTINT32);  // 显示iRec步的棋局
    procedure dMoveMemoToRecNo(iRec:dTINT32);   // 将注解移入对局记录
    procedure dLoadMemoFromRecNo(iRec:dTINT32); // 将记录中的注解显示出来
    function  isHighlightVarStepActive: Boolean;
    procedure dMovePlayVarUp;
    procedure dMovePlayVarDown;

    procedure dDispVarStepAtRecNo(iRec:dTInt32);
    procedure dLoadAllRecForPlayNode(PN:dTXQPlayNode);
    procedure dAddPlayNodeIntoPlayRec(PN:dTXQPlayNode);
    procedure dOnRecListBoxClick;               // 响应单击棋局记录事件
    procedure dOnVarListBoxDblClick;
    procedure dOnRecMemoChange;
    procedure dRefreshRecStr;
//    procedure dReverseBoard;                    // 棋盘倒转180度
  end;

const
dCXqzXY: dTXQZXY = (80,70,60,50,40,30,20,10,00,72,12,83,63,43,23,03,
                      09,19,29,39,49,59,69,79,89,17,77,06,26,46,66,86);


var
  IsAutoPlaying: Boolean = False;

///////////////////////////////////////////////////////////////////////////
implementation

//-------------------------------------------------------------------------
//
//.........................................................................
constructor dTXQZ.Create(iIdx:dTINT32; sName:String; pic:TPicture;
                         iArms:dTBYTE; bXYStart:dTBYTE);
begin
  Name := sName;  Picture := pic;  Arms := iArms; XYStart := bXYStart;
end;

//-------------------------------------------------------------------------
//
//.........................................................................
constructor dTXQCLOCK.Create;
begin
  ShowMessage('XQCLOCK Create');
end;

destructor dTXQCLOCK.Destroy;
begin

end;


//-------------------------------------------------------------------------
// 象棋类的构造函数
//.........................................................................
constructor dTXIANGQI.Create(imgBoard:TImage;imgXY:dTXQPXY;imgQZMove:TImage;
                             imgMovePosF,imgMovePosT:TImage;picQZ:dTXQZPIC;
                             lbxRec,lbxOther:TListBox;
                             memRec:TMemo; XQZXY:dTXQZXY);
var
  i, j: dTINT32;
begin
  BoardImage := imgBoard;                       // 棋盘图片

  for i:=0 to 8 do for j:=0 to 9 do             // 创建象棋盘中的'兵站'
  begin
    BoardXY[i,j]         := imgXY[i, j];
    BoardXY[i,j].Tag     := i*10 + j;           // Tag 中存有'兵站'坐标
    BoardXY[i,j].Picture := nil;
  end;

  QiziMoveImg := imgQZMove;                     // 拿起移动的棋子的图片

  QiziMove    := nil;                           // 正在移动的棋子

  MovePosFrom         := imgMovePosF;
  MovePosTo           := imgMovePosT;           // 最后移动的棋子的指示
  MovePosTo.Visible   := False;                 // 关掉棋子指示
  MovePosFrom.Visible := False;

  // 创建32个象棋子(需要QiziPic数组)
  QiZi[ 1] := dTXQZ.Create( 1, '车', picQZ[ 1], 1, 80); // Red
  QiZi[ 2] := dTXQZ.Create( 2, '马', picQZ[ 2], 2, 70);
  QiZi[ 3] := dTXQZ.Create( 3, '相', picQZ[ 3], 3, 60);
  QiZi[ 4] := dTXQZ.Create( 4, '士', picQZ[ 4], 4, 50);
  QiZi[ 5] := dTXQZ.Create( 5, '帅', picQZ[ 5], 5, 40);
  QiZi[ 6] := dTXQZ.Create( 6, '士', picQZ[ 4], 4, 30);
  QiZi[ 7] := dTXQZ.Create( 7, '相', picQZ[ 3], 3, 20);
  QiZi[ 8] := dTXQZ.Create( 8, '马', picQZ[ 2], 2, 10);
  QiZi[ 9] := dTXQZ.Create( 9, '车', picQZ[ 1], 1, 00);
  QiZi[10] := dTXQZ.Create(10, '炮', picQZ[ 6], 6, 72);
  QiZi[11] := dTXQZ.Create(11, '炮', picQZ[ 6], 6, 12);
  QiZi[12] := dTXQZ.Create(12, '兵', picQZ[ 7], 7, 83);
  QiZi[13] := dTXQZ.Create(13, '兵', picQZ[ 7], 7, 63);
  QiZi[14] := dTXQZ.Create(14, '兵', picQZ[ 7], 7, 43);
  QiZi[15] := dTXQZ.Create(15, '兵', picQZ[ 7], 7, 23);
  QiZi[16] := dTXQZ.Create(16, '兵', picQZ[ 7], 7, 03);
  QiZi[17] := dTXQZ.Create(17, '车', picQZ[ 8], 1, 09); // Blk
  QiZi[18] := dTXQZ.Create(18, '马', picQZ[ 9], 2, 19);
  QiZi[19] := dTXQZ.Create(19, '象', picQZ[10], 3, 29);
  QiZi[20] := dTXQZ.Create(20, '士', picQZ[11], 4, 39);
  QiZi[21] := dTXQZ.Create(21, '将', picQZ[12], 5, 49);
  QiZi[22] := dTXQZ.Create(22, '士', picQZ[11], 4, 59);
  QiZi[23] := dTXQZ.Create(23, '象', picQZ[10], 3, 69);
  QiZi[24] := dTXQZ.Create(24, '马', picQZ[ 9], 2, 79);
  QiZi[25] := dTXQZ.Create(25, '车', picQZ[ 8], 1, 89);
  QiZi[26] := dTXQZ.Create(26, '炮', picQZ[13], 6, 17);
  QiZi[27] := dTXQZ.Create(27, '炮', picQZ[13], 6, 77);
  QiZi[28] := dTXQZ.Create(28, '卒', picQZ[14], 7, 06);
  QiZi[29] := dTXQZ.Create(29, '卒', picQZ[14], 7, 26);
  QiZi[30] := dTXQZ.Create(30, '卒', picQZ[14], 7, 46);
  QiZi[31] := dTXQZ.Create(31, '卒', picQZ[14], 7, 66);
  QiZi[32] := dTXQZ.Create(32, '卒', picQZ[14], 7, 86);

  PlayTree := dTXQPlayNode.Create(0,'========= ',0,0,XQZXY,nil,nil,nil,nil);
  PlayNode := PlayTree;

  // 32个棋子的当前位置
  for i:=1 to 32 do
  begin
    Qizi[i].XY           := $FF;        // 棋子均不在棋盘上
    PlayTree.QiziXY[i] := XQZXY[i];
  end;

  PlayRec[0] := PlayTree;

  RecListBox := lbxRec;
  VarListBox := lbxOther;
  RecMemo    := memRec;
  RecListBox.Items.Add(' ============ ');

  //  Clock       : dTXQCLOCK;                    // 计时钟

  RedPlayer := 'RedPlayer';
  BlkPlayer := 'BlkPlayer';

  PlayStepNo:= 0; // 当前行棋的总步数

  PlayRecHook := nil;
  RefreshHook := nil;

  ReverseH    := False;

  dDispQiziAtRecNo(0);
  dEnablePlayer(PlayTree);
end;

constructor dTXIANGQI.Create(imgBoard:TImage;imgXY:dTXQPXY;imgQZMove:TImage;
                             imgMovePosF,imgMovePosT:TImage;picQZ:dTXQZPIC;
                             lbxRec,lbxOther:TListBox;memRec:TMemo);
begin
  Create(imgBoard,imgXY,imgQZMove,imgMovePosF,imgMovePosT,picQZ,
         lbxRec,lbxOther,memRec,dCXQZXY);
end;

destructor dTXIANGQI.Destroy;
var
  i: dTINT32;
begin
  for i:=1 to 32 do Qizi[i].Destroy;
  //XQRecLBX.Free;
  PlayTree.Free;
  inherited Destroy;
end;

function dTXiangQi.sGetFMTRecStr(PN: dTXQPlayNode):string;
var
  s : string;
begin
  sGetFMTRecStr := '';
  if (PN=nil) then Exit;
  case PN.StepNo mod 2 of
    1:
      begin
        s := IntToStr((PN.StepNo + 1) div 2);
        case Length(s) of
          1: s := '  ' + s;
          2: s := ' ' + s;
        end;
        s := s + '. ' + PN.StrRec + ' ';
      end;
    0:
      begin
        s := '     ' + PN.StrRec + ' ';
      end;
  end;
  if (PN=PlayTree) then s := ' ============ ';

  if ((PN.LParent<>nil)or(PN.RChild<>nil)) then s := s + 'm';
  if PN.Remark <> nil then s := s + '*';

  sGetFMTRecStr := s;
end;


//-------------------------------------------------------------------------
//
//.........................................................................
procedure dTXIANGQI.dStartMoveFromXY(XY:dTBYTE);
var
  iIdx, X, Y: dTINT32;
begin
  QiziMove := nil;  X := XY div 10;  Y := XY mod 10;

⌨️ 快捷键说明

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