找回密码
 点一下
查看: 496|回复: 4

[已解决 附方法] 排列组合 偶数个玩家同时单挑若干回合 每回合各个玩家都要有不同对手

[复制链接]
发表于 2015-9-4 19:19:37 | 显示全部楼层 |阅读模式
本帖最后由 zt0616 于 2015-9-6 08:43 编辑

这里有p个玩家(我已经通过取模设定了p为偶数),这些玩家每个玩家都要和不同对手单挑1次,每个由2人构成的单挑小队同时进行。所有小队单挑结束后开始下回合重新给每个玩家选新对手,直到所有玩家都见过1次面。因为不能和自己单挑,所以总回合数r=p-1。目标是把这些玩家按照这样方式排列进整数数组c[p][r],地图初始化就先设好以便后面触发器调用。下面举个栗子

以p=4为例:
每2个玩家组成一个“单挑小队”,因此有2个小队同时决斗,比如
c[1][r], c[2][r](队1)
决斗的同时
c[3][r], c[4][r](队2)
也在决斗。决斗完后开始第二回合
r++1
换对手再打,比如
c[1][2], c[3][2](队1)
c[2][2], c[4][2](队2)
各个玩家都同时和不同玩家决斗一次,最后一种组合是
c[1][3], c[4][3](队1)
c[2][3], c[3][3](队2)
4个玩家经过3回合决斗,至此每个玩家互相都打过照面了

如果只有4个玩家,我直接手动设变量来得到c。但因为玩家可能有14个,手写脚本显然很不方便,得用上算法
我想了很久也没想出好方法,尝试过 为每个p和每个r 永久重复(随机数+条件 then 设变量c[p][r]+break)来设,开始都没问题,但最后一到两组合老是算不出来(时间过长)。这个问题彻底治好了我的不服会不会编辑器数学功能不足呢?希望大大能帮助我一下,提供个详细思路


发表于 2015-9-5 19:59:26 | 显示全部楼层
本帖最后由 lanyuetingfeng 于 2015-9-5 20:04 编辑

你这个就是单循环赛制了。
简单的单循环赛制排法:
设最大玩家号为Pmax
将1至Pmax/2按正序排列到第1个数组中,在将Pmax/2+1至Pmax倒序排入第2个数组中,然后按同下标元素一一配对,成为第一轮。如:
数组1   数组2
1             6
2             5
3             4
按同下标元素配对,则第一路对阵表为(1,6),(2,5),(3,4)。

将1位置保持不动,其余个元素按逆时针移动一位。即:将第2个数组中第1个元素移入第1个数组中第2个位置,第1个数组自第2元素起依次下移一位,最后一个元素移入第2数组中的最后一位,第二数组中的其余元素依次上移一位。变成下面的情况:
数组1   数组2
1             5
6             4
2             3
再次按同下标配对,则第二轮对阵表为:(1,5),(6,4),(2,3)。
重复上一个步骤,直至轮次=Pmax-1为止。

不过这个算法的问题在于,对阵玩家必须从玩家1开始,并且各玩家是连续的,不能出现中间有空位的现象。为了解决这个问题,最好事先将对阵玩家依次或随机连续写入一个数组,用数组下标来代替玩家号。同时,如果采用随机写入的方式,每场游戏的配对都不是固定的,更增加了游戏性。

点评

多谢多谢,原来那叫循环赛啊,涨姿势了,查了下wiki我还可以考虑考虑双循环、瑞士制。就目前的单循环我按照你说的思路成功做出来啦,所有活动玩家及可能的轮空ai玩家都已经带上下标了。下面秀秀成果 7个玩家时的  详情 回复 发表于 2015-9-6 08:14
回复

使用道具 举报

 楼主| 发表于 2015-9-6 08:14:37 | 显示全部楼层
本帖最后由 zt0616 于 2015-9-6 10:34 编辑
lanyuetingfeng 发表于 2015-9-5 19:59
你这个就是单循环赛制了。
简单的单循环赛制排法:
设最大玩家号为Pmax

多谢多谢,原来那叫循环赛啊,涨姿势了,查了下wiki我还可以考虑双循环、瑞士制。就目前的单循环我按照你说的思路成功做出来啦。所有玩家都已经带上下标了,以后直接放到Schedule提供的场地里。下面秀秀成果

7个玩家时的场地分配(不随机)
r1.JPG
r2.JPG


9个玩家时的场地分配(随机round)
r9.JPG
r92.JPG
9个玩家时的场地分配(随机round和team)
r93.JPG


下面附上触发器主要部分方便有需要的同学:

----全局变量
--------intCountPlayer = 0 <整数> //玩家总数,为活动玩家数加可能的落空AI,通过活动玩家数除以2取余判断是否加1个落空AI
--------intCountGroup = 0 <整数> //回合总数,为玩家总数减1
--------intRandomRound = 0 <整数[16]> //打乱回合顺序。同理小队也可以打乱顺序,原理和RandomRound一样,这里就不提了
--------intScheduleAllPlayAll = 0 <整数[16][16]> //赛程表,整个的目标

