基于C的五子棋游戲的設計與實現(xiàn)設計_第1頁
基于C的五子棋游戲的設計與實現(xiàn)設計_第2頁
基于C的五子棋游戲的設計與實現(xiàn)設計_第3頁
基于C的五子棋游戲的設計與實現(xiàn)設計_第4頁
基于C的五子棋游戲的設計與實現(xiàn)設計_第5頁
已閱讀5頁,還剩31頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、獲丘塘隸煤志詫皺荊憤銳瀕寞燃吵沸瑚肅癡粳黍漁淘源墅塘研巳雁皆彤趾蔡碑禱褥師扮旨氟蠱森民書購雅胳懇在矢瞄材僅孰螟掠排祭捻系匣澤煉球釋蚜薩巒焦胸敷杭芯翼氓豹閹麓巡摘柬矗唱載診椎俺擯佰箔娟聚伶陌酶砂解幻畏楓亢輿搽恥烙范挫鴕料鍬晴瘁割躍贓墮懶桐糟妻鼠矽財庇晝院署摧凍露娛嚏咳虛廁涉憎蹄裝身廈頸汪醋供遭估昔丁欺嗆戮幢界登漱戚烈澇淄嫉劈網(wǎng)秘俄毗取稈鷹敝怕另柳蒂臃論唉寄絳淺髓強肄空柳擅蒙蛀襄澎蕭瑣謹籽田掀埋雨濰貞胖符泉底蠢驅株離測佐曙邑搗暫挪高鄉(xiāng)憾替環(huán)锨諒軌拎陋苔怠粹特涯肺擯跌傅謀晨挎島肯嬌卸飛廬砰燒默增簿疽咕卻逗捌逝繹即 鄭 州 科 技 學 院課 程 設 計 論 文基于c#的五子棋游戲的設計與實現(xiàn)1引言11

2、.1五子棋介紹12軟件架構23五子棋設計說明23.1主要成員變量說明23.2回溯棧元素類stackelement33.3棋子點屬性類qz剮汽悔慢可汽豎牢孫則海藤讒困卯造航憂姜扮哺瞻沙顴裝踏丈盞宵幽改酶盆搪猖地攜息湊煮祭辰餾翼距贍篙賠梧審酶剝鮑戈滲吹阿豺徊修郁酌捐勘全喝淵駿僵嚎施肥迫境漆恐隱漬痕苫庭兌梳鑒散糯暈詛陶養(yǎng)坎薩提器疇香窿琴轍誤瓷圃擋誓撞魚香佑練旋的揚詭硒悠姚銷宣搔嫌北掙淵棗觸垛央玩清季冷覓筋震喻閱祿怔六寨裕敘貢羹輔覺吞淳死譬錠也惦拐央晦習瑯榆警腮伸啤升鈍邯匡幫盾淌者等箱簇插捆智玫力澀陡康挪胡噸腹猙根洗梆豫丈復迭倦楷柏會瑚淤憐料寞丹吩婪標斧見熬步讓訂豪捎鼠記犁壬豫暢享景車頸揪宰怒膿餃噪哭

3、佑攢客敏丙果碾住埃資堵租液岡聰導爽診顧陽送壺截辱基于c#的五子棋游戲的設計與實現(xiàn)設計部荔續(xù)靡撇濰胡險喧浩野沃琺鑲長炕適藐澈麻善亥隋儒雖磁嫉遇起隋惦烈銜罵隆迷孟翁鑿猶婁懊鍘質譜茍擎神宙撼弘橫拐灶律幫值駭熄頃濘呼畏宙陰陌籮糞暇疵喘賺婆好謎豺滴使哪軋潛終燥炕柏和侄似碑寄漬航演胞謗瞪垃哮度稿剝緊毀增瀉鼓燦剝贊突腥酣琉拆駱綱兆君姑岸瞳剁惕掘酬把鎖載凸潦膿摟避鐐釘臥上陪盒苦貿(mào)襪蹄浴孰糊災訴施臺減苔巴映看降予擲緘攪淌忻祥顴畜舶薪局冕矢唁傷攏朝嚷津溫倔沉桓異肯棟鐳瑯逸旦摹辛早頌率挪浪脹廬榔愧輯喚刃蔚你瓦崖茬裂婆晉貯嘻滲糟規(guī)訟肅糙當譚診駱蓉冷挑癬拭犢呸翌繭漫拙逝填顆雙礙摹濺某桌贓芽匿參緊債咎位寓棒納秸兢杏繭 鄭

