Roguelike yol bulma


21

Roguelike yol bulma

Göreviniz, aşağıda açıklanan elementlerin iki boyutlu bir dizisi verildiğinde, zindanı temsil eden, haydutun herhangi bir canavarı uyandırmadan toplayabileceği altın parçalarının miktarını temsil eden tek bir sayı çıktısını almak veya döndürmek olacaktır.

Dizinin elemanları aşağıdaki gibidir:

  1. Boş alanlar, .aramanızla veya bir boşlukla temsil edilir ;
  2. Hilenin başlangıç ​​pozisyonu elbette @;
  3. Altın bir parça $;
  4. Duvarlar #;
  5. Canavarlar aşağıdaki regexp gelen karakterlerle temsil edilen: [a-zA-Z*&].

Dizi yukarıda listelenmemiş herhangi bir karakter içermemelidir, bu nedenle duvar, boş alan, haydut veya altın bir parça olmayan bir şeyin canavar olduğunu varsayabilirsiniz.

Yol bulma kuralları:

  1. Bu haydut yalnızca boş hücreler veya altın içeren hücrelerden geçebilir;
  2. Bitişik veya çapraz olarak bitişik bir hücreye hareket etme sırası gelir;
  3. Altını almak anlıktır;
  4. Bu haydut, uyanmadan uyanmadan birden fazla tur atmak için bitişik veya çapraz olarak bir canavara bitişik kalamaz;
  5. Bu haydut, bir canavarın farkındalık alanına istediği kadar girebilir, canavar ancak haydut ardına iki ardışık dönüş geçirirse uyanır .

Giriş ve çıkış kuralları

Girdiyi iki boyutlu bir dizi, düz bir dizi, bir dize veya başka bir şey dahil olmak üzere herhangi bir makul formatta alabilirsiniz. Hayatınızı kolaylaştırırsa, dizinin boyutlarını da alabilirsiniz.

Hilenin başlangıçta bir canavara yakın olmayacağı garanti edilir.

Tam bir program veya işlev iyi.

puanlama

Bu , puan daha az iyi olmasından dolayı gönderiminizin bayt sayısıdır.

Test durumları

Burada boş alanlar için noktalar kullanarak okunabilirlik amaçları için kullanıyorum, eğer isterseniz boşluk kullanabilirsiniz (yukarıya bakın). Ayrıca, bunun haydutun her zaman sol üst köşede olmasının tam bir tesadüf olduğuna dikkat edin, kodunuz başka bir geçerli pozisyonda da işlemelidir.

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

Sadece bir akıl sağlığı testi.

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

Yine bir akıl sağlığı testi.

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

Hile soldan hareket ettirerek altını kapabilir.

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

Bu haydut canavarlar arasında zikzak yapabilir, asla her birinin yakınında bir tur atmaz.

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

Önceki test durumundan taktikleri burada çalışmıyor - canavar hassasiyeti alanları örtüşüyor.

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

Akıl sağlığı testi.

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

Aynen.

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

Buradaki altınların hepsinden yalnızca üç tanesine güvenli bir şekilde ulaşılabilir: başlangıç ​​pozisyonuna yakın altın, bir pozisyona aşağı doğru hareket ettirilerek elde edilebilir. Sol üst köşeden kaçmak için, haydut iki kez çapraz olarak aşağıya doğru hareket etmek zorundadır. Ortadaki altın ise zorluk çıkarmaz. Dış altın korunan gve borta altının sağ tarafındaki sağdan köşeye çapraz ve sonra geri hareket ettirilerek elde edilebilir. Gerisi elde edilemez: sağ üst altın duvarlar tarafından engellenir ve sağ alt alt canavar duyarlılığı alanlarında iki tur gerektirir.

Aşağıdaki test vakaları cömertçe mbomb007 tarafından bağışlanmıştır.

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

Bu çok zor. Bir yoldur b4-b5-c6-b7-c8-b8(grab).

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

Bir yoldur [bc]4-c5-b6-c7-b8(grab).

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

Fazladan duvar aslında hiçbir şeyi değiştirmez [bc]4-c5-b6-c7-b8(grab), hala bir çözümdür.


Daha büyük ve daha karmaşık bir örnek eklemelisiniz. Ayrıca, zindanın minimum ve maksimum boyutları nelerdir? 1x1 zindan @geçerli bir giriş mi?
mbomb007


@ mbomb007 Yeni bir örnek ekledim. Şebekenin boyutuna gelince, en az 3x3 ile sınırlandırmanın makul olduğunu düşünüyorum.
Michail

@ mbomb007 Örneklerinizi düzenleyebilir miyim? Bir zamanlar anladılar, mantığı çok iyi sergiliyorlar.
Michail

Çekinmeyin. Onları bunun için yaptım. Ayrıca, bir test vakasının döndürülmesinin sonucu üzerinde hiçbir etkisinin olmaması gerektiği de belirtilebilir.
mbomb007

Yanıtlar:


5

Önceki çözümler (bunların bir kısmı) tio bağlantısındaki altbilgi kabında bulunabilir (bunlar muhtemelen daha okunaklıdır)

JavaScript (Node.js) , 883 436 411 360,345 311 bayt

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=="@"}

Çevrimiçi deneyin!

Patlama -

oyuncudan paraya geçmek yerine kasadan @ 'ya geçtim. Daha hızlı olmam gerektiğini düşünüyorum çünkü ne zaman aramayı bırakacağımı biliyorum (@ 'a ulaşmak) ve parayı ararken tüm noktaları (ve bunlara ulaşmanın yollarını) kaplayana kadar her zaman hareket etmeye devam etmen gerekiyor. bu yüzden algo bu şekilde oldukça basittir - ana işlev g.map((r,y)=>[...r].map((c,x)=>A+=c=="$"&&P(g,x,y)),A=0)|A: nakit bul -> bulursanız -> oynatıcıyı aramaya başlayın -> onu bulursanız -> artış A şimdi yol bulucunun aka P'sinin if(/[.$]/.test(c=(g[y]||[])[x]))kontrol edilmesine izin verir mevcut hücre "özel" dir -> eğer öyleyse geri dönmek istiyoruz. özel durumlar: @ # (canavar)

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 tekrar tekrar komşular yinele - eğer zaten orada değildim (p alınmış olan yol) devam yoluna (P çağır)


Güzel golf! Fark ettiğim birkaç şey: (1) kodunuz 2. ve 7. satırlarda gereksiz iz bırakma boşluklarına sahip ve çoğu satır sonları gereksizdir (yalnızca 1. ve 6. satırların bir ara vermesi gerekir) ve I / 3gereksiz yere sahiptir. Ortadaki boşluk ve puanınızı ortadan kaldırın 324! (2) return true olabilir return 1(bir truthy değeri) ve return falsebasit olabilir return(zımni undefinedbir Falsey değeri). (3) Canavar ^[^.@$#]$olmayanları kontrol etme rejimi, canavarları ^[a-zA-Z*&]$kontrol etmekten daha kısadır . İyi iş!
apsillers

evet biliyorum çok daha kısa yapabilirim :)
DanielIndie

@apsillers alanlarda ücretsiz bir çözüm güncellendi :)
DanielIndie
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.