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

📄 chessboard.pas

📁 基于delphi7.0
💻 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 + -