Roguelike pathfinding


21

Roguelike pathfinding

งานของคุณจะถูกกำหนดให้เป็นสองมิติขององค์ประกอบที่อธิบายไว้ด้านล่างซึ่งหมายถึงดันเจี้ยนเพื่อส่งออกหรือส่งกลับจำนวนเดียวแสดงจำนวนชิ้นทองคำที่คนโกงสามารถรวบรวมได้โดยไม่ต้องตื่นขึ้นมอนสเตอร์ใด ๆ

องค์ประกอบของอาร์เรย์มีดังนี้:

  1. ช่องว่างจะแสดงด้วย.การโทรของคุณหรือช่องว่าง
  2. ตำแหน่งเริ่มต้นของ Rogue นั้นถูกแทนด้วยแน่นอน@;
  3. ชิ้นส่วนทองจะถูกแทนด้วย$;
  4. ผนังถูกแทนด้วย#;
  5. มอนสเตอร์จะถูกแทนด้วยตัวละครจาก regexp [a-zA-Z*&]ต่อไปนี้:

อาเรย์จะต้องไม่มีตัวอักษรใด ๆ ที่ไม่ได้ระบุไว้ข้างต้นดังนั้นคุณสามารถสันนิษฐานได้ว่าอะไรก็ตามที่ไม่ใช่กำแพงพื้นที่ว่างอันธพาลหรือชิ้นส่วนทองคำเป็นสัตว์ประหลาด

กฎสำหรับการหาเส้นทางคือ:

  1. คนโกงสามารถเดินผ่านเซลล์ที่ว่างเปล่าหรือเซลล์ที่มีทองคำ
  2. มันใช้เวลาในการเปลี่ยนไปยังเซลล์ที่อยู่ติดกันหรือแนวทแยงมุม
  3. การหยิบทองคำขึ้นมาทันที
  4. พวกอันธพาลไม่สามารถอยู่ใกล้เคียงหรือแนวทแยงมุมกับมอนสเตอร์ได้มากกว่าหนึ่งเทิร์นโดยไม่ต้องตื่นขึ้นมาซึ่งเป็นสิ่งต้องห้าม
  5. คนโกงสามารถเข้าสู่พื้นที่การรับรู้ของสัตว์ประหลาดได้หลายครั้งสัตว์ประหลาดจะตื่นขึ้นมาก็ต่อเมื่อคนโกงใช้เวลาสองรอบติดต่อกันใกล้ ๆ

กฎอินพุตและเอาต์พุต

คุณสามารถรับอินพุตในรูปแบบที่เหมาะสมรวมถึงอาเรย์สองมิติอาเรย์แบนสตริงหรืออะไรก็ได้ ถ้ามันทำให้ชีวิตของคุณง่ายขึ้นคุณก็อาจต้องใช้มิติของอาเรย์ด้วยเช่นกัน

รับประกันได้ว่าคนโกงจะไม่อยู่ใกล้กับสัตว์ประหลาดในตอนเริ่มต้น

โปรแกรมหรือฟังก์ชั่นเต็มรูปแบบใช้ได้

เกณฑ์การให้คะแนน

นี่คือคะแนนคือจำนวนไบต์ที่คุณส่งโดยมีน้อยกว่าดีกว่า

กรณีทดสอบ

ฉันใช้จุดสำหรับช่องว่างที่นี่เพื่อการอ่านถ้าคุณต้องการคุณอาจใช้ช่องว่าง (ดูด้านบน) นอกจากนี้โปรดทราบว่านี่เป็นเรื่องบังเอิญที่แท้จริงว่าคนโกงอยู่ที่มุมบนซ้ายเสมอรหัสของคุณควรจัดการกับตำแหน่งที่ถูกต้องอื่น ๆ เช่นกัน

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

แค่ทดสอบสติ

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

ทดสอบสติอีกครั้ง

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

พวกอันธพาลสามารถคว้าทองคำโดยการย้ายจากด้านซ้าย

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

คนพาลสามารถซิกแซกระหว่างสัตว์ประหลาดไม่เคยอยู่ใกล้มากกว่าหนึ่งหันใกล้แต่ละ

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

