最近实现了一款斗牛的棋牌游戏,觉得还是有很多心得体会,想分享出来。今天主要分享一下斗牛的算牛的算法。
斗牛的牌型是 A、2、3、4、5、6、7、8、9、10、J、Q、K, 为了方便计算, 我们将它们转换成数值。 A=1, 2=2, 3=3,4=4,5=5,6=6,7=7,8=8,9=9, 10=10, J=11, Q=12,K=13。
斗牛的算法,核心内容是这样的: 先算出五张牌的总值除以十的余数为A,然后再遍历枚举任意的两张牌, 如果存在两张牌的和除以十的余数等于A,那么其他三张牌必然总和为十的倍数,那么这个余数A就是牛数,否则不存在牛。
定义牌的结构体如下:
struct NiuNiuPokerStyle_t
{
int num;// 牌的数值
int type;// com 牌的花色
};
下面这个函数将实现斗牛的算牛的算法:
int calcCow(std::v%ector<NiuNiuPokerStyle_t> pokers)
{
if (pokers.size() != 5) return 0;
int lave = 0;
for (std::size_t i = 0; i < pokers.size(); i++)
{
lave += ((int)pokers[i].num > 10 ? 10 : (int)pokers[i].num);
}
lave = lave % 10;
for (std::size_t i = 0; i < pokers.size() - 1; i++)
{
for (std::size_t j = i + 1; j < pokers.size(); j++)
{
int a = (int)pokers[i].num > 10 ? 10 : (int)pokers[i].num;
int b = (int)pokers[j].num > 10 ? 10 : (int)pokers[j].num;
if ((a + b) % 10 == lave)
{
if (lave == 0)
{
return 10;
}
else
{
return lave;
}
}
}
}
return 0;
}
下面来写个测试测试一下该函数的正确性。
test.cpp:
int main(int argc, char ** argv)
{
if (argc != 6)
{
std::cout << "参数错误. 比如: 1 2 3 4 5" << std::endl;
return -1;
}
std::vector<NiuNiuPokerStyle_t> pokers;
std::vector<int> nums(13, 0);
for (int i = 1; i < argc; i++)
{
int p = atoi(argv[i]);
if (p < 1 || p > 13)
{
std::cout << "牌不能小于1, 且不能大于13" << std::endl;
return -1;
}
NiuNiuPokerStyle_t poker;
poker.num = p;
poker.type = 1;
nums[p]++;
pokers.push_back(poker);
}
for (std::size_t i = 0; i < nums.size(); i++)
{
if (nums[i] > 4)
{
std::cout << "牌错误" << std::endl;
return -1;
}
}
int cow = calcCow(pokers);
if (cow == 10)
{
std::cout << " 牛牛" << std::endl;
}
else if (cow == 0)
{
std::cout << " 没牛" << std::endl;
}
else
{
std::cout << " 牛" << cow << std::endl;
}
return 0;
}
结果:
./a.out 1 2 3 4 5
牛5
./a.out 10 11 12 9 8
牛7
看来算牛的结果是没有什么问题。好了,算牛的算法就分享到这里,大家有兴趣可以自己去测试一下。之后将会分享更多的棋牌游戏开发中的经验,感谢阅读。
标签: com