【学习工作赛道】水下曲棍球赛事调度助手 —— 可交互 Demo

【正文】 至少包含以下 4 个部分,可以增加额外的部分(比如自我介绍、经验总结、踩坑复盘等)

0. 先和大家打个招呼吧 :waving_hand:

  • 你是谁: 一名水下曲棍球业余赛事组织者,平时靠 Excel 手工排赛程,每次赛前都要熬好几个通宵,而且赛程公布后,还会被挑战各种安排的“冲突”;

  • 你是怎么用 TRAE 把 Demo 做出来的: 说实话我没什么代码基础,但 TRAE 让我第一次觉得“原来我也可以”。我把脑子里关于赛程编排的规则一条条讲给它听——比如“队伍不能连续打三场”、“裁判不能吹自己队伍的比赛”、“换色背靠背要避免”——它就帮我一步步搭出了这个系统。

    最让我惊喜的是,当系统出现 Cannot access 'slotDur' before initialization 这个 bug 时,我完全看不懂报错含义,但 TRAE 帮我逐行定位了问题——原来是在不同函数中重复声明了同一个变量。它一边帮我修复,一边解释原因,让我这种非技术背景的人也能理解。还有一次,我跟它说“每次生成赛程结果都一样,应该不是唯一解吧”,它分析了整个算法流程后告诉我“当前是 100% 确定性的,因为没有随机扰动”,然后帮我加入了多轮最优机制——现在每次点击生成,系统会在后台跑 5 套方案,自动选平均得分最高的那套。这种感觉就像有一个懂技术的搭档在帮我落地想法,我负责“想”,它负责“实现”。

1. Demo 简介

  • 是什么:一个基于浏览器的水下曲棍球赛事调度系统(Web 应用) ,无需安装,打开即用。

  • 面向谁:水下曲棍球赛事组织者、俱乐部管理人员、业余体育赛事策划人员。

  • 主要功能:

  1. 智能排赛(核心亮点) :确认分组后,系统在后台生成 5 套赛程方案,自动选择各队平均得分最高的那套发布。每次重新生成都会对比上一次赛程,提示“与上次相比,更改了 X 场比赛”。
  2. 手动拖拽分组:支持拖拽队伍在组间移动,可锁定队伍位置(:locked:),避免自动分组时被移动。
  3. 赛程公平性诊断:给每支队伍的赛程打分(满分 100),高亮显示“背靠背”、“换色背靠背”、“连续 3 场”、“裁判/比赛冲突”等不利安排,并给出标准差衡量整体均衡性。
  4. 比分录入与射手榜:支持录入比分和进球者,淘汰赛需录入实际结束时间,系统会自动调整后续比赛时间确保休息充分。

2. Demo 创作思路

  • 灵感来源:源于我在组织业余比赛时的亲身经历——手工排赛程不仅耗时,还经常出现某支队伍被连续安排三场比赛、裁判分身乏术等问题,参赛体验很不好。

  • 想解决的问题:

  1. 赛程编排耗时长、易出错;
  2. 背靠背、换色冲突难以人工发现;
  3. 裁判分配缺乏公平性校验;
  4. 缺乏量化评估赛程合理性的手段。
  • 为什么做这个方向:水下曲棍球是小众运动,市面上没有现成的赛事管理工具。与其抱怨,不如试着用 TRAE 做一个。我判断这个工具的核心难点在于“规则约束的复杂性”,而非界面本身——刚好可以发挥 TRAE 在逻辑梳理和代码生成上的优势。经过多次迭代,现在系统已经能处理:参赛+裁判双重冲突检测、同城队伍同组预警、基于多轮评分的赛程生成。

3. Demo 体验地址(三选一)

  • 交互式可体验的HTML格式文件,请使用Zip格式打包上传到社区;

  • 下载附件 UWH-scheduler.zip,解压后双击 HTML 文件即可在浏览器中直接运行,无需任何配置。

    注:本项目为纯前端应用,所有数据仅在本地浏览器中存储,无需服务器。

4. TRAE 实践过程

  1. 需求描述:向 TRAE 口述水下曲棍球赛事的完整规则(小组赛/淘汰赛时长、裁判规则、换色约束等)。
  2. 架构设计:TRAE 帮助梳理出“队伍管理 → 分组管理(拖拽+锁定) → 赛程生成 → 裁判分配 → 比分录入 → 淘汰赛 → 公平性分析”的完整数据流。
  3. 关键 Bug 修复:在 detectConflicts 和 analyzeSchedule 中,const slotDur 被重复声明导致 TDZ 错误。TRAE 逐行定位并修复,统一使用外层函数级变量。
  4. 功能迭代:从确定性单次生成升级为“后台 5 轮随机生成 → 取平均得分最高”的机制,并加入“与上次相比更改了 X 场比赛”的对比提示。
  5. 界面打磨:让 TRAE 生成可直接运行的 HTML 界面,并逐步调整分组拖拽、弹窗交互等细节。
  • 附开发关键步骤截图(不少于 3 张):3242883963160160:cc35a24628a7c49e1f57eadaf0ccc3e9_6a5741a216af480fb6379759.6a5742670546191e9df751db.6a5742670546191e9df751d9:TRAE Work CN.0.1.36.no_sid.no_ppe.T(2026/7/15 16:18:47)

