骆驼杯:AI棋盘比赛


11

骆驼杯2k18

在这个挑战中,我们将玩半受欢迎的桌游Camel Up。

骆驼起来!是一种棋盘游戏,有玩家押注骆驼以赢得回合,赢得游戏或输掉游戏,设置陷阱以影响移动或移动骆驼。这些决定中的每一个都会奖励您获得一些钱的机会,这才是决定赢家的原因。玩家应使用概率,游戏状态考虑因素和对手的租约来做出决定。这是一个简短的视频,向玩家展示如何玩

怎么玩

这是玩法的粗略构想。观看其中一部视频可能会更有帮助,因为它们具有视觉效果:)

轮到您有4个选择。

  1. 移动骆驼。这会从尚未移动的人中选取骆驼,并在1-3个空格之间移动。您会得到1个硬币。当所有五个骆驼都移动时,回合结束,然后它们就可以全部移动
  2. 放置一个陷阱。这会一直持续到董事会结束。您选择+ 1 / -1陷阱。如果骆驼或骆驼叠落在上面,它们会移动+ 1 / -1,您会得到一个硬币。您不能在正方形0上放置陷阱。可以将陷阱放置在骆驼所在的位置,尽管它只会影响落在其后的骆驼。
  3. 回合赢家投注。您下注一个回合赢家。他们赢了您会得到5/3/2/1,具体取决于您是该骆驼的第一/第二/第三。
  4. 游戏赢家/输家。您押注谁将在比赛结束时排在第一或最后。根据您是否是1st / 2nd / 3rd / etc赌那只骆驼,您会得到8/5/3/1/1(我认为)

笔记:

  • 有5只骆驼。它们从0-2随机开始。
  • 当骆驼移动时(参见上面的触发方式),它们移动1-3格。如果将它们与另一个骆驼放在一个正方形上,则将它们放在另一个骆驼的“顶部”,从而创建一个骆驼堆栈。如果要移动骆驼,它将所有骆驼移动到骆驼堆栈上。栈顶的骆驼被认为是领先
  • 如果您落在+1陷阱上(请参见上文,触发此陷阱),您将向前移动一格。适用标准堆叠规则。
  • 但是,如果您遇到-1陷阱,则会向后移动一个方块。你去,是在该广场上,如果任何骆驼的堆栈。
  • 骆驼碰到正方形16时游戏结束。这立即调用回合结束和游戏结束触发器
  • 每个骆驼只能进行一次获胜/失败者下注。也就是说,您不能押注骆驼来赢得输掉比赛

挑战

在此挑战中,您将编写一个Python 3程序来扮演四人游戏,获胜者将赢得Camel Up的所有荣耀游戏

您的程序将收到gamestate,其中包含:

  • camel_track:骆驼的位置
  • trap_track:陷阱的位置(格式为[trap_type(-1,1),播放器]的条目)
  • player_has_placed_trap:一个数组,告诉您玩家是否在本回合放置了陷阱
  • round_bets:本轮下注的数组。形式为[骆驼,玩家]
  • game_winner_bets / game_loser_bets:玩家为骆驼赢得或输掉游戏而进行的一系列下注。您将只能看到下注的玩家的价值,而不是下注的玩家的价值。您可以知道您的赌注。#形式[骆驼,玩家]
  • player_game_bets:game_winner_bets / game_loser_bets的另一种表示形式。同样,仅查看您的机器人所下的赌注。
  • player_money_values:一个数组,显示每个玩家的钱数。
  • camel_yet_to_move:一个数组,显示骆驼是否已移动到这一轮。

除了游戏状态外,您还可以获得:

  • 玩家:一个整数,告诉您您是哪个玩家号码(0-3)。

玩家应该返回的语法是:

  • [0]:移动骆驼
  • [1,trap_type,trap_location]:放置陷阱
  • [2,projected_round_winner]:进行圆形胜者下注
  • [3,projected_game_winner]:让游戏获胜者下注
  • [4,projected_game_loser]:输掉游戏输家

这应该包装在move(player,gamestate)方法中

例如,如果有一位玩家在最后一位,将进行一轮获胜者下注。如果不是,则将陷阱放置在随机的正方形上。

class Player1(PlayerInterface):
     def move(player,g):
         if min(g.player_money_values) == g.player_money_values[player]:
            return [2,random.randint(0,len(g.camels)-1)]
        return [1,math.floor(2*random.random())*2-1,random.randint(1,10)]

选择该游戏的原因有几个:它有相对较小的选项可供选择(每回合大约20个选择,很容易缩小到通常的3-4个左右),游戏很短,而且运气很高(这使得它很幸运)因此,即使是“不良”机器人也可以获胜)。

游戏玩法

