術(shù)語解釋:
叫牌:
挖到或者前面的玩家出牌,輪到自己對這個(gè)牌發(fā)表意見。?? 包括:放棄、吃、筷、對、水、丟
要牌:
當(dāng)前輪到的牌,自己叫牌優(yōu)先級最高,可以將牌與自己手中的牌與底牌匹配,吞掉(吃、筷、對、水、丟)
等牌:
其他玩家在對牌做處理,要么是在要牌(等他打出新的牌),要么是在等待這個(gè)玩家叫牌。
摸牌:
上一張牌已經(jīng)確定了沒有人叫牌,輪到自己從底牌中拿起新的一張牌。
丟牌:
邏輯
角色與規(guī)則定義:
兩邊是另外兩個(gè)玩家,玩家輪流摸牌,摸到牌依次叫牌,叫牌后根據(jù)優(yōu)先級最高的人判斷給誰優(yōu)先處理。
每一個(gè)玩家摸到牌之后,其他玩家自動彈出對或者吃的提示。由玩家確定要選擇哪種,
特殊點(diǎn):選擇丟牌,則讓玩家選出手中用來丟牌的另外兩張牌,合法的邏輯就可以讓該玩家丟牌,并結(jié)束游戲。要牌的玩家,如果不是丟牌,則需要打出一張新的牌。
叫牌后的牌,分派牌的優(yōu)先級規(guī)則是:吃 < 塊 < 塊水 < 硬對(或者塊水,2張硬牌)< 丟(結(jié)束游戲)。
限定要牌的時(shí)間為15秒(暫定),限定聽牌的時(shí)間為20秒(暫定)。
洗牌規(guī)則:
- 模擬短牌在桌面上的洗牌方式。
對半開+使用隨機(jī)數(shù)(小于10)再分配半的數(shù)量,
得到:數(shù)組A + 數(shù)組B,在A、B之間隨機(jī)獲得其中一方的最前面一張牌(根據(jù)奇偶性質(zhì)),并移動到新的數(shù)組C中,直到AB數(shù)組都移除。重復(fù)此過程3次即可。
打牌規(guī)則:
分為:ABCD三個(gè)角色玩家,由系統(tǒng)分配玩家(1234)角色,角色和玩家之間的對應(yīng)關(guān)系為A頭家,BC陪玩,D閑家。
發(fā)牌以類似區(qū)塊鏈的規(guī)則處理,底牌直接以每次10張發(fā)送給玩家,少于3張時(shí),再次發(fā)送10張,直到底牌發(fā)完。
這樣每個(gè)玩家都有3到13張底牌,可以在摸牌的時(shí)候不會因?yàn)榫W(wǎng)絡(luò)慢而不能立刻看到摸起來的牌。頭家打牌之后,輪次發(fā)放牌。發(fā)牌之后從摸牌家起輪詢是否要牌。
tnA, tnB, tnC: turnA, turnB, turnC
1、挖牌后:
logic A,叫牌:
tnA是否喊牌,然后輪詢其他玩家是否攔截。
tnB喊牌,tnC決定是否攔截。
tnC家決定是否要牌,輪詢結(jié)束。
任意一家輪詢過程中給丟牌了,都結(jié)束游戲,并且不再輪詢后續(xù)玩家。
logic B,要拍:
若沒有人叫牌,玩家輪流的角色變更。開始新的一輪叫牌。
有人叫牌,
需要前面的玩家再次叫牌,原本優(yōu)先級低(并且不是叫吃、筷)的玩家是否要丟。
則根據(jù)誰的優(yōu)先級高,分派牌給對應(yīng)的玩家。
2、頭家出牌:排除丟牌的邏輯,B是否要牌,C是否攔截。
B不要牌,C是否要牌。
A的牌,C不能吃。
除了摸牌并有人丟牌,其他情況都是挨個(gè)輪詢對這個(gè)牌的決定,上家要牌后,下家要牌的規(guī)則需要比上一家高。
輪詢完成后才實(shí)行實(shí)際的分配,指定玩家得以放牌。
放牌的玩家的下家開始重復(fù)邏輯2,如果沒有人要牌,重復(fù)邏輯1。
偽代碼:
服務(wù)器對客戶端的要牌規(guī)則的優(yōu)先級是:
logic_diu = [](){
if X 丟了{(lán) 則直接結(jié)束, return true}
return false;
}
logic_hard_couple = [](surplus_players){
if logic_diu(B) { return true; }
if logic_diu (C) {return true;}
do it on this player;
return true;
}
logic_shui_with2xcard = [](surplus_players){
if logic_hard_couple(B, C) {
return false;
}else{
do it; return true;
}
}
logic_kuai_with1xcard = [](surplus_players){
if logic_shui_with2xcard(B, C) {
return false;
}else{
do it; return true;
}
}
任何一種喊法都是可以放棄不要牌的,但是喊吃不能丟,喊筷不能吃和硬對,
func on_player_x_turn(current, surplus){
status = ask_player_status(current);
if status == logic_diu {
return true;
}else if status == logic_hard_couple { // A 硬(無聽用)對牌 或者硬水牌(只帶一個(gè)聽用)
return true;
}else if status == logic_shui_with2xcard { //A 水牌+帶2個(gè)聽用
return true;
}else if status == logic_kuai_with1xcard { //筷牌
return true;
}else if status == logic_chi{
return true;
}else{ //status == logic_ignore
return on_player_x_turn(surplus->next, surplus-1);
}
}
客戶端配合邏輯:
客戶端玩家要牌,需要收到服務(wù)器的輪詢結(jié)論后,才能知道自己的牌是不是可以成功的獲得喊出來的機(jī)會。
最終的攔截玩家獲得放牌的機(jī)會,如果獲得放牌機(jī)會的玩家放棄機(jī)會,則把放牌機(jī)會留給后面一家。
func call_in_desktop_card(c, others){
bool did_other_called = false
int call_priority = 0
others.foreach{
if ($0.did_call_this_card){
did_other_called = true;
call_priority = max($0.call_priority, call_priority)
}
}
higher_logic_call(c, call_priority);
}
while(no_one_did_diu){
card = waite_to_new_card(); //
if card.is_from_outside {
if card.is_from_desktop{
bool diu = call_in_desktop_card(); //
if (diu){
no_one_did_diu = false;
break;
}
}else{ //is from other users
call_in_other_users_none_desktop_card(card);
}
}else{ //is from my turn, got it from desktop
bool diu = call_in_desktop_card();
if(diu){
no_one_did_diu = false;
break;
}
}
}