3242883963160160:751b6173fcfdf99b268d1a2b283984f1_6a5741a216af480fb6379759.6a57847a0546191e9df755fa.6a57847a0546191e9df755f8:TRAE Work CN.0.1.36.no_sid.no_ppe.T(2026/7/15 21:00:42)

3242883963160160:2d295d3f0a69ee577d6344ba07a72155_6a5741a216af480fb6379759.6a5787370546191e9df75673.6a5787370546191e9df75671:TRAE Work CN.0.1.36.no_sid.no_ppe.T(2026/7/15 21:12:23)

3242883963160160:ba8f5a582540a22c9621eadb63fde99d_6a5741a216af480fb6379759.6a577ea00546191e9df7552b.6a577ea00546191e9df75529:TRAE Work CN.0.1.36.no_sid.no_ppe.T(2026/7/15 20:35:44)

5. 踩坑复盘:那些与 TRAE 一起“打怪升级”的时刻

坑点一:变量重复声明引发的“幽灵错误”

在开发中期,系统突然报错 Cannot access 'slotDur' before initialization。作为一个非技术背景的人,看到这种报错完全懵了。我对着代码看了半天,完全没发现哪里有问题。

后来我把报错信息完整贴给 TRAE,它没有直接丢给我一段修复代码就完事,而是一步步帮我分析:先定位到 detectConflicts 和 analyzeSchedule 两个函数,然后发现我在外层已经定义了 const slotDur,但在内层 forEach 回调里又用 const 重新声明了同名变量。由于 JavaScript 的“暂时性死区(TDZ)”机制,内层的声明遮蔽了外层的值,导致访问时还未初始化。

:light_bulb: 收获:我学会了“变量声明要统一,不要重复造轮子”。现在遇到类似报错,我会先检查是否在同一作用域内重复定义了变量。

坑点二:赛程每次生成都一模一样,说好的“随机优化”呢?

原本我以为系统既然考虑了“减少背靠背”,那每次点击“生成赛程”应该会有不同的排列组合。但实际测试时,我发现无论点多少次,结果都完全一样。

我把这个疑惑跟 TRAE 说了:“排赛程这个事,应该不是唯一解吧?” TRAE 分析后告诉我:整个算法流程是 100% 确定性的。虽然在数学上存在大量等价排列空间,但贪心算法永远只走同一条路径,没有引入随机探索。

:wrench: 解决方案:我们联手做了两处升级:

  1. 在配对评分中加入 (Math.random() - 0.5) * 8 的随机扰动,让等价方案有不同选择。

  2. 引入“多轮最优机制”:每次点击生成,系统在后台默默跑 5 套方案,计算各队的平均公平性得分,自动选用得分最高的那套。

:light_bulb: 收获:优化不仅靠规则,还要靠“随机探索 + 择优录取”的策略。现在每次生成都有可能有不同的最优解,而且还能提示我“与上次相比,更改了 X 场比赛”。

坑点三:淘汰赛时间是“死的”,但比赛是“活的”

淘汰赛的时间非常难预估(涉及加时、进球决胜)。最初我固定了半决赛、季军赛、决赛的时间,但实际比赛中,只要半决赛拖延了,后面的季军赛和决赛时间就全乱了。

我和 TRAE 讨论后,做了一个很实用的“动态时间联动”功能:在录入半决赛比分时,同时录入实际结束时间。系统自动计算两场半决赛结束较晚的那个时间,然后以此为基准,自动向后推算出季军赛(保证至少休息 30 分钟)和冠亚军决赛的时间,并实时更新在赛程表上。

:light_bulb: 收获:做赛事系统,不能只盯着“理想情况”,必须预留“意外”的处理机制。系统要能根据现场实际数据动态调整后续安排。

6. 经验总结:我和 TRAE 配合的“心法”

