五子棋 |
答題得分者是:小傑克
|
WDF
一般會員 發表:1 回覆:1 積分:0 註冊:2009-04-27 發送簡訊給我 |
板上各位大大你們好.小弟我是一位新手.約在半年前在公司一位工程師的帶領下踏入了Delphi的領域.但俗語說師父領進門修行在個人 這半年期間小弟我也有翻閱了一些書籍與網站.當然也有請教當初領進門的大師.但小弟天資愚鈍.....(半年期間也感覺沒什麼長進...哀) 這五子棋是小弟用來做練習的.目前寫到可單機雙人對打.但小弟想請教各位高手 要如何加入AI的功能.意思就是如何可與電腦對戰 請各位指點小弟一個方向.小弟在此先感謝各位耐心看完 以下是我原始程式與程式壓縮檔 懇請各位賜教 [code delphi] unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls; Type markarray=record x:integer; y:integer; color:Byte; end; type TForm1 = class(TForm) Image1: TImage; Edit2: TEdit; Edit1: TEdit; Button1: TButton; Edit4: TEdit; procedure Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormCreate(Sender: TObject); procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } aa:boolean; pcounter:integer; letmark: array [0..1155]of markarray; procedure repainline; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var A,B,C,D,i,w,e:integer; label outexit; begin if (x<13) or (x>837) or (Y>783)or (Y<13) //設定邊界 then goto outexit; begin A := X div 25; C := X mod 25; if C > 12 then A := A 1; A := A * 25; W := A div 25; end; begin B := Y div 25; D := Y mod 25; if D > 12 then B := B 1; B := B * 25; E := B div 25; end; edit1.Text := '棋子位置' inttostr(W) '.' inttostr(E); edit2.Text := '實際座標' inttostr(X) '.' inttostr(Y); for i := 0 to pcounter-1 do begin if (letmark[i].x = A) and (letmark[i].y =B) then goto outexit; end; if aa = false then begin aa:=true; image1.Canvas.Brush.Color :=clred; letmark[pcounter].color := 1; end else begin aa:=false; image1.Canvas.Brush.Color := clblack; letmark[pcounter].color := 2; end; letmark[pcounter].x := A; letmark[pcounter].y := B; inc(pcounter); image1.Canvas.Ellipse(rect(A-10,B-10,A 10,B 10)); outexit: end; procedure TForm1.repainline; var X1, Y1, X2, Y2: Integer; begin with Image1.Canvas do begin for X1 := 1 to 200 do begin X2 := (X1*25) ; // 方格大小 MoveTo(X2,0); // X起點 LineTo(X2,1000); // X末點 MoveTo(0,X2); // Y起點 LineTo(10000,X2); // Y末點 end; end; end; procedure TForm1.FormCreate(Sender: TObject); begin edit1.Text := '棋子位置' ; edit2.Text := '實際座標' ; repainline; end; procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin edit4.Text := 'X軸' inttostr(x) ' ' 'Y軸' inttostr(Y); end; procedure TForm1.Button1Click(Sender: TObject); //清除棋子 var ii :integer; begin for ii:= 0 to 1155 do begin letmark[ii].color := 0; letmark[ii].x := 0; letmark[ii].y := 0; end; begin image1.Canvas.Brush.Color := clWhite; image1.Canvas.FillRect(rect(0,0,850,800)); repainline; edit1.Text := '棋子位置' ; edit2.Text := '實際座標' ; edit4.Text := ''; end; end; end. [/code] |
老大仔
尊榮會員 發表:78 回覆:837 積分:1088 註冊:2006-07-06 發送簡訊給我 |
|
WDF
一般會員 發表:1 回覆:1 積分:0 註冊:2009-04-27 發送簡訊給我 |
|
小傑克
資深會員 發表:5 回覆:209 積分:357 註冊:2009-02-16 發送簡訊給我 |
|
小傑克
資深會員 發表:5 回覆:209 積分:357 註冊:2009-02-16 發送簡訊給我 |
雖然我也沒寫過下棋的AI 但是我提供一些我的想像
我最先想到的是暴力破解法,就像開四碼鎖 就從0000 一直試到9999, 也就是把所有可能的黑白子位置都輪流填入,但這樣組合實在太多了, 19*19棋盤就是361! 級數,這太大了 所以要快的話, 要模擬人思考的測試邏輯, 首先要做能判斷連線的邏輯 也就是能知道兩黑子相連是連2 , 三子相連是連3 , 五子相連就獲勝, 然後按照人思考的方式 把所有能形成的可能的型態配置權值,比如說連二給一點,連三給兩點, 然後把棋盤中每個格子的權值重算出來 所以要先做判斷類型的邏輯,五子棋走勢類型很多,我舉幾個就好 連2 連2但一邊有檔 連3 連3但一邊有檔 連4 連4但一邊有檔 兩子中間空一格 連二空一格在一個 把這些型態按照獲勝可能機率編上權值, 每一格計算權值都時候就把周邊棋子能形成的型態的權值加總 AI 就是下在權值最高的那一格, 理論上你只要列出更多的型態, 調整權值比重, 就能讓AI 越利害 但這只是我想像,沒實際做不知有沒有困難
------
額有朝天骨,眼中有靈光 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |