关于五子棋的编程问题(200分)

P

phgh

Unregistered / Unconfirmed
GUEST, unregistred user!
我想做一个五子棋的游戏,主要是用于人机对战,请高手指点如何做。关键是
进攻和防守的算法。
 
介绍一个经典网站
http://vip.6to23.com/mays/index.html
上面有游戏算法的探讨,有两篇关于五子棋的。
我曾看过,不错!
 
如果你能把先手的禁手规则判断出来,我就F你
 
看到过两人对战的!~
到网上down去
 
我用C++BUILDER写过一个
 
五子棋源代码
grhunter


摘 要:一个五子棋程序的完整源代码
关键字:五子棋
类 别:其它


unit Main;

interface

uses
 Windows, Messages, SysUtils, Classes, Controls, Forms, Dialogs,
 ExtCtrls, StdCtrls, ComCtrls, Buttons, Graphics, mmsystem;

type
 TForm1 = class(TForm)
  StatusBar1: TStatusBar;
  GroupBox1: TGroupBox;
  GroupBox2: TGroupBox;
  Panel1: TPanel;
  Label1: TLabel;
  BitBtn1: TBitBtn;
  BitBtn2: TBitBtn;
  Label3: TLabel;
  Label4: TLabel;
  BitBtn3: TBitBtn;
  Image1: TImage;
  Image2: TImage;
  Label5: TLabel;
  Label2: TLabel;
  Label6: TLabel;
  Label7: TLabel;
  Label8: TLabel;
  Label9: TLabel;
  Label10: TLabel;
  Timer1: TTimer;
  Label11: TLabel;
  procedure BitBtn2Click(Sender: TObject);
  procedure BitBtn1Click(Sender: TObject);
  procedure Image2MouseDown(Sender: TObject; Button: TMouseButton;
   Shift: TShiftState; X, Y: Integer);
  procedure FormCreate(Sender: TObject);
  procedure BitBtn3Click(Sender: TObject);
  procedure Timer1Timer(Sender: TObject);
  procedure Label11MouseDown(Sender: TObject; Button: TMouseButton;
   Shift: TShiftState; X, Y: Integer);

 private
  { Private declarations }
 public
  { Public declarations }
 end;

 FiveChess_Struct=record
     x1 : integer;
     y1 : integer;
     x2 : integer;
     y2 : integer;
     state : byte;
 end;
 FiveChess_Data=array [0..14,0..14] of FiveChess_Struct;

 Player = ( NON,White,Black);

var
 Form1: TForm1;
 Start_Flag : Boolean;
 FiveChess_Array:FiveChess_Data ;
 Online: player;
 whitewin,blackwin:byte;
 whitetime,blacktime:integer;
 px1,px2,py1,py2 : integer;

 Undo_i,Undo_j : integer;
function Ini_Main():Boolean ;
implementation

uses Option;

{$R *.DFM}
//{$R AOE.RES}


procedure Ini_FiveChess_Array();
var
  i , j,k: integer;
begin

   For i:=0 to 14 do begin
     For j:=0 to 14 do begin
       FiveChess_Array[i,j].x1:=16+25*j;
       FiveChess_Array[i,j].y1:=16+25*i;
       FiveChess_Array[i,j].x2:=36+25*j;
       FiveChess_Array[i,j].y2:=36+25*i;
       FiveChess_Array[i,j].state:=0;
       end;
    end;
end;

procedure Draw_qipan();
var
   i,j : integer;
begin
   Form1.Image2.Canvas.Brush.Color:=RGB(247,207,16);
   Form1.Image2.Canvas.FillRect(Rect(0,0,400,400));
   Form1.Image2.Canvas.pen.Color:=RGB(0,0,0);
   for i:=1 to 16 do begin
     Form1.Image2.Canvas.MoveTo(0,25*i);
     Form1.Image2.Canvas.LineTo (400,25*i);
     Form1.Image2.Canvas.MoveTo(25*i,0);
     Form1.Image2.Canvas.LineTo (25*i,400);
   end;

end;


procedure Undo_Run();
var
   x1,x2,y1,y2 : integer;