经过这一轮完整的开发,我总结了三条跟 AI 搭档写代码的实战经验:

  1. 把“规则”说成“扣分项”,比说“我想要”更管用:

    • 一开始我说“尽量减少背靠背”,TRAE 给的方案比较模糊。后来我改成“换色背靠背扣 100 分,普通背靠背扣 30 分,连续三场扣 300 分”,系统瞬间就懂得如何权衡取舍了。把目标量化成具体的“损失/得分”,AI 就能精准地按优先级执行。
  2. 不用担心报错,报错是 AI 帮你理解代码的最佳时机:

    • 以前我看到满屏的报错红字就头大。这次我学会了直接把报错堆栈贴给 TRAE,它会像老师一样逐行解释“为什么错”、“哪里错”、“怎么改”。几次下来,我竟然能看懂一些基础的 JavaScript 报错类型(比如 TDZ、重复声明、作用域)了。
  3. 需求要分“硬约束”和“软目标”:

    • 硬约束(如:裁判不能吹自己队的比赛、同城回避)绝对不能破,必须写在最前面。

    • 软目标(如:减少背靠背、均衡裁判工作量)可以交给评分系统去权衡。

    • 把这套思路理清后,TRAE 写出来的代码就很少出现“为了优化 A 而牺牲 B”的极端情况了。

7. 给未来的自己和其他办赛者

这个系统虽然只是一个 Demo,但它承载了我对这项运动的热爱。以前组织比赛,Excel 表格满天飞,赛前焦虑到失眠。现在至少有一个工具雏形,能让我看到“一键排赛”的希望。

如果你也是一名小众运动的组织者,或者你也想试试让 AI 帮你解决工作中的繁琐问题,我的建议是:先别管代码,把你脑子里最痛的那个点,用大白话讲给 TRAE 听。 它能听懂,而且会帮你找到解法。

目前这个版本是一个纯前端 Demo,所有数据都存在浏览器本地,关掉页面就没了。但这只是第一步,我真正想做的,是把它变成一套可部署、可持久化、可回溯的赛事管理系统。

短期规划(1-2 个月内落地):

  1. 云端部署:将后端用轻量框架(如 Node.js + SQLite 或 Supabase)重构,部署到云服务器上。组织者打开网址就能用,不再依赖本地文件。

  2. 赛程持久化存储:所有数据(队伍、分组、赛程、比分、射手榜)存入数据库,关闭浏览器再打开,数据依然在,随时可以继续编辑。

  3. 赛程历史备份:每次生成赛程时自动保存一个“快照版本”,支持回溯查看历史赛程、对比不同版本之间的调整差异。如果现场临时改了赛制,也能追溯“上一版是怎么排的”。

远期愿景(3-6 个月):

  1. 多赛事管理:支持同一个账号创建多个赛事(如“2026 秋季联赛”、“2027 全国邀请赛”),每个赛事独立管理赛程和数据,形成赛事档案库。

  2. 数据导出与分享:支持将完整赛程、积分表、射手榜导出为图片或 PDF,方便在微信群、公众号中分享给参赛队伍。

  3. 赛制模板库:把本次积累的规则配置(小组赛时长、淘汰赛规则、裁判分配策略)沉淀为可复用的“赛事模板”,下次办赛时一键套用,真正做到“一次配置,终身复用”。

为什么这些很重要:

业余赛事最大的痛点不是“排一次赛程难”,而是**“每次办赛都要从零开始”**。如果这个系统只是本地 HTML,那它只能帮到我这一次。但如果它变成了一个云端系统,每一次比赛的组织经验——分组策略、时间预算、裁判调度经验——都会被积累下来,成为下一次办赛的“组织财富”。这才是真正降低办赛门槛、推动小众运动规范化的关键路径。

我相信,好的赛事工具不只是一个排程器,更应该是赛事组织的数字助手和知识库。

希望,未来真的能下水服役!:person_swimming:

UWH-scheduler.html.zip (31.5 KB)

2 个赞

很有创意,是我想象的那种,已投票。麻烦帮帮我给我的作品投一票,互相支持支持吧https://forum.trae.cn/t/topic/96939/15?u=一叶孤舟

2 个赞

v

很有创意 ,已投票。麻烦帮帮我给我的作品投一票,互相支持支持吧

2 个赞

你好!我是集客智库·项目超市的运营。在 Trae 大赛看到你的「【学习工作赛道】水下曲棍球赛事调度助手 —— 可交互 Demo」,特意体验了一下 Demo,完成度很高,交互也很顺滑,非常惊喜!想邀请你的项目入驻我们集客智库·项目超市——这里能帮项目找到合伙人、客户和投资。

大赛的结果只代表一轮比赛的反馈,不代表你项目的真实价值。好项目总会发光,我们希望你的项目能借助集客超市永远在线、持续被关注,最终拿到你想要的资源和投资。

入驻方式:微信小程序搜索「集客智库」注册,在“项目超市”上传项目,提交后告诉我们,我们免费帮你上架推广。整个过程目前完全免费。期待在集客智库看到你的项目!有任何疑问欢迎随时找我~

2 个赞