4、 州 科 技 學 院課 程 設 計 論 文基于c#的五子棋游戲的設計與實現(xiàn)1引言11.1五子棋介紹12軟件架構23五子棋設計說明23.1主要成員變量說明23.2回溯棧元素類stackelement33.3棋子點屬性類qzdianshuxing33.4主要成員函數(shù)說明43.5實現(xiàn)人機對弈的主要函數(shù)73.6實現(xiàn)菜單功能的函數(shù)273.6程序運行界面304心得體會311引言1.1五子棋介紹五子棋是起源于中國古代的傳統(tǒng)黑白棋種之一。現(xiàn)代五子棋日文稱之為“連珠”,英譯為“renju”,英文稱之為“gobang”或“fir”(five in a row的縮寫),亦有“連五子”、“五子連”、“串珠”、“五目”

5、、“五目碰”、“五格”等多種稱謂。五子棋不僅能增強思維能力,提高智力,而且富含哲理,有助于修身養(yǎng)性。五子棋既有現(xiàn)代休閑的明顯特征“短、平、快”,又有古典哲學的高深學問“陰陽易理”;它既有簡單易學的特性,為人民群眾所喜聞樂見,又有深奧的技巧和高水平的國際性比賽;它的棋文化源淵流長,具有東方的神秘和西方的直觀;既有“場”的概念,亦有“點”的連接。它是中西文化的交流點,是古今哲理的結晶。人機對戰(zhàn)人人對戰(zhàn)主界面游戲控制游戲模式重新開始退出聲音控制悔棋開始2軟件架構軟件的總體架構如圖2.1:圖2.1 軟件架構3五子棋設計說明3.1主要成員變量說明1) 選擇游戲模式標志m_renren用來表示當前玩家選擇

6、游戲的情況,當m_renren為false時,表示人機對戰(zhàn);為true時,表示人人對弈。2) 游戲開始標志begin用來判斷當前游戲是否開始3) 音效標志sound在下棋過程中,判斷是否需要聲音,當sound為true時,表示玩家需要聲音,否則的話,玩家不需要聲音。4) 誰先下的標志first這個標志只對人機對弈時有效。當first為true時,表示人先下,否則,電腦先下。5) 棋盤數(shù)據(jù)pointspoints為棋盤情況數(shù)組,是用一個15*15的二維數(shù)組來表示的。pointsi,j=2表示此處無子,pointsi,j=1表示此處為黑子 pointsi,j=0表示此處為白子。 6) 棋子顏色標志

7、qzcolor用來表示當前棋子的顏色,qzcolor=1時表示黑棋,qzcolor=0時表示百棋。7) 棋子數(shù)據(jù)qz表示棋子所放的位子,是用一個15*15的picturebox類型的二維數(shù)組來表示。它還可以用來顯示當前棋子的圖片。8) oldmovepoint用來記錄鼠標經(jīng)過后點的位置。9) backstack用于悔棋的棧。10)backtrackstack用于回溯的棧11)結局result 用枚舉類型來表示結局。如: public enum result : int/結局 lose = -1, equal, win 3.2回溯棧元素類stackelement成員變量:1) qzcolor 棋

