术语解释:
叫牌:
挖到或者前面的玩家出牌,轮到自己对这个牌发表意见。�� 包括:放弃、吃、筷、对、水、丢
要牌:
当前轮到的牌,自己叫牌优先级最高,可以将牌与自己手中的牌与底牌匹配,吞掉(吃、筷、对、水、丢)
等牌:
其他玩家在对牌做处理,要么是在要牌(等他打出新的牌),要么是在等待这个玩家叫牌。
摸牌:
上一张牌已经确定了没有人叫牌,轮到自己从底牌中拿起新的一张牌。
丢牌:
逻辑
角色与规则定义:
-
两边是另外两个玩家,玩家轮流摸牌,摸到牌依次叫牌,叫牌后根据优先级最高的人判断给谁优先处理。
-
每一个玩家摸到牌之后,其他玩家自动弹出对或者吃的提示。由玩家确定要选择哪种,
特殊点:选择丢牌,则让玩家选出手中用来丢牌的另外两张牌,合法的逻辑就可以让该玩家丢牌,并结束游戏。 -
要牌的玩家,如果不是丢牌,则需要打出一张新的牌。
-
叫牌后的牌,分派牌的优先级规则是:吃 < 块 < 块水 < 硬对(或者块水,2张硬牌)< 丢(结束游戏)。
-
限定要牌的时间为15秒(暂定),限定听牌的时间为20秒(暂定)。
洗牌规则:
- 模拟短牌在桌面上的洗牌方式。
对半开+使用随机数(小于10)再分配半的数量,
得到:数组A + 数组B,在A、B之间随机获得其中一方的最前面一张牌(根据奇偶性质),并移动到新的数组C中,直到AB数组都移除。重复此过程3次即可。
打牌规则:
-
分为:ABCD三个角色玩家,由系统分配玩家(1234)角色,角色和玩家之间的对应关系为A头家,BC陪玩,D闲家。
-
发牌以类似区块链的规则处理,底牌直接以每次10张发送给玩家,少于3张时,再次发送10张,直到底牌发完。
这样每个玩家都有3到13张底牌,可以在摸牌的时候不会因为网络慢而不能立刻看到摸起来的牌。 -
头家打牌之后,轮次发放牌。发牌之后从摸牌家起轮询是否要牌。
tnA, tnB, tnC: turnA, turnB, turnC
1、挖牌后:
logic A,叫牌:
tnA是否喊牌,然后轮询其他玩家是否拦截。
tnB喊牌,tnC决定是否拦截。
tnC家决定是否要牌,轮询结束。
任意一家轮询过程中给丢牌了,都结束游戏,并且不再轮询后续玩家。
logic B,要拍:
若没有人叫牌,玩家轮流的角色变更。开始新的一轮叫牌。
有人叫牌,
需要前面的玩家再次叫牌,原本优先级低(并且不是叫吃、筷)的玩家是否要丢。
则根据谁的优先级高,分派牌给对应的玩家。
2、头家出牌:排除丢牌的逻辑,B是否要牌,C是否拦截。
B不要牌,C是否要牌。
A的牌,C不能吃。
除了摸牌并有人丢牌,其他情况都是挨个轮询对这个牌的决定,上家要牌后,下家要牌的规则需要比上一家高。
轮询完成后才实行实际的分配,指定玩家得以放牌。
放牌的玩家的下家开始重复逻辑2,如果没有人要牌,重复逻辑1。
伪代码:
服务器对客户端的要牌规则的优先级是:
logic_diu = [](){
if X 丢了{ 则直接结束, 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 硬(无听用)对牌 或者硬水牌(只带一个听用)
return true;
}else if status == logic_shui_with2xcard { //A 水牌+带2个听用
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);
}
}
客户端配合逻辑:
客户端玩家要牌,需要收到服务器的轮询结论后,才能知道自己的牌是不是可以成功的获得喊出来的机会。
最终的拦截玩家获得放牌的机会,如果获得放牌机会的玩家放弃机会,则把放牌机会留给后面一家。
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;
}
}
}
网友评论