begin




   if (Undo_i<>-1) and (Undo_j<>-1) then  begin
     FiveChess_array[Undo_i,Undo_j].state :=0;
     x1:= FiveChess_Array[Undo_i,Undo_j].x1-2;
     y1:= FiveChess_Array[Undo_i,Undo_j].y1-2;
     x2:= FiveChess_Array[Undo_i,Undo_j].x2+2;
     y2:= FiveChess_Array[Undo_i,Undo_j].y2+2;
     Form1.Image2.Canvas.Brush.Color:=RGB(247,207,16);
     Form1.Image2.Canvas.FillRect(rect(x1,y1,x2,y2));
     Form1.Image2.Canvas.pen.Color:=RGB(0,0,0);
     Form1.Image2.Canvas.MoveTo((x1+x2)div 2-1 , y1);
     Form1.Image2.Canvas.LineTo((x1+x2)div 2-1 , y2);
     Form1.Image2.Canvas.MoveTo(x1,(y1+y2)div 2-1);
     Form1.Image2.Canvas.LineTo(x2,(y1+y2)div 2-1);

     end;

   If Online=black then
     Online:=White
   else
     Online:=Black; 


end;



function Ini_Main():Boolean ;


begin

   Result:=true;

   px1:=0;
   px2:=0;
   py1:=0;
   py2:=0;

   Undo_i:=-1;
   Undo_j:=-1;

   whitetime:=0;
   blacktime:=0;

   form1.Label9.Caption :=inttostr(whitewin);
   form1.Label10.Caption :=inttostr(blackwin);


   Ini_FiveChess_Array;
   Draw_Qipan;
end;






Function Judge_Success_on_off (X,Y,State:integer):Boolean;
var
   i,j,k,count : integer;
begin
   Count:=0;
   Result:=false;

   // 判断竖列
   For i:=X-4 to X+4 do
     if (i>=0) and (i<=15) then
      begin
         if FiveChess_array[i,y].state=state then
           begin
             Inc(Count) ;
             if count=5 then begin
               result:=true;
               break;
               end;
           end
         else
           Count:=0;
      end;
   //判断横行
   count:=0;
   For j:=y-4 to y+4 do
     if (j>=0) and (j<=15) then
      begin
         if FiveChess_array[X,j].state=state then
           begin
             Inc(Count) ;
             if count=5 then begin
               result:=true;
               break;
               end;
           end
         else
           Count:=0;
      end;
   //判断'/'方向
   count:=0;
   For k:=-4 to 4 do begin
       i:=X+k;
       j:=Y+k;
       if (j>=0) and (j<=15) And(i>=0) and(i<=15) then
        begin
         if FiveChess_array[i,j].state=state then
           begin
             Inc(Count) ;
             if count=5 then begin
               result:=true;
               break;
               end;
           end
         else
           Count:=0;
      end;
   end;
  //判断'/'方向
   count:=0;
   For k:=-4 to 4 do begin
       i:=X+k;
       j:=Y-k;
       if (j>=0) and (j<=15) And(i>=0) and(i<=15) then
        begin
         if FiveChess_array[i,j].state=state then
           begin
             Inc(Count) ;
             if count=5 then begin
               result:=true;
               break;
               end;
           end
         else
           Count:=0;
      end;
   end;

end;



procedure TForm1.BitBtn2Click(Sender: TObject);
begin
   Application.Terminate ;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
   Start_Flag:=true;
   If Start_Flag then begin
    Form1.Image2.Enabled := true;
    Form1.Timer1.Enabled := true;
    Ini_Main;

   end;

end;

function Draw_Qizi_White(X,Y : Integer):boolean;
var
   i,j,x1,x2,y1,y2 : integer;
