テストドライバー • チャレンジディスカッション • 冒険家を提出する
(画像ソース)
数人のライバルの冒険者が宝物のために廃insを襲撃していますが、彼らは一度に多くを運ぶことができるだけで、持久力の限界があります。彼らは最も価値のある宝物を手に入れ、疲れすぎて続行できない前に出たいと思っています。彼らは略奪するシェナンガンから可能な限り金持ちになろうとしています。
ゲームプレイ
それぞれの冒険者は、1000個のスタミナポイントとバックパックに50kgのスペースがあるダンジョンの最初の部屋から始まります。
ゲームはターンベースの方法で動作し、すべてのプレイヤーが同時にターンを解決します。ターンごとに、次のアクションのいずれかを実行できます。
- 次の部屋に移動します。
- 前の部屋に移動します。
- 宝を取るためにスタミナを入札します。
- 宝物をドロップします。
部屋間を移動するには、10スタミナに加えて、現在バックパックに入っている5 kgごとに1スタミナが必要です。たとえば、3kgの宝物を運ぶ冒険者の移動には11体のスタミナが必要で、47kgの宝物の移動には20体のスタミナが必要です。
宝をドロップするには、ドロップする宝に関係なくスタミナが1つ必要です。
廃insを出ると、プレイヤーはこれ以上ターンを行いません。
プレーヤーがこれらのアクションのいずれかを実行できない場合(スタミナの不足または宝物の欠如)、冒険者は疲弊して死に、保有している宝物を現在占有されている部屋にこぼします。同様に、プレイヤーが無効なアクションを行おうとすると、冒険者は代わりにトラップで殺され、同じ宝物が流出します。
入札
宝の最低入札価格は、宝の重さ1kgにつき1スタミナです。宝物を獲得する可能性が高くなるように、追加のスタミナポイントを入札することもできます。入札されたスタミナは、結果がどうであれ消費されます。
複数のプレイヤーが同じ宝を獲得するために入札した場合、最高額を入札したプレイヤーが宝を獲得します。複数のプレイヤーが最高入札を行った場合、誰も宝を受け取りません。
勝利条件
宝物の合計値が最大のプレイヤーが勝者です。まれにネクタイが発生した場合、タイは最小の総重量、次に最小の宝物数、次に最も価値のある宝物、2番目に貴重なもの、3番目...に至るまで続きます。ほぼ不可能なこの時点で引き分けがある場合、テストドライバーは「それをねじ込む」と言い、勝者はそれによって任意に決定されます。
トーナメントの文脈では、プレイヤーは1位で10ポイント、2位で9ポイント、3位で8ポイント、などとランク付けされます。
遺跡について
- 各部屋は、最初の間に含まと宝物。(は部屋番号です)
- 冒険者のスタミナと探検意欲によってのみ制限される、任意の多くの部屋があります。
- 各宝には、金銭的価値(全体で$)と重量(全体でkg)があります。
- 遺跡の奥深くに行くほど、宝物はより価値があり、豊富になる傾向があります。
- 宝物を生成するための具体的な式は次のとおりです:(サイコロロールに表記を使用)
- 式(最小1)を使用して最初に重みが生成されます
- トレジャー値は、(は部屋番号、は重量)
プレイヤーに見える情報
各ターンで、プレイヤーは次の情報を取得します。
- 現在いる部屋の番号。これは1から始まるため、概念的には出口は「部屋0」にあります。
- 現在部屋にある宝物のリスト
- 現在ルームにいる他のプレイヤーのリスト。
- 現在の宝の目録
- 現在のスタミナレベル
コーディング
テストドライバーはこちらにあります。
このAdventurer
クラスのサブクラスを実装する必要があります。
class Adventurer:
def __init__(self, name, random):
self.name = name
self.random = random
def get_action(self, state):
raise NotImplementedError()
def enter_ruins(self):
pass
get_action
メソッドをオーバーライドするだけです。enter_ruins
ゲームの開始前に実行され、ゲームの準備ができているものを準備するチャンスです。オーバーライドする必要はありませんし__init__
、本当にすべきではありません。__init__
クラッシュした場合、失格となります。
get_action
namedtuple
次のフィールドを持つ1つの引数を受け取ります(構造化を希望する場合は、この順序で):
room
:現在いる部屋の番号treasures
:部屋の宝物のリストplayers
:ルーム内の他のプレイヤーのリスト。この方法でプレイヤー名を取得するだけなので、どのボットがプレイヤーやそのインベントリ/スタミナを制御しているかはわかりません。inventory
:バックパック内の宝物のリストstamina
:現在のスタミナレベル
このオブジェクトは、さらに2つのユーティリティプロパティを提供します。
carry_weight
:持っているすべての宝物の総重量total_value
:あなたが持っているすべての宝物の合計値
treasures
そしてinventory
リストは含まれてnamedtuple
これらの属性を持つ秒:
name
:宝の名前(化粧用)value
:宝物の金銭的価値($)。weight
:宝物の重量(kg)
get_action
次の値/パターンのいずれかを返す必要があります。
'next'
または'previous'
次/前の部屋に移動する'take', <treasure index>, <bid>
(はい、タプルとして、どのシーケンスも技術的には機能しますが)ルームのトレジャーリスト内の指定されたインデックスでトレジャーに入札します。両方の引数は整数でなければなりません。フロートは切り捨てられます。'drop', <inventory index>
指定されたインデックスで見つかったキャリートレジャーをドロップします。インデックスは(当然)整数でなければなりません。
その他の制限
- 擬似乱数の初期化中に提供されたランダムインスタンスのみを使用できます。
- 行動の非決定性を引き起こす可能性のあるものは許可されません。ここでの目的は、新しいボット(および潜在的にテストドライバーのバグ)のテストを支援するために、同じシードが与えられたときにボットを同じように動作させることです。宇宙放射線のみが逸脱/非決定論を引き起こすはずです。
- Python 3ではハッシュコードがランダム化される
hash
ため、意思決定に使用することは許可されていません。dict
Python 3.6以降、一貫性が保証されているため、決定に反復順序を使用する場合でもsは問題ありません。
ctypes
ハックまたはinspect
スタックブードゥー(またはその他の方法)を使用してテストドライバーを回避することはできません。これらのモジュールを使用すると、驚くほど恐ろしいことができます。しないでください。- 各ボットは、防御的なコピーと
namedtuple
sの自然な不変性によって合理的にサンドボックス化されますが、パッチ適用できない抜け穴/エクスプロイトがいくつかあります。 - 他の機能
inspect
とはctypes
限り回避制御機能に使用されないどちらとして使用することができます。 - 現在のゲームで他のボットのインスタンスを取得する方法は許可されていません。
- 各ボットは、防御的なコピーと
- ボットは単独で動作する必要があり、他のボットと何らかの目的で調整することはできません。これには、一方が他方の成功のために犠牲になるような、異なる目標を持つ2つのボットの作成が含まれます。10を超える競合他社が存在する場合、実際には同じゲームに2つのボットがいることは保証されず、冒険者の名前はボットクラスを示すものではありません。
- 現在、実行時間に厳しい制限はありませんが、トーナメントに時間がかかりすぎる場合は、将来的にそれを強く制限する権利を留保します。合理的であり、ターン処理を100ms未満に保つようにしてください。これは、そのしきい値以下に制限する必要があるとは思わないからです。(すべてのボットが1ターンあたり約100ミリ秒かかる場合、トーナメントは約2時間で実行されます。)
- ボットクラスには、すべての提出物の中で一意の名前を付ける必要があります。
- ゲームの間に何も覚えていないかもしれません。(ただし、ターン間で物事を覚えることができます)
- sys.modulesを編集しないでください。インスタンス変数以外は、定数として扱う必要があります。
- 独自のコードを含め、プログラムでボットのコードを変更することはできません。
- これには、コードの削除と復元が含まれます。これは、デバッグとトーナメントをより合理化するためです。
- コントローラーをクラッシュさせるコードはすぐに失格となります。ほとんどの例外がキャッチされますが、いくつかは抜け落ち、セグメンテーション違反はキャッチできません。(はい、おかげでPythonでセグメンテーション違反を起こすことができます
ctypes
)
提出
回答のスクレイピングを支援するために、回答の上部にボットの名前を指定し、#Header1
回答に少なくとも1つのコードブロックが含まれていることを確認します(回答の最初のブロックのみが使用されます)。スクレーパーによって自動的に追加されるため、インポートやdocstringを含める必要はありません。
私は、詳細で理解可能な説明で回答を支持する傾向があります。他の人も同じように振る舞います。
大まかに言えば、あなたの答えは次のような形式にする必要があります。
# Name of Bot
Optional blurb
#imports go here
class BotName(Adventurer):
#implementation
Explanation of bot algorithm, credits, etc...
(としてレンダリング)
ボットの名前
オプションの宣伝文句
#imports go here class BotName(Adventurer): #implementation
ボットアルゴリズム、クレジットなどの説明...
テストドライバーをローカルで実行する
Python 3.7+が必要になります。pipを使用してインストールすることもお勧めしますtabulate
。提出のためにこのページをスクレイピングするにはlxml
、さらにとが必要requests
です。最良の結果を得るには、ANSIカラーエスケープをサポートする端末も使用する必要があります。Windows 10でこれを設定する方法については、こちらをご覧ください。
ruins.py
(ruins_bots
デフォルトで)と同じディレクトリ内のサブディレクトリ内のファイルにボットを追加from __main__ import Adventurer
し、モジュールの一番上に追加してください。これは、スクレーパーが提出物をダウンロードするときにモジュールに追加されます。これは間違いなくハックですが、これはボットが適切にアクセスできるようにする最も簡単な方法ですAdventurer
。
そのディレクトリ内のすべてのボットは実行時に動的にロードされるため、これ以上変更する必要はありません。
トーナメント
最終的な勝者は、各ゲームに最大10個のボットがある一連のゲームで決定されます。合計10件を超える提出がある場合、上位10個のボットは、すべてのボットが(正確に)20ゲームをプレイするまで、10個のグループに体系的に分割することによって決定されます。上位10のボットがリセットスコアでこのグループから選択され、1位のボットが2位のボットに対して50ポイントのリードを獲得するまで、または500ゲームがプレイされるまでゲームをプレイします。
少なくとも10件の提出があるまで、空のスロットは「Drunkards」で満たされ、廃whichをランダムにさまよい、スタミナを使い果たして出口に向かうまでランダムな宝物を奪います(場合によってはドロップします)。
新しいサブミッションがある場合、トーナメントは毎週再実行されます。これは、終了日が設定されていないオープンKOTHチャレンジです。
リーダーボード
2019年5月4日午後4時25分(MDT)の実行から:(2019-05-04 4:25 -6:00)
Seed: K48XMESC
Bot Class | Score | Mean Score
--------------+---------+--------------
BountyHunter | 898 | 7.301
Scoundrel | 847 | 6.886
Accountant | 773 | 6.285
Ponderer | 730 | 5.935
Artyventurer | 707 | 5.748
PlanAhead | 698 | 5.675
Sprinter | 683 | 5.553
Accomodator | 661 | 5.374
Memorizer | 459 | 3.732
Backwards | 296 | 2.407
更新-4月15日:いくつかのルールの更新/説明
更新-4月17日:他のボットのコードの変更など、悪意のあるアクションのいくつかの顕著なエッジケースの禁止。
更新-5月4日:Backwardsを完全に破壊したことで、Sleafarに賞金が授与されました。おめでとうございます!
pip
インストールし、上のPATH
窓から、あなたが実行することができます(新しいインストール私の知る限りでのデフォルトである)pip install modulename
promptコマンドでは。他の状況(私は知らない)については、pipに移動して、必要なモジュールを検索し、オプションを選択します。