0

0

JavaScript格斗赛程编排:实现选手轮休间隔的动态算法设计

霞舞

霞舞

发布时间:2025-12-13 12:08:08

|

289人浏览过

|

来源于php中文网

原创

JavaScript格斗赛程编排:实现选手轮休间隔的动态算法设计

本文详细介绍了一种javascript算法,旨在解决格斗赛程编排中确保选手轮休间隔的问题。通过动态维护一个“疲劳选手列表”和“已编排场次索引”,该算法能够根据用户设定的最小轮休场次间隔,智能地为每场比赛分配合适的序号,避免同一选手连续参赛,从而实现公平且符合规则的赛程安排。

赛程编排挑战:确保选手轮休

在竞技体育赛事,尤其是格斗比赛中,确保选手在连续比赛之间有足够的休息时间至关重要。这不仅关系到选手的体能恢复和比赛表现,更是出于对选手健康的保护。一个常见的规则是,同一位选手在参加完一场比赛后,必须间隔一定数量的比赛(例如3-4场)才能再次上场。

传统或简单的赛程编排方法往往难以满足这一复杂约束。例如,如果仅按原始顺序分配比赛场次,很容易出现同一选手在短时间内连续作战的情况,如下面的错误示例所示:

const data = [
  {"id":"1","fighter1":"paul","fighter2":"anna","fightNumber":1},
  {"id":"2","fighter1":"jack","fighter2":"paul","fightNumber":2}, // 错误:paul连续参赛
  {"id":"3","fighter1":"roger","fighter2":"law","fightNumber":3},
  {"id":"4","fighter1":"lee","fighter2":"law","fightNumber":4},
  {"id":"5","fighter1":"law","fighter2":"paul","fightNumber":5}, // 错误:paul在短间隔后再次参赛
  // ...
];

目标是生成一个全新的赛程,其中每位选手的两次比赛之间都满足设定的最小场次间隔。例如,如果间隔为3场,Paul在第1场比赛后,其下一次比赛最早应在第1+3+1=5场。

核心算法设计

为了解决上述问题,我们需要一种动态分配比赛场次的策略。该策略的核心思想是:在确定每一场比赛的序号时,需要实时检查所有参与过近期比赛的选手,确保他们处于“疲劳”状态,不能立即再次参赛。

立即学习Java免费学习笔记(深入)”;

算法主要通过以下几个关键概念实现:

  1. 最小轮休间隔(gapNumber):这是一个可配置的参数,表示选手两次比赛之间至少需要间隔的场次数量。
  2. 疲劳选手列表(tiredFightersList):一个动态维护的列表,记录了最近 gapNumber 场比赛中出场的选手。这些选手在当前场次中被视为“疲劳”,不能再次参赛。
  3. 已编排场次索引(compiledIndexes):一个集合,用于记录原始比赛数据中哪些场次已经被成功编排到新的赛程中,避免重复编排。

算法流程如下:

MyMap AI
MyMap AI

使用AI将想法转化为图表

下载
  1. 初始化: 设置 tiredFightersList 和 compiledIndexes 为空。
  2. 遍历生成新赛程: 算法将从 fightNumber: 0 开始,依次为每一场比赛分配序号。
    • 确定当前疲劳选手: 对于当前的 fightNumber,从 tiredFightersList 的末尾取出最近 gapNumber 场比赛中涉及的所有选手。将这些选手汇总成一个临时的“当前疲劳选手”集合。
    • 寻找可用比赛: 遍历原始的比赛数据 data。对于每一场原始比赛:
      • 检查该比赛是否已被编排(通过 compiledIndexes)。
      • 检查该比赛的两位选手是否都在“当前疲劳选手”集合中。
      • 如果该比赛尚未被编排,且其两位选手均不在“当前疲劳选手”集合中,则认为这是一场“可用比赛”。
    • 编排比赛: 找到第一场“可用比赛”后,将其分配给当前的 fightNumber。
    • 更新状态:
      • 将该场比赛的两位选手添加到 tiredFightersList 的当前位置(对应当前的 fightNumber)。
      • 将该比赛在原始数据中的索引添加到 compiledIndexes。
    • 处理无可用比赛情况: 如果遍历完所有原始比赛仍未找到“可用比赛”,则表示当前 gapNumber 设定下,数据不足以填满所有场次。此时,可以为该 fightNumber 创建一个空比赛记录(或仅保留序号),表示该场次无法安排。

代码实现

以下是基于JavaScript的实现代码,它结合了HTML界面,允许用户动态选择轮休间隔。

HTML 用户界面







请注意:间隔越大,可能导致无足够选手可用,部分场次可能为空。

JavaScript 核心逻辑

const data = [
  { id: "1", fighter1: "paul", fighter2: "anna", fightNumber: null },
  { id: "2", fighter1: "jack", fighter2: "paul", fightNumber: null },
  { id: "3", fighter1: "roger", fighter2: "law", fightNumber: null },
  { id: "4", fighter1: "lee", fighter2: "law", fightNumber: null },
  { id: "5", fighter1: "law", fighter2: "paul", fightNumber: null },
  { id: "6", fighter1: "roger", fighter2: "anna", fightNumber: null },
  { id: "7", fighter1: "lee", fighter2: "jack", fightNumber: null },
  { id: "8", fighter1: "roger", fighter2: "anna", fightNumber: null },
  { id: "9", fighter1: "lee", fighter2: "jack", fightNumber: null },
];

