キャメルアップカップ:AIボードゲームトーナメント


11

キャメルアップカップ2k18

このチャレンジでは、半人気のボードゲームCamel Upをプレイします。

キャメルアップ!ラウンドに勝つ、ゲームに勝つ、またはゲームに負けるためにラクダに賭けているプレイヤーがいるボードゲームです。これらの決定のそれぞれは、いくらかのお金を得るチャンスであなたに報酬を与えます、それは勝者を決定するものです。プレイヤーは、確率、ゲームの状態、および対戦相手のテナントを使用して決定を下す必要があります。これはプレイヤーがプレイする方法を示す短いビデオです。

遊び方

プレイ方法の大まかなアイデアを以下に示します。ビデオのいずれかを見ると、視覚効果があるため、より役立つ場合があります:)

あなたの番には4つの選択肢があります。

  1. ラクダを動かします。これは、移動していない人からラクダを選び、1〜3スペース間で移動します。あなたは1コインを取得します。5頭すべてのラクダが移動するとラウンドが終了し、その後すべて移動できます
  2. トラップを配置します。これはラウンドの終わりまでボードに残ります。+ 1 / -1トラップを選択します。ラクダまたはラクダのスタックがその上に着地した場合、それらは+ 1 / -1移動し、コインを受け取ります。正方形0にトラップを配置することはできません。ラクダがいる場所にトラップを配置することはできますが、その後に着くラクダにのみ影響します。
  3. ラウンド勝者の賭け。ラウンドの勝者に賭けます。あなたは、あなたがそのラクダに賭ける1/2/2/3であるかどうかに応じて5/3/2/1を獲得します。
  4. ゲームの勝者/敗者。ゲームの最後に誰が最初か最後かを賭けます。あなたがそのラクダに賭けたのが1/2/2/3だったかどうかに基づいて8/5/3/1/1(私は思う)を得る

ノート:

  • 5匹のラクダがいます。0から2までの位置からランダムに開始します。
  • ラクダを動かすと(これをトリガーするものについては上記を参照)、1〜3マス移動します。それらが別のラクダと正方形に配置される場合、それらは他のラクダの「上」に配置され、ラクダスタックが作成されます。ラクダが移動する場合は、ラクダスタック上でラクダの上にあるすべてのラクダを移動します。スタックの最上部にあるラクダが先頭にいると見なされます
  • +1トラップに着地した場合(これをトリガーするものについては上記を参照)、1マス先に移動します。標準のスタッキングルールが適用されます。
  • ただし、-1トラップをヒットすると、1マス後ろに移動します。あなたは行くの下であれば、その広場にあるラクダのスタック。
  • ラクダがスクエア16に達すると、ゲームは終了します。これにより、ラウンドエンドとゲームエンドトリガーが直ちに呼び出されます。
  • ゲームの勝者/敗者のベットは、ラクダごとに1回のみ行うことができます。つまり、あなたが勝つためにラクダに賭けることができないゲームを失います

チャレンジ

この課題では、4人のプレーヤーをプレイするPython 3プログラムを作成し、勝者はCamel Upのすべての栄光のゲームを取ります

あなたのプログラムは以下を含むゲームステートを受け取ります:

  • camel_track:ラクダの位置
  • trap_track:トラップの場所([trap_type(-1,1)、player]の形式のエントリ)
  • 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:ラクダがこのラウンドを移動したかどうかを示す配列。

ゲームステートの上部には次のものもあります:

  • player:プレーヤー番号(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)]

ゲームはいくつかの理由で選択されました:選択できる選択肢は比較的小さく(1ターンあたり約20の選択肢があり、通常は約3-4に簡単に絞り込めます)、ゲームは短く、運の要素があります(それを作るそのため、「悪い」ボットでさえ勝つことができます)。

ゲームプレイ

トーナメントランナーはここにあります:camel-up-cup。実行camelup.pyしてトーナメントを実行するか、PlayGame関数を使用してゲームを実行します。そのリポジトリを新しいサブミッションで更新し続けます。サンプルプログラムはにありますplayers.py

