首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >法克尔节2k19:人工智能骰子游戏锦标赛

法克尔节2k19:人工智能骰子游戏锦标赛
EN

Code Golf用户
提问于 2019-09-03 03:09:00
回答 2查看 939关注 0票数 7

法克尔节2k19

在这个挑战中,我们将玩半流行的骰子游戏“法克尔”。

法克尔是一种骰子游戏,玩家可以选择保存骰子,或者将骰子重新放置到更多的点数中,以增加总数。玩家应该利用概率,游戏状态的考虑和对手的倾向来做出他们的决定.

如何玩

规则解除从这个PDF,其中包括得分.有一些不同之处,你应该注意到。

每个玩家轮流掷骰子。当轮到你时,你会同时掷出所有六个骰子。每次你掷1或5、3对、3对、6骰子(1,2,3,4, 5,6)或两个三胞胎时,你都会得到分数。如果你的骰子都赚不到分数,那就是法克尔!因为你没有得到分数,你把骰子传给下一个玩家。如果你掷出至少一个得分骰子,你可以将你的分数存入下一个玩家,或者冒险你在这一轮中刚获得的分数,把一些或全部获胜的骰子(骰子)放在一边,然后滚动剩下的骰子。剩下的骰子可能会给你额外的分数,但如果你法克尔,你就会失去你在这一轮中所获得的一切。如果你所有的骰子都贡献了你的分数,你重新滚动骰子,并添加到已经滚动的点数,但一个法克尔将失去所有的积分,包括滚动。这就是所谓的“热-连续”得分是基于骰子在每卷。你可以通过从不同的骰子中组合骰子来获得分数。你可以继续滚动骰子,直到你通过或法克尔。然后下一个玩家掷出这六个骰子,直到他们通过或者法克尔。游戏继续进行,直到轮到你。最后一轮开始时,任何球员达到2万或更多的分数。评分:5= 50 1=10 0 3 1=10 0 3 2=2 0 0 3 2=2 0 0 3 3=3 0 0 3 4=4 0 0 3 5=5 0 0 3 6=5 0 0 1 3 6=6 0 0 1 3 6=6 0 0 1 3对=1 500 3对=1 500 3对=1 500 2 4类=1 000 5类=2 0 0 0 6

备注:

  • 有不同的计分表。使用上面链接和重写的
  • 大多数在线版本都会说“你不能通过组合不同卷的骰子来获得分数”。我不是这样玩的。如果你掷出三重六和重升,最后得到另外六个,你现在有六个四分。
  • 收尾分数从10,000增加到20,000。这增加了决策点,降低了随机性。
  • 有些变体有一个“开始获取点数的阈值”(通常在500左右)。如果你的分数是0(或者是负的),这将阻止你保持一个少于500的滚动。这一规则并不有效。

挑战

在这个挑战中,你将编写一个Python 3程序来玩一个三人游戏,胜利者会拿出法克尔所有的荣耀游戏。

您的程序将收到游戏状态,其中包括:

index (where you sit at the table) end\_score (score required to win (20,000)) game\_scores (all the players current score) state\_variable (space for you to put whatever you want) #round values, these change during the round round\_score (score of the current set of dice) round\_rollover (score from previous "hot streaks") round\_dice (current dice) round\_set\_aside (dice you set aside before rolling) round\_used\_in\_score (lets you know which dice are adding to your score)

玩家应该返回一个数组,显示他们想要保留的骰子。这应该封装在set_dice_aside(self)方法中

举个例子,这里有一个玩家可以保存骰子,然后再加分,直到他们得到的分数达到500或更高

代码语言:javascript
复制
class GoForFiveHundred(Bot):
    def set_dice_aside(self):
        while (self.round_score + self.round_rollover) < 500:
            return self.round_used_in_score
        return [True, True, True, True, True, True]

游戏

参赛选手可以在这里找到:法克尔_喜庆_2K19。运行main.py以运行一个锦标赛。我会随时更新新的投稿。示例程序可以在farkle_bots.py中找到。很多代码都是从马克斯中删除的,非常感谢这个框架和代码。

一场比赛包括每10名玩家5000场比赛(加起来,14名选手意味着10,000场比赛)。每场比赛将由三名随机从玩家池中选出来填补这三个位置。玩家将不能在游戏两次。

评分

每场比赛的胜利者都是在比赛结束时得分最多的球员。如果在游戏结束时打成平局,所有最高金额的玩家都会得到一个积分。比赛结束时得分最多的球员获胜。我将在运行游戏时发布分数。

提交的球员将被添加到池中。我加了三个笨机器人开始。

警告

不要修改输入。不要试图影响任何其他程序的执行,除非通过合作或叛变。不要做出牺牲的屈服,试图承认另一个屈服,并使对手的利益,而由其自己的费用。标准漏洞被禁止。

限制你的机器人所花费的时间是~1s的每一个回合。

提交的材料不得重复先前提交的材料。

如果你有任何问题,请随便问。

比赛将无限期开放,因为新的投稿被张贴。然而,在这个问题发布两个月后(11月2日),我将根据结果宣布获胜者(接受答案)。

模拟5000个游戏,5个机器人在675.7秒内完成,每场比赛平均持续15.987000回合,8场比赛在两个或更多机器人之间打成平局,0场比赛一直跑到回合极限,最高一轮是48场。

