Tìm đường Roguelike


21

Tìm đường Roguelike

Nhiệm vụ của bạn sẽ là, đưa ra một mảng hai chiều của các yếu tố được mô tả bên dưới, đại diện cho ngục tối, để xuất hoặc trả về một số duy nhất đại diện cho số lượng vàng mà kẻ lừa đảo có thể thu thập mà không đánh thức bất kỳ quái vật nào.

Các yếu tố của mảng như sau:

  1. Các khoảng trống được thể hiện bằng một .hoặc một khoảng trắng , cuộc gọi của bạn;
  2. Vị trí bắt đầu của Rogue được đại diện bởi, tất nhiên , @;
  3. Một miếng vàng được đại diện bởi $;
  4. Tường được đại diện bởi #;
  5. Quái vật được đại diện bởi các nhân vật từ regrec sau : [a-zA-Z*&].

Mảng không được chứa bất kỳ ký tự nào không được liệt kê ở trên, vì vậy bạn có thể cho rằng bất cứ thứ gì không phải là một bức tường, một khoảng trống, kẻ lừa đảo hoặc một miếng vàng đều là một con quái vật.

Các quy tắc cho tìm đường là:

  1. Kẻ lừa đảo chỉ có thể đi qua các ô trống hoặc các ô chứa vàng;
  2. Phải mất một lượt để di chuyển đến một ô liền kề hoặc theo đường chéo;
  3. Nhặt vàng là ngay lập tức;
  4. Kẻ lừa đảo không thể ở liền kề hoặc theo đường chéo với một con quái vật trong hơn một lượt mà không đánh thức nó dậy, điều đó bị cấm;
  5. Kẻ lừa đảo có thể đi vào khu vực nhận thức của một con quái vật bất kỳ số lần, con quái vật sẽ chỉ thức dậy nếu kẻ lừa đảo dành hai lượt liên tiếp gần nó.

Quy tắc đầu vào và đầu ra

Bạn có thể nhận đầu vào ở bất kỳ định dạng hợp lý nào, bao gồm mảng hai chiều, mảng phẳng, chuỗi hoặc bất cứ thứ gì khác. Nếu nó làm cho cuộc sống của bạn dễ dàng hơn, bạn cũng có thể lấy kích thước của mảng.

Nó được đảm bảo rằng kẻ lừa đảo sẽ không ở gần một con quái vật ngay từ đầu.

Một chương trình đầy đủ hoặc một chức năng là tốt.

Chấm điểm

Đây là , điểm số là số byte trong bài nộp của bạn với ít hơn là tốt hơn.

Các trường hợp thử nghiệm

Tôi sử dụng dấu chấm cho các khoảng trống ở đây cho mục đích dễ đọc, nếu bạn muốn bạn có thể sử dụng khoảng trắng (xem bên trên). Cũng lưu ý rằng đây là một sự trùng hợp thuần túy rằng kẻ lừa đảo luôn ở góc trên bên trái, mã của bạn cũng sẽ xử lý bất kỳ vị trí hợp lệ nào khác.

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

Chỉ là một bài kiểm tra vệ sinh.

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

Một lần nữa, một bài kiểm tra sự tỉnh táo.

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

Kẻ lừa đảo có thể lấy vàng bằng cách di chuyển từ bên trái.

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

Kẻ lừa đảo có thể ngoằn ngoèo giữa những con quái vật, không bao giờ ở lại quá một lượt gần nhau.

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

Các chiến thuật từ trường hợp thử nghiệm trước không hoạt động ở đây - các khu vực nhạy cảm quái vật chồng chéo.

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

Kiểm tra sự tỉnh táo.

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

Như trên.

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

Trong số tất cả vàng ở đây, chỉ có thể đạt được ba mức an toàn: vàng gần vị trí bắt đầu có thể nhận được bằng cách di chuyển xuống một và sau đó quay trở lại vị trí bắt đầu. Để thoát khỏi góc trên cùng bên trái, kẻ lừa đảo phải di chuyển theo đường chéo xuống bên phải hai lần. Vàng ở giữa đặt ra không có thách thức. Vàng bên ngoài được bảo vệ bởi gbcó thể có được bằng cách di chuyển theo đường chéo từ nơi bên phải của vàng giữa và sau đó quay trở lại. Phần còn lại không thể có được: vàng phía trên bên phải bị chặn bởi các bức tường và vàng phía dưới bên phải yêu cầu hai lượt trong khu vực nhạy cảm với quái vật.