トーナメントは、10人のプレイヤーごとに100のゲームで構成されます(端数切り上げのため、14人のプレイヤーは200ゲームを意味します)。各ゲームは、4つのポジションを満たすためにプレイヤーのプールから選択された4人のランダムなプレイヤーになります。プレイヤーはゲームに2回参加することはできません。

得点

各ゲームの勝者は、ゲーム終了時に最もお金を持っているプレーヤーです。ゲーム終了時に同点の場合、最大金額を持つすべてのプレイヤーにポイントが付与されます。トーナメントの最後に最も多くのポイントを持つプレイヤーが勝ちます。ゲームの実行中にスコアを投稿します。

提出されたプレイヤーはプールに追加されます。私は3つの本当に物足りないボットと私が始めたものを追加しました。

注意事項

入力を変更しないでください。協力または欠陥を除き、他のプログラムの実行に影響を与えないでください。別の提出物を認識し、その費用をかけて相手に利益をもたらすことを試みる犠牲的提出物を作成しないでください。標準的な抜け穴は禁止されています。

ボットにかかる時間を1ターンあたり最大10秒に制限します。

提出物は以前の提出物と重複してはなりません。

他のプレイヤーからのgame_winnerやgame_loserのベットを見ないでください。とても簡単ですが、それでも不正行為です。

ご質問がある場合は、お気軽にお問い合わせください。

勝ち

新しい応募が投稿されると、コンテストは無期限に開催されます。ただし、この質問が投稿されてから1か月後(7月20日)の結果に基づいて、勝者を宣言します(回答を受け入れます)。

結果

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

たぶん私はそれを過去に読んだかもしれませんが、いくつのラクダが遊びにありますか?また、反対側にたどり着くには何マス移動する必要がありますか?あなたのGitHubコードに基づいて、私はそれが5つのラクダと25の正方形であると確信していますが、これはチャレンジの説明で言及されていません。賭けをすることに関して、私たちはどんな額でも賭けることができますか、それはデフォルトで1を賭けますか?支出制限はありますか、それともすべてのラウンドを無期限に賭けることができますか?ラクダを動かすプレーヤーについては、どのラクダが動かされますか?一致するplayer-nrのラクダ?はいの場合、なぜ4人のプレイヤーが5人のラクダがあるのですか?
ケビンCruijssen

1
Perlの答えを持っているのに完璧だったでしょう
ランダムな男

PPCGへようこそ!
AdmBorkBork

10人の選手あたり100のゲームは特にそれほどランダムでゲームで、IMOはかなり低いと思われる
ネイサンメリル

1
@AdmBorkBorkありがとうございます!私はこれが初めてなので、すべてのポインタを歓迎します。これは実際の生活でうまく機能しました
タイラーバロン

回答:


1

Sir_Humpfree_Bogart.py

これは私がキャメルアップカップトーナメントのために作ったボットです。

最初に、彼らはラウンドの終わりにラクダが終わる可能性のあるすべての構成を調べます。次に、ラウンドに勝ったラクダに賭ける期待値を決定します

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

その後、ラクダが勝つまでラクダをランダムに動かします。これを数千回行った後、各ラクダが勝ち負ける可能性を見積もることができます。繰り返しますが、これらを使用して期待値を取得します

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

他の唯一のオプションは、ラクダの移動(常に1つのコインが得られるため、期待される値は1)とトラップの配置です。両チームは、トラップを配置することは完全にそれを無視するのに十分弱いオプションであると感じました。この情報を使用して、ボットは期待値が最も高いオプションを選択しました。

トーナメントは2位を最後の1位と同じように見たので、もしあなたが遅れて1位になればチャンスがあります。SBHはdistance_from_first_placeとnearness_to_endを使用して、ボットの危険度を判断しました。最初から遠く、終わりに近い場合は危険度が高く、ゲームの最初または最後にいる場合は危険度は低くなります。リスクが低い場合、ボットは期待値オプションが高いアクションを決定し、リスクが高いとオプションの結果が高くなります。正確な方程式は

Functional_EV = EV + (upshot-EV) * riskiness

upshotは、決定から得られる最高の支払いであり、リスクの範囲は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)]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.