NetHackは、プレイヤーがダンジョンの最下層からイェンダーの魔除けを取得しなければならないローグライクゲームです。一般にtelnetを介してプレイされるゲーム全体は、ASCIIグラフィックで表されます。ゲームは非常に挑戦的であり、成功するためには多くのゲームの仕組みの知識が必要です。
この課題のために、ダンジョン全体が単一のレベルであり、5×16文字のみであると仮定します。さらに、これは「安全な」ダンジョンであるか、プロトタイプのみを実装していると想定します。モンスター、空腹に関する懸念などはありません。実際、キャラクターとアミュレットとゲームの位置のみを追跡する必要があります。プレイヤーがアミュレットと同じ場所に到着すると効果的に終了します。
チャレンジ要件
- 5×16のダンジョン(シングルレベル)があります。
- プレイヤーに開始場所(オプションでランダム)を与え、アミュレットにダンジョン内の別のランダム(プログラムが実行されるたびに異なる)開始広場を与えます。つまり、魔除けはプレイヤーと同じマスから始めることはできません。
- プレーヤーを一度に1マスずつ移動する4つの入力キー(4つの基本方向)を受け入れます。他の入力の読み取り/処理が許可されます( 'enter'などを押す必要があるreadline()関数)。
- ダンジョンの境界外への移動は許可されていません。たとえば、プレイヤーがダンジョンの右端にいる場合、右を押しても何も実行されません。
- 初期生成後および各移動後に、ゲームの状態を印刷します。これはコードゴルフであり、印刷はかなり面白くないので、状態の変化がないと仮定して、印刷関数と関数呼び出しの文字数を無視します。空のセルはピリオド(
.)、アミュレットは二重引用符(")、文字はアットマーク()として表示する必要があります@。 - プレイヤーがアミュレットを「発見」するとゲームは終了します(同じ広場に到着します)
勝ち
これは、ゴルフの挑戦であり、今日から1週間の要件を満たす最短のコードが勝者と宣言されます。
例
基本的な要件とサンプル出力を示すC#(ungolfed)のソリューションの例を次に示します。
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');
}
}
}
}
合計文字数は1474ですが、print関数とその定義の呼び出しを無視すると、最終的な文字数はになり896ます。
プログラム実行時の出力:
................
...."...........
..........@.....
................
................
「a」キーを2回押した後の出力(上記を含む):
................
...."...........
..........@.....
................
................
................
...."...........
.........@......
................
................
................
...."...........
........@.......
................
................

