java输战舰_什么是最好的战舰AI?

战舰!

早在2003年(当时我17岁),我就参加了战舰AI编码比赛。 即使我输掉了那场比赛,我也玩得很开心并从中学到了很多东西。

现在,我想在这场比赛中复活,寻找最好的战舰AI。

获奖者将获得+450声望! 比赛将于2009年11月17日开始 。 不接受17日零时以外的参赛作品或编辑。 (中央标准时间)提前提交您的参赛作品,这样您就不会错过机会!

为了保持这个目标 ,请遵循竞争精神。

游戏规则:

游戏将在10x10网格上进行。

每个参赛者将5艘船(长度分别为2,3,3,4,5)放置在其网格上。

没有船只可能重叠,但它们可能相邻。

然后竞争对手轮流对对手开枪。

游戏的一个变种允许每次击球射击多次射击,每个幸存的船只射击一次。

如果击球下沉,命中或未命中,对手将通知对手。

当任何一个玩家的所有船只都沉没时,游戏结束。

比赛规则:

竞争的精神是找到最好的战舰算法。

任何被视为违反竞争精神的东西都将被取消资格。

干扰对手是违背竞争精神的。

多线程可以在以下限制下使用:

在轮到你的时候,不超过一个线程可能正在运行。 (但是,任意数量的线程可能处于“暂停”状态)。

没有线程可以以“正常”以外的优先级运行。

鉴于上述两个限制,您将在转弯期间保证至少3个专用CPU核心。

每个游戏的CPU时间限制为1秒,分配给主线程上的每个竞争对手。

时间不多会导致当前游戏失败。

任何未处理的异常都将导致失去当前的游戏。

允许网络访问和磁盘访问,但您可能会发现时间限制相当令人望而却步。 然而,为了减轻时间紧张,增加了一些设置和拆卸方法。

代码应作为答案发布在堆栈溢出上,或者如果太大则链接。

条目的最大总大小(未压缩)为1 MB。

官方说来,.Net 2.0 / 3.5是唯一的框架要求。

您的条目必须实现IBattleshipOpponent接口。

评分:

101场比赛中最好的51场比赛是一场比赛的胜利者。

所有竞争对手都将相互配对,循环风格。

然后,最好的一半竞争者将参加双重淘汰赛以确定获胜者。 (实际上,2的最小功率大于或等于一半。)

结果将在此处公布。

如果您提交多个条目,则只有您的得分最高的条目才有资格获得双重条目。

祝好运! 玩得开心!

编辑1:

感谢Freed ,他在Ship.IsValid函数中发现了一个错误。 它已被修复。 请下载该框架的更新版本。

编辑2:

由于人们对将统计信息持久存储到磁盘等方面非常感兴趣,因此我添加了一些应该提供所需功能的非定时设置和拆除事件。 这是一个半破坏性的变化 。 也就是说:界面已经过修改以添加功能,但不需要它们。 请下载该框架的更新版本。

编辑3:

错误修复1: GameWon和GameLost只是在超时的情况下被调用。

错误修复2:如果引擎在每场比赛中超时,则比赛永远不会结束。

请下载该框架的更新版本。

编辑4:

比赛结果:

5R5Bm.png

#1楼

这是我的参赛作品! (最天真的解决方案)

“随机1.1”

namespace Battleship

{

using System;

using System.Collections.ObjectModel;

using System.Drawing;

public class RandomOpponent : IBattleshipOpponent

{

public string Name { get { return "Random"; } }

public Version Version { get { return this.version; } }

Random rand = new Random();

Version version = new Version(1, 1);

Size gameSize;

public void NewGame(Size size, TimeSpan timeSpan)

{

this.gameSize = size;

}

public void PlaceShips(ReadOnlyCollection ships)

{

foreach (Ship s in ships)

{

s.Place(

new Point(

rand.Next(this.gameSize.Width),

rand.Next(this.gameSize.Height)),

(ShipOrientation)rand.Next(2));

}

}

public Point GetShot()

{

return new Point(

rand.Next(this.gameSize.Width),

rand.Next(this.gameSize.Height));

}

public void NewMatch(string opponent) { }

public void OpponentShot(Point shot) { }

public void ShotHit(Point shot, bool sunk) { }

public void ShotMiss(Point shot) { }

public void GameWon() { }

public void GameLost() { }

public void MatchOver() { }

}

}

#2楼

你写了:

任何被视为违反竞争精神的东西都将被取消资格。

干扰对手是违背竞争精神的。

请定义“反对竞争精神”和“干扰对手”?

另外 - 为了简化,我建议你:

在对手的CPU插槽中完全不允许使用CPU。

禁止线程并行,而是在单个线程上提供更多CPU秒。 这将简化AI的编程,并且不会伤害任何CPU /内存绑定的人。

PS - 潜伏在这里的CS博士后的问题:这个游戏不是可以解决的(即有一个单一的,最好的策略吗?)。 是的,电路板尺寸和步数使得minimax等强制要求,但我仍然不得不怀疑......它与Go和国际象棋的复杂程度相差甚远。

#3楼

这不是极小极大。 实际上在放置船只之后,每个玩家都不能独自玩耍,导致他转向每一个对手的船只转了几圈? 花费较少的人获胜。

我不认为除了沉没的船只之外还有任何好的一般策略,并试图尽量减少射击次数以覆盖船只可能隐藏的其余可能的地方。

当然,任何不随机的事情都可能存在反策略。 但我不认为有些策略可以对抗所有可能的球员。

#4楼

我预测那个设法逆转他们的对手随机种子和通话模式的人将获胜。

不知道有多大可能。

#5楼

实际上,我认为这个难题的最大问题在于它本质上是两个动作。 一方面是放置你的船只,另一方面是找到敌人的船只(不过第二部分可能分段,除了试图用随机因素击败时钟,它只是'运行你的算法')。 没有任何机制可以试图确定并反击敌人的策略,这就是使基于连续几轮“石头剪刀”的类似比赛非常有趣的原因。

另外,我认为如果你将游戏指定为网络协议然后提供框架来在C#中实现该协议,而不是规定所有解决方案都应该是C#,那我会更酷,但这只是我的意见。

编辑:我取消了我的初始观点,因为我没有仔细阅读比赛规则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值