flex 聯機游戲開發 - 斗地主游戲:(一)核心邏輯
這是我希望開發的第一個紙牌類游戲,斗地主本身來說是一個有限用戶的回合制游戲,核心邏輯與棋類游戲并無多大的不同,但是因為并無多大的行棋算法,所以位置顯得不那么的重要。所以我決定還是用開發四國軍棋形成的flexchessapi來開發這個游戲,如果flexchessapi不能勝任這個工作,我會考慮形成一個通用的flexcardapi來開發這個游戲。這樣,我就能利用flexcardapi開發更多的游戲,比如詐金花等。
核心邏輯開發完成后效果如圖所示
好了,現在我們開始設計一些紙牌類的一般邏輯思考,放在一個靜態類如CardHelp.as中。。
1) 設計一幅牌
我們對一幅牌的每一張牌應該給定一個值,每個值包括花色與本身的大小,這樣,我們就以一個3位數的值來代表一張牌,比如303代表紅花3,414代表黑桃A,這樣,我們就能夠設計出一幅牌的完整數組,不同的牌需要的完整數不同,比如扎金花是不要王,斗地主是要王的,現在,我們設計一幅牌。
/**
*斗地主帶王的一幅完整的牌
* 在斗地主中,2是比A還大的牌,我們不能叫102,就叫115吧。
*/
public static const CARDS_WITH_JOKER:Array=[115,103,104,105,106,107,108,109,110,111,112,113,114,215,203,204,205,206,207,208,209,210,211,212,213,214,315,303,304,305,306,307,308,309,310,311,312,313,314,415,403,404,405,406,407,408,409,410,411,412,413,414,518,519];
/**
*扎金花不帶王的一幅完整的牌
*/
public static const CARDS_NO_JOKER:Array=[102,103,104,105,106,107,108,109,110,111,112,113,114,202,203,204,205,206,207,208,209,210,211,212,213,214,302,303,304,305,306,307,308,309,310,311,312,313,314,402,403,404,405,406,407,408,409,410,411,412,413,414];
設計兩個幫助方法
/**
*獲得特定處于的花色
* @param card
* @return
*
*/
public static function getHuaShe(value:int):int{
return Math.floor(value/100);
}
/**
* 獲得特定牌的原始值
* @param card
* @return
*
*/
public static function getPureValue(value:int):int{
return value%100;
}
2)牌有了,我們開始設計一個發牌的函數
2.1)發一張牌,發牌函數相對比較簡單,直接從一幅牌的數組中取一張即可,注意的是,取完后應該將該牌刪除,以免下次再發一樣的牌。
/**
* 獲得牌組中一張隨機的牌值
* @param cards
* @return
*
*/
public static function getRadomCard(cards:ArrayCollection):int{
if (cards.length==0) return -1;
var key:int=Math.round(Math.random()*(cards.length-1));
return cards.removeItemAt(key) as int;
}
2.2)發一手牌,對斗地主來說,一手牌就是17張,最后的三張就是底牌,在發牌的時候,我們考慮的是給牌排序,這樣,發完牌后就自動從大到小排列。
/**
* 獲得一個隨機的一手牌。
* @param cards 全部牌
* @param num 牌的數量
* @param sort 是否排序
* @return
*
*/
public static function getRadomCards(cards:ArrayCollection,num:int,sort:Boolean=true):ArrayCollection{
var temp:ArrayCollection=new ArrayCollection();
do{
var cardvalue:int=getRadomCard(cards);
trace("生成牌:"+getDisplayName(cardvalue));
if (!sort)
temp.addItem(cardvalue);
else
{
var added:Boolean=false;
for (var i:int=0;i<temp.length;i++)
{
var value:int=temp.getItemAt(i) as int;
if (cardvalue%100>value%100)
{
temp.addItemAt(cardvalue,i);
added=true;
break;
}
}
if (!added)
{
temp.addItemAt(cardvalue,i);
}
}
num--;
}while(num>0);
trace("排序后:"+temp.toString());
return temp;
}
3)進入斗地主的邏輯,我們現在設計一個通用類叫 DoudizhuHelp.as。
斗地主游戲中的牌型很多,算法也各有不同,但我總覺得網上一些通用的算法有點鋪天蓋地,所以,我決定自己來重新想一下算法,總的來說,無論你出什么處于,三帶二,炸,4帶一等,你總是有個主牌的,從牌只認張數,大小是無所謂的,所以,我將主牌清點出來應該就只有 對子,3條,炸彈,雙王,順子這五類,所以,在發牌或者拿到底牌后,我們直接將所有的主牌類型清理出來即可。
現在,寫一個清理主牌類型的函數。
/**
*獲得當前牌的所有牌型
* @return
*
*/
public function initType():void{
var temp:ArrayCollection=new ArrayCollection();
for (var i:int=0;i<_cardAC.length-1;i++)
{
var card1:ICard=_cardAC.getItemAt(i) as ICard;
var card2:ICard=_cardAC.getItemAt(i+1) as ICard;
//添加至雙王
if (card1.pureValue==18||card1.pureValue==19)
{
if (!shuangwangAC.contains(card1.pureValue))
shuangwangAC.addItem(card1.pureValue);
}
//相同部分,我們只需要判斷一次
if (card1.pureValue==card2.pureValue)
{
//添加至炸彈
if (this.santiaoAC.contains(card1.pureValue))
{
if (!this.zhadanAC.contains(card1.pureValue))
this.zhadanAC.addItem(card1.pureValue);
}
//添加至三條
else if (this.duizhiAC.contains(card1.pureValue))
{
this.santiaoAC.addItem(card1.pureValue);
}
//添加至對子
else
{
this.duizhiAC.addItem(card1.pureValue);
}
}
//添加至順子
else if (card1.pureValue==card2.pureValue+1&&card2.pureValue!=3)
{
//2不能加入順子中
if (card1.pureValue==15) continue;
if (!temp.contains(card1.pureValue))
temp.addItem(card1.pureValue);
if (!temp.contains(card2.pureValue))
temp.addItem(card2.pureValue);
}
//位數不等或者已經到達最后
else
{
if (card2.pureValue==3) temp.addItem(card2.pureValue);
if (temp.length>=5)
{
this.sunzhiAC.addAll(temp);
}
temp=new ArrayCollection();
}
}
//如果沒有雙王,則清空雙王集合
if (shuangwangAC.length<2)
{
shuangwangAC.removeAll();
}
trace("雙王.."+this.shuangwangAC.toString());
trace("對子.."+this.duizhiAC.toString());
trace("三條..."+this.santiaoAC.toString());
trace("順子..."+this.sunzhiAC.toString());
trace("炸彈...."+this.zhadanAC.toString());
}
分析每一句的意義。函數應該比較好懂,暫時還沒發現什么bug,不過我總覺得不放心:),高手們可以幫我找找bug,謝謝了。。。
現在,我試著分析了一手牌。
雙王..
對子..15,9,6,4,3
三條...15,9
順子...10,9,8,7,6,5,4,3
炸彈....
在這一個月里,我已經開了太多的頭,四國軍棋 寫到了3,五子棋 寫到了2,中國象棋 寫到了 1,所以我決定在再完成一個扎金花的游戲邏輯分析后,下一步就開始埋頭做聯機游戲服務器網站 www.boyiju.com 的開發與聯機游戲客戶端api的開發,然后對所有已經完成邏輯的游戲進行統一更新,在第三方應用發展迅猛的今天,我的目標是建成一個所有程序員可以輕松進行第三方游戲應用開發測試的公用開源平臺,平臺將一個完整的sns網站測試環境與以下的各類api,感興趣的朋友可以隨時關注項目開發進展情況,如果你極端感興趣,或者您仍舊懷著工作部分為了理想活著的大志。你也可以加我QQ 2 1 0 7 3 4 5 2 了解這個項目或者參與這個項目的開發,您不必擔心我,你面對的只是一個除了有點忙,沒什么壞習慣的開發者。
浙公網安備 33010602011771號