Skip to content

Commit e4f5818

Browse files
committed
mahjong hu version 4, base from 'yuanfengyun/qipai'
1 parent 8206d31 commit e4f5818

File tree

11 files changed

+701
-0
lines changed

11 files changed

+701
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include <stdio.h>
2+
#include <set>
3+
#include <map>
4+
#include "table_mgr.h"
5+
6+
std::map<int, bool> gui_tested[9];
7+
std::map<int, bool> gui_eye_tested[9];
8+
9+
bool check_add(int cards[], int gui_num, bool eye) {
10+
int key = 0;
11+
for (int i=0; i<9; i++) {
12+
key = key * 10 + cards[i];
13+
}
14+
15+
if (key == 0) {
16+
return false;
17+
}
18+
19+
std::map<int, bool>* m;
20+
if (!eye) {
21+
m = &gui_tested[gui_num];
22+
} else {
23+
m = &gui_eye_tested[gui_num];
24+
}
25+
if(m->find(key) != m->end()){
26+
return false;
27+
}
28+
29+
(*m)[key] = true;
30+
31+
for (int i=0; i<9; i++){
32+
if (cards[i] > 4) {
33+
return true;
34+
}
35+
}
36+
TableMgr::add(key, gui_num, eye, false);
37+
return true;
38+
}
39+
40+
static void parse_table_sub(int cards[], int num, bool eye) {
41+
for (int i=0; i<9; i++) {
42+
if (cards[i] == 0) {
43+
continue;
44+
}
45+
46+
cards[i]--;
47+
48+
if (!check_add(cards, num, eye)) {
49+
cards[i]++;
50+
continue;
51+
}
52+
53+
if (num < 8) {
54+
parse_table_sub(cards, num + 1, eye);
55+
}
56+
cards[i]++;
57+
}
58+
}
59+
60+
static void parse_table(int cards[], bool eye) {
61+
if (!check_add(cards, 0, eye)) {
62+
return;
63+
}
64+
parse_table_sub(cards, 1, eye);
65+
}
66+
67+
void gen_auto_table_sub(int cards[], int level, bool eye) {
68+
for(int i=0;i<7;++i) {
69+
if(cards[i] > 3) continue;
70+
cards[i] += 3;
71+
72+
parse_table(cards, eye);
73+
if(level<4) {
74+
gen_auto_table_sub(cards, level + 1, eye);
75+
}
76+
cards[i] -= 3;
77+
}
78+
}
79+
80+
void gen_table() {
81+
int cards[34] = {0};
82+
gen_auto_table_sub(cards, 1, false);
83+
}
84+
85+
void gen_eye_table() {
86+
int cards[34] = {0};
87+
for(int i=0; i<7; ++i) {
88+
cards[i] = 2;
89+
parse_table(cards, true);
90+
gen_auto_table_sub(cards, 1, true);
91+
cards[i] = 0;
92+
}
93+
}
94+
95+
int main() {
96+
TableMgr::init();
97+
printf("generate feng table begin...\n");
98+
gen_table();
99+
gen_eye_table();
100+
TableMgr::dump_feng_table();
101+
102+
return 0;
103+
}