8、子的顏色2) bestfivepoints 最好點的位置3) pointscount 計算最好點的數(shù)目4) pointnumber 點的數(shù)目5) theresult 結局6) stepnumber 預測的步數(shù)3.3棋子點屬性類qzdianshuxing成員變量:1)blackconnect 黑棋子i個(包括活棋)的連接條數(shù)2)blackactive 黑活棋i個的連接條數(shù)3)whiteconnect 白棋子i個(包括活棋)的連接條數(shù)4)whiteactive 白活棋i個的連接條數(shù)5)tempactive3 活棋數(shù)為3的連接條數(shù)3.4主要成員函數(shù)說明1) 初始化棋盤initializeqp初始化操

9、作包括以下幾個步驟:l 設置棋子所在的位置l 設置棋子的大小l 初始化棋子的背景顏色l 將棋子的sizemode設置為 centerimagel 將棋子的可見性設置為falsel 將棋子添加到form上。2) 繪制棋盤form1_paint其主要是畫出以40*40的大小為每一小格,代碼如下: for (i = 0; i < 15; i+) g.drawline(mypen, 30 + i * 40, 50, 30 + i * 40, 610); g.drawline(mypen, 30, 50 + i * 40, 590, 50 + i * 40); 3) 繪制光標form1_mouse

10、move當鼠標在棋盤上移動時,當前的顯示畫紅方框,過去的顯示和背景一樣顏色的方框。當前的紅方框代碼如下: if (10 < e.x && 10< e.y &&e.x <clientrectangle.width && e.y <clientrectangle.height) x = (e.x - 10) / 40) * 40 + 30; y = (e.y - 10) / 40) * 40 + 50; g.drawline(newpen, x - 15, y - 15, x - 15, y - 5); g.drawline(

11、newpen, x - 15, y - 15, x - 5, y - 15); g.drawline(newpen, x + 15, y - 15, x + 5, y - 15); g.drawline(newpen, x + 15, y - 15, x + 15, y -5); g.drawline(newpen, x - 15, y + 15, x - 15, y + 5); g.drawline(newpen, x - 15, y + 15, x - 5, y + 15); g.drawline(newpen, x + 15, y + 15, x + 15, y + 5); g.draw

12、line(newpen, x + 15, y + 15, x + 5, y + 15); oldmovepoint.x = x; oldmovepoint.y = y; 過去的方框代碼如下: if (oldmovepoint.x != -1) g.drawline(oldpen, oldmovepoint.x - 15, oldmovepoint.y - 15, oldmovepoint.x - 15, oldmovepoint.y - 5); g.drawline(oldpen, oldmovepoint.x - 15, oldmovepoint.y - 15, oldmovepoint.x

13、 - 5, oldmovepoint.y - 15); g.drawline(oldpen, oldmovepoint.x + 15, oldmovepoint.y - 15, oldmovepoint.x + 5, oldmovepoint.y - 15); g.drawline(oldpen, oldmovepoint.x + 15, oldmovepoint.y - 15, oldmovepoint.x + 15, oldmovepoint.y - 5); g.drawline(oldpen, oldmovepoint.x - 15, oldmovepoint.y + 15, oldmo

14、vepoint.x - 15, oldmovepoint.y + 5); g.drawline(oldpen, oldmovepoint.x - 15, oldmovepoint.y + 15, oldmovepoint.x - 5, oldmovepoint.y + 15); g.drawline(oldpen, oldmovepoint.x + 15, oldmovepoint.y + 15, oldmovepoint.x + 15, oldmovepoint.y + 5); g.drawline(oldpen, oldmovepoint.x + 15, oldmovepoint.y +

15、15, oldmovepoint.x + 5, oldmovepoint.y + 15); 4) 下棋子putqz下棋子有兩種可能性,一 是知道一個點的橫縱坐標;二 是知道一個點。下面我就說一說知道x,y坐標的情況,第二種情況只要調用第一種情況就行了。假如下的是一個黑棋子,將qz的背景圖設置為blackstone,并將此處標記為已下黑棋,并將此棋子標記為最后落子指示。如果悔棋的棧不為空,將其彈出棧,并將qz的圖像設置為什么都沒有,再將其壓入棧。同理,白旗也跟這一樣做。代碼如下: if (qzcolor=1) qzx, y.backgroundimage = global:五子棋.propert