比赛亚军可以在这里找到:骆驼杯。运行camelup.py以运行锦标赛,或者运行PlayGame功能运行游戏。我将使用新提交的内容更新该存储库。可以在中找到示例程序players.py

锦标赛每10名玩家包括100场比赛(四舍五入,因此14名玩家意味着200场比赛)。每个游戏将从玩家池中选择四个随机玩家来填补四个位置。玩家将无法两次进入游戏。

计分

每个游戏的赢家是游戏结束时拥有最多金钱的玩家。如果在游戏结束时出现平局,则所有具有最大金额的玩家都将获得一个积分。比赛结束时得分最高的玩家获胜。我将在运行游戏时发布分数。

提交的玩家将被添加到池中。我添加了三个非常笨的机器人,以及一个我开始做的机器人。

注意事项

请勿修改输入。除非通过合作或背叛,否则不要试图影响任何其他程序的执行。不要做出牺牲性尝试,以试图认出另一种提议并自费让该对手受益。禁止出现标准漏洞

将您的漫游器所花费的时间限制为每转约10秒。

提交的内容不得与之前的提交重复。

请不要查看其他玩家的game_winner或game_loser投注。它很容易做到,但仍然会作弊。

如果您有任何问题随时问。

获奖

比赛将无限期开​​放,因为新的参赛作品将被发布。但是,我将在发布此问题后一个月(7月20日)的结果宣布获胜者(接受答案)。

结果

Player0: 12
Player1: 0
Player2: 1
Sir_Humpfree_Bogart: 87

也许我读了过去,但是有几只骆驼在玩呢?另外,到达另一边还要走多少个正方形?根据您的GitHub代码,我非常确定它是5个骆驼和25个正方形,但是我没有在挑战说明中看到这一点。至于下注,我们可以下注多少,还是默认情况下下注1?我们是否有支出限制,还是可以无限期下注每一轮?至于移动骆驼的玩家,哪个骆驼被移动?骆驼与您匹配的玩家-nr?如果是,为什么会有4个玩家而不是5个骆驼?
Kevin Cruijssen

1
拥有Perl答案将是完美的
随机的家伙

欢迎来到PPCG!
AdmBorkBork

每10位玩家100场比赛的IMO似乎很低,尤其是随机性如此之高的游戏
Nathan Merrill

1
@AdmBorkBork谢谢!我对此并不陌生,欢迎所有指点。这在现实生活中效果很好 -可以在这里看到效果如何
泰勒·巴伦

Answers:


1

Sir_Humpfree_Bogart.py

这是我为Camel Up Cup Tournament制作的机器人。

首先,他们研究了骆驼可能会在回合结束时结束的所有可能配置。然后他们使用以下方法确定对赢得一轮比赛的骆驼的预期投注值

EV_roundwin = (chance_1st)*(payout) + (chance_2nd)*(payout) - (chance_3rd_or_worse)*(cost)

然后他们随机移动骆驼,直到骆驼获胜。经过几千次之后,您可以估计每只骆驼获胜的机会。同样,我们使用

EV_gamewin = (chance_1st)*(payout) - (chance_2nd_or_worse)*(cost)

唯一的其他选择是移动骆驼(它总是能产生一枚硬币,因此其期望值为一枚硬币)并放置陷阱。两支球队都认为放置陷阱是一个微弱的选择,无法完全忽略它。机器人根据这些信息选择了期望值最高的选项。

由于锦标赛的第二名和最后一名相同,因此如果您落后于机会进入第一名,那就很有意义。SBH使用distance_from_first_place和nearness_to_end来确定该机器人应该有多大的风险,如果您离第一名很远并且接近终点,那么风险会很高;如果您位于游戏的第一名或末尾,则风险会很低。 。风险低的机器人将决定具有高期望值选项和高风险的动作,从而产生具有较高预期的选项。确切的方程是

Functional_EV = EV + (upshot-EV) * riskiness

决定是您可以从决策中获得的最高支出,风险范围从0到1。


0

players.py

这些都是令人难以置信的傻瓜机器人,可以使比赛顺利进行。它们几乎没有逻辑,但充当人们使用的框架

import random
import math
from playerinterface import PlayerInterface

class Player0(PlayerInterface):
    def move(player,g):
        #This dumb player always moves a camel
        return [0]

class Player1(PlayerInterface):
    def move(player,g):
        #This player is less dumb. If they have the least amount of money they'll make a round winner bet
        #If they aren't in last then they'll place a trap on a random square. Still p dumb though
        if min(g.player_money_values) == g.player_money_values[player]:
            return [2,random.randint(0,len(g.camels)-1)]
        return [1,math.floor(2*random.random())*2-1,random.randint(1,10)]

class Player2(PlayerInterface):
    def move(player,g):
        #This dumb player always makes a round winner bet
        return [2,random.randint(0,len(g.camels)-1)]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.