mahjong/mahjongHu_v4/gen_table.cpp

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#include <stdio.h>
2+
#include <set>
3+
#include <map>
4+
#include "table_mgr.h"
5+
6+
std::map<int, bool> gui_tested[9];
7+
std::map<int, bool> gui_eye_tested[9];
8+
9+
bool check_add(int cards[], int gui_num, bool eye) {
10+
int key = 0;
11+
12+
for (int i=0; i<9; i++) {
13+
key = key * 10 + cards[i];
14+
}
15+
16+
if (key == 0) {
17+
return false;
18+
}
19+
20+
std::map<int, bool>* m;
21+
if (!eye) {
22+
m = &gui_tested[gui_num];
23+
} else {
24+
m = &gui_eye_tested[gui_num];
25+
}
26+
if(m->find(key) != m->end()){
27+
return false;
28+
}
29+
30+
(*m)[key] = true;
31+
32+
for (int i=0; i<9; i++) {
33+
if (cards[i] > 4) {
34+
return true;
35+
}
36+
}
37+
TableMgr::add(key, gui_num, eye, true);
38+
return true;
39+
}
40+
41+
static void parse_table_sub(int cards[], int num, bool eye) {
42+
for (int i=0; i<9; i++) {
43+
if (cards[i] == 0) {
44+
continue;
45+
}
46+
47+
cards[i]--;
48+
49+
if (!check_add(cards, num, eye)) {
50+
cards[i]++;
51+
continue;
52+
}
53+
54+
if (num < 8) {
55+
parse_table_sub(cards, num + 1, eye);
56+
}
57+
cards[i]++;
58+
}
59+
}
60+
61+
static void parse_table(int cards[], bool eye) {
62+
if (!check_add(cards, 0, eye)) {
63+
return;
64+
}
65+
parse_table_sub(cards, 1, eye);
66+
}
67+
68+
void gen_auto_table_sub(int cards[], int level, bool eye) {
69+
for(int i=0;i<16;++i) {
70+
if(i <= 8) {
71+
if(cards[i] > 3) continue;
72+
cards[i] += 3;
73+
} else {
74+
int index = i - 9;
75+
if(cards[index]>5 || cards[index+1]>5 || cards[index+2]>5)
76+
continue;
77+
cards[index] += 1;
78+
cards[index+1] += 1;
79+
cards[index+2] += 1;
80+
}
81+
82+
parse_table(cards, eye);
83+
if(level<4) {
84+
gen_auto_table_sub(cards, level + 1, eye);
85+
}
86+
87+
if(i <= 8) {
88+
cards[i] -= 3;
89+
} else {
90+
int index = i - 9;
91+
cards[index] -= 1;
92+
cards[index + 1] -= 1;
93+
cards[index + 2] -= 1;
94+
}
95+
}
96+
}
97+
98+
void gen_table() {
99+
int cards[34] = {0};
100+
gen_auto_table_sub(cards, 1, false);
101+
}
102+
103+
void gen_eye_table() {
104+
int cards[34] = {0};
105+
106+
for(int i=0; i<9; ++i) {
107+
printf("eye %d\n",i);
108+
cards[i] = 2;
109+
parse_table(cards, true);
110+
gen_auto_table_sub(cards, 1, true);
111+
cards[i] = 0;
112+
}
113+
}
114+
115+
int main() {
116+
TableMgr::init();
117+
printf("generate table begin...\n");
118+
gen_eye_table();
119+
gen_table();
120+
TableMgr::dump_table();
121+
printf("generate table end...\n");
122+
123+
return 0;
124+
}

mahjong/mahjongHu_v4/genv4.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
if [ ! -d "tbl" ]; then
3+
mkdir tbl
4+
fi
5+
g++ test_table.cpp set_table.cpp table_mgr.cpp hulib.cpp -ov4

