我有一些现有的 C# 代码,用于非常非常简单的 RogueLike 引擎。这是故意天真,因为我试图尽可能简单地做最少的数量。它所做的只是使用箭头键和 System.Console 在硬编码地图周围移动 @ 符号:
//define the map
var map = new List<string>{
" ",
" ",
" ",
" ",
" ############################### ",
" # # ",
" # ###### # ",
" # # # # ",
" #### #### # # # ",
" # # # # # # ",
" # # # # # # ",
" #### #### ###### # ",
" # = # ",
" # = # ",
" ############################### ",
" ",
" ",
" ",
" ",
" "
};
//set initial player position on the map
var playerX = 8;
var playerY = 6;
//clear the console
Console.Clear();
//send each row of the map to the Console
map.ForEach( Console.WriteLine );
//create an empty ConsoleKeyInfo for storing the last key pressed
var keyInfo = new ConsoleKeyInfo( );
//keep processing key presses until the player wants to quit
while ( keyInfo.Key != ConsoleKey.Q ) {
//store the player's current location
var oldX = playerX;
var oldY = playerY;
//change the player's location if they pressed an arrow key
switch ( keyInfo.Key ) {
case ConsoleKey.UpArrow:
playerY--;
break;
case ConsoleKey.DownArrow:
playerY++;
break;
case ConsoleKey.LeftArrow:
playerX--;
break;
case ConsoleKey.RightArrow:
playerX++;
break;
}
//check if the square that the player is trying to move to is empty
if( map[ playerY ][ playerX ] == ' ' ) {
//ok it was empty, clear the square they were standing on before
Console.SetCursorPosition( oldX, oldY );
Console.Write( ' ' );
//now draw them at the new square
Console.SetCursorPosition( playerX, playerY );
Console.Write( '@' );
} else {
//they can't move there, change their location back to the old location
playerX = oldX;
playerY = oldY;
}
//wait for them to press a key and store it in keyInfo
keyInfo = Console.ReadKey( true );
}
我在 F# 中玩弄它,最初我试图使用函数概念来编写它,但结果我有点过头了,所以我做了一个直接的移植——它不是真正的 F# 程序(尽管它编译并运行)它是一个用 F# 语法编写的过程程序:
open System
//define the map
let map = [ " ";
" ";
" ";
" ";
" ############################### ";
" # # ";
" # ###### # ";
" # # # # ";
" #### #### # # # ";
" # # # # # # ";
" # # # # # # ";
" #### #### ###### # ";
" # = # ";
" # = # ";
" ############################### ";
" ";
" ";
" ";
" ";
" " ]
//set initial player position on the map
let mutable playerX = 8
let mutable playerY = 6
//clear the console
Console.Clear()
//send each row of the map to the Console
map |> Seq.iter (printfn "%s")
//create an empty ConsoleKeyInfo for storing the last key pressed
let mutable keyInfo = ConsoleKeyInfo()
//keep processing key presses until the player wants to quit
while not ( keyInfo.Key = ConsoleKey.Q ) do
//store the player's current location
let mutable oldX = playerX
let mutable oldY = playerY
//change the player's location if they pressed an arrow key
if keyInfo.Key = ConsoleKey.UpArrow then
playerY <- playerY - 1
else if keyInfo.Key = ConsoleKey.DownArrow then
playerY <- playerY + 1
else if keyInfo.Key = ConsoleKey.LeftArrow then
playerX <- playerX - 1
else if keyInfo.Key = ConsoleKey.RightArrow then
playerX <- playerX + 1
//check if the square that the player is trying to move to is empty
if map.Item( playerY ).Chars( playerX ) = ' ' then
//ok it was empty, clear the square they were standing on
Console.SetCursorPosition( oldX, oldY )
Console.Write( ' ' )
//now draw them at the new square
Console.SetCursorPosition( playerX, playerY )
Console.Write( '@' )
else
//they can't move there, change their location back to the old location
playerX <- oldX
playerY <- oldY
//wait for them to press a key and store it in keyInfo
keyInfo <- Console.ReadKey( true )
所以我的问题是,为了更实用地重写它,我需要学习什么,你能给我一些提示,一个模糊的概述之类的东西。
我宁愿朝正确的方向推进,而不是仅仅看一些代码,但如果这是你向我解释它的最简单方法,那么很好,但在这种情况下,你能否也解释一下“为什么”而不是“如何”的吗?