กลยุทธ์จากกรณีทดสอบก่อนหน้านี้ไม่ทำงานที่นี่ - พื้นที่ความไวของมอนสเตอร์ทับซ้อนกัน

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

ทดสอบสติ

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

เหมือนกัน

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

ในทองคำทั้งหมดที่นี่มีเพียงสามเท่านั้นที่สามารถเข้าถึงได้อย่างปลอดภัย: ทองคำที่อยู่ใกล้ตำแหน่งเริ่มต้นสามารถทำได้โดยการเลื่อนลงหนึ่งตำแหน่งแล้วกลับไปที่ตำแหน่งเริ่มต้น ในการหลบหนีจากมุมซ้ายด้านบนหัวไม้จะต้องเลื่อนแนวทแยงมุมลงสองครั้ง ทองคำที่อยู่ตรงกลางไม่มีความท้าทาย ทองคำชั้นนอกที่ได้รับการปกป้องgและbสามารถเคลื่อนย้ายได้ในแนวทแยงมุมจากสถานที่ไปทางด้านขวาของทองคำกลางแล้วถอยหลัง ส่วนที่เหลือไม่สามารถทำได้: ทองด้านบนขวาถูกปิดกั้นโดยกำแพงและทองด้านล่างขวาต้องเลี้ยวสองครั้งในบริเวณที่ไวต่อสัตว์ประหลาด

กรณีทดสอบต่อไปนี้ได้รับการบริจาคอย่างไม่เห็นแก่ตัวโดย mbomb007

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

@ mbomb007 ฉันได้เพิ่มตัวอย่างใหม่ สำหรับขนาดของกริดฉันคิดว่าการ จำกัด ให้อย่างน้อย 3x3 นั้นสมเหตุสมผล
Michail

@ mbomb007 โปรดทราบไหมถ้าฉันแก้ไขตัวอย่างใน พวกเขาเมื่อเข้าใจแล้วแสดงให้เห็นถึงตรรกะได้เป็นอย่างดี
Michail

ตามสบาย. นั่นคือสิ่งที่ฉันทำเพื่อพวกเขา อาจสังเกตได้ว่าการหมุนกรณีทดสอบไม่ควรมีผลกระทบต่อผลการทดสอบ
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=="@"}

ลองออนไลน์!

Explantion -

แทนที่จะไปจากผู้เล่นเป็นเงินสดฉันไปจากเคสไปที่ @ ฉันคิดว่าฉันควรจะเร็วกว่านี้เพราะฉันรู้ว่าเมื่อไหร่ที่จะหยุดมอง (ถึง @) และเมื่อคุณมองหาเงินสดคุณจะต้องเดินหน้าต่อไปเรื่อย ๆ จนกว่าคุณจะครอบคลุมทุกจุด (และวิธีที่จะเข้าถึงพวกเขา) ฟังก์ชั่นหลัก g.map((r,y)=>[...r].map((c,x)=>A+=c=="$"&&P(g,x,y)),A=0)|A: หาเงินสด -> หากคุณพบมัน -> เริ่มมองหาผู้เล่น -> หากคุณพบเขา -> การเพิ่มขึ้น A ตอนนี้ให้ไปที่ตัวค้นหาเส้นทาง aka P if(/[.$]/.test(c=(g[y]||[])[x]))เพียงตรวจสอบว่า เซลล์ปัจจุบันคือ "พิเศษ" -> ถ้าเราต้องการส่งคืนถ้าเป็นผู้เล่น กรณีพิเศษ: @ # (สัตว์ประหลาด)

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 true สามารถreturn 1(ค่าตามจริง) และreturn falseสามารถเป็นได้return(โดยนัยundefinedคือค่าเท็จ) (3) regex ^[^.@$#]$เพื่อตรวจสอบว่าไม่มีมอนสเตอร์ที่สั้นกว่า^[a-zA-Z*&]$การตรวจสอบมอนสเตอร์ เยี่ยมมาก!
apsillers

ใช่ฉันรู้ว่าฉันสามารถทำให้มันสั้นลงได้มากขึ้น :)
DanielIndie

@apsillers อัปเดตเป็นทางออกที่ว่างแล้ว :)
DanielIndie
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.