Các trường hợp thử nghiệm sau đây đã được tặng bởi mbomb007.

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

Điều này là khó khăn. Một con đường là b4-b5-c6-b7-c8-b8(grab).

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

Một con đường là [bc]4-c5-b6-c7-b8(grab).

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

Bức tường phụ không thực sự thay đổi bất cứ điều gì, [bc]4-c5-b6-c7-b8(grab)vẫn là một giải pháp.


Bạn nên thêm một ví dụ lớn hơn và phức tạp hơn. Ngoài ra, kích thước tối thiểu và tối đa của ngục tối là gì? Là dungeon 1x1 @là một đầu vào hợp lệ?
mbomb007


@ mbomb007 Tôi đã thêm một ví dụ mới. Về kích thước của lưới, tôi nghĩ việc giới hạn nó ở ít nhất 3x3 là hợp lý.
Michail

@ mbomb007 Nếu tôi chỉnh sửa ví dụ của bạn trong? Họ, một khi đã hiểu, thể hiện logic rất tốt.
Michail

Đừng ngại. Đó là những gì tôi làm cho họ. Cũng có thể lưu ý rằng việc xoay một trường hợp thử nghiệm sẽ không có tác động đến kết quả của nó.
mbomb007

Câu trả lời:


5

các giải pháp trước đó (một phần của chúng) có thể được tìm thấy trong thùng chứa chân trang trong liên kết tio (những giải pháp có thể dễ đọc hơn)

JavaScript (Node.js) , 883 436 411 360.345 311 byte

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

Hãy thử trực tuyến!

Giải thích -

thay vì chuyển từ người chơi sang tiền mặt tôi đã chuyển từ vụ án sang @. Tôi nghĩ rằng tôi nên nhanh hơn bởi vì tôi biết khi nào nên ngừng tìm kiếm (đạt tới @) và khi bạn tìm kiếm tiền mặt, bạn cần phải luôn luôn di chuyển cho đến khi bạn bao quát tất cả các điểm (và cách để đến với họ). Vì vậy, thuật toán này khá đơn giản theo cách đó - chức năng chính g.map((r,y)=>[...r].map((c,x)=>A+=c=="$"&&P(g,x,y)),A=0)|A: tìm tiền mặt -> nếu bạn tìm thấy nó -> bắt đầu tìm kiếm người chơi -> nếu bạn tìm thấy anh ta -> gia tăng A bây giờ hãy đến công cụ tìm đường dẫn aka P if(/[.$]/.test(c=(g[y]||[])[x]))chỉ cần kiểm tra xem ô hiện tại là "đặc biệt" -> nếu vậy chúng tôi muốn quay lại nếu đó là trình phát. trường hợp đặc biệt: @ # (quái vật)

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 lặp lại hàng xóm một lần nữa - nếu tôi chưa ở đó (p là đường dẫn được thực hiện) tiếp tục đường dẫn (gọi P)


Chơi golf tốt Một vài điều tôi nhận thấy: (1) mã của bạn có khoảng trắng theo dõi không cần thiết trên dòng thứ 2 và thứ 7, và hầu hết các ngắt dòng là không cần thiết (chỉ dòng 1 và 6 cần nghỉ) và I / 3có không gian không cần thiết. Loại bỏ khoảng trắng đó và điểm số của bạn thực sự là 324! (2) return true có thể là return 1(một giá trị trung thực) và return falsecó thể chỉ đơn giản là return(ngụ ý undefined, một giá trị falsey). (3) Regex ^[^.@$#]$để kiểm tra không có phi quái vật nào ngắn hơn ^[a-zA-Z*&]$kiểm tra quái vật. Công việc tốt đẹp!
apsillers

vâng tôi biết tôi có thể làm cho nó ngắn hơn rất nhiều :)
DanielIndie

@apsillers được cập nhật vào giải pháp không gian miễn phí :)
DanielIndie
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.