begin
   result := false;
   for i:=0 to 14 do
     For j:=0 to 14 do begin
       if (X> FiveChess_Array[i,j].x1)and(X<FiveChess_Array[i,j].x2)
      and (y> FiveChess_Array[i,j].y1)and(y<FiveChess_Array[i,j].y2)
      and (FiveChess_Array[i,j].state=0)  then
      begin
         if FiveChess_Array[Undo_i,Undo_j].state<>0 then begin
          Form1.Image2.Canvas.Brush.Color:=Rgb(100,100,100);
          Form1.Image2.Canvas.FillRect (Rect(px1,py1,px2,py2));
         end;

         Form1.Image2.Canvas.Brush.Color:=Rgb(255,255,255);
         Form1.Image2.Canvas.Ellipse ( FiveChess_Array[i,j].x1,
         FiveChess_Array[i,j].y1,FiveChess_Array[i,j].x2,FiveChess_Array[i,j].y2);
         Form1.Image2.Canvas.Brush.Color:=RGB(255,255,255);
         Form1.Image2.Canvas.Ellipse ( FiveChess_Array[i,j].x1-2,
         FiveChess_Array[i,j].y1-2,FiveChess_Array[i,j].x2-2,FiveChess_Array[i,j].y2-2);
         FiveChess_array[i,j].state:=1;

         Undo_i:=i;
         Undo_j:=j;


         Form1.Image2.Canvas.Brush.Color:=clred;
         px1:= FiveChess_Array[i,j].x1+3;
         py1:= FiveChess_Array[i,j].y1+3;
         px2:= FiveChess_Array[i,j].x2-7;
         py2:= FiveChess_Array[i,j].y2-7;
         Form1.Image2.Canvas.Ellipse (px1,py1,px2,py2);





         if Judge_Success_on_off(i,j, FiveChess_Array[i,j].state) then
          begin
             whitewin:=whitewin+1;
             if whitewin>1 then
              Application.MessageBox ('臭棋篓!比鱼头还臭!','胜败乃兵家常事',0)
             else
              Application.MessageBox ('白方已胜利!','胜败乃兵家常事',0);

             form1.label9.caption:=inttostr(whitewin);
             form1.Image2.Enabled :=false;
             Form1.Timer1.Enabled := false;
          end;

         Result := true;
         break;
      end;
   end;
end;

function Draw_Qizi_Black(X,Y : Integer): boolean;
var
   i,j,x1,x2,y1,y2 : integer;
begin
   result:=false;
   for i:=0 to 14 do
     for j:=0 to 14 do begin
       if (X> FiveChess_Array[i,j].x1)and(X<FiveChess_Array[i,j].x2)
         and (y> FiveChess_Array[i,j].y1)and(y<FiveChess_Array[i,j].y2)
         and (FiveChess_Array[i,j].state=0)  then
         begin
           if FiveChess_Array[Undo_i,Undo_j].state<>0 then begin
             Form1.Image2.Canvas.Brush.Color:=Rgb(255,255,255);
             Form1.Image2.Canvas.FillRect (Rect(px1,py1,px2,py2));
           end;
           Form1.Image2.Canvas.Brush.Color:=RGB(0,0,0);
           Form1.Image2.Canvas.Ellipse ( FiveChess_Array[i,j].x1,
              FiveChess_Array[i,j].y1,FiveChess_Array[i,j].x2,FiveChess_Array[i,j].y2);
           Form1.Image2.Canvas.Brush.Color:=RGB(100,100,100);
           Form1.Image2.Canvas.Ellipse ( FiveChess_Array[i,j].x1-2,
           FiveChess_Array[i,j].y1-2,FiveChess_Array[i,j].x2-2,FiveChess_Array[i,j].y2-2);

           FiveChess_array[i,j].state := 2;

           Undo_i:=i;
           Undo_j:=j;

           Form1.Image2.Canvas.Brush.Color:=clred;
           px1:= FiveChess_Array[i,j].x1+3;
           py1:= FiveChess_Array[i,j].y1+3;
           px2:= FiveChess_Array[i,j].x2-7;
           py2:= FiveChess_Array[i,j].y2-7;
           Form1.Image2.Canvas.Ellipse (px1,py1,px2,py2);


           if Judge_Success_on_off(i,j, FiveChess_Array[i,j].state) then
            begin
               blackwin:=blackwin+1;
               if blackwin>1 then
                Application.MessageBox ('不会吧!难道比鱼头还臭!','胜败乃兵家常事',0)
               else
                Application.MessageBox ('黑方已胜利!','胜败乃兵家常事',0);

               form1.label10.caption:=inttostr(blackwin);
               form1.Image2.Enabled :=false;
               Form1.Timer1.enabled := False;
            end;
           Result:=true;
           break;
         end;
   end;
end;

procedure TForm1.Image2MouseDown(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);

begin
     if Online = White then  begin
      if draw_Qizi_white(X,Y) then
        Online := Black
      end
     else
        if draw_Qizi_Black(X,Y) then
         Online:=White;



end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   Online:=white;
   form1.Label11.Caption :='人不到伤痕累累'#13+'就不会懂得后悔!';
   Start_Flag:=false;
   Form1.Image2.Enabled := false;
  



end;

procedure TForm1.BitBtn3Click(Sender: TObject);
begin
    form2.show;

