我制造了原始战舰,现在我正在寻求将我的AI从随机猜测升级为统计猜测位置。我无法在线查找算法,所以我的问题是这个应用程序已经存在哪种算法?我将如何实现一个?
船舶:5,4,3,3,2
字段:10X10
板:
OCEAN = "O"
FIRE = "X"
HIT = "*"
SIZE = 10
SEA = [] # Blank Board
for x in range(SIZE):
SEA.append([OCEAN] * SIZE)
如果你想看到剩下的代码,我在这里发布:(https://github.com/Dbz/Battleship/blob/master/BattleShip.py);我不想用很多不相关的代码来混淆这个问题。
答案 0 :(得分:5)
最终的天真解决方案是通过每一个可能的船只安置(合法的信息已知)并计算每个方格已满的次数。
显然,在一个相对空白的董事会中,这不会起作用,因为有太多的排列,但一个好的开始可能是:对于船上的每个方格:浏览所有船只并计算它在该方格中适合的方式,即每个方格的船长检查它是否适合水平和垂直。
如果其他船舶可以合法放置,同时覆盖所有已知的“撞击”(已知包含船舶的地方),则可以对每个可能的船舶放置进行检查。为了提高性能,如果只有一艘船可以放置在给定的位置,则不再需要在其他位置进行测试。此外,当有许多“命中”时,首先覆盖所有已知的“命中”可能会更快,并且每个可能的封面都可以通过其余部分。
编辑:您可能想要查看DFS。
编辑:在评论中详细说明OP的(@Dbz)建议:
持有一套被解雇的船只('被解雇')的船只(可以表示为字符串,比如说"4V5x3"
表示长度为4的船只在5x3,5x4,5x5,5x6中),在猜测之后你添加所有的猜测放置的位置,然后对于每个方格保持一组与它相交的放置('placements [x,y]'),则概率为:
34-|intersection(placements[x,y], dissmissed)|/(3400-|dismissed|)
要添加到已被删除的列表:
placements[x,y]
<(2,3a,3b,4,5)>H<X+1>x<Y>
,<(2,3a,3b,4,5)>V<X>x<Y+1>
<(2,3a,3b,4,5)>H<X-(2,3,3,4,5)>x<Y>
,<(2,3a,3b,4,5)>V<X>x<Y-(2,3,3,4,5)>
2H<X+-1>x<Y+(-2 to 1)>
,3aH<X+-1>x<Y+(-3 to 1)>
... 2V<X+(-2 to 1)>x<Y+-1>
,3aV<X+(-3 to 1)>x<Y+-1>
... |intersection(placements[x,y], dissmissed)|==33
,即只有一个展示位置可以添加(见下文)添加船只:
placements[x,y]
而不包含实际展示位置我可能已经过度复杂了,可能会有一些冗余的行动,但你明白了。
答案 1 :(得分:2)
很好的问题,我喜欢你对统计方法的想法。
我想我会尝试machine learning解决这个问题的方法如下:
首先将您的问题建模为classification problem。
分类问题是:给定一个方格(x,y)
- 你想知道在这个方格中有一艘船的可能性。让这个可能性为p
。
接下来,您需要开发一些功能&#39;。您可以将(x,y)
的周围[因为您可能对其有部分了解]作为您的功能。
例如,以下迷你电路板中间的功能(+表示您想要确定是否有船的正方形):
OO*
O+*
?O?
可以是:
f1 = (0,0) = false
f2 = (0,1) = false
f3 = (0,2) = true
f4 = (1,0) = false
**note skipping (1,1)
f5 = (1,2) = true
f6 = (2,0) = unknown
f7 = (2,1) = false
f8 = (2,2) = unknown
我实现了相对于原点的功能(在这种情况下为(1,1)
),而不是船上的绝对位置(因此(3,3)
之前的正方形也将是f2)
现在,创建一个训练集。训练集是一个标记为&#39;一组功能 - 基于一些真正的主板。您可以手动创建它(创建大量的电路板),通过随机的放置生成器或您可以收集的其他数据自动创建。
将训练集提供给学习算法。该算法应该能够处理未知数&#39;并且能够给出&#34; true&#34;的概率。而且不仅仅是一个布尔答案。我认为Naive Bayes的变体可以很好地适应这里。
获得分类器后 - 将其与AI一起使用。
轮到你时,选择射击最大值为p
的正方形。首先,镜头将是随机的 - 但是你射击更多的镜头,你将获得更多关于棋盘的信息,AI将利用它来进行更好的预测。
请注意,我根据大小为1的正方形提供了功能。您当然可以选择任何k
并在这个更大的广场上查找功能 - 它会为您提供更多功能,但每个功能可能都不太准确。没有经验法则会更好 - 而且应该进行测试。
答案 2 :(得分:1)
主要问题是,您如何找到统计上可能的位置。他们已经知道了,或者你想弄明白吗? 无论哪种情况,我只是让网格称重。在您的情况下,每个插槽的初始权重为1.0 /(SIZE ^ 2)。权重之和必须等于1。 然后,您可以根据从N个最后一场比赛中收集的统计数据调整权重。 现在,当您的AI做出选择时,它会根据加权概率选择一个坐标。快速而简单的方法是:
在[0..1]
从插槽(0,0)开始添加权重,即S = W(0,0)+ W(0,1)+ ....其中W(n,m)是权重相应的插槽。一旦S&gt; = R,你就得到了要点击的坐标。
这可以通过预先计算每一行的累积权重进行优化,玩得开心:)
答案 3 :(得分:1)
当然,它可以变得像你想要的那么复杂。你也可以问自己,而不是我的下一个命中,哪些命中组合将给我带来更少的命中数或任何其他组合/参数化问题的胜利。祝你好运!