求掼蛋同花顺代码(Lua)和C++

第一个参数传入手牌值,每张牌的0xXY,X代表花色(0-3),Y代表值(A-K),还有大小王。第二个参数传癞子数量。癞子可以当任意牌使用。手牌无癞子则传0.
function getTongHuaShunCardData(tabHandCardData,anyCount)
    local  checkCount = 5
    local findTongHuaShun = function()
        local countNum = {{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}}}
        local cardCount = #tabHandCardData
        for i=1,cardCount do
            local cardData = tabHandCardData[i]
            local cardValue = bit.band(cardData,0x0f)
            countNum[cardValue][1] = countNum[cardValue][1] + 1
            table.insert(countNum[cardValue][2],cardData)
        end

        local sameCardDataArr = {}
        for _,v in ipairs({1,2,3,4,5,6,7,8,9,10}) do
            local isTongShun = 0
            local arr = {}
            for i=1,checkCount - anyCount do
                local cardValue = v+i-1
                if cardValue==14 then
                    cardValue = 1
                end

                if countNum[cardValue][1]>=1 then
                    isTongShun = isTongShun + 1
                end
                table.insert(arr,cardValue)
            end

            if isTongShun>=(checkCount-anyCount) then
                for _,color in ipairs({0x00,0x10,0x20,0x30}) do
                    local oderSame = true
                    for _,v in ipairs(arr) do
                        local isSameColor = false
                        for _,cardData in ipairs(countNum[v][2]) do
                            local cardColor = bit.band(cardData,0xf0)
                            if cardColor==color then
                                isSameColor = true
                            end
                        end
                        oderSame = oderSame and isSameColor
                    end

                    if oderSame then
                        table.insert(sameCardDataArr,bit.bor(color,arr[1]))
                    end
                    
                end
            end
        end

        return sameCardDataArr
    end
    return findTongHuaShun()
end

返回同花顺的第一张牌的下标。 

测试用例:

getTongHuaShunCardData({0x01,0x02,0x03,0x04,0x05,0x06,0x21,0x22,0x23,0x24,0x25,0x33,0x43},1) --手牌,癞子数

2018.6.21更新C++版本:

enum {
	MEIHUA =0x00,
	HONGTAO=0x10,
	FANGKUAI=0x20,
	HEITAO=0x30,
	JOKER=0x40,
	LAIZI =0x50
};

enum {
	CARD_A = 0x01,
	CARD_2 = 0x02,
	CARD_3 = 0x03,
	CARD_4 = 0x04,
	CARD_5 = 0x05,
	CARD_6 = 0x06,
	CARD_7 = 0x07,
	CARD_8 = 0x08,
	CARD_9 = 0x09,
	CARD_10 = 0x0a,
	CARD_J = 0x0b,
	CARD_Q = 0x0c,
	CARD_K = 0x0d,
	CARD_SMALL_JOKER = 0x0e,
	CARD_BIG_JOKER = 0x0f,
};



map<int, map<int, map<int, int>>> ttt(const vector<int>&vecCardValue) {
	map<int, vector<int>>mCard;
	for (auto card:vecCardValue) {
		switch (card&0xf0)
		{
		case MEIHUA:
			cout << "meihua" << endl;
			mCard[MEIHUA].push_back(card);
			break;
		case HONGTAO:
			mCard[HONGTAO].push_back(card);
			break;
		case HEITAO:
			mCard[HEITAO].push_back(card);
			break;
		case FANGKUAI:
			mCard[FANGKUAI].push_back(card);
			break;
		case JOKER:
			mCard[JOKER].push_back(card);
			break;
		case LAIZI:
			mCard[LAIZI].push_back(card);
			break;
		default:
			break;
		}
	}

	//单一花色中
	map<int, map<int, map<int, int>>> singleColor;
	for (auto i=mCard.begin(); i != mCard.end(); ++i) {
		map<int, int> tmpVec;
		sort(i->second.begin(),i->second.end());
		for (auto card : i->second) {
			tmpVec[card & 0x0f] += 1;
		}
		//对某个值的牌
		map<int, map<int, int>>result;
		for (auto it = tmpVec.begin();it!=tmpVec.end();++it)
		{
			map<int, int>ivec = {};
			ivec[it->first] += 1;
			auto iter = it;
			for (iter;iter!=tmpVec.end();++iter)
			{
				if (iter->first > it->first&&iter->first < it->first + 5) {
					ivec[iter->first] += 1;
				}
					//cout << it->first << endl;
			}
			if (it->first > CARD_10&&it->first <= CARD_K) {
				if (tmpVec[CARD_A]) {
					ivec[CARD_A] += 1;
				}
			}
			result[it->first] = ivec;
		}
		singleColor[i->first] = result;
	}

	return singleColor;
}

上述可以返回手牌中每一张牌其能组成的最大顺子(最大长度为5,如梅花2,3,4,5,6)。

测试用例如下:

int main() {
	vector<int>vecCard = { 0x03,0x04,0x05,0x05,0x06,0x05,
		0x07,0x09,0x09,0x0a,0x0b,0x0c,0x01,

		0x14,0x15,0x20,0x35,0x42 };
	map<int, map<int, map<int, int>>> singleColor = ttt(vecCard);
	for (auto i = singleColor.begin(); i != singleColor.end(); ++i) {
		auto mColor = i->second;
		for (auto j = mColor.begin(); j != mColor.end(); ++j) {
			auto card = j->first^i->first;
			cout <<card<<":"<< j->second.size() << endl;
		}
	}
	return 0;
}

输出如下,冒号后面值小于5的,都可以加上癞子牌来凑成5张组成同花顺。


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
淮安是一种流行的扑克牌游戏,可以用C++语言编写。以下是一个简单的示例,仅供参考: ```c++ #include <iostream> #include <vector> #include <algorithm> #include <ctime> using namespace std; // 定义牌的种类和值 const vector<string> card_types {"♠", "♥", "♦", "♣"}; const vector<string> card_values {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"}; // 定义牌的结构体 struct Card { string type; string value; int point; Card(string t, string v, int p) : type(t), value(v), point(p) {} }; // 定义玩家结构体 struct Player { string name; vector<Card> cards; int score; Player(string n) : name(n), score(0) {} }; // 创建一副牌 vector<Card> create_deck() { vector<Card> deck; for (auto t : card_types) { for (int i = 0; i < card_values.size(); i++) { int point = i < 9 ? i + 2 : 10; deck.push_back(Card(t, card_values[i], point)); } } return deck; } // 洗牌 void shuffle_deck(vector<Card>& deck) { srand(time(NULL)); // 以时间为种子生成随机数 random_shuffle(deck.begin(), deck.end()); } // 发牌 void deal_cards(vector<Card>& deck, vector<Player>& players) { for (int i = 0; i < players.size(); i++) { for (int j = 0; j < 13; j++) { players[i].cards.push_back(deck.back()); deck.pop_back(); } } } // 排序函数 bool cmp(Card c1, Card c2) { if (c1.type != c2.type) { return c1.type < c2.type; } else { return c1.point < c2.point; } } // 玩家出牌 Card play_card(Player& player, Card& card) { auto it = find(player.cards.begin(), player.cards.end(), card); if (it != player.cards.end()) { player.cards.erase(it); return card; } else { cout << "你没有这张牌!" << endl; return Card("", "", 0); } } // 计算得分 int calculate_score(vector<Card> cards) { int score = 0; for (auto c : cards) { if (c.value == "10" || c.value == "K" || c.value == "A") { score += 10; } else if (c.value == "5") { score += 5; } } return score; } // 判断是否为炸弹 bool is_bomb(vector<Card> cards) { if (cards.size() != 4) { return false; } for (int i = 1; i < cards.size(); i++) { if (cards[i].value != cards[0].value) { return false; } } return true; } // 判断胜负 bool is_win(vector<Card> cards1, vector<Card> cards2) { int score1 = calculate_score(cards1); int score2 = calculate_score(cards2); if (is_bomb(cards1)) { score1 *= 2; } if (is_bomb(cards2)) { score2 *= 2; } return score1 > score2; } int main() { vector<Player> players; players.push_back(Player("玩家1")); players.push_back(Player("玩家2")); vector<Card> deck = create_deck(); shuffle_deck(deck); deal_cards(deck, players); sort(players[0].cards.begin(), players[0].cards.end(), cmp); sort(players[1].cards.begin(), players[1].cards.end(), cmp); while (players[0].cards.size() > 0 && players[1].cards.size() > 0) { // 玩家1出牌 cout << players[0].name << "的手牌:"; for (auto c : players[0].cards) { cout << c.type << c.value << " "; } cout << endl; string type, value; cout << "请" << players[0].name << "出牌(输入牌的花色和点数):"; cin >> type >> value; Card card(type, value, 0); Card played_card = play_card(players[0], card); if (played_card.value != "") { // 玩家2出牌 cout << players[1].name << "的手牌:"; for (auto c : players[1].cards) { cout << c.type << c.value << " "; } cout << endl; int index = rand() % players[1].cards.size(); played_card = play_card(players[1], players[1].cards[index]); if (played_card.value != "") { if (is_win({card}, {played_card})) { cout << players[0].name << "赢了这一轮!" << endl; players[0].score++; } else { cout << players[1].name << "赢了这一轮!" << endl; players[1].score++; } } } } if (players[0].score > players[1].score) { cout << players[0].name << "赢了游戏!" << endl; } else if (players[0].score < players[1].score) { cout << players[1].name << "赢了游戏!" << endl; } else { cout << "平局!" << endl; } return 0; } ``` 这个示例程序只是一个简单的框架,还有很多地方需要完善。例如: - 玩家出牌的逻辑需要更加灵活,可以考虑加入提示、判断牌是否符合规则等功能。 - 计分规则可以根据实际情况进行修改,比如加入对炸弹的特殊处理。 - 程序没有图形界面,需要在命令行中输入数据,可以考虑使用QT等GUI库进行开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值