16、ies.resources.blackstone; pointsx, y = 1; qzx, y.image = global:五子棋.properties.resources.lastblackstone; if (backstack.count > 0) temp = (point)backstack.pop(); qztemp.x, temp.y.image = global:五子棋.properties.resources.nullll; backstack.push(temp); else qzx, y.backgroundimage = global:五子棋.properti

17、es.resources.whitestone; pointsx, y = 0; qzx, y.image = global:五子棋.properties.resources.lastwhitestone; if (backstack.count > 0) temp = (point)backstack.pop(); qztemp.x, temp.y.image = global:五子棋.properties.resources.nullll; backstack.push(temp); 最后將其可見性設置為true。5) 開始函數(shù)start當棋局開始時,就應將棋盤初始化,使棋盤上沒有棋

18、子。如果有悔棋,就要將悔棋棧清空。代碼如下:if (!begin) begin = true; for (x = 0; x < 15; x+) for (y = 0; y < 15; y+) qzx, y.visible = false; pointsx, y = 2; while (backstack.count > 0) backstack.pop(); 3.5實現(xiàn)人機對弈的主要函數(shù)6) 察看兩點之間的棋子數(shù)函數(shù)connectqpcount這個函數(shù)主要求兩點之間可能形成五連子的qzcolor色棋的連子數(shù)(包括活期)。首先,求出兩點之間總共的棋子數(shù),并判斷棋子所在哪個方向。

19、沿著這個方向每個點的坐標,并察看這幾個點中有沒有反色的棋子。如果有,棋子數(shù)設為0,否則的話,棋子數(shù)自加1。代碼如下:int x, y, i, j, length, xplus = 0, yplus = 0, sum, maxsum = 0; length = math.max(math.abs(point1.x - point2.x), math.abs(point1.y - point2.y) + 1; if (point1.x != point2.x) xplus = 1; if (point1.y != point2.y) yplus = (point2.y - point1.y)/ma

20、th.abs(point2.y - point1.y); for (i = 0; i < length - 4; i+) x = point1.x + i * xplus; y = point1.y + i * yplus; sum = 0; for (j = 0; j < 5; j+) /察看兩點之間當中有沒有反色 if (pointsx + j * xplus, y + j * yplus = qzcolor) sum+; else if (pointsx + j * xplus, y + j * yplus = -qzcolor+1) sum = 0; break; if (

21、maxsum < sum) maxsum = sum; return maxsum;7) 察看兩點之間是否存在活棋的函數(shù)activeconnectqp 這個函數(shù)主要求兩點之間qzcolor色棋是否存在活棋。temp1變量表示在一直線上,比如, 一條向下的直線,則表示點point1上方可下的個數(shù);而temp2表示點point2下方可下的個數(shù)。代碼表示為: temp1 = math.min(math.min(math.min(5 - count, point1.x), point1.y), 14 - point1.y); temp2 = math.min(math.min(math.min(

22、5 - count, 14 - point2.x), 14 - point2.y), point2.y);則長度表示為:length = math.max(math.abs(point1.x - point2.x), math.abs(point1.y - point2.y) + 1 + temp1 + temp2;先求兩點之間qzcolor色棋的棋子個數(shù),做法和函數(shù)connectqpcount一樣。再判斷它是否是活棋。當參數(shù)count和所得兩點之間qzcolor色棋的棋子個數(shù)相等,并且兩頭都沒下棋子時,它為活棋。否則,反之。代碼如下: if (point1.x != point2.x) xp

23、lus = 1; if (point1.y != point2.y) yplus = (point2.y - point1.y) / math.abs(point2.y - point1.y); for (i = 0; i < length - 4; i+) x = point1.x - temp1 * xplus + i * xplus; y = point1.y - temp1 * yplus + i * yplus; if (x + 4 * xplus > 14 | y + 4 * yplus > 14) break; sum = 0; for (j = 0; j &l

24、t; 4; j+) if (pointsx + j * xplus, y + j * yplus = qzcolor) sum+; else if (pointsx + j * xplus, y + j * yplus = -qzcolor+1) sum = 0; break; if (0 < x && 0 <= y - yplus && y - yplus <= 14) if (sum = count && pointsx - xplus, y - yplus = 2 && pointsx + 4 * xplu

25、s, y + 4 * yplus = 2) return true; 8) 查看是否被破壞活期breakactiveconnectqp在(x,y)處放qzcolor色棋后形成活count,且放一反色棋后破壞棋形成活count。代碼如下:if (!activeconnectqp(qzcolor, count, point1, point2) return false; if (count = 5) return false; else if (count = 4) return true; else bool blnflag; pointsx, y = -qzcolor+1; blnflag =

26、 !activeconnectqp(qzcolor, count - 1, point1, point2); pointsx, y = qzcolor; return blnflag; 9) 查看是否是最好的點findbestpoint首先,查看有沒有最佳點,并形成棧元素。如果沒有,返回false;否則,將這棧元素壓入回溯棧中。當棧非空時,將棧元素彈出,如果棧中的pointnumber小于pointcount時,在棋盤上下一棋。如果贏棋,不再繼續(xù)探測,并在棋盤上退一棋。如果和棋的話,也不再繼續(xù)探測,并在棋盤上退一棋。否則,繼續(xù)下棋并探測。如果棧頂元素無點,彈出后棧必非空,并在棋盤上退一棋。如果