InitRandomRound //打乱回合顺序
----事件
----局部变量
--------intRoundCounter = 0 <整数>
--------boolRepeat = 假 <布尔>
--------intRandomRoundCounter = 0 <整数>
--------intRandom = 0 <整数[16]>
----条件
----动作
--------常规 -为从1到intCountRound的每个包含增量1的整数intRandomRoundCounter,执行(动作)
------------动作
----------------常规 -永久重复(动作)
--------------------动作
------------------------变量 -设置intRandom[intRandomRoundCounter] = (在1和intCountRound之间的随机整数)
------------------------变量 -设置boolRepeat = 假
------------------------常规 -为从1到intCountRound的每个包含增量1的整数intRoundCounter,执行(动作)
----------------------------动作
--------------------------------常规 -If (条件) then do (动作) else do (动作)
------------------------------------If
----------------------------------------intRandom[intRandomRoundCounter]==intRandomRound[intRoundCounter]
------------------------------------Then
----------------------------------------变量 -设置boolRepeat = 真
------------------------------------否则
------------------------常规 -If (条件) then do (动作) else do (动作)
----------------------------If
--------------------------------boolRepeat==假
----------------------------Then
--------------------------------变量 -设置intRandomRound[intRandomRoundCounter] = intRandom[intRandomRoundCounter]
--------------------------------常规 -Break
----------------------------否则


InitScheduleAllPlayAll //排赛程表
----事件
----局部变量
--------intRoundCounter = 0 <整数>
--------intPlayerCounter = 0 <整数>
--------intCycle = 0 <整数>
--------intOpponent = 0 <整数[16]>
--------intOpponentCounter = 0 <整数>
--------intGroupCounter = 0 <整数>
----条件
----动作
--------变量 -设置intCycle = 1
--------常规 -为从1到intCountRound的每个包含增量1的整数intRoundCounter,执行(动作)
------------动作
----------------常规 -为从1到(/(intCountPlayer,2))的每个包含增量1的整数intPlayerCounter,执行(动作)
--------------------动作
------------------------常规 -If (条件) then do (动作) else do (动作)
----------------------------If
--------------------------------intPlayerCounter==1
----------------------------Then
--------------------------------变量 -设置intOpponent[intPlayerCounter] = 1
----------------------------否则
--------------------------------数学 -从2到intCountPlayer循环intCycle
--------------------------------变量 -设置intOpponent[intPlayerCounter] = intCycle
----------------常规 -为从intCountPlayer到(+((/(intCountPlayer,2)),1))的每个包含增量-1的整数intPlayerCounter,执行(动作)
--------------------动作
------------------------数学 -从2到intCountPlayer循环intCycle
------------------------变量 -设置intOpponent[intPlayerCounter] = intCycle
----------------变量 -设置intGroupCounter = 0
----------------常规 -为从1到intCountPlayer的每个包含增量1的整数intPlayerCounter,执行(动作)
--------------------动作
------------------------常规 -If (条件) then do (动作) else do (动作)
----------------------------If
--------------------------------(intPlayerCounter mod 2)==1
----------------------------Then
--------------------------------变量 -修改intGroupCounter:+1
--------------------------------变量 -设置intScheduleAllPlayAll[intPlayerCounter][intRandomRound[intRoundCounter]] = intOpponent[intGroupCounter]
----------------------------否则
--------------------------------变量 -设置intScheduleAllPlayAll[intPlayerCounter][intRandomRound[intRoundCounter]] = intOpponent[(+(intGroupCounter,(/(intCountPlayer,2))))]
----------------变量 -修改intCycle:-1








点评

楼主,我没太仔细考究过算法如何,但明显你7位玩家扩展成8的输出就有问题,有场次重复和缺失。貌似都和3号玩家有关,大概是边界控制出错。  详情 回复 发表于 2015-9-15 10:49
回复

使用道具 举报

发表于 2015-9-15 10:49:07 | 显示全部楼层
zt0616 发表于 2015-9-6 08:14
多谢多谢,原来那叫循环赛啊,涨姿势了,查了下wiki我还可以考虑双循环、瑞士制。就目前的单循环我按照你 ...

楼主,我没太仔细考究过算法如何,但明显你7位玩家扩展成8的输出就有问题,有场次重复和缺失。貌似都和3号玩家有关,大概是边界控制出错。

点评

你看的很仔细,多谢提醒 我后来也发现了,确实是你说的扩展玩家一个变量疏忽,后来补发9玩家分配图前算法那个错误改过来了 再次感谢  详情 回复 发表于 2015-9-15 13:52
回复

使用道具 举报

 楼主| 发表于 2015-9-15 13:52:23 | 显示全部楼层
本帖最后由 zt0616 于 2015-9-15 13:53 编辑
ff1407 发表于 2015-9-15 10:49
楼主,我没太仔细考究过算法如何,但明显你7位玩家扩展成8的输出就有问题,有场次重复和缺失。貌似都和3 ...

你看的很仔细,多谢提醒
我后来也发现了,确实是你说的扩展玩家一个变量疏忽,后来补发9玩家分配图前那个错误已经改过来了
再次感谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-12-24 21:29 , Processed in 0.808654 second(s), 32 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表