生成一張n維的圖去分析, 比較容易一些
這個是2人麻將, 4人麻將改幾個數值就可以用了;
判斷胡牌的思路:
比如 :
1~9萬, 0x01 ~ 0x09 ;
1~9筒 , 0x11~0x19;
1~9條 , 0x21~ 0x29;
東南西北中發白 : 0x31 ~ 0x39
花牌 : 0x41 ~ 0x48;
弄乙個 arr[4][10] 的陣列, 做乙個牌型的圖出來 , 不算花牌;
然後比如 筒子 : (0x11&0xf0 << 4) 作為花色 , 0x11 & 0x0f 作為值[不論什麼牌都是 1 ~ 9 ];
陣列的第乙個索引放花色 ; 這個花色索引對應的陣列首個元素存放此花色的數量
現在比如有 2萬,2萬, 3萬 ,1筒
在陣列應是 arr[0][0] == 3, arr[1][0] == 1; 第0個元素作為此花色的總數量, 他們的值統計在對應的陣列上;
因此 arr[0][2] == 2 , arr[1][1] == 1.
這樣每個索引都記錄此牌的數量; 如此就知道了所有的牌;
胡牌首先判斷7個一對, 有了這個陣列, 直接迴圈就可以得出結果;
然後迴圈每個花色的首元素, 通過牌的數量來判斷, 如果要胡牌必然有一對, 其他的牌都是3個一組.
因此對 3 除餘. 如果餘數是 1 則不滿足胡牌的牌數, 如果是 2 則表示 此花色或許在此行中 ;
接下去就要分析牌型了, 寫乙個能判斷順子和剋子的函式, 除了一對所在的行, 把其他行都扔進去看看能否滿足牌型;
之後要對 一對所在的行做特殊處理, 因為你無法知道一對是什麼樣的牌型 1[11] / [11]
因此需要每次要在對應的索引上 減去2, 然後把剩餘的牌去匹配是否是順子/剋子;
如果能匹配成功, 最後能得到 [一對] 所在的 索引;
下面的**只用了乙個arr[2][10] 來做演示 , arr[0] 筒子, arr[1] 風牌;
**裡全是注釋;
//先寫2個後面要用的函式
int getcolor(char card)
int getvalue(char card)
//檢查是否是花牌
bool isflowercard(char card)
//所有的牌都是16進製制
//每個陣列第乙個元素用於計算此種花色含有多少張牌
//此分布圖, 不允許放入花牌,花牌先成其他牌後再使用此圖即可
struct card_pic
}bool gen_pic(char * arr, int len)
++cards[color_index][0]; //增加此牌型的數量
++cards[color_index][value]; //增加此牌的數量
}return true;
}void reset()
void show()
cout << endl;
}cout << endl;
}//復原牌, hand_cars 能足夠長度 14就ok,我就不做檢測了
int restorecards(char * hand_cards)}}
}std::sort(hand_cards, hand_cards + count);
return count;
}//檢查七對
bool check_qidui()
else if(cards[i][j] == 4)}}
return qidui_count == 7;
}//胡
bool checkhu()
//檢測是否滿足33332模型
//任意一行上必然一對, 因此從總數上 cards[i]%3 == 2 ,就是 " 一對"所在的位置
//第一遍只從數量上來分析一次, 把不能滿足此條件的先過濾掉
int ret = 0;
bool dui_exists = 0;
int dui_pos = 0;
for(int i = 0 ; i < 2; ++i)
else if( 2 == ret)
}//現在開始分析牌面,由於一對所在的行,會影響檢測,把一對所在的行放到後面檢測
//因此先把別的行進行檢測 , 別的行必然要滿足3333/333/33/3 這種模型
for(int i = 0 ; i < 2; ++i)
}//到此,證明別的行 都能滿足胡的條件了, 現在開始檢測 一對所在的行
//由於這個[一對]不知道是怎麼形成的,可能是1[11],也可以是11[11],或11,因此要迴圈
bool find = false;
int pos = -1;
for(int i = 1; i < 10 ; ++i)
}cout << "yi dui :" << pos << endl;
return find;
}//用於分析第n行的順子和剋子
//遞迴呼叫 . 每次把找到的順子或克子 減掉後[ -3 ], 在去遞迴,直到把此行的牌都減完,說明此行可以
bool fenxi_shunzi_kezi(int index , bool isfengpai)
bool ret = false;
int start_index = 0;
//找到第乙個不為0的,開始處理順子和剋子
for(int i = 1 ; i < 10 ; ++i)
}//如果首先找到的是剋子
if(cards[index][start_index] >=3)
//由於風牌[東南西北中發白] 沒有順子,因此首先判斷是不是風牌
if( !isfengpai && start_index < 8 &&
cards[index][start_index] > 0 &&
cards[index][start_index + 1] > 0 &&
cards[index][start_index + 2] > 0)
return ret;
}};bool checkting(char * leftcards, int leftcards_len , char * handcards, int handcards_len); //把花牌都刪去
int left_count = 0;
for(int i = 0 ; i < leftcards_len ; ++i)
}setsets(filter_leftcards, filter_leftcards+left_count);
set::iterator iter_end = sets.end();
set::iterator iter_begin = sets.begin();
char cp_handcards[14];
memset(cp_handcards,0,sizeof(cp_handcards));
memcpy(cp_handcards,handcards,handcards_len);
cout << "handcards:" << endl;
for(int i = 0; i < handcards_len ; ++ i)
cout << endl;
static card_pic pic;
int icount = 0 ;
for(; iter_begin != iter_end ; ++iter_begin)
if(pic.checkhu())
cp_handcards[i] = restore_card;}}
return false;
}//測試
int main(int argc, char* ar**)
; char arr[14] = ;
int len = 14;
char qarr[14] = ;
card_pic pic(qarr,len);
pic.show();
cout << (pic.checkhu() ? "hu!" : "nooooooooooo") << endl;
checkting(a,72,qarr,14);
return 0;
}
麻將胡牌演算法 C
這裡只介紹普通的麻將胡牌演算法,也就是7個對子或者 1個對子 3 n n 三個順子或者三個一樣的 其中字牌 東南西北中發白 不能算順子。首先對於每張牌 它有牌的的數字 1 9,牌的種類 萬條筒以及字 所以先封裝乙個牌的包裝類。如果要和伺服器互動的話就應該給這個類序列化 即加上system.seria...
麻將胡牌判決
胡牌有以下幾種情況 1 乙個對子 4組 3個相同的牌或者順子。只有m s p是可以構成順子的。東西南北這樣的牌沒有順子。2 7個不同的對子。3 1m,9m,1p,9p,1s,9s,1c,2c,3c,4c,5c,6c,7c.這13種牌每種都有,而且僅有這13種牌。肯定是有一種2張。其他的1張。首先是列...
麻將胡牌判決
就是給了13張牌。問增加哪些牌可以胡牌。胡牌有以下幾種情況 1 乙個對子 4組 3個相同的牌或者順子。只有m s p是可以構成順子的。東西南北這樣的牌沒有順子。2 7個不同的對子。3 1m,9m,1p,9p,1s,9s,1c,2c,3c,4c,5c,6c,7c.這13種牌每種都有,而且僅有這13種牌...