C++_五子棋人機對戰(zhàn)游戲設計_第1頁
C++_五子棋人機對戰(zhàn)游戲設計_第2頁
C++_五子棋人機對戰(zhàn)游戲設計_第3頁
C++_五子棋人機對戰(zhàn)游戲設計_第4頁
C++_五子棋人機對戰(zhàn)游戲設計_第5頁
已閱讀5頁,還剩14頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、 Visual C+ 期末考評 學院: 計算機工程學院 班 級: 11計算機科學2班 學生姓名: 吳暉 學 號: 2011404010221 設計地點(單位) A5-101 設計題目: 五子棋 完成日期: 2014年 6月 3日 指導教師評語: _成績(五級記分制):_ 教師簽名:_ 目 錄1 引言-3 1.1游戲介紹-3 1.2目的-3 1.3主要問題 -32 需求分析-43 功能模塊設計-4 3.1變量和函數-4 3.2框架的搭建-54 算法分析與設計-6 4.1.游戲界面的設計-6 4.2核心算法-75總結-19五子棋人機對戰(zhàn)游戲摘要:本文用visual c+來設計與實現簡單的五子棋人機

2、對戰(zhàn)游戲的基本功能,玩家可以在游戲區(qū)域中適當的位置來放棋子,通過程序設計讓電腦選擇最佳的落棋點,來實現人機對戰(zhàn)。文中對該游戲的算法進行了詳細的介紹,其中核心內容包括界面的設計、最佳落棋位置的判斷以及游戲勝利判斷功能的實現。程序實現起來較簡單,同時也比較實用。關鍵詞: 五子棋 ,vc,人機對戰(zhàn)游戲 1.引言1.1 游戲介紹五子棋是一種很受人們喜愛的智力游戲,它的規(guī)則簡單,但玩法變化多端,富有趣味性,特別鍛煉人的智力,適合人們消遣。1.2 目的網絡小游戲制作的目的是滿足了人們休閑的需要,在緊張工作之余休閑類的小游戲能夠給人帶來最大程度的放松,也可以增進人們之間的交流,溝通,通過游戲還可以認識更多的

3、朋友,也可以到達跨省、跨市,甚至跨國間人們互相娛樂的目的。 1.3 主要問題 開始制作游戲時,主要要解決的問題有以下幾個方面:1. 如何設置整個游戲的界面;2 判斷是否可以放下棋子;3. 如何讓電腦選擇最佳位置;4. 判斷是黑棋勝還是白棋勝。2 需求分析關于五子棋游戲的功能描述如下:運行游戲并進行初始化工作,將整個游戲區(qū)域中縱線和橫線相交的點坐標化,并且這些點是將來下棋的位置。玩家可以在任意沒有放棋子的點放下棋子,直到一方有五個棋子連成一條線為勝方。 游戲的整體運行效果如圖1.1。圖1.13. 功能模塊的設計3.1 變量和函數 在view類中添加變量函數如下:保存vscomputer時白棋位置

4、 CPoint vspoint;CPoint bpointcan4, /這個位置空,它旁邊有四個黑棋wpointcan4, /這個位置空,它旁邊有四個白棋bpointcan3, /這個位置空,它的旁邊有三個黑棋wpointcan3, /這個位置空,它的旁邊有三個白棋bpointcan2, /這個位置空,它的旁邊有兩個黑棋wpointcan2, /這個位置空,它的旁邊有兩個白棋bpointcan1; /不是以上情況,這個位置空 在得到最大值和方向上尋找落棋點,其中i、j表示搜索起點,n表示方向void searchcandown1(int i,int j,int n);void searchca

5、ndown2(int i,int j,int n);void searchcandown3(int i,int j,int n);void searchcandown4(int i,int j,int n);計算最大值及方向CPoint maxnum(int a,int b,int c,int d);最好落棋點void bestputdown(int i,int j);計算機下棋void computerdown();在位置point放下棋子void putdown(CPoint point);人對機菜單afx_msg void OnCpmputer();3.2.框架的搭建 新建工程,選擇單文

6、檔,在Step 4 of 6中先中Windows Sockets復選框4 算法分析與設計4.1游戲界面的設計由于游戲的棋盤大小是一定的,不能改變大小的,是應該符合要求的。用如下函數設置窗口大?。築OOL CMainFrame:PreCreateWindow(CREATESTRUCT& cs) if( !CFrameWnd:PreCreateWindow(cs) ) return FALSE; / TODO: Modify the Window class or styles here by modifying / the CREATESTRUCT cs cs.dwExStyle=cs.