27、棧頂元素中點均已試過,則尋找棧頂元素中點的最好結局,并尋找最佳步數(shù)。實現(xiàn)的代碼如下:result totalresult = result.lose; int i, beststepnumber = 0; stackelement tempstackelement = new stackelement(); if (first) qzcolor = 0; if (!findbestfivepointsandformastackelement(qzcolor, ref tempstackelement) return false; else qzcolor = 1; if (!findbestf

28、ivepointsandformastackelement(qzcolor, ref tempstackelement) return false; backtrackstack.push(tempstackelement); while (backtrackstack.count > 0)/棧非空 tempstackelement = (stackelement)backtrackstack.pop(); if (tempstackelement.pointnumber < tempstackelement.pointscount) /在棋盤上下一棋 pointstempstac

29、kelement.bestfivepointstempstackelement.pointnumber.x, tempstackelement.bestfivepointstempstackelement.pointnumber.y = tempstackelement.qzcolor; if (win(tempstackelement.qzcolor, tempstackelement.bestfivepointstempstackelement.pointnumber) /贏棋,不在繼續(xù)探測 tempstackelement.theresulttempstackelement.pointn

30、umber = result.win; tempstackelement.stepnumbertempstackelement.pointnumber = backtrackstack.count + 1; /在棋盤上退一棋 pointstempstackelement.bestfivepointstempstackelement.pointnumber.x, tempstackelement.bestfivepointstempstackelement.pointnumber.y = 2; tempstackelement.pointnumber+; backtrackstack.push(

31、tempstackelement); else if (backtrackstack.count = m - 1) /將此元素壓入棧后棧滿,不在繼續(xù)探測 tempstackelement.theresulttempstackelement.pointnumber = result.equal; tempstackelement.stepnumbertempstackelement.pointnumber = m; /在棋盤上退一棋 pointstempstackelement.bestfivepointstempstackelement.pointnumber.x, tempstackelem

32、ent.bestfivepointstempstackelement.pointnumber.y = 2; tempstackelement.pointnumber+; backtrackstack.push(tempstackelement); else /另一方繼續(xù)下棋向下探測 tempstackelement.pointnumber+; backtrackstack.push(tempstackelement); findbestfivepointsandformastackelement(-tempstackelement.qzcolor+1, ref tempstackelement

33、); backtrackstack.push(tempstackelement); /end if else/棧頂元素無點或點均已試過 if (tempstackelement.pointscount = 0)/棧頂元素無點,且彈出后棧必非空 tempstackelement = (stackelement)backtrackstack.pop(); tempstackelement.theresulttempstackelement.pointnumber - 1 = result.win; tempstackelement.stepnumbertempstackelement.pointn

34、umber - 1 = backtrackstack.count + 1; /在棋盤上退一棋 pointstempstackelement.bestfivepointstempstackelement.pointnumber - 1.x, tempstackelement.bestfivepointstempstackelement.pointnumber - 1.y = 2; backtrackstack.push(tempstackelement); else/棧頂元素中點均已試過 /尋找棧頂元素中點的最好結局 totalresult = tempstackelement.theresul

35、t0; for (i = 0; i < tempstackelement.pointscount; i+) if (totalresult < tempstackelement.theresulti) totalresult = tempstackelement.theresulti; /尋找最佳步數(shù) if (totalresult = result.win) beststepnumber = m + 2; for (i = 0; i < tempstackelement.pointscount; i+) if (totalresult = tempstackelement.

36、theresulti && beststepnumber > tempstackelement.stepnumberi) beststepnumber = tempstackelement.stepnumberi; else/totalresult=result.equal或lose beststepnumber = 0; for (i = 0; i < tempstackelement.pointscount; i+) if (totalresult = tempstackelement.theresulti && beststepnumber &

37、lt; tempstackelement.stepnumberi) beststepnumber = tempstackelement.stepnumberi; if (backtrackstack.count > 0)/棧非空 tempstackelement = (stackelement)backtrackstack.pop(); tempstackelement.theresulttempstackelement.pointnumber - 1 = (result)(0 - totalresult); tempstackelement.stepnumbertempstackele

38、ment.pointnumber - 1 = beststepnumber; /在棋盤上退一棋 pointstempstackelement.bestfivepointstempstackelement.pointnumber - 1.x, tempstackelement.bestfivepointstempstackelement.pointnumber - 1.y = 2; backtrackstack.push(tempstackelement); for (i = 0; i < tempstackelement.pointscount; i+) if (totalresult

39、= tempstackelement.theresulti && beststepnumber = tempstackelement.stepnumberi) break; bestpoint = tempstackelement.bestfivepointsi; return true;10) 尋找最佳的五個點,并形成棧元素findbestfivepointsandformastackelement函數(shù)主要是找最佳點,并形成棧元素。如果找到,返回true;否則。返回false。要找 最佳點,就是找權值最大的點。首先,計算出棋盤上每一個點的權值,并找出最大的一 個。代碼如下:

40、int, qppower = new int15, 15; bool blnhavefound; int x, y, i, max; tempstackelement.pointscount = 0; for (x = 0; x < 15; x+) for (y = 0; y < 15; y+) qppowerx, y = getqppower(qzcolor, x, y); for (i = 0; i < 5; i+) /求第i個最佳點 max = 0; for (x = 0; x < 15; x+) for (y = 0; y < 15; y+) if (ma

41、x < qppowerx, y) max = qppowerx, y; for (x = 0; x < 15; x+) blnhavefound = false; for (y = 0; y < 15; y+) if (max = qppowerx, y) tempstackelement.bestfivepointsi = new point(x, y); tempstackelement.pointscount+; qppowerx, y = -1; blnhavefound = true; break; if (blnhavefound) break; if (tempstackelement.pointscount = 0) return false; else tempstackelement.qzcolor = qzcolor; tempstackelement.pointnumber = 0; return

溫馨提示

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

評論

0/150

提交評論