版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、<p> 24點游戲的開發(fā)和實現(xiàn)</p><p> 摘 要:近年來,隨著經濟的日益發(fā)展,人們的生活水平不斷提高,生活質量也在漸漸的改善。適當的娛樂游戲對人們的業(yè)余生活是不可必缺的。說到娛樂游戲,人們可能會想到網絡上許許多多讓人迷戀的網絡游戲,比如說,傳奇,奇跡,cs等等。是的,的確這些游戲給人們的業(yè)余生活添加了很多樂趣。借鑒網上的邊鋒游戲,我用vc++開發(fā)設計了24點游戲的實現(xiàn)算法,并在window
2、s圖形環(huán)境下設計出一個人機交互的游戲系統(tǒng)(類似于紙牌游戲)。</p><p> 關鍵詞:窮舉法 棧 遞歸函數</p><p> The development and realization of 24 pionts game</p><p> Abstract:Recently,with the development of economic ,the pe
3、ople’s life becomes better and better,life condition also is improving more and more.Proper recreation is indispensable in the people’s pasttime life.Mentioned to the game,people may associate many fascinated online game
4、s,such as Legend,MU,CS and so on.Certainly,these games enrich people’s life with more and more joys.Using the wing game for reference ,I developed and designed the realization arithmetic of 24 points game.Next I designed
5、 a</p><p> Keyword:enumerating method stack recursive function</p><p> 1 24點游戲算法實現(xiàn)</p><p> 1.1 24點游戲簡介</p><p> 要開發(fā)一個游戲不是那么容易的,哪怕是簡單的算術游戲。要是沒有一定的專業(yè)知識,沒有一定的思維能力是不行的
6、。24點游戲是一個傳統(tǒng)的算術游戲,其游戲之精髓就是考驗人腦的反應能力。所謂24點游戲,就是通過加,減,乘,除4則運算,將給定的4個整數算出24。當然,傳統(tǒng)的紙牌游戲其數字是有限定范圍的,一般是從1到13。經統(tǒng)計,當算的目標數把24改為2的時候,獨立解數更多,就是解的形式趣于集中化,大多數最后一步用減法(如:2*8-3*5)。游戲時會感到單調。由于24的因數多,解的形式就豐富,能充分發(fā)掘游戲者數學發(fā)散思維能力。要做好一個簡單的24點游戲要
7、具備很多知識。其中最主要的思想就是,24點的表達式要怎樣行成,這是此游戲的關鍵。而要做一個完美的24點紙牌游戲,則需要的知識將會更多。現(xiàn)今,網絡上的紙牌游戲數不甚數,比較出名的有聯(lián)眾游戲,邊鋒游戲,qq游戲。當然,他們的開發(fā)隊伍龐大之極不是我們個人可以比及的。因此要一個人做好一個比較完美的游戲,是需要一定的游戲天分。以下我就開發(fā)24點游戲的幾個關鍵算法和分析做詳細的剖析。</p><p> 1.2 24點游戲的
8、算法</p><p> 1.2.1 24點算法(1)</p><p> 24點游戲的算法,其中最主要的思想就是窮舉法。所謂窮舉法就是列出4個數字加減乘除的各種可能性,包括括號的算法。我們可以將表達式分成以下幾種:首先我們將4個數設為a,b,c,d,,其中算術符號有+,—,*,/,(,)。其中有效的表達式有a*(b-c/b),a*b-c*d,等等。列出所有有效的表達式。其中我們用枚舉類型
9、將符號定義成數字常量,比如用1表示+,2表示-等。如下是我對窮舉法的一種編程語言。在編程的頭部要對變量做下定義。其中a,b,c,d的范圍是1到13。因為傳統(tǒng)的24點游戲是紙牌游戲,而紙牌游戲的數字就是從1到13,其中a是1,K是13,Q是12,J是11,其他的就是牌面的數字。這就需要在定義變量的時候要有限制。在vc++中的MFC編程中,在定義控件的變量范圍可以直接填寫變量的最大和最小,在此編程中的最大是13,最小是1。這就給編程寫語句帶
10、來了方便(因為其自動會生成語句)。下面我介紹下窮舉法的主要實現(xiàn),我們知道要實現(xiàn)24點的算法,就是通過4個數字,4個運算符號和2對括號(最多為2對),通過各種組合判斷其結果是否為24。我們用a,b,c,d代替4個數字??紤]每種可能,總的算法就有7</p><p> 2有括號的(形如(a * b) * c * d);3有括號的(形如(a * b * c) * d);4有括號的(形如a * (b * c) * d);
11、5有括號的(形如(a * b) * (c * d));6有括號的(形如((a * b) * c) * d);7有括號的(形如(a * (b * c)) * d)。接下來就是對每一種進行分析判斷。我們拿2種情況做為例子,一種是沒括號的,一種有括號的。先拿沒括號的分析。我們知道沒括號的式子包括其運算符和數字總共為7個(3個運算符,4個數字),于是我們定義一個數組,用于存放運算符和數字。運算符我們可以用枚舉變量來定義,首先我們通過循環(huán)語句形成
12、一個表達式子(但這個表達式的運算循序是亂的)。表達式子有很多種情況,利用循環(huán)語句我們可以一一將其寫出,例如(a+b+c+d,a+b+c-d,a+b+c*d,a+b+c/d….等等)生成表達式子的后,接著就是判別運算順序。在沒有括號存在的情況下,我們令其先運算*,/。這個順序的選擇很輕松,我們可以定義一個bool類型的函數,我們對數組進行掃描,當掃描到/,*,其返回真值,就直接進行運算。依次照樣進行掃描,當所</p><
13、;p> 1.2.2 24點游戲算法(2)</p><p> 24點游戲的算法各種各樣,各有千秋,現(xiàn)在讓我們來討論另一種24點游戲算法。此算法是在dos下實現(xiàn)的,但其思想明確,語句簡短。其主要思想是簡化算法,他將24點的算法排序分成如下幾種,如下我們用a,b來代替變量。他將其分成如下6種情況,分別是a+b,a-b,b-a,a*b,a/b,b/a這6種情況,我們知道a+b和b+a是一樣的,a*b和b*a是
14、一樣的。這樣就可以省去2種算法。提高系統(tǒng)的使用效率,內存占用量小。還有其第2個思想是在判別24點正確與否的時候,采用了與24點相減絕對直在1E-6之外則判別其為正確,這就給運算帶來了精確度,就如5 5 5 1等的數字也可以輕松算出,不會略過了。如下我們通過一段程序來看看其主程序段。</p><p> bool Search(int n) </p><p><b> { <
15、;/b></p><p> if (n == 1) { </p><p> if ( fabs(number[0] - NUMBER_TO_CAL) < PRECISION ) { </p><p> cout << expression[0] << endl; </p><p> return t
16、rue; </p><p><b> } else { </b></p><p> return false; </p><p><b> } </b></p><p><b> } </b></p><p> for (int i = 0;
17、i < n; i++) { </p><p> for (int j = i + 1; j < n; j++) { </p><p> double a, b; </p><p> string expa, expb; </p><p> a = number[i]; </p><p> b =
18、number[j]; </p><p> number[j] = number[n - 1]; </p><p> expa = expression[i]; </p><p> expb = expression[j]; </p><p> expression[j] = expression[n - 1]; </p>
19、<p> expression[i] = '(' + expa + '+' + expb + ')'; </p><p> number[i] = a + b; </p><p> if ( Search(n - 1) ) return true; </p><p> expression[i] =
20、 '(' + expa + '-' + expb + ')'; </p><p> number[i] = a - b; </p><p> if ( Search(n - 1) ) return true; </p><p> expression[i] = '(' + expb + '
21、-' + expa + ')'; </p><p> number[i] = b - a; </p><p> if ( Search(n - 1) ) return true; </p><p> expression[i] = '(' + expa + '*' + expb + ')'
22、; </p><p> number[i] = a * b; </p><p> if ( Search(n - 1) ) return true; </p><p> if (b != 0) { </p><p> expression[i] = '(' + expa + '/' + expb + &
23、#39;)'; </p><p> number[i] = a / b; </p><p> if ( Search(n - 1) ) return true; </p><p><b> } </b></p><p> if (a != 0) { </p><p> expre
24、ssion[i] = '(' + expb + '/' + expa + ')'; </p><p> number[i] = b / a; </p><p> if ( Search(n - 1) ) return true; </p><p><b> } </b></p>
25、<p> number[i] = a; </p><p> number[j] = b; </p><p> expression[i] = expa; </p><p> expression[j] = expb; </p><p><b> } </b></p><p>
26、<b> } </b></p><p> return false; </p><p><b> } </b></p><p> 我們簡單分析下以上的程序,我們可以清楚看到,SEARCH函數一個遞歸函數,其返回的是bool類型的值,其中number[0]為計算結果,假若其值和24相減為1E-6,則說明算法正確。其主
27、要思想如下:首先我們取前面的兩個數a,b對其進行相加,接著將兩個相加的數結果存放于number[i]中,于是第2次循環(huán)的運算的時候,令其a= number[i];則a成了原先的a和b之和,接著再將其存放于number[i]中,接著我們看到了程序中的遞歸函數SEARCH(n-1)。當調用遞歸函數的時候,我們可以看到其實現(xiàn)了所有數的相加,其中的n從原來的最大值4,經過遞歸達到2,最后生成4個數之和。接著就是遞歸函數的調用,假如number[
28、i]其中i=0時,如果number[i]與24相減為零,則可以算出24點。如果,其返回直為否,則說明不能算出24點。則程序往下繼續(xù)執(zhí)行,接著是判斷其他運算。同樣的道理可以得出其返回值的正假,由此判斷出24點的生成算法。注意假如我們只是簡單的用計算結果和24相減為0則大錯特錯了,因為其中牽涉了到小數的問題。假如在運算中遇到了小數的式子不算,則此種判別是正確的,但24點游戲是</p><p> 我們可以舉個例子如5
29、 5 5 1 ,其中的運算就牽涉到了小數,其算法為(5-1/5)*5。只要我們的判別是如以上程序的,則此算式將輕易的解出。還有一點就是,簡化式子的算法。形如a+b和b+a是一樣的,可以省略其中的一種。</p><p> 24點游戲的算法有多種多樣,以上我只是簡單對2種不同思想的算法做了簡短的介紹,當然還有些算法也是大同小異,我們也不逐一列出了。介紹了24點算法后,接下來我們來探討一下,一個有著紙牌圖形界面的24
30、點游戲將怎樣完成。</p><p> 1.2.3 24點算法的多樣性(即多解的算法和優(yōu)化算法)的討論</p><p> 我們拿遞歸算法來分析其算法的多樣性。我們知道遞歸算法是通過調用一個遞歸函數,將n值依次減1到最小值為止。并且在此遞歸的過程中實現(xiàn)了,表達式的4則運算,然而在以上的遞歸函數中已經考慮到了各種算法的可能性。其主要思想就是對4個數字的運算順序和運算符號通過遞歸逐一的算出各
31、種表達式。先重加法算起,依次算到除法(被除數不為零)為止。顯然,其中已經包括了24點的所有算法,假如要輸出每種可能性進性判別其優(yōu)化性,那就需要用到編譯原理的知識。通過逆波蘭式的判定,求出其最優(yōu)化的算法。我們拿a+b+c+d為例子,我們知道在有括號的情況下,(a+b)+(c+d)以及(a+b+c)+d這3種情況中,很明顯前一種是最簡潔。那我們在程序中要如何設置其最簡單的算法呢。這就需要對兩種算法進行逆波蘭式的判別,我們將前者寫成逆波蘭式,
32、則為ab+c+d+,第2種寫成逆波蘭式為也為ab+c+d+。說明兩者運算的結果是一樣的。但是很明顯,前者簡潔。因此,對于逆波蘭式相同,但實際程序中不同的程序,就可以判斷其優(yōu)化程度。假如我們將左右括號定義為枚舉變量,接著掃描每個字符,假如字符串最短的則為最優(yōu)化的算法。還有我們假定,在能用中間過程</p><p> 1.3 24點游戲輸入表達式的判別算法</p><p> 討論了24點游戲
33、的各種算法思想后,接著要考慮的是游戲的關鍵技術,即是表達式的判別。表達式的判別是除了算法之后的首當其沖也解決的問題。何為表達式判別?所謂表達式的判別就是,你在對話框中輸入數字和字符的時候,是不是牌面所顯示的值,這是一個非常關鍵的重點。我們舉個例子說明下,假設現(xiàn)在我們已經開始某一個24點紙牌游戲,然后按下開始鍵。接著游戲截面顯示了,紅桃A,黑桃5,紅桃5和梅花5這4張牌,要求你算出24點。假設現(xiàn)在你要測試這個游戲的表達式判別怎么樣。那我們
34、可以輕松的試出其正確與否。我們可輸入1*2*3*4這個算式子。如果系統(tǒng)未提示任何錯誤,反而彈出計算正確的提示。則說明此游戲沒有做任何的表達式判別,至少沒有對輸入數字進行控制。這就是所謂的表達式判別。然而要做到表達式真正的符和要求,其需要對其采取一定的措施。表達式判別有簡單有復雜,我們的目的是力爭簡潔但實用。要進行表達式的判別,我們必須要用編譯原理。編譯原理是對計算機語言進行文法分析,詞法分析的一種學科。特別是對表達式運算順序和表達式輸入
35、正確與否能輕易的做出。我們將在文本中輸入的一段字符串,將其進性文法分析和語法判斷。我們可以輕松的將其判斷</p><p> 我們拿上面最復雜的例子做分析,得出逆波蘭式子的思想。其實,逆波蘭的思想是利用了棧的功能。我們看,我們將第一個字符a推入棧頂,接著推入第2字符,接著第3,4一直將推如棧中。假如,中間遇到了運算符號,就如在c后面遇到了*號,則系統(tǒng)將離*號最近的兩個變量進行乘運算,得到一個結果。將b,c棧合并用
36、于存放結果。接著在往棧中推入b,d,我們看到在d后又出現(xiàn)了*號,著將離*最近的兩個變量進行想乘,并且合并棧,將結果存放于棧中。依著以上的思想進行運算,就可以實現(xiàn)語句a:=b*c+b*d。因此我們在判斷輸入表達式是否錯誤的時候就可以利用此種思維方法。我們將每個輸入的字符推入棧中,并且對其進行判別,假如遇到的字符是除了如(1—9,+,-,*,/,(,))等符號外的數據,則說明輸入有誤,此算法完成了語法錯誤的判別。接著是判斷,輸入的數字和系統(tǒng)
37、給的直是否一樣,這也非常的簡單。我們對每次推入棧的數字和系統(tǒng)的數字進行比較,假如有不同的則報“數字和系統(tǒng)提供的不相同”的錯誤。在判斷括號匹配的時候,我們可以定義一整形數組變量a[]和2個整形變量count1,count2另其初始值全為0,當遇到左括號字符是另其變量a[0</p><p> 1.4 紙牌游戲界面的算法</p><p> 1.4.1 獲得紙牌界面的函數</p>
38、<p> 接下來是紙牌游戲的制作,要做紙牌游戲。首先必須要有紙牌的界面。界面需要通過截圖來獲得。將一副標準撲克牌的52張牌面截下來,將其加入到vc++的res文件夾中,也就是資源文件夾。并且將其中的52張紙牌牌面進行系統(tǒng)化的命名。比如,用a前綴代替紅桃,b前綴代替黑桃,c前綴代替梅花,d前綴代替方塊。這樣52張牌就對應了52個圖形文件。做好了牌面的截圖后就是對其進行發(fā)牌。發(fā)牌算發(fā)也是一個直的考慮是關鍵。我們將其中的52個數
39、設為數組行如:a[52] ,這樣每張牌就對應了數組中的一個變量。我們先將每個數和數組相連接起來。接著我們用一個隨即函數令其隨即的產生4個數,函數行如:</p><p> b[1]=rand() b[2]=rand() b[3]=rand() b[4]=rand(),其函數的意思就是產生隨即數。但是這里產生的隨即數都是任意的,可能大于52。這樣我們需要對產生的隨即數進行處理。在這里我們使用整除求余功能,如:b[1
40、]=rand()%52+1 這樣每次輸出隨即數就不會大于52了,達到了預期的效果。</p><p> 此程序的關鍵就是隨即搜索牌面的路徑,通過牌面的搜索和刷新,形成一組新的數字,根據此4個數字生成24點。其中最主要的函數就是一個隨即函數rand(),此函數是c++系統(tǒng)中自帶的函數,存放于stblib.h頭文件中。此函數在使用之前,必須有個誘導函數srand()。通過調用Rand()函數就可以生成隨即數據,但隨即
41、函數生成的數字是凌亂無序的,它范圍很大,因此必須對它加以限定范圍,這時我們用到了一個方法,就是用整除求余的方法。假如將52張牌標記成0到51的數字,那么我們可以通過對隨即函數求余的方法,找到每張牌。其函數形式為rand()%52+1;其中形成的0到51個數將代表一副撲克牌中的52張。牌面在程序中將怎樣生成?首先我們要做的是截圖,所謂截圖就是從已有的紙牌游戲中截下相應的52張牌(不包括大,小王)。將其中的52張牌存放為52個圖片文件。要注
42、意在文件命名的時候是有講究的,因為此后要搜索牌的路徑。因此給其中的牌面文件命名時要有統(tǒng)一性,又要有區(qū)別性。統(tǒng)一性就是我們可以將4種不同花色的牌分別命名以a,b,c,d開頭,區(qū)分性就是我們用每張牌面的數值來區(qū)分其不同行。比如,我們命名黑桃k為a13,</p><p> rectdate[0].originrect.top =rectdate[0].rect.top =50;</p><p
43、> rectdate[0].originrect.bottom=rectdate[0].rect.bottom =rectdate[0].rect.top+height;</p><p> rectdate[0].originrect.left =rectdate[0].rect.left =50;</p><p> rectdate[0].originrect.right
44、=rectdate[0].rect.right =rectdate[0].rect.left+width;</p><p> rectdate[0].firstrect =rectdate[0].originrect;</p><p> 4張紙牌對應于其中的4個如上的函數,其他三個同理可得。只是大小上有點差別,比如高度,左右位置等都應該有相應的變化。</p><p
45、> 存放位置編好了之后,接著就是在怎樣生成圖片了。在API中生成圖片我們用到了繪制圖片的功能和刷新功能。</p><p> 1.4.2不發(fā)重復牌的算法</p><p> 我們在完成紙牌游戲界面的設計之后,接著要考慮的一個問題就是:因為你用到的是一副牌,如何實現(xiàn)每次發(fā)牌的時候不產生相同的牌面。這是游戲中的一個關鍵,也是程序成功與否的關鍵因素。其實,要完成此功能也極為簡單。既然我們
46、在做界面的時候已經給52張牌給了命名,則我們只要對52張牌的花色進行分類。就如上面所提到的,用52個有著相同點又有區(qū)別的圖形文件來區(qū)分其花色和大小。接著我們定義一個a[52],將52張牌按順序依次存放于數組中。其中花色一樣的牌為一樣的順序,例如紅桃花色的牌存放在a[0]-a[12]中,黑桃的牌存放在a[13]-a[25]中,梅花花色為a[26]-a[38]中,方塊為a[39]-a[51]中。這樣做的目的是為了有利于判別其花色。將花色進行
47、了分類后,我們可以對其進行選擇判斷了。比如我們要拿一張紅桃10,則具備兩個條件的數組值只有一個。首先我們找出大小為10的值,我們知道有4個,接著我們要找到紅桃花色,這只要我們做簡單的判斷,即數組的下標(這里我們設它為i)0=<i<=12。通過以上的查找我們可以找到紅心10。我們知道一張牌有兩個要素組成,一個是大小,一個花色。大小我們可以對其很好的做</p><p> 1.4.3重新發(fā)牌的函數<
48、/p><p> 重新開始游戲的算法簡介。我們知道游戲中重新開始是肯定要用到的,你不可能讓別人只算一次,這就失去了其實際意義,也得不到娛樂和益智的效果。因此,重新發(fā)牌也是其中很重要的算法。在API的編程中,我們使用了一個關鍵技術,那就是刷新函數。刷新函數可以令原有的界面撤消,然后在重新繪制界面。</p><p> 如下讓我們看看此24游戲中,重新發(fā)牌的關鍵程序。</p><
49、;p> void CWorkView::OnPaint() //重新繪制牌面的程序</p><p><b> {</b></p><p><b> int i;</b></p><p> CPaintDC dc(this); // device context for painting</p>
50、<p> for(i=0;i<4;i++)</p><p><b> {</b></p><p> rectdate[i].hBitmap=(HBITMAP)LoadImage(AfxGetInstanceHandle(),rec</p><p> GetObject(rectdate[i].hBitmap, size
51、of BITMAP, &bm1);</p><p> SelectObject(hSrcDC1, rectdate[i].hBitmap);</p><p> ::SetStretchBltMode(hDesDC1,COLORONCOLOR); </p><p> ::StretchBlt(hDesDC1, rectdate[i].rect
52、.left, rectdate[i].rect.top, width, height, hSrcDC1, 0, 0, bm1.bmWidth, bm1.bmHeight,+SRCCOPY);</p><p><b> }</b></p><p> 通過以上的函數,我們就可以得到下一輪游戲的牌面。</p><p> 以上是完成一個簡單24點
53、游戲必要的程序設計,接著我介紹下游戲中其他的一些控件。比如時間控制,開始和結束控制等。</p><p> 1.5 其他一些控件的設置</p><p> 1.5.1 時鐘的設置</p><p> 時鐘是用來控制游戲速度,和提高的人的智力所必需的控件。也是為游戲增添樂趣,提供思索空間所必需的。時鐘的設置在vc++鐘也是比較簡單的,其中用到的函數也非常簡介,接著讓我
54、們來看看其簡單的程序。</p><p> void CWorkView::OnTimer(UINT nIDEvent) //定時器響應程序</p><p> {CString temp;</p><p> UpdateData(true);</p><p> temp=m_edit;</p><p> t
55、imercount--;</p><p> m_edit4=timercount;</p><p> UpdateData(FALSE);}</p><p> if(timercount<=0)</p><p> {KillTimer(1) ;</p><p> timercount=30;</p
56、><p> (CButton*)CWnd::GetDlgItem(IDC_BUTTON5)->EnableWindow(TRUE);}</p><p> 查看如上函數,我們看到的關鍵函數就只有一個,那就是KillTimer函數。我們從他的拼寫可以看到,其意思是消除時間。其中還用到了控制時間秒數的變量timercount,在如上函數中其最大直為30,則說明游戲將在30秒內結束。另外在時
57、間控制下,其他一些控件也要實行相應的變化。在如上程序中,id為IDC-BUTTON5的空件在時間結束的時候要消除灰化。</p><p> 1.5.2 游戲的開始和結束控制</p><p> 每個游戲都有其游戲的開始控制和結束控制,當然24點游戲也不例外。因此要控制游戲的開始結束也是游戲中必要的控件。我們來看下其程序:</p><p> void CWorkVi
58、ew::OnButton5()</p><p> {if(istimer==false)</p><p> {SetTimer(1,1000,NULL);</p><p> (CButton*)CWnd::GetDlgItem(IDC_BUTTON5)->EnableWindow(FALSE);</p><p> (CButto
59、n*)CWnd::GetDlgItem(IDC_BUTTON3)->EnableWindow(FALSE);</p><p> (CButton*)CWnd::GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);</p><p> (CButton*)CWnd::GetDlgItem(IDC_BUTTON4)->EnableWin
60、dow(FALSE);}}</p><p> 其中在控件中我們添加了控件BUTTOM5,用于控制游戲的開始。當按下開始按鈕時,我們將控件BUTTTON3,2,4都灰化。這就實現(xiàn)了簡單的游戲開始控制。 </p><p> 結束按鈕和開始按鈕大同小異,這里我們就不詳細介紹了。</p><p> 1.6 游戲的實現(xiàn)其具體的函數</p><p>
61、; 1.6.1 游戲實現(xiàn)后的主要界面</p><p> 完成了以上4大節(jié)工作之后,一個簡單的24點游戲程序就基本生成了。接著就是在程序上做簡單的修改,查漏補缺。通過游戲的連接,編譯并運行。運行沒有出錯,程序就運行如下。</p><p> 從界面中我們看到了其中的主要功能都具備了。有相應的表達式輸入功能,查看結果功能,顯示正確答案功能,重新發(fā)牌,牌面設置以及定時控制。在菜單中有文件和幫
62、助兩個主菜單。其中文件菜單中有開始和結束控制。</p><p> 如下分細節(jié)對系統(tǒng)實現(xiàn)進行分析,首先我們來看下按下設置牌面產生的效果。</p><p> 我們看到,在按下了設置牌面的時候,彈出一個牌面設置的窗口。在請輸入牌面的輸入框中默認了牌面數字全為1,當然我么可以將其改寫,比如我們改為3 4 3 5 并按下確定,則彈出如下窗口。</p><p> 我們可以
63、看到按照如上的要求我們實現(xiàn)了牌面的自定義功能。接著我們來看看表達式輸時產生的一些錯誤信息提示,包括語法錯誤,括號匹配,數字匹配等。我在如下一一都顯示出來。</p><p> 其中的3個錯誤我們可以清楚的看到,當我們看到在第一個窗口中輸入了與紙牌數字不正確的數字之后,提示了“請注意輸入的數值是否正確”。在第二個窗口中輸入了左括號后直接點擊“單機查看結果”鍵時彈出“括號不匹配”的錯誤提示。在第三個窗口中輸入“方法”
64、倆漢字的時候,我們看到了“輸入語法錯誤”的提示。以上我將所有的錯誤信息都做了很好的圖文說明。</p><p> 以下是輸入正確表達式,并得出24點算法后的界面顯示。我們在牌面設置的時候輸入5 5 5 1 4個數字的時候,顯示正確結果的截面如下。</p><p> 如上我們看到界面中彈出了“計算正確”的消息框,實現(xiàn)了24點游戲表達式的最后判別。</p><p>
65、 1.6.2 24點算法的程序實現(xiàn)</p><p> //計算24點的答案程序</p><p> BOOL Calc24(int iNum1, int iNum2, int iNum3, int iNum4, CString& strResult) // </p><p> { //括號的幾種情況</p><p><b
66、> //無括號</b></p><p> //2 (a b) c d同a b (c d), 下省略</p><p> //3 (a b c) d</p><p> //4 a (b c)d</p><p> //5 (a b) (c d)</p><p> //6 ((a b) c) d
67、</p><p> //7 (a (b c)) d</p><p> int iNumArr[4];//定義一維數組 用于存放輸入的數值</p><p> iNumArr[0] = iNum1;</p><p> iNumArr[1] = iNum2;</p><p> NumArr[2] = iNum3;&
68、lt;/p><p> iNumArr[3] = iNum4;</p><p> if (CalcArray1(iNumArr, strResult))//調用CalcArray1函數判斷其是否能算出24 </p><p><b> {</b></p><p> return TRUE;</p><
69、p><b> }</b></p><p> if (CalcArray2(iNumArr, strResult)) //調用CalcArray2函數判斷其是否能算出24 </p><p><b> {</b></p><p> return TRUE;</p><p><b>
70、; }</b></p><p> if (CalcArray3(iNumArr, strResult)) 調用CalcArray3函數判斷其是否能算出24</p><p><b> {</b></p><p> return TRUE;</p><p><b> }</b>&l
71、t;/p><p> if (CalcArray4iNumArr, strResult)) 調用CalcArray4函數判斷其是否能算出</p><p><b> {</b></p><p> return TRUE;</p><p><b> }</b></p><p>
72、 if (CalcArray6(iNumArr, strResult)) 調用CalcArray6函數判斷其是否能算出</p><p><b> {</b></p><p> return TRUE;</p><p><b> }</b></p><p> if (CalcArray7(i
73、NumArr, strResult)) 調用CalcArray7函數判斷其是否能算出</p><p><b> {</b></p><p> return TRUE;</p><p><b> }</b></p><p> return FALSE;</p><p>
74、<b> }</b></p><p> BOOL CalcArray1(int iNumInput[], CString& strResult)//沒有括號的一個函</p><p> //數,類似的函數還有6個,這里不另外寫上去了。</p><p><b> {</b></p><p&g
75、t; // a * b * c * d 7 number</p><p> int iNumMaths[7][2];//其中包括數值變量和運算符號有7個字符</p><p> for(int i=0;i<4;i++)//循環(huán)語句判斷輸入的4個數字</p><p><b> {</b></p><p>
76、; for(int j=0;j<4;j++) </p><p><b> {</b></p><p><b> if(j==i)</b></p><p><b> {</b></p><p><b> continue;</b><
77、;/p><p><b> }</b></p><p> for(int k=0;k<4;k++)</p><p><b> {</b></p><p> if(k==i||k==j)</p><p><b> {</b></p>
78、<p><b> continue;</b></p><p><b> }</b></p><p> for(int l=0;l<4;l++)</p><p><b> {</b></p><p> if(l==i||l==j||l==k)</
79、p><p><b> {</b></p><p><b> continue;</b></p><p><b> }</b></p><p> iNumMaths[0][0]=iNumInput[i];//將數值存入數組中</p><p> iNu
80、mMaths[2][0]=iNumInput[j];</p><p> iNumMaths[4][0]=iNumInput[k];</p><p> iNumMaths[6][0]=iNumInput[l];</p><p> iNumMaths[0][1]=eNumber;//將此字符代表數值還是運算符號的值存入數組</p><p>
81、 iNumMaths[2][1]=eNumber;</p><p> iNumMaths[4][1]=eNumber;</p><p> iNumMaths[6][1]=eNumber;</p><p> for (int oneOP = eAdd; oneOP <= eDiv; oneOP++)//通過循環(huán)語句實現(xiàn)運算順序</p>&l
82、t;p> for (int twoOP=eAdd; twoOP<=eDiv; twoOP++)</p><p> for (int threeOP=eAdd; threeOP<=eDiv; threeOP++)</p><p><b> {</b></p><p> iNumMaths[1][0] = oneOP;//
83、通過循環(huán)得到第一個字符的運算符號先/,*后+ ,-</p><p> iNumMaths[1][1] = eOperator;//表明第一個輸入的字符為變量還是運算符號</p><p> iNumMaths[3][0] = twoOP;</p><p> iNumMaths[3][1] = eOperator;</p><p> iN
84、umMaths[5][0] = threeOP;</p><p> iNumMaths[5][1] = eOperator;</p><p> double dRes = CalcOneExpress(iNumMaths, 7);</p><p> if(Equal24(dRes))</p><p> CombineResult(iN
85、umMaths, 7, strResult);//合并結果</p><p> return TRUE;</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> }//e
86、nd for (int oneOP</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> return
87、FALSE;</p><p><b> }</b></p><p> 1.6.3 24點算法表達式的判別程序</p><p> int temp=0;//用于控制if語句的判斷</p><p> int total;//用于判斷輸入數字和牌面數字是否匹配</p><p> rrorNum
88、=3;//3種錯誤判斷和一種正確結果的變量</p><p> CString s;//用于在輸入框中輸入字符的變量</p><p> UpdateData(true);</p><p><b> s=m_edit;</b></p><p> int length=s.GetLength();</p>
89、<p><b> int dd;</b></p><p> UpdateData(FALSE);</p><p> int nLength=m_edit.GetLength();</p><p> har * sz=new char[nLength];</p><p> sz=m_edit.GetB
90、uffer(0);</p><p> UpdateData(true);</p><p> dd=eval_exp(sz);</p><p> m_edit3=dd;</p><p> if(errorNum==0)// errorNum有4個值,分別用以判斷出錯信息和正確消息</p><p><b>
91、; {</b></p><p> MessageBox("輸入語法錯誤");</p><p><b> }</b></p><p> else if(errorNum==1)</p><p> { MessageBox("輸入括號不匹配"
92、;)</p><p><b> }</b></p><p> else if(errorNum==2)</p><p><b> {</b></p><p> MessageBox("表達式不存在");</p><p><b> }&l
93、t;/b></p><p> else if(errorNum==3)//假如errorNum為3則判斷其表達式的長度</p><p><b> {</b></p><p> for(j=0;j<length-1;j++)</p><p><b> { </b></p&
94、gt;<p> int getatq=s.GetAt(j); </p><p> int getath=s.GetAt(j+1);</p><p> if((getatq=='1')&&(getath=='0'))</p><p><b> {</b></p>
95、<p> s.SetAt(j,'a');</p><p> s.Delete(j+1,1);</p><p> length=s.GetLength();</p><p><b> }</b></p><p> if((getatq=='1')&&(ge
96、tath=='1'))</p><p><b> {</b></p><p> s.SetAt(j,'b');</p><p> s.Delete(j+1,1);</p><p> length=s.GetLength();</p><p><b>
97、; }</b></p><p> if((getatq=='1')&&(getath=='2'))</p><p><b> {</b></p><p> s.SetAt(j,'c');</p><p> s.Delete(j+1,1)
98、;</p><p> length=s.GetLength();</p><p><b> }</b></p><p> if((getatq=='1')&&(getath=='3'))</p><p><b> {</b></p>
99、<p> s.SetAt(j,'d');</p><p> s.Delete(j+1,1);</p><p> length=s.GetLength();</p><p><b> }</b></p><p><b> }</b></p><
100、;p> for(i=1;i<14;i++)//循環(huán)語句判斷輸入值和牌面給定的牌是否匹配</p><p><b> {</b></p><p> temp=0;start=0;</p><p> while(temp!=(-1))</p><p><b> {</b></p
101、><p> temp=s.Find(d[i],start);</p><p> start=temp+1;</p><p> f(temp!=(-1))</p><p><b> {</b></p><p><b> a[i]++;</b></p><
102、;p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> for(i=1;i<14;i++)</p><p><b> {</b></p><p>
103、; if(c[i]==m_iNum[0])</p><p><b> {</b></p><p><b> a[i]--;</b></p><p><b> }</b></p><p> if(c[i]==m_iNum[1])</p><p>
104、<b> {</b></p><p><b> a[i]--;</b></p><p><b> }</b></p><p> if(c[i]==m_iNum[2])</p><p><b> {</b></p><p>
105、<b> a[i]--;</b></p><p><b> }</b></p><p> if(c[i]==m_iNum[3])</p><p><b> {</b></p><p><b> a[i]--;</b></p><
106、;p><b> }</b></p><p><b> }</b></p><p> total=abs(a[1])+abs(a[2])+abs(a[3])+abs(a[4])+abs(a[5])+abs(a[6]) </p><p> +abs(a[7])+abs(a[8])+abs(a[9])+abs(a[
107、10])+abs(a[11])+abs(a[12])+abs(a[13]);</p><p> if(total!=0) //利用total變量實現(xiàn)了數字匹配問題,假如total為0則匹配正確 否則錯誤</p><p> MessageBox("請注意輸入數值是否正確");</p><p><b> }</b><
108、/p><p><b> else{</b></p><p> if(dd==24)</p><p> MessageBox("計算正確");</p><p> m_edit3=dd;</p><p> UpdateData(FALSE);</p><p
109、><b> }</b></p><p><b> else </b></p><p><b> {</b></p><p> MessageBox("計算錯誤,請重新輸入");</p><p><b> }</b><
110、;/p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> 1.6.4 24點游戲紙牌發(fā)牌算法(不重復)</p><p> void CWorkView::RandomSele
111、ct() //初始化牌面文件的路徑,初始化牌面的數值,花色</p><p><b> {</b></p><p> int tempdate[4]; </p><p> double number[4];</p><p><b> int i,j;</b></p><p&
112、gt; char realdate[4][80];</p><p> char temppath[80];</p><p> char pathname[52][80]={"res\\a1.bmp","res\\a2.bmp","res\\a3.bmp","res\\a4.bmp",</p>
113、<p> "res\\a5.bmp","res\\a6.bmp","res\\a7.bmp","res\\a8.bmp",</p><p> "res\\a9.bmp","res\\a10.bmp","res\\a11.bmp","res\\a12.
114、bmp",</p><p> "res\\a13.bmp","res\\b1.bmp","res\\b2.bmp","res\\b3.bmp",</p><p> "res\\b4.bmp","res\\b5.bmp","res\\b6.bmp&q
115、uot;,"res\\b7.bmp",</p><p> "res\\b8.bmp","res\\b9.bmp","res\\b10.bmp","res\\b11.bmp",</p><p> "res\\b12.bmp","res\\b13.bmp&quo
116、t;,"res\\c1.bmp","res\\c2.bmp",</p><p> "res\\c3.bmp","res\\c4.bmp","res\\c5.bmp","res\\c6.bmp",</p><p> "res\\c7.bmp",&qu
117、ot;res\\c8.bmp","res\\c9.bmp","res\\c10.bmp",</p><p> "res\\c11.bmp","res\\c12.bmp","res\\c13.bmp","res\\d1.bmp",</p><p> "
118、;res\\d2.bmp","res\\d3.bmp","res\\d4.bmp","res\\d5.bmp",</p><p> "res\\d6.bmp","res\\d7.bmp","res\\d8.bmp","res\\d9.bmp",</p>
119、<p> "res\\d10.bmp","res\\d11.bmp","res\\d12.bmp","res\\d13.bmp"</p><p> };//將52紙牌文件路徑按順序依次存放于數組中</p><p> for(i=0;i<4;i++)</p><p&g
120、t; {tempdate[i] =(int)((double)rand()/RAND_MAX*52.0);//隨即函數得到0到51之間的數字</p><p> for(j=0;j<i;j++)</p><p> { while(tempdate[i]==tempdate[j])</p><p><b> {</b></p&g
121、t;<p> //tempdate[i] =(int)((double)rand()/RAND_MAX*52.0);</p><p> if(tempdate[i]==51)</p><p><b> {</b></p><p> tempdate[i]=0;</p><p><b>
122、}</b></p><p><b> else</b></p><p><b> {</b></p><p> tempdate[i]++;</p><p><b> }</b></p><p><b> }</b&
123、gt;</p><p><b> }</b></p><p> if(tempdate[i]<13)//判斷牌的花色為方塊</p><p><b> {</b></p><p> m_iNum[i]=tempdate[i]+1;//得到其數值大小</p><p>
124、;<b> }</b></p><p> else if(tempdate[i]<26)//判斷牌的花色為黑桃</p><p><b> {</b></p><p> m_iNum[i]=tempdate[i]-12; //得到其數值大小</p><p><b> }<
125、;/b></p><p> else if(tempdate[i]<39)//判斷牌的花色為紅桃</p><p> m_iNum[i]=tempdate[i]-25; //得到其數值大小</p><p><b> }</b></p><p><b> else</b></p
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 24點游戲軟件的開發(fā)課程設計
- 24點游戲課程設計報告
- 24點游戲課程設計報告
- 游戲24點課程設計報告
- c程序課程設計報告(24點游戲)
- java課程設計--基于java的24點游戲
- [vc畢設]24點游戲的開發(fā)和實現(xiàn)
- 數據結構課程設計--24點游戲源代碼
- [vc++畢設]vc++24點游戲的開發(fā)和實現(xiàn)
- java課程設計-21點小游戲
- c_課程設計游戲21點
- c語言課程設計--- 21點游戲設計
- vb課程設計掃雷游戲的設計與開發(fā)
- 算24點游戲--教學設計
- 貪吃蛇游戲的實現(xiàn)課程設計
- 課程設計報告--數獨小游戲的開發(fā)
- java課程設計--連連看游戲的開發(fā)
- 24點游戲題目
- 24點游戲技巧
- 24點游戲教案
評論
0/150
提交評論