mahjong/mahjongHu_v4/hulib.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#include <string.h>
2+
#include "hulib.h"
3+
#include "table_mgr.h"
4+
5+
bool HuLib::get_hu_info(char* cards, char cur_card, int gui_index) {
6+
int gui_num = 0;
7+
if (cur_card != 34)
8+
++cards[cur_card];
9+
if (gui_index != 34)
10+
gui_num = cards[gui_index];
11+
12+
cards[gui_index] = 0;
13+
14+
bool hu = split(cards, gui_num);
15+
if (gui_index != 34)
16+
cards[gui_index] = gui_num;
17+
if (cur_card != 34)
18+
--cards[cur_card];
19+
return hu;
20+
}
21+
22+
bool check(int gui, int eye_num, int gui_num, int& gui_sum) {
23+
if (gui < 0) return false;
24+
25+
gui_sum += gui;
26+
if (gui_sum > gui_num)
27+
return false;
28+
29+
if (eye_num == 0)
30+
return true;
31+
32+
return gui_sum + (eye_num - 1) <= gui_num;
33+
}
34+
35+
bool HuLib::split(char* const cards, int gui_num) {
36+
int eye_num = 0;
37+
int gui_sum = 0;
38+
int gui = 0;
39+
40+
gui = _split(cards, gui_num, 0, 8, true, eye_num);
41+
if (!check(gui, eye_num, gui_num, gui_sum))
42+
return false;
43+
44+
gui = _split(cards, gui_num-gui_sum, 9, 17, true, eye_num);
45+
if (!check(gui, eye_num, gui_num, gui_sum))
46+
return false;
47+
48+
gui = _split(cards, gui_num-gui_sum, 18, 26, true, eye_num);
49+
if (!check(gui, eye_num, gui_num, gui_sum))
50+
return false;
51+
52+
gui = _split(cards, gui_num-gui_sum, 27, 33, false, eye_num);
53+
if (!check(gui, eye_num, gui_num, gui_sum))
54+
return false;
55+
56+
if (eye_num == 0) {
57+
return gui_sum + 2 <= gui_num;
58+
}
59+
60+
return true;
61+
}
62+
63+
int HuLib::_split(char* const cards, int gui_num, int min, int max, bool chi, int& eye_num) {
64+
int key = 0;
65+
int num = 0;
66+
67+
for(int i = min; i <= max; ++i) {
68+
key = key*10 + cards[i];
69+
num = num + cards[i];
70+
}
71+
72+
if (num == 0)
73+
return 0;
74+
75+
for (int i = 0; i <= gui_num; ++i) {
76+
int yu = (num + i) % 3;
77+
if (yu == 1) continue;
78+
bool eye = (yu == 2);
79+
if (TableMgr::check(key, i, eye, chi)) {
80+
if (eye) eye_num++;
81+
return i;
82+
}
83+
}
84+
85+
return -1;
86+
}
87+

mahjong/mahjongHu_v4/hulib.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include <string.h>
2+
3+
struct Wave
4+
{
5+
};
6+
7+
class HuLib
8+
{
9+
public:
10+
static bool get_hu_info(char* const hand_cards, char cur_card, int gui_index);
11+
private:
12+
static bool split(char* const cards, int gui_num);
13+
static int _split(char* const cards, int gui_num, int min, int max, bool chi, int& eye_num);
14+
};

mahjong/mahjongHu_v4/set_table.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include "set_table.h"
4+
#include <algorithm>
5+
#include <vector>
6+
7+
using namespace std;
8+
9+
bool compare(int a, int b) {
10+
return a < b;
11+
}
12+
13+
SetTable::SetTable() {
14+
}
15+
16+
SetTable::~SetTable() {
17+
}
18+
19+
bool SetTable::check(int number) {
20+
return m_tbl.find(number) != m_tbl.end();
21+
}
22+
23+
void SetTable::add(int key) {
24+
m_tbl.insert(key);
25+
}
26+
27+
void SetTable::dump(char* name) {
28+
FILE *fp = fopen(name, "wb+");
29+
if(!fp) {
30+
return;
31+
}
32+
33+
vector<int> vec;
34+
copy(m_tbl.begin(), m_tbl.end(), back_inserter(vec));
35+
sort(vec.begin(), vec.end(), compare);
36+
for(std::vector<int>::iterator it=vec.begin(); it!=vec.end(); ++it) {
37+
fprintf(fp, "%d\n", *it);
38+
}
39+
// for(std::set<int>::iterator it=m_tbl.begin(); it!=m_tbl.end(); ++it) {
40+
// fprintf(fp, "%d\n", *it);
41+
// }
42+
43+
fclose(fp);
44+
}
45+
46+
void SetTable::load(char* name) {
47+
FILE *fp = fopen(name, "rb");
48+
if(!fp) {
49+
return;
50+
}
51+
52+
int key = 0;
53+
int num = 0;
54+
while (fscanf(fp, "%d\n", &key) != EOF) {
55+
num++;
56+
add(key);
57+
}
58+
//printf("load %s %d key, set_size = %d\n", name, num, m_tbl.size());
59+
fclose(fp);
60+
}

0 commit comments

Comments
 (0)