function calculatreFight() {
  // 获取用户设定的轮休间隔
  const gapNumber = parseInt(document.getElementById("gapNumberInput").value);

  // 存储每场比赛的选手,用于判断后续比赛的疲劳状态
  const tiredFightersList = []; 
  // 存储已编排的原始比赛的索引,避免重复编排
  const compiledIndexes = []; 

  // 使用 map 遍历生成新的赛程数组
  const fights = data.map((element, index) => {    
    // 从 tiredFightersList 中获取最近 gapNumber 场比赛的选手
    // slice(-gapNumber) 获取数组末尾的 gapNumber 个元素
    // reduce 将这些元素(每场比赛的选手数组)扁平化成一个包含所有疲劳选手的数组
    const tiredFighters = tiredFightersList.slice(-gapNumber).reduce((prev, curr) => {
      if (curr) { // 确保 curr 不是 undefined (处理无可用比赛的情况)
        curr.map(fighter => !prev.includes(fighter) ? prev.push(fighter) : null)
      }
      return prev;
    }, []);

    let searchIndex = 0; // 从原始数据开头开始搜索
    // 循环查找符合条件的比赛:
    // 1. 比赛的 fighter1 或 fighter2 不在 tiredFighters 中
    // 2. 该比赛的原始索引尚未被编排 (compiledIndexes)
    while (tiredFighters.includes(data[searchIndex]?.fighter1) ||
           tiredFighters.includes(data[searchIndex]?.fighter2) ||
           compiledIndexes.includes(searchIndex)) {
      searchIndex += 1;
      // 如果搜索到数据末尾,说明没有可用的比赛了
      if (searchIndex >= data.length) break;
    }

    // 记录当前场次(index)的选手,用于后续的疲劳判断
    // 如果 searchIndex 超出范围,data[searchIndex] 为 undefined,此时记录的选手也为 undefined
    tiredFightersList[index] = [data[searchIndex]?.fighter1, data[searchIndex]?.fighter2];
    // 记录当前编排的原始比赛索引
    compiledIndexes.push(searchIndex);

    // 返回新的比赛对象,包含原始数据和新的 fightNumber
    // 如果 data[searchIndex] 为 undefined,则只返回 { fightNumber: index }
    return {
      ...data[searchIndex], // 展开原始比赛数据
      fightNumber: index + 1 // fightNumber 从 1 开始
    };
  });

  console.log(fights);
}

运行与验证

通过上述HTML和JavaScript代码,用户可以选择不同的 gapNumber 来测试赛程编排效果。例如,当选择 gapNumber 为3时,预期的输出应类似于:

[
  { id: "1", fighter1: "paul", fighter2: "anna", fightNumber: 1 },
  { id: "3", fighter1: "roger", fighter2: "law", fightNumber: 2 },
  { id: "7", fighter1: "lee", fighter2: "jack", fightNumber: 3 },
  { id: "2", fighter1: "jack", fighter2: "paul", fightNumber: 4 }, // paul 间隔了 2 场 (2,3) 再次出场
  { id: "6", fighter1: "roger", fighter2: "anna", fightNumber: 5 },
  { id: "4", fighter1: "lee", fighter2: "law", fightNumber: 6 },
  { id: "5", fighter1: "law", fighter2: "paul", fightNumber: 7 }, // paul 间隔了 2 场 (5,6) 再次出场
  { id: "8", fighter1: "roger", fighter2: "anna", fightNumber: 8 },
  { id: "9", fighter1: "lee", fighter2: "jack", fightNumber: 9 }
]

在上述示例中,paul 在 fightNumber: 1 之后,于 fightNumber: 4 再次出场,间隔了 fightNumber: 2 和 fightNumber: 3 两场比赛,符合 gapNumber = 3 的要求(即至少间隔 gapNumber - 1 场)。

注意事项与总结

  1. 数据充足性: 当 gapNumber 设置得较大,或者原始比赛数据中的选手种类和数量有限时,算法可能会遇到无法找到符合条件的比赛的情况。此时,data[searchIndex] 将为 undefined,生成的比赛对象可能只包含 fightNumber 属性,而没有选手信息。这是预期行为,表示该场次无法安排。
  2. 算法效率: 内部的 while 循环在最坏情况下可能遍历整个 data 数组,而 map 函数也遍历 data 数组。因此,对于非常庞大的数据集,算法的性能可能需要进一步优化。但在大多数实际赛程编排场景中,比赛数量通常在可接受范围内。
  3. 公平性考量: 当前算法是按照原始 data 数组的顺序寻找第一个符合条件的比赛。如果需要更复杂的公平性(例如,避免某些选手总是优先出场),可能需要调整 while 循环中的搜索策略,例如引入随机性或更复杂的优先级排序。
  4. fightNumber 的起始值: 代码中 fightNumber: index + 1 是为了让比赛序号从1开始,如果需要从0开始,可以直接使用 index。

通过这种动态规划和实时检查的算法,我们能够有效地解决格斗赛程编排中选手轮休间隔的复杂约束,确保赛事的公平性和选手的健康。这种方法具有良好的可配置性,可以根据具体规则调整 gapNumber,以适应不同的赛事需求。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

97

2023.09.25

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

75

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

36

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

61

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

42

2025.11.27

undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

5398

2023.07.31

网页undefined是什么意思
网页undefined是什么意思

网页undefined是指页面出现了未知错误的意思,提示undefined一般是在开发网站的时候定义不正确或是转换不正确,或是找不到定义才会提示undefined未定义这个错误。想了解更多的相关内容,可以阅读本专题下面的文章。

3099

2024.08.14

网页undefined啥意思
网页undefined啥意思

本专题整合了undefined相关内容,阅读下面的文章了解更多详细内容。后续继续更新。

683

2025.12.25

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

54

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.4万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.6万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号