ローグライクパスファインディング


21

ローグライクパスファインディング

あなたのタスクは、ダンジョンを表す以下に説明する要素の2次元配列を与えられ、怪物を起こさずにローグが収集できる金貨の量を表す単一の数値を出力または返すことです。

配列の要素は次のとおりです。

  1. 空のスペースは.、コールのいずれかまたはスペースで表されます。
  2. Rogueの開始位置は、もちろん次のように表され@ます。
  3. 金色のピースは$; で表されます。
  4. 壁はで表され#ます。
  5. モンスターは、次の正規表現の文字で表されます[a-zA-Z*&]

配列には上記以外の文字が含まれてはならないため、壁、空きスペース、ならず者、または金のピース以外のものはすべてモンスターであると想定できます。

経路探索のルールは次のとおりです。

  1. 悪党は空のセルまたは金を含むセルのみを通過できます。
  2. 隣接するセルまたは斜めに隣接するセルに移動するにはターンが必要です。
  3. 金を手に入れるのは瞬時です。
  4. ならず者は目を覚ますことなく、モンスターに1ターン以上隣接したり斜めに隣接したりすることはできません。
  5. ならず者は何回でもモンスターの認識エリアに入ることができ、モンスターは近くで2 ターン連続してモンスターを目覚めさせます。

入出力規則

入力は、2次元配列、フラット配列、文字列など、あらゆる妥当な形式で取得できます。作業が楽になる場合は、配列の次元も取得できます。

不正は最初はモンスターの近くにいないことが保証されています。

完全なプログラムまたは機能は問題ありません。

得点

これはであり、スコアは提出物のバイト数であり、少ないほうが良いです。

テストケース

読みやすくするために、ここでは空のスペースにドットを使用しています。スペースを使用したい場合は、上記を参照してください。また、これは不正が常に左上隅にあるという単なる偶然の一致であり、コードは他の有効な位置も処理する必要があることに注意してください。

1)
@..
.$.
...  -> 1

ただ健全性テスト。

2)
@....
...g$
.....  -> 0

再び、健全性テスト。

3)
@....
...$g
.....  -> 1

悪党は左から入ることで金をつかむことができます。

4)
@....g..
.......$
........
.....h..  -> 1

ならず者はモンスターの間でジグザグに動き、それぞれの近くに1ターン以上滞在することはありません。

5)
@....z..
.......$
.....b..  -> 0

前のテストケースの戦術はここでは機能しません-モンスターの感度領域は重複しています。

6)
@$#.
###$
....  -> 1

健全性テスト。

7)
@..#..
$.$g.$
...#..  -> 2

同上。

8)
@#.d#$
$...##
e.....
..$...
##..$b
.#..g$  -> 3

ここにあるすべての金のうち、安全に到達できるのは3つだけです。開始位置の近くの金は、1つ下に移動してから開始位置に戻すことで取得できます。左上隅から脱出するには、ローグは右下に2回斜めに移動する必要があります。真ん中の金は問題ありません。外側金によって守らgb当時の真ん中に金の右の場所から斜めに移動するとによって得することができます。残りは手に入れることができません。右上の金は壁でブロックされており、右下の金はモンスターの感受性の高いエリアで2ターン必要です。

次のテストケースはmbomb007からgeneしみなく寄付されました。

9)
  12345678
a @....g.D
b .......$
c ......#.
d .....h..  -> 1

これはトリッキーです。パスはb4-b5-c6-b7-c8-b8(grab)です。

10)
  12345678
a @....g.D
b .......$
c .......#
d .....h..  -> 1

パスは[bc]4-c5-b6-c7-b8(grab)です。

11)
  12345678
a @....g.D
b ......#$
c .......#
d .....h..  -> 1

余分な壁は実際に[bc]4-c5-b6-c7-b8(grab)は何も変えませんが、それでも解決策です。


より大きく複雑な例を追加する必要があります。また、ダンジョンの最小寸法と最大寸法は何ですか?1x1ダンジョン@は有効な入力ですか?
mbomb007


@ mbomb007新しい例を追加しました。グリッドのサイズに関しては、少なくとも3x3に制限するのが妥当だと思います。
ミハイル

@ mbomb007例を編集する場合は注意してください。彼らは、一度理解されると、ロジックを非常によく示します。
ミハイル

お気軽に。それが私が彼らのために作ったものです。また、テストケースを回転させても、結果に影響を与えないことに注意してください。
mbomb007

回答:


5

以前のソリューション(それらの一部)は、tioリンクのフッターコンテナーにあります(おそらくより読みやすいです)

JavaScript(Node.js)883 436 411 360,345 311バイト

g=>g.map((r,y)=>[...r].map((c,x)=>A+=c=="$"&&P(g,x,y)),A=0)|A
P=(g,x,y,m={},p={},I=i=9,M={})=>{if(/[.$]/.test(c=(g[y]||0)[x])){for(;i--;)if(/^[^.@$#]$/.test(C=(g[y+~-(i/3)]||0)[x+i%3-1])){if(m[C])return
M[C]=1}for(;I--;)if(!p[(X=x+~-(I/3))+","+(Y=y+I%3-1)]&&P(g,X,Y,M,{...p,[x+","+y]:1}))return 1}return c=="@"}

オンラインでお試しください!

外植-

プレイヤーから現金に行く代わりに、ケースから@に行きました。探すのをやめるとき(@に達する)を知っているので、私は速くなるべきだと思います。現金を探すときは、すべてのスポット(およびそれらに到達する方法)をカバーするまで常に動き続ける必要があります。ALGOは非常に単純であるので、そのように-主な機能 g.map((r,y)=>[...r].map((c,x)=>A+=c=="$"&&P(g,x,y)),A=0)|A:検索の現金- >あなたはそれを発見した場合- >インクリメントA今P別名パスファインダーになったことができます-あなたは、彼が見つかった場合> - >プレーヤーを探し始める if(/[.$]/.test(c=(g[y]||[])[x]))だけかどうかを確認現在のセルは「特殊」です->もしそうなら、そのプレーヤーであれば戻ります。特殊なケース:@#(monster)

for(;i--;) if(/^[a-zA-Z*&]$/.test(C=(g[y+~-(i/3)]||0)[x+i%3-1])) -> if my neighbor is a monster {if(m[C])return false -> and it already was in the previous turn - this path is not value M[C]=1} -> if not just add it to the neighbors monsters for(;I--;) if(!p[(X=x+~-(I / 3))+","+(Y=y+I%3-1)]&&P(g,X,Y,M,{...p,[x+","+y]:1}))return true 隣人を再度反復する-私がまだいなかった場合(pはとられたパスである)パスを続ける(Pを呼び出す)


素敵なゴルフ!(1)コードの2行目と7行目に余分な末尾の空白があり、ほとんどの改行は不要であり(1行目と6行目のみに改行が必要です)、I / 3不要なスペースがあります。その空白を削除すると、スコアは実際に324!(2)return truereturn 1(真理値)であり、return false単純にreturn(暗黙のundefined、偽値)です。(3)^[^.@$#]$モンスター以外をチェックする正規表現は^[a-zA-Z*&]$、モンスターをチェックするより短いです。よくやった!
-apsillers

はい、私はそれをもっと短くできることを知っています:)
ダニエルインディー

@apsillersがスペースのないソリューションに更新されました:)
DanielIndie
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.