在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

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

  1. 编写Java程序,创建Dota游戏中的防御塔类,通过两个坐属性显示防御塔所在的位置

    返回本章节 返回作业目录 需求说明: 创建Dota游戏中的防御塔类 通过两个坐属性显示防御塔所在的位置 实现思路: 创建防御塔(TowerDefense)类 在该类中定义了两个属性,分别是int类型横 ...

  2. 编写Java程序,创建Dota游戏中的兵营类,兵营类有一个类成员变量count、一个实例变量name和另一个实例变量selfCount。

    返回本章节 返回作业目录 需求说明: 创建Dota游戏中的兵营类 兵营类有一个类成员变量count.一个实例变量name和另一个实例变量selfCount. count表示的是兵营已经创建士兵的总数: ...

  3. DOTA游戏相关的文章

    DOTA里面到底有几号位?各代表什么? DOTA新手进阶之S.SHIFT及M键的使用 Dota开局 对线方法技巧总结 dota补刀的技巧 dota需要注意的小细节 dota前期如何对线 DotA 命令 ...

  4. LeetCode 22 Generate Parentheses(找到所有匹配的括号组合)

    题目链接 : https://leetcode.com/problems/generate-parentheses/?tab=Description   给一个整数n,找到所有合法的 () pairs ...

  5. 浅谈公平组合游戏IGC

    浅谈公平组合游戏IGC IGC简介 一个游戏满足以下条件时被叫做IGC游戏 (前面三个字是自己YY的,不必在意) 竞争性:两名玩家交替行动. 公平性:游戏进程的任意时刻,可以执行的操作和操作者本人无关 ...

  6. 【博弈论】组合游戏及SG函数浅析

    目录 预备知识 普通的Nim游戏 SG函数 预备知识 公平组合游戏(ICG) 若一个游戏满足: 由两名玩家交替行动: 游戏中任意时刻,合法操作集合只取决于这个局面本身: 若轮到某位选手时,若该选手无合 ...

  7. C#简单游戏外挂制作(以Warcraft Ⅲ为例)

    网上有很多外挂制作的教程,大多是讲针对大型网络游戏的,主要包含一些抓包.反汇编.C++的知识综合.事实也如此,常见的外挂都是使用VC++写的,从来没有过C#或者其他.NET语言编写的外挂. 作为微软. ...

  8. 淘宝SKU组合查询算法实现

    淘宝SKU组合查询算法实现 2015-11-14 16:18 1140人阅读 评论(0) 收藏 举报  分类: JavaScript(14)    目录(?)[+]   前端有多少事情可以做,能做到多 ...

  9. 游戏AI之感知(1)

    目录 感知 视觉感知 听力感知 其它感知 实现 感知 视觉感知 视觉感知是一种常见的感知. 在许多即时战略游戏或者类DOTA游戏里,一个单位的视觉感知往往是圆形范围的. 当然在其他大部分俯视角游戏里, ...

随机推荐

  1. jmeter使用中的问题

    1.响应乱码 step1:指定请求节点下,新建后置控制器"BeanShell PostProcessor" step2:其脚本框中输入以下代码,保存 //获取响应代码Unicode ...

  2. 精品工具【音乐下载器(可下载VIP音乐)】

    工具信息 更新时间:2020年5月26日00点07分更新内容:1. 增加快捷键2. 细分下载列表清除功能一款可以下载付费音乐的音乐下载器 下载链接:https://nitian1207.lanzous ...

  3. 第 3篇 Scrum 冲刺博客

    一.站立式会议 1.站立式会议照片 2.昨天已完成的工作 登录窗口的构建 3.今天计划完成的工作 ①帮助不会的同学连接数据库 ②登录识别模块 4.工作中遇到的困难 ①出现一些同学使用了不同种类的数据库 ...

  4. java视频格式转换

    项目中需要对各种视频格式转码为mp4格式,试了好多办法,最后使用ffmpeg 工具完美转码,ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等) 链接 ...

  5. watch监听对象的属性

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. Java程序执行过程及内存机制

    本讲将介绍Java代码是如何一步步运行起来的,其中涉及的编译器,类加载器,字节码校验器,解释器和JIT编译器在整个过程中是发挥着怎样的作用.此外还会介绍Java程序所占用的内存是被如何管理的:堆.栈和 ...

  7. 关于大视频video播放的问题以及解决方案(m3u8的播放)

    在HTML5里,提供了<video>标签,可以直接播放视频,video的使用很简单: <video width="320" height="240&qu ...

  8. .net core WebAPI性能监控-MiniProfiler与Swagger集成

    ------------恢复内容开始------------ 安装Nuget Install-Package MiniProfiler.AspNetCore.Mvc Install-Package M ...

  9. 05-flask基础补充

    flask数据获取 request.args - 请求参数 request.form - 请求参数 request.files - 请求文件 request.cookies - 请求cookies r ...

  10. Flink读取resource资源文件

    public static ParameterTool getParameterTool(String[] args){ try { return ParameterTool .fromPropert ...