end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
   if online=white then
     whitetime:=whitetime +1
   else
     blacktime:=blacktime +1;

   Form1.Label7.caption:=inttostr(whitetime);
   Form1.Label8.caption:=inttostr(blacktime);



end;

procedure TForm1.Label11MouseDown(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
begin
   if (Button = mbleft) and (ssShift in shift) And (form1.Image2.Enabled = true)then
     Undo_Run;

   end;


end.

end;


//////////////////////////


unit Option;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls, Buttons;

type
 TForm2 = class(TForm)
  GroupBox1: TGroupBox;
  RadioButton1: TRadioButton;
  RadioButton2: TRadioButton;
  BitBtn1: TBitBtn;
  BitBtn2: TBitBtn;
  GroupBox2: TGroupBox;
  RadioButton3: TRadioButton;
  RadioButton4: TRadioButton;
  RadioButton5: TRadioButton;
  procedure FormCreate(Sender: TObject);
  procedure BitBtn1Click(Sender: TObject);
  procedure BitBtn2Click(Sender: TObject);
 private
  { Private declarations }
 public
  { Public declarations }
 end;

var
 Form2: TForm2;


implementation


uses
   Main;
{$R *.DFM}

procedure TForm2.FormCreate(Sender: TObject);
begin
    form2.RadioButton1.Checked := true;
    form2.RadioButton3.Checked := true;
end;

procedure TForm2.BitBtn1Click(Sender: TObject);
begin
   if form2.RadioButton1.Checked = true then
     Online := White
   else
     Online := Black;

   if  form2.RadioButton3.Checked then
      begin
         whitewin:=0;
         blackwin:=0;
      end ;


   Ini_main;


   form2.close;




end;

procedure TForm2.BitBtn2Click(Sender: TObject);
begin
   form2.Close ;
end;

end.


投稿人:grhunter 投稿日期:2001-5-25 17:40:00



 
楼上的同志,您好像没有审清楚题呀——人家要得可是带人工智能的,往棋盘上画棋子谁不会呀。

to liuxudong:
这有什么难的,判断一下不就可以了吗?我自己做了一个五子棋就实现了:

//Filter
if (den_max>=160) and (den_min_step<=2) then //free three
FilterIt(2);
if TurnTo=-1 then //if I'm black, 过滤禁手
FilterAvoid;
//Analyse (base on step)
//理论上不会出低级错误
ccx:=0;
ccy:=0;
ListCheck(ListFound);
if (ListFound[2].n>=625) then//win in this step
begin
ccx:=ListFound[2].x;
ccy:=ListFound[2].y;
end
else if ListFound[1].n>=125 then //four 堵它!
begin
ccx:=ListFound[1].x;
ccy:=ListFound[1].y;
end
else if ListFound[2].n>=125*2 then //Attack:two four
begin
//the case of TurnTo is -1 (I'm black) has been filtered
ccx:=ListFound[2].x;
ccy:=ListFound[2].y;
end
else if ListFound[2].n>=125+25 then //Attack:four and free three
begin
//you should add some codes here to check if the player can attack through defence
if ListFound[1].n<5 then //no three or more
begin
ccx:=ListFound[2].x;
ccy:=ListFound[2].y;
end;
end
else if (ListFound[2].n>=125) and (all_check[ListFound[2].x][ListFound[2].y][1][1]>=230) then //free four
begin
ccx:=ListFound[2].x;
ccy:=ListFound[2].y;
end;
if ccx>0 then
goto analyse_done;
if (ListFound[2].n<125) and ((ListFound[1].n>25) and (ListFound[1].n mod 5>=1)) then
//Defence:free three and free two (it will become free four and free three) only one postion can stop it
begin //堵它!
ccx:=ListFound[1].x;
ccy:=ListFound[1].y;
end
else if (ListFound[2].n<125) and (ListFound[2].n>=25*2) then //Attack:two free three
begin
//the case of TurnTo is -1 (I'm black) has been filtered
if ListFound[1].n<5 then
begin
ccx:=ListFound[2].x;
ccy:=ListFound[2].y;
end;
end;
if ccx>0 then
goto analyse_done;
 
拜托,人家要的是好的算法,前人的程序拿来做甚!
creation-zy的吗,研究研究再说!
 
http://202.112.108.158/down/default.asp?page=5
由一个人智能编写的五子棋算法,可以一起分析一下
 
顶部