NetHack to gra typu roguelike, w której gracz musi odzyskać Amulet Yendora z najniższego poziomu lochu. Cała gra, powszechnie używana przez telnet, jest reprezentowana przez grafikę ASCII. Gra jest niezwykle wymagająca i wymaga wiedzy na temat wielu mechanizmów gry, aby odnieść sukces.
Na potrzeby tego wyzwania załóż, że cały loch ma jeden poziom i tylko 5 × 16 znaków. Ponadto załóż, że jest to „bezpieczny” loch lub że wdrażasz tylko prototyp - nie będzie potworów, obaw związanych z głodem itp. W rzeczywistości musisz jedynie śledzić położenie postaci, amuletu i gry zakończy się skutecznie, gdy gracz dotrze do tego samego miejsca co amulet.
Wymagania dotyczące wyzwań
- Będzie loch 5 × 16 (pojedynczy poziom).
- Daj graczowi początkową lokalizację (opcjonalnie losową), a amulet osobną losową (inną przy każdym uruchomieniu programu) kwadrat początkowy w lochu. Oznacza to, że amulet nie może startować na tym samym polu co gracz.
- Zaakceptuj cztery klawisze wprowadzania, które poruszają gracza po jednym kwadracie na raz (cztery główne kierunki). Odczytywanie / przetwarzanie innych danych jest dozwolone (funkcja readline (), która wymaga naciśnięcia „enter” itp.).
- Podróżowanie poza granice lochu jest zabronione. Np. Jeśli gracz znajduje się na prawej krawędzi lochu, wciśnięcie w prawo nie powinno nic zrobić.
- Po początkowym wygenerowaniu i po każdym ruchu wydrukuj stan gry. Ponieważ jest to kod golfowy, a drukowanie jest raczej nieciekawe, zignoruj liczbę znaków dla funkcji drukowania i wywołania funkcji, zakładając, że nie zmieniają się żadne stany . Puste komórki powinny być pokazane jako kropka (
.
), amulet jako podwójny cudzysłów ("
) i znak jak przy symbolu (@
). - Gra kończy się, gdy gracz „odkrywa” amulet (przybywa na ten sam kwadrat)
Zwycięski
To jest golfowa gra w golfa, najkrótszy kod spełniający wymagania za tydzień od dzisiaj zostanie ogłoszony zwycięzcą.
Przykład
Oto przykładowe rozwiązanie w języku C # (bez golfa), które pokazuje podstawowe wymagania i przykładowe wyniki.
using System;
namespace nh
{
class Program
{
static Random random = new Random();
// player x/y, amulet x/y
static int px, py, ax, ay;
static void Main(string[] args)
{
px = random.Next(0, 16);
py = random.Next(0, 5);
// amulet starts on a position different from the player
do { ax = random.Next(0, 16); } while (px == ax);
do { ay = random.Next(0, 5); } while (py == ay);
print();
do
{
// reads a single keypress (no need to press enter)
// result is cast to int to compare with character literals
var m = (int)Console.ReadKey(true).Key;
// Move the player. Here standard WASD keys are used.
// Boundary checks for edge of dungeon as well.
if (m == 'W')
py = (py > 0) ? py - 1 : py;
if (m == 'S')
py = (py < 5) ? py + 1 : py;
if (m == 'A')
px = (px > 0) ? px - 1 : px;
if (m == 'D')
px = (px < 16) ? px + 1 : px;
// print state after each keypress. If the player doesn't
// move this is redundant but oh well.
print();
// game ends when player is on same square as amulet
} while (px != ax || py != ay);
}
static void print()
{
Console.Write('\n');
for (int y=0; y<5; y++)
{
for (int x = 0; x < 16; x++)
{
if (x == px && y == py)
Console.Write('@');
else if (x == ax && y == ay)
Console.Write('"');
else
Console.Write('.');
}
Console.Write('\n');
}
}
}
}
Całkowita liczba znaków wynosi 1474, ale ignorowanie wywołań funkcji drukowania i jej definicji to końcowa liczba znaków 896
.
Dane wyjściowe po uruchomieniu programu:
................
...."...........
..........@.....
................
................
Wyjście (w tym powyżej) po dwukrotnym naciśnięciu klawisza „a”:
................
...."...........
..........@.....
................
................
................
...."...........
.........@......
................
................
................
...."...........
........@.......
................
................