Dota游戏匹配的所有组合

来源:互联网 发布:淘宝拍衣服的要求 编辑:程序博客网 时间:2024/05/16 14:53

在Dota游戏中有一种匹配玩法,任意5人以下玩家组队,加入匹配系统,由系统组合出5人 vs 5人的组合进行游戏,比如2人+3人  vs 1人+4人。抽象出这个问题,就变成两边各有m个玩家,最多允许n个人组队(n <= m),计算所有的组合方式。思路是,先考虑单边阵营的组合,比如5人,可以1+4,2+3,1+1+1+1+1...,用递归的方式可以计算出所有的单边阵营组合。将单边阵营的组合两两配对,就获取到双边阵营的组合。假设单边组合有n个,那么双边组合就会有c(n, 2)个。但是这里面会有重复的组合,还得把重复的组合去掉。


void TestLadderRule(){#define OUTPUT_INFO printf("input max camp amount and max team amount(e.g. 5 5): ");OUTPUT_INFO;int nCampMbr = 0;int nMaxTeamMbr = 0;while (scanf_s("%d %d", &nCampMbr, &nMaxTeamMbr) == 2){LadderRule(nCampMbr, nMaxTeamMbr);OUTPUT_INFO;}}// 参数:阵营人数,最多允许组队人数void LadderRule( int nCampMbr, int nMaxTeamMbr ){if (nCampMbr < 1)return;if (nMaxTeamMbr < 0 || nMaxTeamMbr > nCampMbr)return;// 单阵营规则vector< vector<int> > campRules;// 匹配规则vector<string> matchRules;// 已经使用过的匹配规则set<string> usedRules;// 用于生成单阵营规则int *rule = new int[nCampMbr+1];memset(rule, 0, sizeof(int)*(nCampMbr+1));// 找出单边阵营的所有规则int nTeamMbr = 1;int nSum = 0;bool bUpAmount = false;while (true){if (!nTeamMbr)break;if (nTeamMbr < nMaxTeamMbr){if (bUpAmount){++rule[nTeamMbr];nSum += nTeamMbr;bUpAmount = false;}if (nSum > nCampMbr){nSum -= rule[nTeamMbr] * nTeamMbr;rule[nTeamMbr] = 0;--nTeamMbr;bUpAmount = true;}else{++nTeamMbr;}}else{if ((nCampMbr - nSum) % nMaxTeamMbr == 0){rule[nMaxTeamMbr] = (nCampMbr - nSum) / nMaxTeamMbr;vector<int> tempRule;for (int i = 1; i <= nCampMbr; ++i)tempRule.push_back(rule[i]);campRules.push_back(tempRule);}rule[nMaxTeamMbr] = 0;--nTeamMbr;bUpAmount = true;}}// 将单边阵营的规则两两组合,形成匹配规则for (size_t i = 0; i < campRules.size(); ++i){for (size_t j = i; j < campRules.size(); ++j){// 总的规则char chRule[1025] = { 0 };char *chPos = chRule;int nLength = 1024;for (int k = 0; k < nCampMbr; ++k){sprintf_s(chPos, nLength, "%2d ", campRules[i][k] + campRules[j][k]);chPos += 3;nLength -= 3;}// 剔除重复的匹配规则if (usedRules.count(chRule))continue;usedRules.insert(chRule);sprintf_s(chPos, nLength, "| ");chPos += 2;nLength -= 2;// 左边阵营规则for (int k = 0; k < nCampMbr; ++k){sprintf_s(chPos, nLength, "%2d ", campRules[i][k]);chPos += 3;nLength -= 3;}sprintf_s(chPos, nLength, "| ");chPos += 2;nLength -= 2;// 右边阵营规则for (int k = 0; k < nCampMbr; ++k){sprintf_s(chPos, nLength, "%2d ", campRules[j][k]);chPos += 3;nLength -= 3;}matchRules.push_back(chRule);}}sort(matchRules.begin(), matchRules.end());printf("match rules' amount: %d\n", matchRules.size());for (auto it = matchRules.begin(); it != matchRules.end(); ++it){printf("%s\n", it->c_str());}delete[] rule;}

代码:https://github.com/windpenguin/WindUtilities

0 0
原创粉丝点击