7、dwExStyle|WS_EX_TOPMOST; / cs.style=WS_SYSMENU|WS_OVERLAPPED|WS_MINIMIZEBOX;/; /設置窗口大?。?00*340 cs.cx=450; cs.cy=500; return TRUE;畫棋盤: 在OnDraw(CDC* pDC)函數中畫棋盤,由于在游戲過程中有可能重畫棋盤,而那時棋盤上面有棋子,所以,我們在這個函數里面必須有畫棋子的語句。在此用數組的做為1表示白棋,-1表示黑棋。 void CMy3_1View:OnDraw(CDC* pDC) CMy3_1Doc* pDoc = GetDocument(); ASSER

8、T_VALID(pDoc); /畫背景 CBrush mybrush1; mybrush1.CreateSolidBrush(RGB(192,192,192); CRect myrect1(0,0,1200,800); pDC->FillRect(myrect1,&mybrush1); /畫棋盤框線 CPen mypen; CPen*myoldPen; mypen.CreatePen(PS_SOLID,1,RGB(0,0,0); myoldPen=pDC->SelectObject(&mypen); for(int i=0;i<19;i+) pDC->M

9、oveTo(40,40+i*20); pDC->LineTo(400,40+i*20); pDC->MoveTo(40+i*20,40); pDC->LineTo(40+i*20,400); /重畫時顯示存在的棋子 CDC Dc; if(Dc.CreateCompatibleDC(pDC)=FALSE) AfxMessageBox("Can't create DC"); for(int n=0;n<19;n+) for(int m=0;m<19;m+) if(wzqnm=1) /顯示白棋 Dc.SelectObject(m_bmwhit

10、e); pDC->BitBlt(n*20+32,m*20+32,160,160,&Dc,0,0,SRCCOPY); else if(wzqnm=-1) /顯示黑棋 Dc.SelectObject(m_bmblack); pDC->BitBlt(n*20+32,m*20+32,160,160,&Dc,0,0,SRCCOPY); 棋盤的效果如圖4.2核心算法 在完成界面設計后,就開始展開游戲核心的設計,該部分主要包括計算機搜索最佳落棋位置,游戲勝利判斷的實現。5.1 搜索最佳落棋位置 計算機是怎樣下棋?這就是定位的問題了。即搜索棋盤,找出一個最佳點,放下黑棋。我們實現的

11、方法是:全盤搜索,并把搜索到的位置,保存在變量。由于有多種情況,我們定義變量如下:CPoint bpointcan4, /這個位置空,它旁邊有四個黑棋 wpointcan4, /這個位置空,它旁邊有四個白棋 bpointcan3, /這個位置空,它的旁邊有三個黑棋 wpointcan3, /這個位置空,它的旁邊有三個白棋 bpointcan2, /這個位置空,它的旁邊有兩個黑棋 wpointcan2, /這個位置空,它的旁邊有兩個白棋 bpointcan1; /不是以上情況,這個位置空 并在搜索之前都賦值為(-1,-1),然后,進行搜索,并把相應的值保存在相應變量里面,而如果前面已經對變量賦值

12、,我們依然賦值,用新值代替舊值。注意:只保存最后一個值,這樣的一個好處是,避免了每次都從左上角開始,并且它的隨機性比隨機函數還隨機。全盤搜索完之后,由于上面的變量中至少有一個已經被賦值,即不是(-1,-1),可以采用多數優(yōu)先的方法,讓已經有多個同色棋子的位置先下棋。其原理是,如果已經有四個黑棋,計算機再下一個黑棋就贏了;否則,如果人已經有四個白棋,那么計算機就必須放下一個黑棋,阻止白棋下一步贏;如果已經有三個黑棋,再下一個黑棋,變成四個;否則,如果已經有三個白棋,下一個黑棋,破壞它;兩個棋子的同理;否則,在剛才白棋下的地方,順便找一個位置,下棋。computerdown()函數如下:/輪到計算

13、機下棋void CMy3_1View:computerdown() /把各種情形賦值為如下 bpointcan4=(-1,-1); wpointcan4=(-1,-1); bpointcan3=(-1,-1); wpointcan3=(-1,-1); bpointcan2=(-1,-1); wpointcan2=(-1,-1); bpointcan1=(-1,-1); /搜索最好的落棋點 for(int i=0;i<19;i+) for(int j=0;j<19;j+) bestputdown(i,j); /判斷放在哪里 /棋多的位置優(yōu)先 /黑白一樣多時黑先 /不是-1就表示已經被

14、賦值! if(bpointcan4.x!=-1) putdown(bpointcan4); return; else if(wpointcan4.x!=-1) putdown(wpointcan4); return; else if(bpointcan3.x!=-1) putdown(bpointcan3); return; else if(wpointcan3.x!=-1) putdown(wpointcan3); return; else if(bpointcan2.x!=-1) putdown(bpointcan2); return; else if(wpointcan2.x!=-1)

15、putdown(wpointcan2); return; else putdown(bpointcan1); return; 上面又有兩個新函數,分別定義為空函數,如下: 搜索最佳位置 void bestputdown(int i,int j); 放下黑棋 void putdown(CPoint point);現在,對上面兩個空函數進行定義 在指定位置下棋: 由于putdown(CPoint point)函數的原理非常簡單,我們先說明如下: /黑棋下void CMy3_1View:putdown(CPoint point) CDC *pDC=GetDC(); CDC Dc; if(Dc.Cre

16、ateCompatibleDC(pDC)=FALSE) AfxMessageBox("Can't create DC"); Dc.SelectObject(m_bmblack); pDC->BitBlt(point.x*20+32,point.y*20+32,160,160,&Dc,0,0,SRCCOPY); wzqpoint.xpoint.y=-1;/由于原來我們檢查是否結束時用的是鼠標點下的坐標,而現在/putdown(CPoint point)函數用的是數組棋盤的坐標,所以必須轉換 CPoint overpoint; overpoint.x=po

17、int.x*20+30; overpoint.y=point.y*20+30; over(overpoint); colorwhite=true; 搜索最佳落棋點: 現在還有void bestputdown(int i,int j)函數沒有定義。它的實現原理是:在四個方向上,各自計算那個方向上棋子的狀態(tài),利用原來定義的白棋為1,黑棋為-1的思想,讓同個方向上的五個棋子的值相加,取絕對值并賦值給為這個方向定義的局部變量numi。 如果幾個棋子是同色的,無論黑白,它的絕對值必然大,而對于幾個棋子中有黑棋和白棋的,其值必然相加而抵消變小。所以我們可以利用這種方法來尋找旁邊有多個同色棋子的空位置(前面

18、已經具體說明)。在每一個棋盤位置,計算以它為起點的四個方向(橫、豎、撇、捺),再比較這四個方向中哪個值最大,然后在這個方向上尋找落棋點。/檢查四個方向,各算出五個棋子的和并賦值void CMy3_1View:bestputdown(int i,int j) /四個方向的值 int num4; int a,k; / num0 -> a=0; if(i<15) for(k=0;k<5;k+) a=a+wzqi+kj; num0=abs(a); / num1 "|" a=0; if(j<15) for(k=0;k<5;k+) a=a+wzqij+k;

19、 num1=abs(a); / num2 "" a=0; if(i<15&&j<15) for(k=0;k<5;k+) a=a+wzqi+kj+k; num2=abs(a); / num3 "/" a=0; if(i>4)&&(j<15) for(k=0;k<5;k+) a=a+wzqi-kj+k; num3=abs(a); 比較哪個方向同色棋最多由于搜索落棋點時用到最大值和方向,可以定義一個Cpoint類變量,讓它返回兩個值。因為這樣你就不用去寫/內聯函數了CPoint numbig;

20、/numbig.x表示方向/numbig.y表示最大值 numbig=maxnum(num0,num1,num2,num3); /在得到最大值和方向上尋找落棋點 switch(numbig.y) case 4: searchcandown4(i,j,numbig.x);break; case 3: searchcandown3(i,j,numbig.x);break; case 2: searchcandown2(i,j,numbig.x);break; default: searchcandown1(i,j,numbig.x); 同樣的方法,為上面還沒有定義的函數添加空函數。 /其中i、j表

21、示搜索起點,n表示方向 void searchcandown1(int i,int j,int n); void searchcandown2(int i,int j,int n); void searchcandown3(int i,int j,int n); void searchcandown4(int i,int j,int n); CPoint maxnum(int a,int b,int c,int d); 最大值函數的實現: 現在先介紹CPoint maxnum(int a,int b,int c,int d)函數,它只是四個整數的比較: CPoint CMy3_1View:ma

22、xnum(int a, int b, int c, int d) /point.x為方向值 /point.y為最大值 CPoint point; if(a>=b) point.x=0; point.y=a; else point.x=1; point.y=b; if(c>point.y) point.x=2; point.y=c; if(d>point.y) point.x=3; point.y=d; return point; 而另外的四個函數,有其相似性,分別介紹如下: void searchcandown4(int i,int j,int n)函數: 如果最大值是四,它

23、必然有一個空位置;可以這樣計算,如果第一個是空,那我們把它賦值給相應變量;否則,先找那個空位置,然后判斷第一個棋子的顏色,并賦相應的值。 /由于相似,下面代碼只解釋第一個方向 /有四個同色棋void CMy3_1View:searchcandown4(int i, int j, int n) int k; / num0 "-" if(n=0) for(k=0;k<5;k+) /如果第一個是空 if(wzqij=0) /如果下面有白棋 if(wzqi+1j=1) /下面位置可以下棋,已經有四個白棋 wpointcan4.x=i; wpointcan4.y=j; brea

24、k; else /下面位置可以下棋,已經有四個黑棋 bpointcan4.x=i; bpointcan4.y=j; break; /如果找到下棋位置,一定能找到! else if(wzqi+kj=0) /如果第一個是白棋 if(wzqjj=1) wpointcan4.x=i+k; wpointcan4.y=j; break; /否則第一個是黑棋 else bpointcan4.x=i+k; bpointcan4.y=j; break; / num1 "|" if(n=1) for(k=0;k<5;k+) if(wzqij=0) if(wzqij+1=1) wpoint

25、can4.x=i; wpointcan4.y=j; break; else bpointcan4.x=i; bpointcan4.y=j; break; else if(wzqij+k=0) if(wzqij=1) wpointcan4.x=i; wpointcan4.y=j+k; break; else bpointcan4.x=i; bpointcan4.y=j+k; break; / num2 "" if(n=2) for(k=0;k<5;k+) if(wzqij=0) if(wzqi+1j+1=1) wpointcan4.x=i; wpointcan4.y=j

26、; break; else bpointcan4.x=i; bpointcan4.y=j; break; else if(wzqi+kj+k=0) if(wzqij=1) wpointcan4.x=i+k; wpointcan4.y=j+k; break; else bpointcan4.x=i+k; bpointcan4.y=j+k; break; / num3 "/" if(n=3) for(k=0;k<5;k+) if(wzqij=0) if(wzqi-1j+1=1) wpointcan4.x=i; wpointcan4.y=j; break; else bpo

27、intcan4.x=i; bpointcan4.y=j; break; else if(wzqi-kj+k=0) if(wzqij=1) wpointcan4.x=i-k; wpointcan4.y=j+k; break; else bpointcan4.x=i-k; bpointcan4.y=j+k; break; void searchcandown3(int i,int j,int n)函數: 如果最大值是三,它有兩種情況,一種是三個同色和兩個空;一種是四個同色和一個異色。前一種必定能找到一個空位置,賦值;后一種必定找不到空位置,不賦值。所以我們的想法很簡單,先找到空位置,證明有三個同色

28、,這對于玩五子棋來說三個同色是很重要的,再判斷是哪種顏色,賦相應的值。void searchcandown2(int i,int j,int n)函數: 如果最大值是二,也有兩種情況:一種是有兩個同色和三個空位置;一種是有三個同色和一個異色和一個空位置,并且只算三個同色不連在一起的情況(因為如果有三個連續(xù)的情況,重全盤搜索的角度看,必然會被另外的情況所代替)。分兩種算法:一種是有一個空位置,一種是有三個空位置。前者先找到空位置,再判斷它下面兩個是否同色,同色則賦值給相應變量,異色則不賦值,因為意義不大;后者只要找到一個空位置就行了。void searchcandown1(int i,int j

29、,int n)函數: 最后的一個函數是searchcandown1(int i, int j, int n),這是為了預防用的,如果以上情況不發(fā)生,這個函數就是為了處理這種情況。這里就說明了為什么我們要添加vspoint的原因了,它保存了上次白棋下棋的位置,而我們在沒有辦法的情況下,在白棋旁邊隨便找個位置就可以了。 /如果五個位置的和是一void CMy3_1View:searchcandown1(int i, int j, int n) /計算剛才白棋落棋點 int ii=(vspoint.x-30)/20; int jj=(vspoint.y-30)/20; int a; for(a=0;a<5;a+) /如果不到邊界 if(ii+a<19) /向右,如果有空位置 if(wzqii+ajj=0) /在這個位置下黑棋 bpointcan1.x=ii+a; bpointcan1.y=jj; return; /到了邊界 else /向左,如果有空位置 if(wzqii-1jj=0) bpointcan1.x=ii-a; bpointcan1.y=jj; return; 5.2 判斷游戲是否結束 用一個over()函數判斷是否結束,是則結束并

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論