战舰游戏!
早在2003年(当时我17岁),我参加了一个战舰AI编程竞赛。即使我输掉了那场比赛,我仍然从中获得了许多乐趣,也学到了很多东西。
现在,我想重新启动这场比赛,寻找最佳的战舰AI。
获胜者将获得+450声望! 比赛将于2009年11月17日开始。17日零时之后提交或编辑的参赛作品将不被接受。(中部标准时间)
请尽早提交您的参赛作品,以免错过机会!
为了保持客观性,请遵循比赛的精神。
游戏规则:
- 游戏在10×10的网格上进行。
- 每位参赛者将在其网格上放置5艘船(长度分别为2、3、3、4、5)。
- 船只不得重叠,但可以相邻。
- 然后,参赛者轮流向对手发射单发炮弹。
- 游戏的变体允许每轮齐射发射多发炮弹,每艘幸存的船只一发。
- 对手将通知参赛者该炮弹是否击沉、击中或未击中。
- 当任何一方的所有船只都被击沉时,游戏结束。
比赛规则:
- 比赛的目的是找到最佳的战舰算法。
- 任何被认为违反比赛精神的行为都将被取消资格。
- 干扰对手违反比赛精神。
- 在以下限制下可以使用多线程:
- 在非你的回合时,最多只能运行一个线程。(但是,任意数量的线程可以处于“暂停”状态)。
- 任何线程都不能以“Normal”以外的优先级运行。
- 鉴于以上两个限制,您将保证在您的回合至少拥有3个专用的CPU核心。
- 每个参赛者在主线程上每局游戏最多分配1秒的CPU时间。
- 耗尽时间会导致输掉当前游戏。
- 任何未处理的异常将导致输掉当前游戏。
- 允许网络访问和磁盘访问,但您可能会发现时间限制相当严格。但是,添加了一些设置和拆卸方法来缓解时间压力。
- 代码应作为答案发布在Stack Overflow上,或者,如果太大,则链接到代码。
- 一个条目的最大总大小(未压缩)为1 MB。
- 正式来说,.Net 2.0 / 3.5是唯一的需求框架。
- 您的条目必须实现IBattleshipOpponent接口。
评分:
- 101局游戏中,取最佳的51局为比赛的胜者。
- 所有参赛者将以循环赛的方式相互比赛。
- 排名前一半的参赛者将参加双败淘汰赛以确定获胜者。(实际上,是大于或等于一半的最小2的幂。)
- 我将使用TournamentApi框架进行比赛。
- 结果将发布在此处。
- 如果您提交多个条目,则只有得分最高的条目才有资格参加双败淘汰赛。
祝你好运!玩得开心!
编辑 1:
感谢@Freed,他发现了Ship.IsValid
函数中的错误。它已被修复。请下载框架的更新版本。
编辑 2:
由于大家对将统计信息持久化到磁盘等功能非常感兴趣,我添加了一些非定时的设置和拆卸事件,这些事件应该提供所需的功能。这是一个半破坏性更改。也就是说:该接口已修改为添加函数,但不需要任何主体。请下载框架的更新版本。
编辑 3:
Bug修复1:GameWon
和GameLost
仅在超时的情况下被调用。
Bug修复2:如果引擎每局游戏都超时,比赛将永远不会结束。
请下载框架的更新版本。
编辑 4:
比赛结果:
回答:
我赞成每场比赛进行更多场游戏。进行50场游戏只是抛硬币。我需要进行1000场游戏才能在测试算法之间获得任何合理的区分。
策略:
-
跟踪所有命中数>0的船只的所有可能位置。该列表永远不会超过〜30K,因此可以精确地保存,不像所有船只的所有可能位置的列表(非常大)。
-
GetShot算法分为两部分,一部分生成随机射击,另一部分尝试完成击沉已经击中的船只。如果存在一个可能的位置(来自上面的列表),其中所有被击中的船只都被击沉,我们就进行随机射击。否则,我们尝试通过选择一个射击位置来完成击沉一艘船,该位置消除了大多数可能的位置(加权)。
-
对于随机射击,根据未击沉的船只重叠该位置的可能性计算最佳射击位置。
-
自适应算法,将船只放置在对手在统计上不太可能射击的位置。
-
自适应算法,倾向于射击对手在统计上更可能放置船只的位置。
-
将船只放置为大部分不互相接触。