Dota游戏匹配的所有组合

在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

时间: 2024-10-24 08:01:25

Dota游戏匹配的所有组合的相关文章

Dota 游戏中的攻击与伤害分析

摘要:在上一篇文章中分析了物理攻击和护甲的攻防分析,但是忽略了英雄对战里面一个很重要的角色--技能攻击.实际上,除了少数后期英雄可以直接靠平砍(即物理攻击)杀人外,大部分英雄尤其是智力英雄还是要靠技能收割人头的.技能的使用也是评价一个玩家水平高低的主要指标.在本文中,我们就技能进行分析. 关键字:技能攻击 魔抗 护甲 伤害类型 攻击类型 Dota中的攻击类型共有普通攻击.穿刺攻击.攻城攻击.混乱攻击.英雄攻击和法术攻击6种.除了法术攻击,其他的统称为物理攻击.然而我们只考虑英雄的话,只有英雄攻击

各种类dota游戏的发展史

一般来说,Dota游戏的进化分几步. 1.首先感谢暴雪强大的魔兽争霸编辑器,提供了各路大神的舞台,这大概在2003年左右 2.出现了防守地图,选择英雄装备,对抗电脑.比如守卫剑阁之类的地图. 3.有人想了,既然可以对抗电脑,为啥不能人对人呢?于是这段时间的代表地图有大海战. 4.出现了dota 5.出现了LOL,dota2,风暴英雄等.2014年

HDU 4315(NIM游戏及其变种,组合游戏相关学习

题目:山上有n个人,每个人给出距离山顶的距离,给出其中一个人为king,每次能挑选一个人向上移动,不能越过其他人,最后将king移动到山顶者获胜.问获胜者. 思路:转化为NIM游戏. 简记: NIM游戏:有n堆石子,每次可以选择一堆拿走任意数量的石子,不能拿石子的一方失败. NIM游戏的必败态为所有堆的石子数目异或值为0的情况,那是因为,如果异或值不为0,设其为x,x的二进制表示中的最左边的一位1必然存在一堆(设为z)与之对应,将这一堆取成y=x^z,那么得到的状态为异或值为0(必败态),而必败

unity游戏之羊刀与Pendragon复盘:DotA做对了什么

[狗刨学习网专稿,转载请注明出处] 狗刨学习网报道/电竞和MOBA已经成为近几年业内非常火的名词,据Riot Games此前公布的数据显示,2014年<英雄联盟>S4韩国总决赛局巅峰同时观看人数突破1120万人,而据SuperData在2014年10月份透露,<英雄联盟>2014年收入将突破11亿美元.毫无疑问,<英雄联盟>和电竞以及MOBA都获得了世界级的成功. 不过,谈到这一切,相信所有人都知道DotA地图对此的贡献,可以说,正是由于DotA的奠基,才有了全球电竞如

[原博客] 组合游戏学习

阅读了<由感性认识到理性认识——透析一类搏弈游戏的解答过程>.<解析一类组合游戏>.<组合游戏略述——浅谈SG游戏的若干拓展及变形>这三篇论文,对组合游戏以及SG函数有了更深的理解.这篇文章摘下了这三篇论文的部分重要内容,以及部分我对组合游戏的理解. 一些名词与约定: 游戏:这里的游戏指的并不是平时玩的那些游戏(Dota2啥的),而是只一些如Nim取石子之类的“益智”组合游戏.并且,我们关注的不是游戏好不好玩,而是游戏有没有必胜策略.下文详细介绍. 状态:用一些数字来表

博弈论题目总结(二)——SG组合游戏及变形

SG函数 为了更一般化博弈问题,我们引入SG函数 SG函数有如下性质: 1.如果某个状态SG函数值为0,则它后继的每个状态SG函数值都不为0 2.如果某个状态SG函数值不为0,则它至少存在一个后继的状态SG函数值为0 如果某个局面SG函数值为0,则该局面先手必败 放到有向图中,该有向图的核就是SG值为0的点构成的集合 游戏的和 游戏的和的SG函数值=所有子游戏SG函数值的异或和Xor 如果所有子游戏都进行完毕,那么Xor=0,必败 如果某个状态的SG函数值为0,那么后手一定可以做出一种动作,保持

量产化游戏

 量产化游戏 ----- 程序员的殿堂之路 -----  作者: 欧阳江平 QQ:75260062 前言: 程序猿 关于两个1的问题? 两个1放在一起,大家都会说这是"两个"1,但如果把一个1放到眼睛前方,一个1放到脑袋后面, 大家会说前面一个1,后面一个1.我们发现,说法不一样了,应为理解的角度不一样了. 概念最终的定义也不一样了. ok,一切都从这么细节的地方出发了. 第一部分: 问题的提出 1. 像工厂一样的做游戏?(都喜欢做的事,扒皮,效果却不尽如人意)? 2. 能量产化到什么

Dota的成名之路

Dota,影响我最多的一款游戏,也是伴随我时间最长的一款游戏. 从大二开始接触dota,那时候dota在国内开始流行.有挤掉三国无双.3C澄海之势.到现在已近八年了,不得不说是dota的一个老菜鸟. 对dota是又爱又恨,恨是怪他占用了我太多的时光,本来我可以成为下一个马云的,现在这个时间被无限期的拉长:爱是因为这就是我过往的生活,不能改变,我在dota中寻找快乐,打发无聊的时光. 现在网吧里面除了玩dota.dota2的,就只剩下LOL了,玩其他游戏的玩家加起来都没这几款游戏多.可见dota之

40款免费开源游戏

开源游戏最大的特点的免费,所以我们玩的开源游戏都是正版游戏,另外开源游戏对外开 放源代码,任何有兴趣的人可以对其改进,其游戏的可玩性,易玩性都会逐步提高,也可以说开源游戏融合了众人智慧,是网友分享的成果.这里搜集了 40款免费开源游戏 ,全部是 WINDOWS版本,喜欢玩游戏的朋友不要错过. 冒险—角色扮演游戏 1.Daimonin 这是一块免费的奇幻网游,总体看游戏在2D MMORPG游戏圈以及低配置游戏圈内是一个不错的选择.玩家在游戏中可体现到不同的游戏经历和开发商独特的游戏设计理念.游戏中