移豆子遊戲是這樣玩的,有一定數目的豆子(比方說有100粒),然後規定,兩個人依次拿走一些數量的豆子數,每次拿走的數目有上限(比方說3粒),而且至少拿一粒。最後,誰拿走最後一堆豆子算誰輸(當然,也可以設定最後拿走的贏)。
這其實是個數學趣題,高中的時候還搞定不了,不過現在自己想想倒也輕鬆搞定,看來的確是有進步啊。
假定遊戲的完法是誰拿走最後一堆豆子算誰輸(會分析這個,誰拿走最後一堆豆子算誰贏的必勝玩法就會容易搞定),我來分析一下這個遊戲的奧秘,quit easy!follow me:
先分析個別情況,(然後推廣至一般情況)假定每次可拿子數為3粒,誰拿走最後一堆豆子算誰輸。
先手必勝用0表示,而先手必敗用1表示(待會兒你就明白為什麼要這樣幹了)
attention:
我們只討先手必勝或必敗的情況,因為當先手必勝時,後手必敗;反之亦然
每次最多拿三粒。
1粒:你是先手嗎?噢,很不幸,你必敗了。 1
2粒:你是先手嗎?呵呵,拿一粒,對手面對一粒,你必勝,而他必敗。0
3粒:有了前車之鑑,先手的你應該聰明了,對了,拿走兩粒,你必 0
勝。4粒:看準了您呢,三粒,對手必敗。 0
5粒:唉呀呀,慘了,拿1,2,3粒時,對手得的子數為4,3,2,對 1
手都必勝了,你必敗了。
6粒:只要拿一粒,讓對手只拿到5粒,對手就必敗了。 0
7粒:2粒,理由同前。 0
8粒:3粒,理由同前。 0
9粒:完了,對手拿到6,7,8粒時對手都必勝,你必敗了。 1
10粒:1粒,讓對手拿10粒必敗。 0
11粒:看出規律了嗎,對了,取2粒。 0
。。。綜上,歸納一下這個小遊戲的必勝演算法:
誰拿走最後一堆誰輸的情況:當先手遇到的子數為1+k*(n+1)時(其中k為整數,n為每次可拿的最大子數),先手是必敗的,其餘情況時先手必勝,所以,這時遊戲的雙方只有乙個目的,把給對手的子湊到1+k*(n+1)就ok了。
再進一步推一下,對手必勝,對你而言,你就是必敗,返之亦然。
1:12:對於1的結果取反,為0。
3:對上面兩個結果取反,再取交集。(1&&0)=0
4:對上面三個結果取反,再取交集。(0&&1&&1)=0
5:對上面三個結果取反,再取交集。(1&&1&&1)=1必敗。
。。。got it?
誰拿走最後一堆誰贏的情況:分析的方法和上面是一樣的(略),小結為先手遇到子數為k*(n+1)時必敗。
下面為實現這個效果的乙個ai類(c++語言描述)
class ai;
int ai::highai(int winmode,int ***num,int limitnum)
else
break;
case 0:
if((t=(***num%(limitnum+1)))==0)
else
break;
}return outnum;
}int ai::lowai(int ***num,int limitnum)while(outnum>***num);
return outnum;
}int ai::aithinking(int winmode,int ***num,int limitnum,int ailevel)
return outnum;
}
nim遊戲的必勝策略
假設有n堆石子,每堆石子的個數分別如下 a1,a2,a3,an 定義nim sum為a1 a2 a3.an 可以證明 1.若a1 a2 a3.an 0 則經過一次合法的移動之後必定可變成 a1 a2.an 0 此時留下的局面為必勝。2.若a1 a2 a3.an 0 則經過一次合法的移動,局面必定成為...
很懷舊的遊戲 吃豆子
又到暑假了,在家裡閒著沒事又拿起了 c語言,沒特殊情況的話,這應該是我用graphic編的最後乙個遊戲了,因為我打算嘗試dev cpp加allegro的組合。這是個很懷舊的遊戲,我記得我第一次在pc上接觸的遊戲就有這個,它的做法也很簡單,和坦克基本相同,大概如下 首先,它是基於貪食蛇的原理作成的,因...
博弈,遊戲,是否有先手必勝的情況
最近做乙個題,說是 判斷 某個遊戲 是否有先手必勝的情況,在草稿紙上畫了畫,想了一陣,發現 把 所有當前遊戲的局面描述為乙個狀態,狀態之間的變化 實際上構成一顆 多叉樹,如果 有先手必勝的情況,那麼這棵樹 就會具有某種特點,即 包含某性質的某顆子樹,然後自己 便陷入 嚴格定義樹的特定,然後 試圖編碼...