下面是我采用我上面介绍的原理编写五子棋程序,它的智能比较低,还没有加入多步预测和禁手判断。我的新程序还没有完成。 unit FiveMain; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, ExtCtrls, Menus, jpeg, Buttons, StdCtrls; const GEZI_WIDTH=24; GEZI_NO=15; QIZI_WIDTH=22; WO=1; DUISHOU=2; CPLAYER=1; CCOMPUTER=2; type BlackOrWhite=(BlackQi,WhiteQi); TPlayerorComputer=(P1,P2,Com); TfrmFiveMain = class(TForm) MainMenu1: TMainMenu; N11: TMenuItem; MainPanel: TPanel; StatusBar1: TStatusBar; pbQipan: TPaintBox; sBack: TShape; Baizi: TImage; Heizi: TImage; nStartGame: TMenuItem; nNewGame: TMenuItem; N2: TMenuItem; nExit: TMenuItem; N4: TMenuItem; N5: TMenuItem; N1: TMenuItem; procedure pbQipanPaint(Sender: TObject); procedure pbQipanMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure pbQipanMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure FormCreate(Sender: TObject); procedure nStartGameClick(Sender: TObject); procedure nExitClick(Sender: TObject); procedure nNewGameClick(Sender: TObject); private WithComputer,GameBegin:Boolean; WhoPlay,WhoFirst:TPlayerorComputer; Table,TempTable:Array[1..15,1..15] of Integer; Player,Computer:Array[1..15,1..15,1..4] of Integer; procedure DrawQipan(PenWidth:Integer;PenColor:TColor); procedure QipanRepaint; procedure PaintQizi(X,Y:Integer;BorW:BlackOrWhite); procedure ComputerPlay; procedure GetanalyseTable; procedure EmptyPorC(Flag:Integer); procedure EmptyTable; function WhoWin:Integer; function AI_Output(Step:Integer):Integer; //核心函数 function AI_GetMax(var m,n:Integer;WhosTable:TPlayerorComputer):Integer; procedure GetAnalyseTableX; //分析棋型表 { Private declarations } public { Public declarations } end; var frmFiveMain: TfrmFiveMain;implementation{$R *.DFM}{ TForm1 }{ TForm1 }procedure TfrmFiveMain.DrawQipan(PenWidth:Integer;PenColor:TColor); var i,j,WeiYi,X,Y:Integer;begin with pbQipan do Begin WeiYi:=Round(GEZI_WIDTH/2); Canvas.Pen.Width:=PenWidth; if (PenWidth>2) or (PenWidth<0) then Canvas.Pen.Width:=1; Canvas.Pen.Color:=PenColor; for i:=0+WeiYi to GEZI_WIDTH*(GEZI_NO-1)+WeiYi do If i mod GEZI_WIDTH=0 then begin Canvas.MoveTo(0+WeiYi,i+WeiYi); Canvas.LineTo(GEZI_WIDTH*(GEZI_NO-1)+WeiYi,i+WeiYi); Canvas.MoveTo(i+WeiYi,0+WeiYi); Canvas.LineTo(i+WeiYi,GEZI_WIDTH*(GEZI_NO-1)+WeiYi); end; if PenWidth=2 then begin Canvas.MoveTo(0+WeiYi,1+WeiYi); Canvas.LineTo(GEZI_WIDTH*(GEZI_NO-1)+WeiYi,1+WeiYi); Canvas.MoveTo(1+WeiYi,0+WeiYi); Canvas.LineTo(1+WeiYi,GEZI_WIDTH*(GEZI_NO-1)+WeiYi); end; Canvas.Pen.Color:=clBlack; for i:=0+Weiyi to GEZI_WIDTH*(GEZI_NO-1)+WeiYi+GEZI_WIDTH do Begin If i mod GEZI_WIDTH=0 then Begin j:=0+Weiyi; while j<=GEZI_WIDTH*(GEZI_NO-1)+WeiYi do begin X:=i-16; Y:=j-4; Canvas.Ellipse(X,Y,X+9,Y+9); j:=j+GEZI_WIDTH; end; end; end; end; end;procedure TfrmFiveMain.PaintQizi(X, Y: Integer;BorW:BlackOrWhite); begin if BorW=BlackQi then pbQipan.Canvas.Draw(X,Y,Heizi.Picture.Bitmap); if BorW=WhiteQi then pbQipan.Canvas.Draw(X,Y,Baizi.Picture.Bitmap); end;procedure TfrmFiveMain.pbQipanPaint(Sender: TObject); begin DrawQipan(2,clNavy); QipanRepaint; end;procedure TfrmFiveMain.pbQipanMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var Dx,Dy,i,j:Integer; begin If (X mod GEZI_WIDTH<20) and (X mod GEZI_WIDTH>4)and(Y mod GEZI_WIDTH<20)and(Y mod GEZI_WIDTH>4) then Begin i:=(X div GEZI_WIDTH); j:=(Y div GEZI_WIDTH); Dx:=i*GEZI_WIDTH; Dy:=j*GEZI_WIDTH; //画出下子的过程 if Table[j+1,i+1]=0 then Case WhoPlay of P1: begin if WhoFirst=P1 then PaintQizi(Dx+1,Dy,BlackQi) else PaintQizi(Dx+1,Dy,WhiteQi); Table[j+1,i+1]:=WO; if WithComputer then Begin Whoplay:=Com;//轮到电脑下子了 ComputerPlay; end else WhoPlay:=P2; end; P2: Begin if WhoFirst=P2 then PaintQizi(Dx+1,Dy,BlackQi) else PaintQizi(Dx+1,Dy,WhiteQi); Table[j+1,i+1]:=DUISHOU; if WithComputer then Begin Whoplay:=Com;//轮到电脑下子了 end else WhoPlay:=P1; end; end; end; end;procedure TfrmFiveMain.pbQipanMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if pbQipan.Canvas.Pixels[X,Y]=clBlack then pbQipan.Cursor:=crHandPoint else pbQipan.Cursor:=crDefault; end;procedure TfrmFiveMain.FormCreate(Sender: TObject); begin GameBegin:=False; end;procedure TfrmFiveMain.QipanRepaint; var i,j:Integer; begin for i:=1 to 15 do for j:=1 to 15 do Begin Case Table[i,j] of 1: if WhoFirst=P1 then PaintQizi((j-1)*GEZI_WIDTH+1,(i-1)*GEZI_WIDTH,BlackQi) else PaintQizi((j-1)*GEZI_WIDTH+1,(i-1)*GEZI_WIDTH,WhiteQi); 2: if WhoFirst=Com then PaintQizi((j-1)*GEZI_WIDTH+1,(i-1)*GEZI_WIDTH,BlackQi) else PaintQizi((j-1)*GEZI_WIDTH+1,(i-1)*GEZI_WIDTH,WhiteQi); end; end; end;procedure TfrmFiveMain.ComputerPlay; var i,j,k,m,n,h,l,Max,PlayerMax:Integer; PlayerHuoSan:Boolean; begin EmptyPorC(CCOMPUTER); EmptyPorC(CPLAYER); GetAnalyseTable; if WhoWin=CPLAYER then Begin Application.MessageBox('你赢了!!','提示',MB_OK); nStartGame.Enabled:=True; pbQipan.Enabled:=False; exit; end; //开始下棋,最简单算法========== Max:=0; m:=1;n:=1; for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do begin if Computer[i,j,k]>Max then Begin m:=i;n:=j; Max:=Computer[i,j,k]; end end; Case Max of 0,1,2://防守 begin PlayerMax:=0; h:=1;l:=1; for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do begin if Player[i,j,k]>PlayerMax then Begin h:=i;l:=j; PlayerMax:=Player[i,j,k]; //电脑判断我方最有可能下的点,进行防守 end end; Case PlayerMax of 0,1://当我方无活三的可能时,电脑试探自己有无活三的可能 begin //Computer活三 for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do begin if (Computer[i,j,1]=2)and(Computer[i,j,k]=2)and(k<>1)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,2]=2)and(Computer[i,j,k]=2)and(k<>2)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,3]=2)and(Computer[i,j,k]=2)and(k<>3)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,4]=2)and(Computer[i,j,k]=2)and(k<>4)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; end; if WhoPlay=Com then begin Table[h,l]:=2; Whoplay:=P1; end; end; 2://电脑判断我方有无活三的可能,如无则试探自己有无活三的可能 begin PlayerHuoSan:=False; //Player活三 for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do begin if (Player[i,j,1]=2)and(Player[i,j,k]=2)and(k<>1)then begin PlayerHuoSan:=True; break; end; if (Player[i,j,2]=2)and(Player[i,j,k]=2)and(k<>2)then begin PlayerHuoSan:=True; break; end; if (Player[i,j,3]=2)and(Player[i,j,k]=2)and(k<>3)then begin PlayerHuoSan:=True; break; end; if (Player[i,j,4]=2)and(Player[i,j,k]=2)and(k<>4)then begin PlayerHuoSan:=True; break; end; end; if PlayerHuoSan=False then for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do begin if (Computer[i,j,1]=2)and(Computer[i,j,k]=2)and(k<>1)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,2]=2)and(Computer[i,j,k]=2)and(k<>2)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,3]=2)and(Computer[i,j,k]=2)and(k<>3)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,4]=2)and(Computer[i,j,k]=2)and(k<>4)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; end; if WhoPlay=Com then begin Table[h,l]:=2; Whoplay:=P1; end; end; 3,4://防守 Table[h,l]:=2; end; if WhoPlay=Com then WhoPlay:=P1; end; 3: begin PlayerMax:=0; h:=1;l:=1; for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do begin if Player[i,j,k]>PlayerMax then Begin h:=i;l:=j; PlayerMax:=Player[i,j,k]; //电脑判断我方最有可能下的点,进行防守 end end; Case PlayerMax of 3,4: begin Table[h,l]:=2; WhoPlay:=P1; end; else begin for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do begin //活三 if (Computer[i,j,1]=2)and(Computer[i,j,k]=3)and(k<>1)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,2]=2)and(Computer[i,j,k]=3)and(k<>2)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,3]=2)and(Computer[i,j,k]=3)and(k<>3)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,4]=2)and(Computer[i,j,k]=3)and(k<>4)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; //三四 if (Computer[i,j,1]=3)and(Computer[i,j,k]=3)and(k<>1)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,2]=3)and(Computer[i,j,k]=3)and(k<>2)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,3]=3)and(Computer[i,j,k]=3)and(k<>3)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,4]=3)and(Computer[i,j,k]=3)and(k<>4)then begin m:=i;n:=j; Table[m,n]:=2; WhoPlay:=P1; break; end; end; end end; if Whoplay=com then begin Table[m,n]:=2; //冲四 WhoPlay:=P1; end; end; 4: begin Table[m,n]:=2; //成五 if Whoplay=com then WhoPlay:=P1; end; end; //=========================== QipanRepaint; GetanalyseTable; if WhoWin=CCOMPUTER then Begin Application.MessageBox('你输了!!','提示',MB_OK); nStartGame.Enabled:=True; pbQipan.Enabled:=False; exit; end; end;procedure TfrmFiveMain.GetanalyseTable; var i,j,k,m,n,h,Dots:Integer; begin //初始化棋型表 for k:=1 to 4 do Case k of 1: //横向遍历 begin //Player 棋型表生成 for i:=1 to 15 do for j:=1 to 15 do if Table[i,j]=0 then Begin Dots:=0; for m:=j-1 downto 1 do if Table[i,m]=1 then Dots:=Dots+1 else Break; for m:=j+1 to 15 do if Table[i,m]=1 then Dots:=Dots+1 else Break; Player[i,j,k]:=Dots; end; //Computer 棋型表生成 for i:=1 to 15 do for j:=1 to 15 do if Table[i,j]=0 then Begin Dots:=0; for m:=j-1 downto 1 do if Table[i,m]=2 then Dots:=Dots+1 else Break; for m:=j+1 to 15 do if Table[i,m]=2 then Dots:=Dots+1 else Break; Computer[i,j,k]:=Dots; end; end; 2://竖向遍历 begin //Player 棋型表生成 for j:=1 to 15 do for i:=1 to 15 do begin h:=Table[i,j]; if h=0 then begin Dots:=0; for m:=i-1 downto 1 do if Table[m,j]=1 then Dots:=Dots+1 else break; for m:=i+1 to 15 do if Table[m,j]=1 then Dots:=Dots+1 else Break; Player[i,j,k]:=Dots; end; end; //Computer 棋型表生成 for j:=1 to 15 do for i:=1 to 15 do if Table[i,j]=0 then begin Dots:=0; for m:=i-1 downto 1 do if Table[m,j]=2 then Dots:=Dots+1 else break; for m:=i+1 to 15 do if Table[m,j]=2 then Dots:=Dots+1 else Break; Computer[i,j,k]:=Dots; end; end; 3: // '\'型棋型表 begin //Player 棋型表生成 for i:=1 to 15 do for j:=1 to 15 do if Table[i,j]=0 then begin m:=i-1;n:=j-1; Dots:=0; while (m>=1)or(n>=1) do begin if Table[m,n]=1 then Dots:=Dots+1 else Break; m:=m-1; n:=n-1; end; m:=i+1;n:=j+1; while(m<=15)or(n<=15)do begin if Table[m,n]=1 then Dots:=Dots+1 else Break; m:=m+1; n:=n+1; end; Player[i,j,k]:=Dots; end; //Computer 棋型表生成 for i:=1 to 15 do for j:=1 to 15 do if Table[i,j]=0 then begin m:=i-1;n:=j-1; Dots:=0; while(m>=1)and(n>=1)do begin if Table[m,n]=2 then Dots:=Dots+1 else Break; m:=m-1; n:=n-1; end; m:=i+1;n:=j+1; while(m<=15)and(n<=15)do begin if Table[m,n]=2 then Dots:=Dots+1 else Break; m:=m+1; n:=n+1; end; Computer[i,j,k]:=Dots; end; end; 4: // '/'行 棋型表生成 begin //Player 棋型表生成 for i:=1 to 15 do for j:=1 to 15 do if Table[i,j]=0 then begin m:=i-1;n:=j+1; Dots:=0; while (m>=1)and(n<=15) do begin if Table[m,n]=1 then Dots:=Dots+1 else Break; m:=m-1; n:=n+1; end; m:=i+1;n:=j-1; while(m<=15)and(n>=1)do begin if Table[m,n]=1 then Dots:=Dots+1 else Break; m:=m+1; n:=n-1; end; Player[i,j,k]:=Dots; end; //Computer 棋型表生成 for i:=1 to 15 do for j:=1 to 15 do if Table[i,j]=0 then begin m:=i-1;n:=j+1; Dots:=0; while (m>=1)and(n<=15) do begin if Table[m,n]=2 then Dots:=Dots+1 else Break; m:=m-1; n:=n+1; end; m:=i+1;n:=j-1; while(m<=15)and(n>=1)do begin if Table[m,n]=2 then Dots:=Dots+1 else Break; m:=m+1; n:=n-1; end; Computer[i,j,k]:=Dots; end; end; end; //========== end;procedure TfrmFiveMain.EmptyPorC(Flag: Integer); var i,j,k:Integer; begin if Flag=CPLAYER then for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do Player[i,j,k]:=0 else for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do Computer[i,j,k]:=0; end;function TfrmFiveMain.WhoWin: Integer; var i,j,k:Integer; begin Result:=-1; for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do if Player[i,j,k]=5 then Result:=CPLAYER; for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do if Computer[i,j,k]=5 then Result:=CCOMPUTER; end;procedure TfrmFiveMain.nStartGameClick(Sender: TObject); begin GameBegin:=True; WhoFirst:=P1; WhoPlay:=WhoFirst; WithComputer:=True; EmptyTable; pbQipan.Enabled:=True; pbQipan.Repaint; nStartGame.Enabled:=False; nNewGame.Enabled:=True; end;procedure TfrmFiveMain.nExitClick(Sender: TObject); begin close; end;procedure TfrmFiveMain.EmptyTable; var i,j:Integer; begin for i:=1 to 15 do for j:=1 to 15 do table[i,j]:=0; end;procedure TfrmFiveMain.nNewGameClick(Sender: TObject); begin If Application.MessageBox('您确定要重新开始游戏吗?','询问',MB_YESNO or MB_ICONQUESTION)=ID_YES then nStartGame.OnClick(Sender); end;function TfrmFiveMain.AI_GetMax(var m, n: Integer;WhosTable:TPlayerorComputer): Integer; var Max,i,j,k:Integer; begin Max:=0; if WhosTable=Com then begin for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do if Computer[i,j,k]>Max then Begin m:=i;n:=j; Max:=Computer[i,j,k]; end; end else begin for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do if Player[i,j,k]>Max then Begin m:=i;n:=j; Max:=Player[i,j,k]; end; end; Result:=Max; end;function TfrmFiveMain.AI_Output(Step: Integer): Integer; var i,j,k,Cx,Cy,Px,Py,Start:Integer; HuoSan:Boolean; begin Start:=1; for i:=1 to 15 do for j:=1 to 15 do TempTable[i,j]:=Table[i,j]; //给临时棋盘状态赋初值 for Start:=1 to Step do Case Start of 1: begin EmptyPorC(CCOMPUTER); //清空Computer表 EmptyPorC(CPLAYER); //清空Player表 GetAnalyseTableX; //依据临时棋盘状态生成棋型表 Case AI_GetMax(Cx,Cy,Com) of //电脑的棋型最大值 0,1,2://电脑无可以攻的招 begin //电脑判断我方最有可能下的点 Case AI_GetMax(Px,Py,WhoPlay) of 0,1: //当我方无活三的可能时,电脑试探自己有无活三的可能 begin for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do begin if (Computer[i,j,1]=2)and(Computer[i,j,k]=2)and(k<>1)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,2]=2)and(Computer[i,j,k]=2)and(k<>2)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,3]=2)and(Computer[i,j,k]=2)and(k<>3)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,4]=2)and(Computer[i,j,k]=2)and(k<>4)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; end; if WhoPlay=Com then begin TempTable[Cx,Cy]:=2; Whoplay:=P1; end; end; 2://电脑判断我方有无活三的可能,如无则试探自己有无活三的可能 begin HuoSan:=False; //Player活三 for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do begin if (Player[i,j,1]=2)and(Player[i,j,k]=2)and(k<>1)then begin HuoSan:=True; break; end; if (Player[i,j,2]=2)and(Player[i,j,k]=2)and(k<>2)then begin HuoSan:=True; break; end; if (Player[i,j,3]=2)and(Player[i,j,k]=2)and(k<>3)then begin HuoSan:=True; break; end; if (Player[i,j,4]=2)and(Player[i,j,k]=2)and(k<>4)then begin HuoSan:=True; break; end; end; if HuoSan=False then for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do begin if (Computer[i,j,1]=2)and(Computer[i,j,k]=2)and(k<>1)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,2]=2)and(Computer[i,j,k]=2)and(k<>2)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,3]=2)and(Computer[i,j,k]=2)and(k<>3)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,4]=2)and(Computer[i,j,k]=2)and(k<>4)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; end; if WhoPlay=Com then begin TempTable[Px,Py]:=2; Whoplay:=P1; end; end; 3,4:Table[Px,Py]:=2; end; if WhoPlay=Com then WhoPlay:=P1; //========================= end; 3: begin case AI_GetMax(Px,Py,WhoPlay) of 3,4: begin TempTable[Px,Py]:=2; WhoPlay:=P1; end; else begin for i:=1 to 15 do for j:=1 to 15 do for k:=1 to 4 do begin //活三 if (Computer[i,j,1]=2)and(Computer[i,j,k]=3)and(k<>1)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,2]=2)and(Computer[i,j,k]=3)and(k<>2)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,3]=2)and(Computer[i,j,k]=3)and(k<>3)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,4]=2)and(Computer[i,j,k]=3)and(k<>4)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; //三四 if (Computer[i,j,1]=3)and(Computer[i,j,k]=3)and(k<>1)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,2]=3)and(Computer[i,j,k]=3)and(k<>2)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,3]=3)and(Computer[i,j,k]=3)and(k<>3)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; if (Computer[i,j,4]=3)and(Computer[i,j,k]=3)and(k<>4)then begin Cx:=i;Cy:=j; TempTable[Cx,Cy]:=2; WhoPlay:=P1; break; end; end; end; end; if Whoplay=com then begin TempTable[Cx,Cy]:=2; //冲四 WhoPlay:=P1; end; end; 4: begin Table[Cx,Cy]:=2; //成五 if Whoplay=com then WhoPlay:=P1; end; 5: begin end; end;//Case Ai_GetMax(Com) end; //在TempTable中模拟Player下子 //========================== end; 2: begin end; 3: begin end; 4: begin end; 5: begin end; 6: begin end; end; result:=0; end;procedure TfrmFiveMain.GetAnalyseTableX; var i,j,k,m,n,h,Dots:Integer; begin //初始化棋型表 for k:=1 to 4 do Case k of 1: //横向遍历 begin //Player 棋型表生成 for i:=1 to 15 do for j:=1 to 15 do if TempTable[i,j]=0 then Begin Dots:=0; for m:=j-1 downto 1 do if TempTable[i,m]=1 then Dots:=Dots+1 else Break; for m:=j+1 to 15 do if TempTable[i,m]=1 then Dots:=Dots+1 else Break; Player[i,j,k]:=Dots; end; //Computer 棋型表生成 for i:=1 to 15 do for j:=1 to 15 do if TempTable[i,j]=0 then Begin Dots:=0; for m:=j-1 downto 1 do if TempTable[i,m]=2 then Dots:=Dots+1 else Break; for m:=j+1 to 15 do if TempTable[i,m]=2 then Dots:=Dots+1 else Break; Computer[i,j,k]:=Dots; end; end; 2://竖向遍历 begin //Player 棋型表生成 for j:=1 to 15 do for i:=1 to 15 do begin h:=TempTable[i,j]; if h=0 then begin Dots:=0; for m:=i-1 downto 1 do if TempTable[m,j]=1 then Dots:=Dots+1 else break; for m:=i+1 to 15 do if TempTable[m,j]=1 then Dots:=Dots+1 else Break; Player[i,j,k]:=Dots; end; end; //Computer 棋型表生成 for j:=1 to 15 do for i:=1 to 15 do if TempTable[i,j]=0 then begin Dots:=0; for m:=i-1 downto 1 do if TempTable[m,j]=2 then Dots:=Dots+1 else break; for m:=i+1 to 15 do if TempTable[m,j]=2 then Dots:=Dots+1 else Break; Computer[i,j,k]:=Dots; end; end; 3: // '\'型棋型表 begin //Player 棋型表生成 for i:=1 to 15 do for j:=1 to 15 do if TempTable[i,j]=0 then begin m:=i-1;n:=j-1; Dots:=0; while (m>=1)or(n>=1) do begin if TempTable[m,n]=1 then Dots:=Dots+1 else Break; m:=m-1; n:=n-1; end; m:=i+1;n:=j+1; while(m<=15)or(n<=15)do begin if TempTable[m,n]=1 then Dots:=Dots+1 else Break; m:=m+1; n:=n+1; end; Player[i,j,k]:=Dots; end; //Computer 棋型表生成 for i:=1 to 15 do for j:=1 to 15 do if TempTable[i,j]=0 then begin m:=i-1;n:=j-1; Dots:=0; while(m>=1)and(n>=1)do begin if TempTable[m,n]=2 then Dots:=Dots+1 else Break; m:=m-1; n:=n-1; end; m:=i+1;n:=j+1; while(m<=15)and(n<=15)do begin if TempTable[m,n]=2 then Dots:=Dots+1 else Break; m:=m+1; n:=n+1; end; Computer[i,j,k]:=Dots; end; end; 4: // '/'行 棋型表生成 begin //Player 棋型表生成 for i:=1 to 15 do for j:=1 to 15 do if TempTable[i,j]=0 then begin m:=i-1;n:=j+1; Dots:=0; while (m>=1)and(n<=15) do begin if TempTable[m,n]=1 then Dots:=Dots+1 else Break; m:=m-1; n:=n+1; end; m:=i+1;n:=j-1; while(m<=15)and(n>=1)do begin if TempTable[m,n]=1 then Dots:=Dots+1 else Break; m:=m+1; n:=n-1; end; Player[i,j,k]:=Dots; end; //Computer 棋型表生成 for i:=1 to 15 do for j:=1 to 15 do if TempTable[i,j]=0 then begin m:=i-1;n:=j+1; Dots:=0; while (m>=1)and(n<=15) do begin if TempTable[m,n]=2 then Dots:=Dots+1 else Break; m:=m-1; n:=n+1; end; m:=i+1;n:=j-1; while(m<=15)and(n>=1)do begin if TempTable[m,n]=2 then Dots:=Dots+1 else Break; m:=m+1; n:=n-1; end; Computer[i,j,k]:=Dots; end; end; end; end; end.
TO:zswang(伴水)(被黑中)
有一位夫人请一名装璜师装修居室,晚上,丈夫回来时去开卧室的灯,不小心手一摸,将新油的墙壁给弄糊了。次日,装璜师刚到,这位夫人赶紧拉住他说:“先生,请您到卧室来,我给你看昨天晚上我丈夫摸过的地方”。 求您啦,先生,请帮我看看这个地方:Http://www.csdn.net/Expert/topic/435/435504.shtm
以下文章摘选自游戏编程配套光盘,助大家理解上面的程序。 总的来说(我们假定您熟悉五子棋的基本规则),要让电脑知道该在哪一点下子,就要根据盘面的形势,为每一可能落子的点计算其重要程度,也就是当这子落下后会形成什么棋型(如:“冲四”、“活三”等),然后通览全盘选出最重要的一点,这便是最基本的算法。当然,仅靠当前盘面进行判断是远远不够的,这样下棋很容易掉进玩家设下的陷阱,因为它没有考虑以后的变化。所以在此基础上我们加入递归调用,即:在电脑中预测出今后几步的各种走法,以便作出最佳选择,这也是我们下棋时常说的“想了几步”。如此一来您的程序便具有一定的水平了。什么?不信!过来试试吧! 总体思路弄清之后,下面进行具体讨论: 一:数据结构先来看看数据结构,我们需要哪些变量?首先得为整个棋盘建立一张表格用以记录棋子信息,我们使用一个15*15的二维数组 Table[15][15] (15*15是五子棋棋盘的大小),数组的每一个元素对应棋盘上的一个交叉点,用‘0’表示空位、‘1’代表己方的子、‘2’代表对方的子;这张表也是今后分析的基础。在此之后还要为电脑和玩家双方各建立一张棋型表Computer[15][15][4]和Player[15][15][4],用来存放棋型数据,就是刚才所说的重要程度,比如用‘20’代表“冲四”的点,用‘15’代表“活三”的点,那么在计算重要性时,就可以根据20>15得出前者比后者重要,下子时电脑便会自动选择“冲四”的点。那为什么棋型表要使用三维数组呢?因为棋盘上的每一个点都可以与横、竖、左斜、右斜四个方向的棋子构成不同的棋型,所以一个点总共有4个记录;这样做的另一个好处是可以轻易判断出复合棋型,例如:如果同一点上有2个‘15’就是双三、有一个‘15’和一个‘20’就是四三。怎么样!3个数组构成了程序的基本数据骨架,今后只要再加入一些辅助变量便可以应付自如了。应该不会太难吧?OK!有了这么多有用的数据,我们就可以深入到程序的流程中去了。 二:程序流程 我们主要讨论五子棋的核心算法,即:人工智能部分,而其他像图形显示、键盘鼠标控制等,因较为简单,所以就不作过多介绍了。 我们看到本程序由六个基本功能模块构成,各模块的详细分析如下:(1)初始化:首先,建立盘面数组Table[15][15]、对战双方的棋型表Computer[15][15][4]和Player[15][15][4]并将它们清零以备使用;然后初始化显示器、键盘、鼠等输入输出设备并在屏幕上画出棋盘。(2)主循环控制模块:控制下棋顺序,当轮到某方下子时,负责将程序转到相应的模块中去,主要担当一个调度者的角色。(3)玩家下子:当轮到玩家下时,您通过键盘或鼠标在棋盘上落子,程序会根据该点的位置,在Table[15][15]数组的相应地方记录‘2’,以表明该子是玩家下的。(4)盘面分析填写棋型表:本程序核心模块之一,人工智能算法的根本依据!其具体实现方法如下:您在下五子棋时,一定会先根据棋盘上的情况,找出当前最重要的一些点位,如“活三”、“冲四”等;然后再在其中选择落子点。但是,电脑不会像人一样分析问题,要让它知道哪是“活三”、哪是“冲四”,就得在棋盘上逐点计算,一步一步的教它。先来分析己方的棋型,我们从棋盘左上角出发,向右逐行搜索,当遇到一个空白点时,以它为中心向左挨个查找,如果遇到己方的子则记录然后继续,如果遇到对方的子、空白点或边界就停止查找。左边完成后再向右进行同样的操作;最后把左右两边的记录合并起来,得到的数据就是该点横向上的棋型,然后把棋型的编号填入到Computer[x][y][n]中就行了(x、y代表坐标,n=0、1、2、3分别代表横、竖、左斜、右斜四个方向)。而其他三个方向的棋型也可用同样的方法得到,当搜索完整张棋盘后,己方棋型表也就填写完毕了。然后再用同样的方法填写对方棋型表。注意:所有棋型的编号都要事先定义好,越重要的号数越大!OK! 怎么样?有点累了吧?不过千万别泄气!因为好戏还在后头。Let's go!(5)电脑下子:有了上面填写的两张棋型表,现在要作的就是让电脑知道在哪一点下子了。其中最简单的计算方法,就是遍历棋型表Computer[15][15][4]和Player[15][15][4]找出其中数值最大的一点,在该点下子即可。但这种算法的弱点非常明显,只顾眼前利益,不能顾全大局,这就和许多五子棋初学者一样犯了“目光短浅”的毛病。要解决这个问题,我们引入‘今后几步预测法’,具体方法是这样的: 首先, 让电脑分析一个可能的点,如果在这儿下子将会形成对手不得不防守的棋型(例如:‘冲四’、‘活三’);那么下一步对手就会照您的思路下子来防守您,如此一来便完成了第一步的预测。这时再调用模块4对预测后的棋进行盘面分析,如果出现了‘四三’、‘双三’或‘双四’等制胜点,那么己方就可以获胜了(当然对黑棋而言‘双三’、‘双四’是禁手,另当别论);否则照同样的方法向下分析,就可预测出第二步、第三步……等一等,要是盘面上没有对手必须防的棋型,哪该怎么办呢?进攻不成的话就得考虑防守了,将自己和对手调换一下位置,然后用上面的方法来预测对手的棋,这样既可以防住对手巧妙的攻击,又能侍机发动反击,何乐而不为呢!但是必须告诉大家的是:预测法的运算量相当之大,据我的经验,用Pentium-100预测3步的走法平均需要15秒以上时间,所以建议预测量在5步以内。可别小瞧了这5步,有时它甚至会走出让您拍手叫绝的妙着呢!(6)胜负判断:务须多言,某方形成五子连即获胜;若黑棋走出‘双三’、‘双四’或长连即以禁手判负。 到现在为止,整个五子棋软件就基本完成了,其水平大约在中级上下。当然,这种算法并不是最好的,但我相信它的基本思路是正确的。
谢谢你的代码,感觉你应该是一个出色的人!向你学习!
[email protected]
发个程序看看,谢谢!!!
不建FuncUnit而把其中的过程函数写在GobangUnit中不行吗?有什么区别吗?
就可以用了
THANKS……………………
unit FiveMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, ExtCtrls, Menus, jpeg, Buttons, StdCtrls;
const
GEZI_WIDTH=24;
GEZI_NO=15;
QIZI_WIDTH=22;
WO=1;
DUISHOU=2;
CPLAYER=1;
CCOMPUTER=2;
type
BlackOrWhite=(BlackQi,WhiteQi);
TPlayerorComputer=(P1,P2,Com);
TfrmFiveMain = class(TForm)
MainMenu1: TMainMenu;
N11: TMenuItem;
MainPanel: TPanel;
StatusBar1: TStatusBar;
pbQipan: TPaintBox;
sBack: TShape;
Baizi: TImage;
Heizi: TImage;
nStartGame: TMenuItem;
nNewGame: TMenuItem;
N2: TMenuItem;
nExit: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
N1: TMenuItem;
procedure pbQipanPaint(Sender: TObject);
procedure pbQipanMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure pbQipanMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormCreate(Sender: TObject);
procedure nStartGameClick(Sender: TObject);
procedure nExitClick(Sender: TObject);
procedure nNewGameClick(Sender: TObject);
private
WithComputer,GameBegin:Boolean;
WhoPlay,WhoFirst:TPlayerorComputer;
Table,TempTable:Array[1..15,1..15] of Integer;
Player,Computer:Array[1..15,1..15,1..4] of Integer;
procedure DrawQipan(PenWidth:Integer;PenColor:TColor);
procedure QipanRepaint;
procedure PaintQizi(X,Y:Integer;BorW:BlackOrWhite);
procedure ComputerPlay;
procedure GetanalyseTable;
procedure EmptyPorC(Flag:Integer);
procedure EmptyTable;
function WhoWin:Integer;
function AI_Output(Step:Integer):Integer; //核心函数
function AI_GetMax(var m,n:Integer;WhosTable:TPlayerorComputer):Integer;
procedure GetAnalyseTableX; //分析棋型表
{ Private declarations }
public
{ Public declarations }
end;
var
frmFiveMain: TfrmFiveMain;implementation{$R *.DFM}{ TForm1 }{ TForm1 }procedure TfrmFiveMain.DrawQipan(PenWidth:Integer;PenColor:TColor);
var
i,j,WeiYi,X,Y:Integer;begin
with pbQipan do
Begin
WeiYi:=Round(GEZI_WIDTH/2);
Canvas.Pen.Width:=PenWidth;
if (PenWidth>2) or (PenWidth<0) then Canvas.Pen.Width:=1;
Canvas.Pen.Color:=PenColor;
for i:=0+WeiYi to GEZI_WIDTH*(GEZI_NO-1)+WeiYi do
If i mod GEZI_WIDTH=0 then
begin
Canvas.MoveTo(0+WeiYi,i+WeiYi);
Canvas.LineTo(GEZI_WIDTH*(GEZI_NO-1)+WeiYi,i+WeiYi);
Canvas.MoveTo(i+WeiYi,0+WeiYi);
Canvas.LineTo(i+WeiYi,GEZI_WIDTH*(GEZI_NO-1)+WeiYi);
end;
if PenWidth=2 then
begin
Canvas.MoveTo(0+WeiYi,1+WeiYi);
Canvas.LineTo(GEZI_WIDTH*(GEZI_NO-1)+WeiYi,1+WeiYi);
Canvas.MoveTo(1+WeiYi,0+WeiYi);
Canvas.LineTo(1+WeiYi,GEZI_WIDTH*(GEZI_NO-1)+WeiYi);
end;
Canvas.Pen.Color:=clBlack;
for i:=0+Weiyi to GEZI_WIDTH*(GEZI_NO-1)+WeiYi+GEZI_WIDTH do
Begin
If i mod GEZI_WIDTH=0 then
Begin
j:=0+Weiyi;
while j<=GEZI_WIDTH*(GEZI_NO-1)+WeiYi do
begin
X:=i-16;
Y:=j-4;
Canvas.Ellipse(X,Y,X+9,Y+9);
j:=j+GEZI_WIDTH;
end;
end;
end;
end;
end;procedure TfrmFiveMain.PaintQizi(X, Y: Integer;BorW:BlackOrWhite);
begin
if BorW=BlackQi then
pbQipan.Canvas.Draw(X,Y,Heizi.Picture.Bitmap);
if BorW=WhiteQi then
pbQipan.Canvas.Draw(X,Y,Baizi.Picture.Bitmap);
end;procedure TfrmFiveMain.pbQipanPaint(Sender: TObject);
begin
DrawQipan(2,clNavy);
QipanRepaint;
end;procedure TfrmFiveMain.pbQipanMouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
Dx,Dy,i,j:Integer;
begin
If (X mod GEZI_WIDTH<20) and (X mod GEZI_WIDTH>4)and(Y mod GEZI_WIDTH<20)and(Y mod GEZI_WIDTH>4) then
Begin
i:=(X div GEZI_WIDTH);
j:=(Y div GEZI_WIDTH);
Dx:=i*GEZI_WIDTH;
Dy:=j*GEZI_WIDTH;
//画出下子的过程
if Table[j+1,i+1]=0 then
Case WhoPlay of
P1:
begin
if WhoFirst=P1 then
PaintQizi(Dx+1,Dy,BlackQi)
else
PaintQizi(Dx+1,Dy,WhiteQi);
Table[j+1,i+1]:=WO;
if WithComputer then
Begin
Whoplay:=Com;//轮到电脑下子了
ComputerPlay;
end
else
WhoPlay:=P2;
end;
P2:
Begin
if WhoFirst=P2 then
PaintQizi(Dx+1,Dy,BlackQi)
else
PaintQizi(Dx+1,Dy,WhiteQi);
Table[j+1,i+1]:=DUISHOU;
if WithComputer then
Begin
Whoplay:=Com;//轮到电脑下子了
end
else
WhoPlay:=P1;
end;
end;
end;
end;procedure TfrmFiveMain.pbQipanMouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
begin
if pbQipan.Canvas.Pixels[X,Y]=clBlack then
pbQipan.Cursor:=crHandPoint
else
pbQipan.Cursor:=crDefault;
end;procedure TfrmFiveMain.FormCreate(Sender: TObject);
begin
GameBegin:=False;
end;procedure TfrmFiveMain.QipanRepaint;
var
i,j:Integer;
begin
for i:=1 to 15 do
for j:=1 to 15 do
Begin
Case Table[i,j] of
1:
if WhoFirst=P1 then
PaintQizi((j-1)*GEZI_WIDTH+1,(i-1)*GEZI_WIDTH,BlackQi)
else
PaintQizi((j-1)*GEZI_WIDTH+1,(i-1)*GEZI_WIDTH,WhiteQi);
2:
if WhoFirst=Com then
PaintQizi((j-1)*GEZI_WIDTH+1,(i-1)*GEZI_WIDTH,BlackQi)
else
PaintQizi((j-1)*GEZI_WIDTH+1,(i-1)*GEZI_WIDTH,WhiteQi);
end;
end;
end;procedure TfrmFiveMain.ComputerPlay;
var
i,j,k,m,n,h,l,Max,PlayerMax:Integer;
PlayerHuoSan:Boolean;
begin EmptyPorC(CCOMPUTER);
EmptyPorC(CPLAYER);
GetAnalyseTable;
if WhoWin=CPLAYER then
Begin
Application.MessageBox('你赢了!!','提示',MB_OK);
nStartGame.Enabled:=True;
pbQipan.Enabled:=False;
exit;
end;
//开始下棋,最简单算法==========
Max:=0;
m:=1;n:=1;
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
begin
if Computer[i,j,k]>Max then
Begin
m:=i;n:=j;
Max:=Computer[i,j,k];
end
end;
Case Max of
0,1,2://防守
begin
PlayerMax:=0;
h:=1;l:=1;
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
begin
if Player[i,j,k]>PlayerMax then
Begin
h:=i;l:=j;
PlayerMax:=Player[i,j,k]; //电脑判断我方最有可能下的点,进行防守
end
end;
Case PlayerMax of
0,1://当我方无活三的可能时,电脑试探自己有无活三的可能
begin
//Computer活三 for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
begin
if (Computer[i,j,1]=2)and(Computer[i,j,k]=2)and(k<>1)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,2]=2)and(Computer[i,j,k]=2)and(k<>2)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,3]=2)and(Computer[i,j,k]=2)and(k<>3)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,4]=2)and(Computer[i,j,k]=2)and(k<>4)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end;
end;
if WhoPlay=Com then
begin
Table[h,l]:=2;
Whoplay:=P1;
end;
end;
2://电脑判断我方有无活三的可能,如无则试探自己有无活三的可能
begin
PlayerHuoSan:=False;
//Player活三
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
begin
if (Player[i,j,1]=2)and(Player[i,j,k]=2)and(k<>1)then
begin
PlayerHuoSan:=True;
break;
end;
if (Player[i,j,2]=2)and(Player[i,j,k]=2)and(k<>2)then
begin
PlayerHuoSan:=True;
break;
end;
if (Player[i,j,3]=2)and(Player[i,j,k]=2)and(k<>3)then
begin
PlayerHuoSan:=True;
break;
end;
if (Player[i,j,4]=2)and(Player[i,j,k]=2)and(k<>4)then
begin
PlayerHuoSan:=True;
break;
end;
end;
if PlayerHuoSan=False then
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
begin
if (Computer[i,j,1]=2)and(Computer[i,j,k]=2)and(k<>1)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,2]=2)and(Computer[i,j,k]=2)and(k<>2)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,3]=2)and(Computer[i,j,k]=2)and(k<>3)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,4]=2)and(Computer[i,j,k]=2)and(k<>4)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end;
end; if WhoPlay=Com then
begin
Table[h,l]:=2;
Whoplay:=P1;
end;
end;
3,4://防守
Table[h,l]:=2;
end;
if WhoPlay=Com then
WhoPlay:=P1;
end;
3:
begin
PlayerMax:=0;
h:=1;l:=1;
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
begin
if Player[i,j,k]>PlayerMax then
Begin
h:=i;l:=j;
PlayerMax:=Player[i,j,k]; //电脑判断我方最有可能下的点,进行防守
end
end;
Case PlayerMax of
3,4:
begin
Table[h,l]:=2;
WhoPlay:=P1;
end;
else
begin
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
begin
//活三
if (Computer[i,j,1]=2)and(Computer[i,j,k]=3)and(k<>1)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,2]=2)and(Computer[i,j,k]=3)and(k<>2)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,3]=2)and(Computer[i,j,k]=3)and(k<>3)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,4]=2)and(Computer[i,j,k]=3)and(k<>4)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end; //三四
if (Computer[i,j,1]=3)and(Computer[i,j,k]=3)and(k<>1)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,2]=3)and(Computer[i,j,k]=3)and(k<>2)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,3]=3)and(Computer[i,j,k]=3)and(k<>3)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,4]=3)and(Computer[i,j,k]=3)and(k<>4)then
begin
m:=i;n:=j;
Table[m,n]:=2;
WhoPlay:=P1;
break;
end;
end;
end
end;
if Whoplay=com then
begin
Table[m,n]:=2; //冲四
WhoPlay:=P1;
end;
end;
4:
begin
Table[m,n]:=2; //成五
if Whoplay=com then
WhoPlay:=P1;
end;
end;
//===========================
QipanRepaint;
GetanalyseTable;
if WhoWin=CCOMPUTER then
Begin
Application.MessageBox('你输了!!','提示',MB_OK);
nStartGame.Enabled:=True;
pbQipan.Enabled:=False;
exit;
end;
end;procedure TfrmFiveMain.GetanalyseTable;
var
i,j,k,m,n,h,Dots:Integer;
begin
//初始化棋型表
for k:=1 to 4 do
Case k of
1: //横向遍历
begin
//Player 棋型表生成
for i:=1 to 15 do
for j:=1 to 15 do
if Table[i,j]=0 then
Begin
Dots:=0;
for m:=j-1 downto 1 do
if Table[i,m]=1 then
Dots:=Dots+1
else
Break;
for m:=j+1 to 15 do
if Table[i,m]=1 then
Dots:=Dots+1
else
Break;
Player[i,j,k]:=Dots;
end;
//Computer 棋型表生成
for i:=1 to 15 do
for j:=1 to 15 do
if Table[i,j]=0 then
Begin
Dots:=0;
for m:=j-1 downto 1 do
if Table[i,m]=2 then
Dots:=Dots+1
else
Break;
for m:=j+1 to 15 do
if Table[i,m]=2 then
Dots:=Dots+1
else
Break;
Computer[i,j,k]:=Dots;
end;
end;
2://竖向遍历
begin
//Player 棋型表生成
for j:=1 to 15 do
for i:=1 to 15 do
begin
h:=Table[i,j];
if h=0 then
begin
Dots:=0;
for m:=i-1 downto 1 do
if Table[m,j]=1 then
Dots:=Dots+1
else
break;
for m:=i+1 to 15 do
if Table[m,j]=1 then
Dots:=Dots+1
else
Break;
Player[i,j,k]:=Dots;
end;
end;
//Computer 棋型表生成
for j:=1 to 15 do
for i:=1 to 15 do
if Table[i,j]=0 then
begin
Dots:=0;
for m:=i-1 downto 1 do
if Table[m,j]=2 then
Dots:=Dots+1
else
break;
for m:=i+1 to 15 do
if Table[m,j]=2 then
Dots:=Dots+1
else
Break;
Computer[i,j,k]:=Dots;
end;
end;
3: // '\'型棋型表
begin
//Player 棋型表生成
for i:=1 to 15 do
for j:=1 to 15 do
if Table[i,j]=0 then
begin
m:=i-1;n:=j-1;
Dots:=0;
while (m>=1)or(n>=1) do
begin
if Table[m,n]=1 then
Dots:=Dots+1
else
Break;
m:=m-1;
n:=n-1;
end;
m:=i+1;n:=j+1;
while(m<=15)or(n<=15)do
begin
if Table[m,n]=1 then
Dots:=Dots+1
else
Break;
m:=m+1;
n:=n+1;
end;
Player[i,j,k]:=Dots;
end;
//Computer 棋型表生成
for i:=1 to 15 do
for j:=1 to 15 do
if Table[i,j]=0 then
begin
m:=i-1;n:=j-1;
Dots:=0;
while(m>=1)and(n>=1)do
begin
if Table[m,n]=2 then
Dots:=Dots+1
else
Break;
m:=m-1;
n:=n-1;
end;
m:=i+1;n:=j+1;
while(m<=15)and(n<=15)do
begin
if Table[m,n]=2 then
Dots:=Dots+1
else
Break;
m:=m+1;
n:=n+1;
end;
Computer[i,j,k]:=Dots;
end;
end;
4: // '/'行 棋型表生成
begin
//Player 棋型表生成
for i:=1 to 15 do
for j:=1 to 15 do
if Table[i,j]=0 then
begin
m:=i-1;n:=j+1;
Dots:=0;
while (m>=1)and(n<=15) do
begin
if Table[m,n]=1 then
Dots:=Dots+1
else
Break;
m:=m-1;
n:=n+1;
end;
m:=i+1;n:=j-1;
while(m<=15)and(n>=1)do
begin
if Table[m,n]=1 then
Dots:=Dots+1
else
Break;
m:=m+1;
n:=n-1;
end;
Player[i,j,k]:=Dots;
end;
//Computer 棋型表生成
for i:=1 to 15 do
for j:=1 to 15 do
if Table[i,j]=0 then
begin
m:=i-1;n:=j+1;
Dots:=0;
while (m>=1)and(n<=15) do
begin
if Table[m,n]=2 then
Dots:=Dots+1
else
Break;
m:=m-1;
n:=n+1;
end;
m:=i+1;n:=j-1;
while(m<=15)and(n>=1)do
begin
if Table[m,n]=2 then
Dots:=Dots+1
else
Break;
m:=m+1;
n:=n-1;
end;
Computer[i,j,k]:=Dots;
end;
end;
end;
//==========
end;procedure TfrmFiveMain.EmptyPorC(Flag: Integer);
var
i,j,k:Integer;
begin
if Flag=CPLAYER then
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
Player[i,j,k]:=0
else
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
Computer[i,j,k]:=0;
end;function TfrmFiveMain.WhoWin: Integer;
var
i,j,k:Integer;
begin
Result:=-1;
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
if Player[i,j,k]=5 then Result:=CPLAYER;
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
if Computer[i,j,k]=5 then Result:=CCOMPUTER;
end;procedure TfrmFiveMain.nStartGameClick(Sender: TObject);
begin
GameBegin:=True;
WhoFirst:=P1;
WhoPlay:=WhoFirst;
WithComputer:=True;
EmptyTable;
pbQipan.Enabled:=True;
pbQipan.Repaint;
nStartGame.Enabled:=False;
nNewGame.Enabled:=True;
end;procedure TfrmFiveMain.nExitClick(Sender: TObject);
begin
close;
end;procedure TfrmFiveMain.EmptyTable;
var
i,j:Integer;
begin
for i:=1 to 15 do
for j:=1 to 15 do
table[i,j]:=0;
end;procedure TfrmFiveMain.nNewGameClick(Sender: TObject);
begin
If Application.MessageBox('您确定要重新开始游戏吗?','询问',MB_YESNO or MB_ICONQUESTION)=ID_YES then
nStartGame.OnClick(Sender);
end;function TfrmFiveMain.AI_GetMax(var m, n: Integer;WhosTable:TPlayerorComputer): Integer;
var
Max,i,j,k:Integer;
begin
Max:=0;
if WhosTable=Com then
begin
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
if Computer[i,j,k]>Max then
Begin
m:=i;n:=j;
Max:=Computer[i,j,k];
end;
end
else
begin
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
if Player[i,j,k]>Max then
Begin
m:=i;n:=j;
Max:=Player[i,j,k];
end;
end;
Result:=Max;
end;function TfrmFiveMain.AI_Output(Step: Integer): Integer;
var
i,j,k,Cx,Cy,Px,Py,Start:Integer;
HuoSan:Boolean;
begin
Start:=1;
for i:=1 to 15 do
for j:=1 to 15 do
TempTable[i,j]:=Table[i,j]; //给临时棋盘状态赋初值
for Start:=1 to Step do
Case Start of
1:
begin
EmptyPorC(CCOMPUTER); //清空Computer表
EmptyPorC(CPLAYER); //清空Player表
GetAnalyseTableX; //依据临时棋盘状态生成棋型表
Case AI_GetMax(Cx,Cy,Com) of //电脑的棋型最大值
0,1,2://电脑无可以攻的招
begin
//电脑判断我方最有可能下的点
Case AI_GetMax(Px,Py,WhoPlay) of
0,1: //当我方无活三的可能时,电脑试探自己有无活三的可能
begin
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
begin
if (Computer[i,j,1]=2)and(Computer[i,j,k]=2)and(k<>1)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,2]=2)and(Computer[i,j,k]=2)and(k<>2)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,3]=2)and(Computer[i,j,k]=2)and(k<>3)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,4]=2)and(Computer[i,j,k]=2)and(k<>4)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end;
end;
if WhoPlay=Com then
begin
TempTable[Cx,Cy]:=2;
Whoplay:=P1;
end;
end;
2://电脑判断我方有无活三的可能,如无则试探自己有无活三的可能
begin
HuoSan:=False;
//Player活三
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
begin
if (Player[i,j,1]=2)and(Player[i,j,k]=2)and(k<>1)then
begin
HuoSan:=True;
break;
end;
if (Player[i,j,2]=2)and(Player[i,j,k]=2)and(k<>2)then
begin
HuoSan:=True;
break;
end;
if (Player[i,j,3]=2)and(Player[i,j,k]=2)and(k<>3)then
begin
HuoSan:=True;
break;
end;
if (Player[i,j,4]=2)and(Player[i,j,k]=2)and(k<>4)then
begin
HuoSan:=True;
break;
end;
end;
if HuoSan=False then
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
begin
if (Computer[i,j,1]=2)and(Computer[i,j,k]=2)and(k<>1)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,2]=2)and(Computer[i,j,k]=2)and(k<>2)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,3]=2)and(Computer[i,j,k]=2)and(k<>3)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,4]=2)and(Computer[i,j,k]=2)and(k<>4)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end;
end;
if WhoPlay=Com then
begin
TempTable[Px,Py]:=2;
Whoplay:=P1;
end;
end;
3,4:Table[Px,Py]:=2;
end;
if WhoPlay=Com then
WhoPlay:=P1;
//=========================
end;
3:
begin
case AI_GetMax(Px,Py,WhoPlay) of
3,4:
begin
TempTable[Px,Py]:=2;
WhoPlay:=P1;
end;
else
begin
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 4 do
begin
//活三
if (Computer[i,j,1]=2)and(Computer[i,j,k]=3)and(k<>1)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,2]=2)and(Computer[i,j,k]=3)and(k<>2)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,3]=2)and(Computer[i,j,k]=3)and(k<>3)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,4]=2)and(Computer[i,j,k]=3)and(k<>4)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end; //三四
if (Computer[i,j,1]=3)and(Computer[i,j,k]=3)and(k<>1)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,2]=3)and(Computer[i,j,k]=3)and(k<>2)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,3]=3)and(Computer[i,j,k]=3)and(k<>3)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end;
if (Computer[i,j,4]=3)and(Computer[i,j,k]=3)and(k<>4)then
begin
Cx:=i;Cy:=j;
TempTable[Cx,Cy]:=2;
WhoPlay:=P1;
break;
end;
end;
end;
end;
if Whoplay=com then
begin
TempTable[Cx,Cy]:=2; //冲四
WhoPlay:=P1;
end;
end;
4:
begin
Table[Cx,Cy]:=2; //成五
if Whoplay=com then
WhoPlay:=P1;
end;
5:
begin
end;
end;//Case Ai_GetMax(Com) end;
//在TempTable中模拟Player下子
//==========================
end;
2:
begin
end;
3:
begin
end;
4:
begin
end;
5:
begin
end;
6:
begin
end;
end;
result:=0;
end;procedure TfrmFiveMain.GetAnalyseTableX;
var
i,j,k,m,n,h,Dots:Integer;
begin
//初始化棋型表
for k:=1 to 4 do
Case k of
1: //横向遍历
begin
//Player 棋型表生成
for i:=1 to 15 do
for j:=1 to 15 do
if TempTable[i,j]=0 then
Begin
Dots:=0;
for m:=j-1 downto 1 do
if TempTable[i,m]=1 then
Dots:=Dots+1
else
Break;
for m:=j+1 to 15 do
if TempTable[i,m]=1 then
Dots:=Dots+1
else
Break;
Player[i,j,k]:=Dots;
end;
//Computer 棋型表生成
for i:=1 to 15 do
for j:=1 to 15 do
if TempTable[i,j]=0 then
Begin
Dots:=0;
for m:=j-1 downto 1 do
if TempTable[i,m]=2 then
Dots:=Dots+1
else
Break;
for m:=j+1 to 15 do
if TempTable[i,m]=2 then
Dots:=Dots+1
else
Break;
Computer[i,j,k]:=Dots;
end;
end;
2://竖向遍历
begin
//Player 棋型表生成
for j:=1 to 15 do
for i:=1 to 15 do
begin
h:=TempTable[i,j];
if h=0 then
begin
Dots:=0;
for m:=i-1 downto 1 do
if TempTable[m,j]=1 then
Dots:=Dots+1
else
break;
for m:=i+1 to 15 do
if TempTable[m,j]=1 then
Dots:=Dots+1
else
Break;
Player[i,j,k]:=Dots;
end;
end;
//Computer 棋型表生成
for j:=1 to 15 do
for i:=1 to 15 do
if TempTable[i,j]=0 then
begin
Dots:=0;
for m:=i-1 downto 1 do
if TempTable[m,j]=2 then
Dots:=Dots+1
else
break;
for m:=i+1 to 15 do
if TempTable[m,j]=2 then
Dots:=Dots+1
else
Break;
Computer[i,j,k]:=Dots;
end;
end;
3: // '\'型棋型表
begin
//Player 棋型表生成
for i:=1 to 15 do
for j:=1 to 15 do
if TempTable[i,j]=0 then
begin
m:=i-1;n:=j-1;
Dots:=0;
while (m>=1)or(n>=1) do
begin
if TempTable[m,n]=1 then
Dots:=Dots+1
else
Break;
m:=m-1;
n:=n-1;
end;
m:=i+1;n:=j+1;
while(m<=15)or(n<=15)do
begin
if TempTable[m,n]=1 then
Dots:=Dots+1
else
Break;
m:=m+1;
n:=n+1;
end;
Player[i,j,k]:=Dots;
end;
//Computer 棋型表生成
for i:=1 to 15 do
for j:=1 to 15 do
if TempTable[i,j]=0 then
begin
m:=i-1;n:=j-1;
Dots:=0;
while(m>=1)and(n>=1)do
begin
if TempTable[m,n]=2 then
Dots:=Dots+1
else
Break;
m:=m-1;
n:=n-1;
end;
m:=i+1;n:=j+1;
while(m<=15)and(n<=15)do
begin
if TempTable[m,n]=2 then
Dots:=Dots+1
else
Break;
m:=m+1;
n:=n+1;
end;
Computer[i,j,k]:=Dots;
end;
end;
4: // '/'行 棋型表生成
begin
//Player 棋型表生成
for i:=1 to 15 do
for j:=1 to 15 do
if TempTable[i,j]=0 then
begin
m:=i-1;n:=j+1;
Dots:=0;
while (m>=1)and(n<=15) do
begin
if TempTable[m,n]=1 then
Dots:=Dots+1
else
Break;
m:=m-1;
n:=n+1;
end;
m:=i+1;n:=j-1;
while(m<=15)and(n>=1)do
begin
if TempTable[m,n]=1 then
Dots:=Dots+1
else
Break;
m:=m+1;
n:=n-1;
end;
Player[i,j,k]:=Dots;
end;
//Computer 棋型表生成
for i:=1 to 15 do
for j:=1 to 15 do
if TempTable[i,j]=0 then
begin
m:=i-1;n:=j+1;
Dots:=0;
while (m>=1)and(n<=15) do
begin
if TempTable[m,n]=2 then
Dots:=Dots+1
else
Break;
m:=m-1;
n:=n+1;
end;
m:=i+1;n:=j-1;
while(m<=15)and(n>=1)do
begin
if TempTable[m,n]=2 then
Dots:=Dots+1
else
Break;
m:=m+1;
n:=n-1;
end;
Computer[i,j,k]:=Dots;
end;
end;
end;
end;
end.