代码语言:javascript
复制
+----------------+----+--------+--------+------+------+-------+
|Bot             |Win%|    Wins|  Played|   Max|   Avg|Avg win|
+----------------+----+--------+--------+------+------+-------+
|WaitBot         |95.6|    2894|    3028| 30500| 21988|  22365|
|BruteForceOdds  |38.7|    1148|    2967| 25150| 15157|  20636|
|GoForFiveHundred|19.0|     566|    2981| 24750| 12996|  20757|
|GoForTwoGrand   |13.0|     390|    2997| 25450| 10879|  21352|
|SetAsideAll     | 0.2|       6|    3027| 25200|  7044|  21325|
+----------------+----+--------+--------+------+------+-------+

+----------------+-------+-----+
|Bot             |   Time|Time%|
+----------------+-------+-----+
|BruteForceOdds  |2912.70| 97.0|
|WaitBot         |  58.12|  1.9|
|GoForTwoGrand   |  13.85|  0.5|
|GoForFiveHundred|  10.62|  0.4|
|SetAsideAll     |   7.84|  0.3|
+----------------+-------+-----+

没有WaitBot的结果,我在道德上还没有决定:

代码语言:javascript
复制
+----------------+----+--------+--------+------+------+-------+
|Bot             |Win%|    Wins|  Played|   Max|   Avg|Avg win|
+----------------+----+--------+--------+------+------+-------+
|BruteForceOdds  |72.0|    2698|    3748| 26600| 19522|  20675|
|GoForFiveHundred|37.2|    1378|    3706| 25350| 17340|  20773|
|GoForTwoGrand   |24.3|     927|    3813| 26400| 14143|  21326|
|SetAsideAll     | 0.1|       5|    3733| 21200|  9338|  20620|
+----------------+----+--------+--------+------+------+-------+
+----------------+-------+-----+
|Bot             |   Time|Time%|
+----------------+-------+-----+
|BruteForceOdds  |4792.26| 98.9|
|GoForTwoGrand   |  24.53|  0.5|
|GoForFiveHundred|  18.06|  0.4|
|SetAsideAll     |  13.01|  0.3|
+----------------+-------+-----+
EN

回答 2

Code Golf用户

回答已采纳

发布于 2019-10-03 04:34:53

BruteForceOdds

这是那个蛮力机器人:

代码语言:javascript
复制
from main import Controller
from farkle_bots import Bot

scoreDevice = Controller(1, 1, [], 0)

class BruteForceOdds(Bot):
    def set_dice_aside(self):
        stop_score = self.round_score + self.round_rollover
        if self.game_scores[self.index] + stop_score > max(self.game_scores + [self.end_score]):
            # Take the win
            return [True, True, True, True, True, True]

        using = self.round_used_in_score[:]
        if self.round_dice.count(5) < 3:
            for i in range(len(using)):
                if self.round_dice[i] == 5 and not self.round_set_aside[i] and using.count(True) > self.round_set_aside.count(True)+1:
                    using[i] = False
        if self.round_dice.count(1) < 3:
            for i in range(len(using)):
                if self.round_dice[i] == 1 and not self.round_set_aside[i] and using.count(True) > self.round_set_aside.count(True)+1:
                    using[i] = False
        if using.count(True) < 3 and self.round_rollover == 0:
            # Stopping here is basically never a good idea
            return using

        if bruteScore(self.round_dice, using, self.round_rollover) > stop_score:
            return using
        return [True, True, True, True, True, True]

def bruteScore(round_dice, set_aside, base_score):
    base_dice = []
    for i in range(len(round_dice)):
        if(set_aside[i]):
            base_dice.append(round_dice[i])
    totalCount = 0
    totalScore = 0
    for new_dice in allPossibleRolls(len(round_dice) - len(base_dice)):
        dice = base_dice + new_dice
        keep = [True]*len(base_dice)+[False]*len(new_dice)
        farkle, round_score, round_rollover, used_in_score = scoreDevice.score(dice, keep, base_score)
        totalCount += 1
        if not farkle:
            totalScore += round_score + round_rollover
    return totalScore / totalCount

def allPossibleRolls(length):
    if length == 0:
        yield []
        return
    for i in range(1,7):
        for l in allPossibleRolls(length-1):
            yield [i]+l

它只比示例程序GoForFiveHundred稍微好一点。

编辑:让它更聪明一点。现在,它比任何一个示例机器人都要好得多。

票数 2
EN

Code Golf用户

发布于 2019-09-03 07:53:08

WaitBot

代码语言:javascript
复制
class WaitBot(Bot):
	def set_dice_aside(self):
		return [self.round_rollover+self.round_score > 5000]*6

在网上试试!

这基本上不需要骰子,直到总比分大于5000。真的,这是打赌在法克尔斯之前就会有火爆的记录。

这赢得了大约97%的时间时,对默认的三个机器人。

编辑:嗯,这可能是无效的,因为您需要putting some or all of the winning die (dice) aside。由于控制器允许,所以我正在等待请求者的确认。

票数 1
EN
页面原文内容由Code Golf提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codegolf.stackexchange.com/questions/191201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档