unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Menus, ExtCtrls, StdCtrls, Buttons,Unit2,Unit3;typeTForm1 = class(TForm)PaintBox1: TPaintBox;MainMenu1: TMainMenu;Game1: TMenuItem;NewGame1: TMenuItem;Eixt1: TMenuItem;Label1: TLabel;Label2: TLabel;Label3: TLabel;BitBtn1: TBitBtn;BitBtn3: TBitBtn;Label4: TLabel;s1: TMenuItem;N1: TMenuItem;N2: TMenuItem;N3: TMenuItem;N4: TMenuItem;N5: TMenuItem;N6: TMenuItem;N7: TMenuItem;N8: TMenuItem;GroupBox1: TGroupBox;PaintBox2: TPaintBox;BitBtn2: TBitBtn;BitBtn4: TBitBtn;BitBtn5: TBitBtn;BitBtn6: TBitBtn;GroupBox2: TGroupBox;Memo1: TMemo;BitBtn7: TBitBtn;N9: TMenuItem;N10: TMenuItem;N11: TMenuItem;N12: TMenuItem;N13: TMenuItem;RadioGroup1: TRadioGroup;RadioGroup2: TRadioGroup;procedure FormCreate(Sender: TObject);procedure PaintBox1Paint(Sender: TObject);procedure NewGame1Click(Sender: TObject);procedure Eixt1Click(Sender: TObject);procedure CrossPaint(x,y,i,j:integer); //自定义画兵格过程procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);procedure FindDrop(NowR,NowC:integer); //扫描可以走棋的点过程procedure PaintCMoveDrop(); //画出可走点过程procedure WhoWin(); //判断输赢过程procedure IsNextWin();//判断是否将军procedure RemHistory();//走棋记录procedure RepentChess(n:integer);procedure FindAGoodMove(); //寻找一个优秀的走法procedure AddPoint(row,column:integer);//加入一个相关点function Eveluate(nSide:integer):integer;//估值函数function Eveluate1(nSide:integer):integer;//测试估值函数function GetRelatePiece(row,column:integer):integer;//枚举一个位置上棋子所有相关的点function GetBingValue(row,column:integer):integer;//为兵返回附加值//创建可能的走法 nPly记录扫描的层数,nSide记录到那边走棋 0为红方,1为黑方 function CreatePossibleMove(nPly,nSide:integer):integer;function MakeMove(depth,n:integer):integer;//猜想过程中生产一个新局面procedure UnMakeMove(depth,n,nChessID:integer); //猜想过程中根据走法恢复一个棋盘function IsGameOver(depth:integer):integer;//猜想过程中判断给定局面是否结束 function AddMove(FormR,FormC,ToR,ToC,nPly:integer):integer;//在nMoveList中插入一个走法function NegaMax(depth:integer):integer; //深度优先搜索负极大技校function Alpha_Beta(depth,alpha,beta:integer):integer;//Alpha-Beta搜索算法 function ChessMoveLaw(NowR,NowC,ToR,ToC,nChessID:integer):boolean; //走棋规则函数function ChessMoveLawPos(NowR,NowC,ToR,ToC,nChessID:integer):boolean; //猜想过程走棋规则函数function CanTouch(NowR,NowC,ToR,ToC,nChessID:integer):boolean;//判断能不能到达目标点function ChessPutLaw(NowR,NowC,ToR,ToC:integer):boolean; //摆起规则函数function ChessMove(NowR,NowC,ToR,ToC:integer):boolean; //走棋函数function AIChessMove(NowR,NowC,ToR,ToC:integer):boolean; //电脑走棋procedure BitBtn1Click(Sender: TObject);procedure FormPaint(Sender: TObject);procedure BitBtn3Click(Sender: TObject);procedure N3Click(Sender: TObject);procedure N2Click(Sender: TObject);procedure N6Click(Sender: TObject);procedure N7Click(Sender: TObject);procedure PaintBox2Paint(Sender: TObject);procedure N8Click(Sender: TObject);procedure PaintBox2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);procedure BitBtn5Click(Sender: TObject);procedure BitBtn4Click(Sender: TObject);procedure BitBtn2Click(Sender: TObject);procedure BitBtn6Click(Sender: TObject);procedure BitBtn7Click(Sender: TObject);procedure N11Click(Sender: TObject);procedure N12Click(Sender: TObject);procedure N13Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;//棋盘格子单位大小mBit:integer;//棋子数组:所有棋子的数值mChess: array[1..14] of string =('车','马','相','士','帅','炮','兵','車','馬','象','仕','将','炮','卒');//===============================棋子价值==============================// //棋子的基础价值m_BaseValue: array[1..14] of integer=(500,350,250,250,10000,370,100,500,350,250,250,10000,370,100);//棋子灵活度基础价值m_Flexible:array[1..14] of integer=(6,12,1,1,0,6,15,6,12,1,1,0,6,15);//每一个位置上的棋子的灵活性即可走步数m_FlexibleNum:array[1..10,1..9]of integer;//每一个位置被威胁的信息m_AttackNum:array[1..10,1..9]of integer;//每一个位置被保护的信息m_GuardNum:array[1..10,1..9]of integer;//每一个棋子是总价值m_ChessValue:array[1..10,1..9]of integer;//红兵附加值矩阵mBing:array[1..10,1..9]of integer=((0,0,0,0,0,0,0,0,0),(90,90,110,120,120,120,110,90,90),(90,90,110,120,120,120,110,90,90),(70,90,110,110,110,110,110,90,70),(70,70,70,70,70,70,70,70,70),(0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0));//黑卒附加值矩阵mZhuzi:array[1..10,1..9]of integer=((0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0),(70,70,70,70,70,70,70,70,70),(70,90,110,110,110,110,110,90,70),(90,90,110,120,120,120,110,90,90),(90,90,110,120,120,120,110,90,90),(0,0,0,0,0,0,0,0,0));//===============================棋子价值==============================////棋盘两边的数表NumWord1:array[1..9] of string =('1','2','3','4','5','6','7','8','9');NumWord2:array[1..10] of string=('一','二','三','四','五','六','七','八','九','十');NumWord3:array[1..14] of integer=//摆子时盒子里剩余的棋子数量(2,2,2,2,1,2,5,2,2,2,2,1,2,5);//棋盘数组:记录什么位置有什么棋子有子地方为mChess里面的数值,无子为0 ChessBoard: array[1..10,1..9] of integer;//电脑猜想时棋盘数组:记录什么位置有什么棋子有子地方为mChess里面的数值,无子为0nPosition: array[1..10,1..9] of integer;//自定义棋盘盒子数组ChessBox:array[1..2,1..7]of integer;//定义导航点数组能走的坐标点存在数组中值为1,不能走为0CMoveDrop:array[1..10,1..9] of integer;//棋盘1拾子标志(True表示已经拾取一个棋子)mPickFlag : boolean;//棋盘2拾子标志(True表示已经拾取一个棋子)mPickFlag2:boolean;//在paintbox1拾起棋子的值mPickChess: integer;//在paintbox2拾起的棋子值mPickChess2:integer;//拾起棋子的行号mPickRow : integer;//拾起棋子的列号mPickColumn :integer;//最大价值棋子的行列MVCRow,MVCColumn:integer;//走棋规则,允许落子标志CanDropFlag : boolean;//鼠标在Paintbox1点中坐标MouseRow,MouseColumn:integer;//鼠标在paintbox2点中的坐标MouseR2,MouseC2:integer;//定义到谁走棋WhoPlay:string;//定义先手方FirstPlay:string;GameMode:integer; //定义游戏模式 1:人人对弈 2:人机对弈 3:自定义棋局 4:思考模式//拾起棋子为哪一方 1为红方,0为黑方mPWhoPlay:string;//判定是否移动棋子IsMove:boolean;//胜利Win : boolean;//走棋步数MCSteep:integer;//总的走法数mMoveCount:integer;//相关位置点的总数mPosCount:integer;//调用估值函数的次数useEveluateCount:integer;//搜索的最大深度mMaxDepth:integer;//Memo1当前加上的最后一行MemoMaxLine:integer;type //自定义记录类型用来记录走棋记录ChessRecord=recordChessBoard:array[1..10,1..9]of integer;Win:boolean;WhoPlay:string;end;varHistory:array[0..300]of ChessRecord;typeHaveNum=recordNumber:integer;end;var ChessHaveNum:array[1..14]of HaveNum; //自定义棋盘是摆起盒子里面剩余的棋子数typePoint=recordrow:integer;column:integer;end;varRelatePos:array[1..20]of Point; //与一个棋子相关的位置typeMoveList=record //走法列表FormR:integer;FormC:integer;ToR:integer;ToC:integer;end;varnMoveList:array[0..10,1..100]of MoveList; //走法列表nBestMove:MoveList;//最佳走法implementationend.implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject); vari,j: integer;begin//设置棋盘格子单位大小,控制棋盘大小mBit:=50; //建议在45~55之间 50最佳//设置paintbox1的大小和位置paintbox1.Top:=65;paintbox1.Left:=10;paintbox1.Width:=10*mBit;paintbox1.Height:=11*mBit;//设置label1的大小和位置label1.Width:=150;label1.Height:=37;label1.Left:=15*mBit+15;label1.Top:=15;//设置label2的位置大小label2.Width:=115;label2.Height:=37;label2.Left:=13*mBit;label2.Top:=15;//设置label3的位置label3.Left:=30;label3.Top:=15;//初始化胜利提示label4.Caption:='';//设置form1的大小和颜色form1.Width:=19*mBit;form1.Height:=14*mBit;//初始化可走点for i:=1 to 10 dofor j:=1 to 9 doCMoveDrop[i,j]:=0;//初始化棋盘数组for i:=1 to 10 dofor j:=1 to 9 dobeginChessBoard[i,j]:=0;nPosition[i,j]:=0;end;//初始化先手FirstPlay:='';//初始化游戏模式GameMode:=0;//拾子标志为falsemPickFlag:=false;//能走棋标志为falseCanDropFlag:=false;//是否移动棋子为falseIsMove:=false;//初始化走棋步数MCSteep:=0;//初始化最大走法数mMoveCount:=0;//初始化相关位置数mPosCount:=0;//初始化游戏模式、先手方、电脑难度 GameMode:=2;N7.Checked:=true;FirstPlay:='红';N2.Checked:=true;mMaxDepth:=3;N12.Checked:=true;//胜利标志win:=false;end;procedure TForm1.PaintBox1Paint(Sender: TObject);vari,j:integer;beginlabel3.Caption:='走棋步数:第'+inttostr(MCSteep)+'步';//初始化胜利提示label4.Caption:='';:='宋体';label1.Font.Size:=25;label1.Caption:=WhoPlay+'方走棋';//<=========================画棋盘begin============================> paintbox1.Canvas.Pen.Width:=2;paintbox1.Canvas.Pen.Color:=clblack;paintbox1.Canvas.Brush.Color:=clSilver;//画出棋盘的外框paintbox1.Canvas.Rectangle(0,0,10*mBit,11*mBit); //棋盘外框for i:=1 to 9 do //棋盘边的行标和列标beginpaintbox1.Canvas.TextOut(i*mBit-3,10,NumWord1[i]);paintbox1.Canvas.TextOut(i*mBit-3,10*mBit+25,NumWord1[i]);end;for i:=1 to 10 dobeginpaintbox1.Canvas.TextOut(10,i*mBit-5,NumWord2[i]);paintbox1.Canvas.TextOut(9*mBit+25,i*mBit-5,NumWord2[i]);end;:='宋体';paintbox1.Canvas.font.Size:=mBit div 2;paintbox1.Canvas.TextOut(mBit+35,5*mBit+8,' 楚河汉界');//棋盘外边的字//棋盘两边的纵向直线paintbox1.Canvas.MoveTo(mBit,mBit);paintbox1.Canvas.LineTo(mBit,10*mBit); paintbox1.Canvas.MoveTo(9*mBit,mBit); paintbox1.Canvas.LineTo(9*mBit,10*mBit);//棋盘上面的横向直线for i:=1 to 10 dobeginpaintbox1.Canvas.MoveTo(mBit,i*mBit);paintbox1.Canvas.LineTo(9*mBit,i*mBit);end;//棋盘上的纵向直线for i:=2 to 8 dobeginpaintbox1.Canvas.MoveTo(i*mBit,mBit);paintbox1.Canvas.LineTo(i*mBit,5*mBit); paintbox1.Canvas.MoveTo(i*mBit,6*mBit); paintbox1.Canvas.LineTo(i*mBit,10*mBit); end;//棋盘上的田字格斜线paintbox1.Canvas.MoveTo(4*mBit,mBit); paintbox1.Canvas.LineTo(6*mBit,3*mBit); paintbox1.Canvas.MoveTo(4*mBit,3*mBit); paintbox1.Canvas.LineTo(6*mBit,mBit);paintbox1.Canvas.MoveTo(4*mBit,8*mBit); paintbox1.Canvas.LineTo(6*mBit,10*mBit); paintbox1.Canvas.MoveTo(4*mBit,10*mBit); paintbox1.Canvas.LineTo(6*mBit,8*mBit);//画兵格炮格i:=1;repeatCrossPaint(i*mBit,4*mBit,5,15);//黑方兵格 CrossPaint(i*mBit,7*mBit,5,15);//红方兵格 i:=i+2;until i>9;//黑方炮格CrossPaint(2*mBit,3*mBit,5,15);CrossPaint(8*mBit,3*mBit,5,15);//红方炮格CrossPaint(2*mBit,8*mBit,5,15);CrossPaint(8*mBit,8*mBit,5,15);//<=========================画棋盘end============================>//<=========================画棋子begin================================>for i:=1 to 10 dofor j:=1 to 9 doif ChessBoard[i,j]<> 0 thenbeginpaintbox1.Canvas.Brush.Color:=clBtnFace;//画出棋子if ChessBoard[i,j]<=7 thenbeginpaintbox1.Canvas.Pen.Width:=2;paintbox1.Canvas.Pen.Color:=clred;paintbox1.Canvas.Ellipse(j*mBit-22,i*mBit-22,j*mBit+22,i*mBit+22);paintbox1.Canvas.Font.Size:=22;:='隶书';paintbox1.Canvas.Font.Color:=clred;paintbox1.Canvas.TextOut(j*mBit-15,i*mBit-15,mChess[ChessBoard[i,j]]); endelsebeginpaintbox1.Canvas.Pen.Width:=2;paintbox1.Canvas.Pen.Color:=clblack;paintbox1.Canvas.Ellipse(j*mBit-22,i*mBit-22,j*mBit+22,i*mBit+22);paintbox1.Canvas.font.Size:=22;:='隶书';paintbox1.Canvas.Font.Color:=clblack;paintbox1.Canvas.TextOut(j*mBit-15,i*mBit-15,mChess[ChessBoard[i,j]]); endend;//<=========================画棋子end================================>end;procedure TForm1.FormPaint(Sender: TObject); //游戏界面beginform1.Canvas.Pen.Width:=2;form1.Canvas.Rectangle(10,10,19*mBit-15,55);//最上方外框form1.Canvas.Rectangle(11*mBit-30,mBit+15,19*mBit-15,12*mBit+15);end;procedure TForm1.NewGame1Click(Sender: TObject);vari,j:integer;beginif(FirstPlay<>'')and((GameMode=1)or(GameMode=2))thenbeginif(MessageDlg('确定要开始新游戏吗?',mtConfirmation,[mbYes,mbNo],0))=mrYes thenbeginGroupBox1.Visible:=false;//隐藏GroupBox1Memo1.Lines.Clear;Memo1.Lines.Add('新游戏开始!');MemoMaxLine:=Memo1.Lines.Add('由'+FirstPlay+'先走棋!');//拾子标志为falsemPickFlag:=false;//能走棋标志为falseCanDropFlag:=false;//胜利标志win:=false;//初始化走棋一方WhoPlay:=FirstPlay;if(WhoPlay='红')thenlabel1.Font.Color:=clred;if(WhoPlay='黑')thenlabel1.Font.Color:=clblack;:='宋体';label1.Font.Size:=25;label1.Caption:='红方走棋';//初始化胜利提示label4.Caption:='';//初始化走棋步数MCSteep:=0;label3.Caption:='走棋步数:第'+inttostr(MCSteep)+'步';//初始化棋盘数组for i:=1 to 10 dofor j:=1 to 9 dobeginChessBoard[i,j]:=0;end;//(1'车',2'马',3'象',4'士',5'帅',6'炮','7兵',8'車',9'馬',10'相',11'仕',12'将',13'炮',14'卒');//设置黑方的棋子ChessBoard[1,1]:=8;ChessBoard[1,2]:=9;ChessBoard[1,3]:=10;ChessBoard[1,4]:=11;ChessBoard[1,5]:=12;ChessBoard[1,6]:=11;ChessBoard[1,7]:=10;ChessBoard[1,8]:=9;ChessBoard[1,9]:=8;ChessBoard[3,2]:=13;ChessBoard[3,8]:=13;ChessBoard[4,1]:=14;ChessBoard[4,3]:=14;ChessBoard[4,5]:=14;ChessBoard[4,7]:=14;ChessBoard[4,9]:=14;//设置红方的棋子ChessBoard[10,1]:=1;ChessBoard[10,2]:=2;ChessBoard[10,3]:=3;ChessBoard[10,4]:=4;ChessBoard[10,5]:=5;ChessBoard[10,6]:=4;ChessBoard[10,7]:=3;ChessBoard[10,8]:=2;ChessBoard[10,9]:=1;ChessBoard[8,2]:=6;ChessBoard[8,8]:=6;ChessBoard[7,1]:=7;ChessBoard[7,3]:=7;ChessBoard[7,5]:=7;ChessBoard[7,7]:=7;ChessBoard[7,9]:=7;refresh();//更新棋盘RemHistory();if(GameMode=2)and(FirstPlay='黑')then //人机对弈模式由黑方先手beginFindAGoodMove();AIChessMove(nBestMove.FormR,nBestMove.FormC,nBestMove.ToR,nBestMove.ToC);if(isMove=true)thenbeginRemHistory();//记录棋子移动WhoPlay:='红';label1.Font.Color:=clred;refresh();paintbox1.Canvas.Pen.Width:=2;paintbox1.Canvas.Pen.Color:=clgreen;CrossPaint(nBestMove.FormC*mBit,nBestMove.FormR*mBit,2,8);//棋子起走点标记CrossPaint(nBestMove.ToC*mBit,nBestMove.ToR*mBit,2,8);//棋子落点标记 isMove:=false;end;end;end;//if(MessageDlg('确定要开始新游戏吗endelseMessageDlg('请设置游戏模式!',mtWarning,[mbOk],0);end;procedure TForm1.CrossPaint(x,y,i,j:integer); //画兵格过程beginif x<>mBit thenbegin//兵格坐标左上部paintbox1.Canvas.MoveTo(x-i,y-i);paintbox1.Canvas.LineTo(x-j,y-i);paintbox1.Canvas.MoveTo(x-i,y-i);paintbox1.Canvas.LineTo(x-i,y-j);//兵格坐标左下部paintbox1.Canvas.MoveTo(x-i,y+i);paintbox1.Canvas.LineTo(x-j,y+i);paintbox1.Canvas.MoveTo(x-i,y+i);paintbox1.Canvas.LineTo(x-i,y+j);end;if x<>9*mBit thenbegin//兵格坐标右上部paintbox1.Canvas.MoveTo(x+i,y-i);paintbox1.Canvas.LineTo(x+i,y-j);paintbox1.Canvas.MoveTo(x+i,y-i);paintbox1.Canvas.LineTo(x+j,y-i);//兵格坐标右下部paintbox1.Canvas.MoveTo(x+i,y+i);paintbox1.Canvas.LineTo(x+j,y+i);paintbox1.Canvas.MoveTo(x+i,y+i);paintbox1.Canvas.LineTo(x+i,y+j);end;end;procedure TForm1.Eixt1Click(Sender: TObject);beginif(MessageDlg('确定要退出游戏?',mtConfirmation,[mbYes,mbNo],0))=mrYes then close;end;procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);varrow,column:integer;//鼠标落点的行,列号Lcross : real;//鼠标落点到棋盘交叉点的距离i,j:integer;beginif GameMode=1 then//判断游戏模式begin//计算出鼠标落下的行,列号row:=Y div mBit;if Y mod mBit>= (mBit div 2)+1 thenrow:=row+1;column:= x div mBit;if X mod mBit>= (mBit div 2)+1 thencolumn:=column+1;//记录鼠标点下的坐标MouseColumn:=column;MouseRow:=row;//当前鼠标点中的棋子mPickChess:=ChessBoard[row,column];//当前选中棋子属于哪一方if(ChessBoard[row,column]<=7)and(ChessBoard[row,column]<>0)thenmPWhoPlay:='红';//红方if(ChessBoard[row,column]>7)thenmPWhoPlay:='黑';//黑方//计算出鼠标落点到棋盘交叉点的距离Lcross:=sqrt(sqr(X-column*mBit)+sqr(Y-row*mBit));if(win=false)then//判断输赢beginif (Button = mbLeft) thenbegin//行号在(1~10),列号在(1~9)且鼠标到棋盘交叉点的距离小于棋盘格子的一半 if (row>=1)and (row<=10) and(column>=1)and(column<=9)and (Lcross<=(mBit div 2)) thenbeginif (mPickFlag = false) thenbeginif (ChessBoard[row,column]<>0)and(mPWhoPlay=WhoPlay) thenbeginmPickChess:=ChessBoard[row,column];//拾起棋子赋值//拾起棋子的坐标mPickRow:=row;mPickColumn:=column;//拾起棋子标志重画paintbox1.Canvas.Pen.Width:=1;paintbox1.Canvas.Pen.Color:=clred;paintbox1.Canvas.Brush.Color:=clblue;paintbox1.Canvas.Ellipse(column*mBit-22,row*mBit-22,column*mBit+22,row*mBit+22); paintbox1.Canvas.Font.Size:=21;:='华文楷体';paintbox1.Canvas.Font.Color:=clwhite;paintbox1.Canvas.TextOut(column*mBit-15,row*mBit-15,mChess[ChessBoard[row,column ]]);//设置拾子标志为truemPickFlag:=true;//能走棋标志为falseCanDropFlag:=false;//扫描能走的点FindDrop(mPickRow,mPickColumn);//画出能走的点PaintCMoveDrop();end;//选中棋子endelse //可以下子begin//调用ChessMove过程,移动棋子ChessMove(mPickRow,mPickColumn,MouseRow,MouseColumn);if(IsMove=false)then //如果没有移动beginrefresh();//更新棋盘mPickFlag:=false;//目标点不合法更新棋盘//继续点自己的棋子直接选中if (ChessBoard[row,column]<>0)and(mPWhoPlay=WhoPlay) thenbeginmPickChess:=ChessBoard[row,column];//拾起棋子赋值//拾起棋子的坐标mPickRow:=row;mPickColumn:=column;//拾起棋子标志重画paintbox1.Canvas.Pen.Width:=1;paintbox1.Canvas.Pen.Color:=clred;paintbox1.Canvas.Brush.Color:=clblue;paintbox1.Canvas.Ellipse(column*mBit-22,row*mBit-22,column*mBit+22,row*mBit+22);paintbox1.Canvas.Font.Size:=21;:='华文楷体';paintbox1.Canvas.Font.Color:=clwhite;paintbox1.Canvas.TextOut(column*mBit-15,row*mBit-15,mChess[ChessBoard[row,column ]]);//设置拾子标志为truemPickFlag:=true;//能走棋标志为falseCanDropFlag:=false;//扫描能走的点FindDrop(mPickRow,mPickColumn);//画出能走的点PaintCMoveDrop();end;end;if(IsMove=true)then //目标点合法更新走棋方begin//MFindDrop(MouseRow,MouseColumn);//移动到目标后该棋子可走点refresh();//更新棋盘IsNextWin();//判断是否将军WhoWin(); //判断输赢if(Win=true)thenexit;if(WhoPlay='红')then //交换走棋方beginWhoPlay:='黑';label1.Font.Color:=clblack;endelsebeginWhoPlay:='红';label1.Font.Color:=clred;end;label3.Caption:='走棋步数:第'+inttostr(MCSteep)+'步';refresh();//更新棋盘RemHistory();//记录棋子移动paintbox1.Canvas.Pen.Width:=2;paintbox1.Canvas.Pen.Color:=clgreen;CrossPaint(mPickColumn*mBit,mPickRow*mBit,2,8);//棋子起走点标记CrossPaint(MouseColumn*mBit,MouseRow*mBit,2,8);//棋子落点标记IsMove:=false;mPickFlag:=false;end;end;end;end;end;//if(win=false)thenend;//if(GameMode=1)if(GameMode=2)then //人机对弈beginif(WhoPlay='红')then //红方走棋begin//计算出鼠标落下的行,列号row:=Y div mBit;if Y mod mBit>= (mBit div 2)+1 thenrow:=row+1;column:= x div mBit;if X mod mBit>= (mBit div 2)+1 thencolumn:=column+1;//记录鼠标点下的坐标MouseColumn:=column;MouseRow:=row;//当前鼠标点中的棋子mPickChess:=ChessBoard[row,column];//当前选中棋子属于哪一方if(ChessBoard[row,column]<=7)and(ChessBoard[row,column]<>0)thenmPWhoPlay:='红';//红方if(ChessBoard[row,column]>7)thenmPWhoPlay:='黑';//黑方//计算出鼠标落点到棋盘交叉点的距离Lcross:=sqrt(sqr(X-column*mBit)+sqr(Y-row*mBit));if(win=false)then//判断输赢beginif (Button = mbLeft) thenbegin//行号在(1~10),列号在(1~9)且鼠标到棋盘交叉点的距离小于棋盘格子的一半 if (row>=1)and (row<=10) and(column>=1)and(column<=9)and (Lcross<=(mBit div2)) thenbeginif (mPickFlag = false) thenbeginif (ChessBoard[row,column]<>0)and(mPWhoPlay=WhoPlay) thenbeginmPickChess:=ChessBoard[row,column];//拾起棋子赋值//拾起棋子的坐标mPickRow:=row;mPickColumn:=column;//拾起棋子标志重画paintbox1.Canvas.Pen.Width:=1;paintbox1.Canvas.Pen.Color:=clred;paintbox1.Canvas.Brush.Color:=clblue;paintbox1.Canvas.Ellipse(column*mBit-22,row*mBit-22,column*mBit+22,row*mBit+22); paintbox1.Canvas.Font.Size:=21;:='华文楷体';paintbox1.Canvas.Font.Color:=clwhite;paintbox1.Canvas.TextOut(column*mBit-15,row*mBit-15,mChess[ChessBoard[row,column ]]);//设置拾子标志为truemPickFlag:=true;//能走棋标志为falseCanDropFlag:=false;//扫描能走的点FindDrop(mPickRow,mPickColumn);//画出能走的点PaintCMoveDrop();end;//选中棋子endelse //可以下子begin//调用ChessMove过程,移动棋子ChessMove(mPickRow,mPickColumn,MouseRow,MouseColumn);if(IsMove=false)then //如果没有移动beginrefresh();//更新棋盘mPickFlag:=false;//目标点不合法更新棋盘//继续点自己的棋子直接选中if (ChessBoard[row,column]<>0)and(mPWhoPlay=WhoPlay) thenbeginmPickChess:=ChessBoard[row,column];//拾起棋子赋值//拾起棋子的坐标mPickRow:=row;mPickColumn:=column;//拾起棋子标志重画paintbox1.Canvas.Pen.Width:=1;paintbox1.Canvas.Pen.Color:=clred;paintbox1.Canvas.Brush.Color:=clblue;paintbox1.Canvas.Ellipse(column*mBit-22,row*mBit-22,column*mBit+22,row*mBit+22); paintbox1.Canvas.Font.Size:=21;:='华文楷体';paintbox1.Canvas.Font.Color:=clwhite;paintbox1.Canvas.TextOut(column*mBit-15,row*mBit-15,mChess[ChessBoard[row,column ]]);//设置拾子标志为truemPickFlag:=true;//能走棋标志为falseCanDropFlag:=false;//扫描能走的点FindDrop(mPickRow,mPickColumn);//画出能走的点PaintCMoveDrop();end;end;if(IsMove=true)then //目标点合法更新走棋方begin//MFindDrop(MouseRow,MouseColumn);//移动到目标后该棋子可走点refresh();//更新棋盘IsNextWin();//判断是否将军WhoWin(); //判断输赢if(Win=true)thenexit;//交换走棋方WhoPlay:='黑';label1.Font.Color:=clblack;label3.Caption:='走棋步数:第'+inttostr(MCSteep)+'步';refresh();//更新棋盘RemHistory();//记录棋子移动paintbox1.Canvas.Pen.Width:=2;paintbox1.Canvas.Pen.Color:=clgreen;CrossPaint(mPickColumn*mBit,mPickRow*mBit,2,8);//棋子起走点标记CrossPaint(MouseColumn*mBit,MouseRow*mBit,2,8);//棋子落点标记IsMove:=false;mPickFlag:=false;end;end;end;end;end;//if(win=false)thenend;//红方走棋if(WhoPlay='黑')then //黑方走棋beginif(win=false)thenbeginFindAGoodMove(); //寻找一个优秀的走法AIChessMove(nBestMove.FormR,nBestMove.FormC,nBestMove.ToR,nBestMove.ToC); if(isMove=true)thenbeginrefresh();IsNextWin();//判断是否将军WhoWin();//判断输赢if(Win=true)thenexit;WhoPlay:='红';RemHistory();//记录棋子移动label1.Font.Color:=clred;refresh();paintbox1.Canvas.Pen.Width:=2;paintbox1.Canvas.Pen.Color:=clgreen;CrossPaint(nBestMove.FormC*mBit,nBestMove.FormR*mBit,2,8);//棋子起走点标记CrossPaint(nBestMove.ToC*mBit,nBestMove.ToR*mBit,2,8);//棋子落点标记isMove:=false;end;end;// if(win=false)thenend;//黑方走棋end;//人机对弈if(Win=true)thenshowmessage(WhoPlay+'方已获胜,本局结束,请重新开始!');if(GameMode=3)then //自定义棋盘模式begin//计算出鼠标落下的行,列号row:=Y div mBit;if Y mod mBit>= (mBit div 2)+1 thenrow:=row+1;column:= x div mBit;if X mod mBit>= (mBit div 2)+1 thencolumn:=column+1;//记录鼠标点下的坐标MouseColumn:=column;MouseRow:=row;//当前鼠标点中的棋子mPickChess:=ChessBoard[row,column];//当前选中棋子属于哪一方if(ChessBoard[row,column]<=7)and(ChessBoard[row,column]<>0)thenmPWhoPlay:='红';//红方if(ChessBoard[row,column]>7)thenmPWhoPlay:='黑';//黑方//计算出鼠标落点到棋盘交叉点的距离Lcross:=sqrt(sqr(X-column*mBit)+sqr(Y-row*mBit));if (Button = mbLeft) thenbegin//行号在(1~10),列号在(1~9)且鼠标到棋盘交叉点的距离小于棋盘格子的一半if (row>=1)and (row<=10) and(column>=1)and(column<=9)and (Lcross<=(mBit div 2)) thenbeginif(mPickFlag2=true)thenbeginif(CMoveDrop[row,column]=1)thenbeginif(ChessHaveNum[mPickChess2].Number<>0)then//该子棋盒里面还有剩余beginMemo1.Lines.Add(mPWhoPlay+mChess[mPickChess2]+'摆在'+'('+inttostr(row)+','+inttostr(column)+')');ChessBoard[row,column]:=mPickChess2;//摆子以后该子剩余:ChessHaveNum[mPickChess2].Number:=ChessHaveNum[mPickChess2].Number-1;mPickFlag2:=false;refresh();GroupBox1.Refresh();endelseshowmessage('棋盘里能摆的“'+mChess[mPickChess2]+'”已经满了!');endelse //选中棋盒又点棋盘上不能摆子的地方beginmPickFlag2:=false;refresh();GroupBox1.Refresh();end;end;//当前没有选中棋子 mPickFlag2=falseif(mPickFlag2=false)and(mPickFlag=false)thenbeginif(ChessBoard[row,column]<>0)thenbeginmPickChess:=ChessBoard[row,column];//拾起棋子赋值//拾起棋子的坐标mPickRow:=row;mPickColumn:=column;//拾起棋子标志重画paintbox1.Canvas.Pen.Width:=1;paintbox1.Canvas.Pen.Color:=clred;paintbox1.Canvas.Brush.Color:=clblue;paintbox1.Canvas.Ellipse(column*mBit-22,row*mBit-22,column*mBit+22,row*mBit+22); paintbox1.Canvas.Font.Size:=21;:='华文楷体';paintbox1.Canvas.Font.Color:=clwhite;paintbox1.Canvas.TextOut(column*mBit-15,row*mBit-15,mChess[ChessBoard[row,column ]]);mPickFlag:=true;exit;end;end;if(mPickFlag2=false)and(mPickFlag=true)thenbeginif(ChessBoard[row,column]<>0)thenbeginmPickFlag:=false;refresh();mPickChess:=ChessBoard[row,column];//拾起棋子赋值//拾起棋子的坐标mPickRow:=row;mPickColumn:=column;//拾起棋子标志重画paintbox1.Canvas.Pen.Width:=1;paintbox1.Canvas.Pen.Color:=clred;paintbox1.Canvas.Brush.Color:=clblue;paintbox1.Canvas.Ellipse(column*mBit-22,row*mBit-22,column*mBit+22,row*mBit+22); paintbox1.Canvas.Font.Size:=21;:='华文楷体';paintbox1.Canvas.Font.Color:=clwhite;paintbox1.Canvas.TextOut(column*mBit-15,row*mBit-15,mChess[ChessBoard[row,column ]]);mPickFlag:=true;exit;end;end;end;end;end;// if(GameMode=3)thenend;//PaintBox1MouseDown//==================棋子走begin==================//function Tform1.ChessMoveLaw(NowR,NowC,ToR,ToC,nChessID:integer):boolean;vari,j:integer; //循环变量begincase nChessID of//------------------车走法begin--------------------------//1:beginif(ToC=NowC)then //竖走beginif(ToR>NowR)then //从上到下beginif(ChessBoard[ToR,ToC]=0)or(ChessBoard[ToR,ToC]>7)then beginfor i:=(NowR+1) to (ToR-1) doif(ChessBoard[i,NowC]<>0)thenexit;CanDropFlag:=true;end;end;if(ToR<NowR)then //从下到上beginif(ChessBoard[ToR,ToC]=0)or(ChessBoard[ToR,ToC]>7)then beginfor i:=(ToR+1)to (NowR-1)doif(ChessBoard[i,NowC]<>0)thenexit;CanDropFlag:=true;end;end;end;if(ToR=NowR)then //横着走beginif(ToC>NowC)then //从左到右beginif(ChessBoard[ToR,ToC]=0)or(ChessBoard[ToR,ToC]>7)then beginfor i:=(NowC+1) to (ToC-1) doif(ChessBoard[NowR,i]<>0)thenexit;CanDropFlag:=true;end;end;if(ToC<NowC)then //从右到左beginif(ChessBoard[ToR,ToC]=0)or(ChessBoard[ToR,ToC]>7)thenbeginfor i:=(ToC+1)to (NowC-1)doif(ChessBoard[NowR,i]<>0)thenexit;CanDropFlag:=true;end;end;end;end;//------------------车走法end--------------------------////-------------------马走法begin----------------------//2:begin//马走日子if((abs(ToC-NowC)+abs(ToR-NowR))=3)and(ToC<>NowC)and(ToR<>NowR)thenbegin//竖日且无子当马脚if(abs(ToR-NowR)=2)and(ChessBoard[(NowR+ToR) div 2,NowC]=0)thenif(ChessBoard[ToR,ToC]=0)or(ChessBoard[ToR,ToC]>7)thenCanDropFlag:=true;//横日且无子当马脚if(abs(ToC-NowC)=2)and(ChessBoard[NowR,(NowC+ToC)div 2]=0)thenif(ChessBoard[ToR,ToC]=0)or(ChessBoard[ToR,ToC]>7)thenCanDropFlag:=true;end;end;//-------------------马走法end----------------------////-------------------相走法begin--------------------//3:begin//相走田if(ToR>5)and(abs(ToR-NowR)=2)and(abs(ToC-NowC)=2)thenif(ChessBoard[(ToR+NowR)div 2,(ToC+NowC)div 2]=0)then //田字格中间无子if(ChessBoard[ToR,ToC]=0)or(ChessBoard[ToR,ToC]>7)then//目标点无子或不是己方CanDropFlag:=true;。