我目前正在开发名为Neutron的棋盘游戏。
let boardArray = array2D [ ["*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"];
["*"; "1"; "*"; "2"; "*"; "3"; "*"; "4"; "*"; "5"; "*"];
["*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"];
["*"; "0"; "*"; "0"; "*"; "0"; "*"; "0"; "*"; "0"; "*"];
["*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"];
["*"; "0"; "*"; "0"; "*"; "N"; "*"; "0"; "*"; "0"; "*"];
["*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"];
["*"; "0"; "*"; "0"; "*"; "0"; "*"; "0"; "*"; "0"; "*"];
["*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"];
["*"; "A"; "*"; "B"; "*"; "C"; "*"; "D"; "*"; "E"; "*"];
["*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"; "*"] ]
我有这个字符串数组。我的问题是,我该如何打印这样的数组?
我最初的想法是使用嵌套的for循环打印出一些boardArray.[row, column]
,但是据我了解,
row
项
for row in boardArray do
是obj类型;而且我不能完全通过需要int的obj。我可以进行转换吗?我应该使用另一种方法?我是否严重误解了每个循环中F#的用法?
答案 0 :(得分:4)
使用for..to循环解决:
let initiateBoard =
for r = 0 to Array2D.length1 boardArray - 1 do
for c = 0 to Array2D.length2 boardArray - 1 do
printfn "%A " boardArray.[r, c]
这将在新行上打印出每个元素,因此除此以外,还需要一个单独的间距处理功能。
答案 1 :(得分:4)
板上的每个项目是否总是一个字符?如果是这样,那么我建议您稍微更改一下数据类型。
首先,如果木板中的每个项目始终都是单个字符,那么使用char
(而不是字符串)作为每个木板位置的数据类型更有意义,就像这样:
let boardArray = array2D [ ['*'; '*'; '*'; '*'; '*'; '*'; '*'; '*'; '*'; '*'; '*'];
['*'; '1'; '*'; '2'; '*'; '3'; '*'; '4'; '*'; '5'; '*'];
// Etc.
]
但是有一种更好的方式来表示这样的2D字符数组,这就是 strings 的一维数组,其中每个字符串都是一行:
let boardArray = [| "***********";
"*1*2*3*4*5*"
// Etc.
|]
现在访问第r
行和第c
列的字符,而不是写board.[r, c]
,而是写board.[r].[c]
。如果您感到困扰,则可以编写如下的帮助函数:
let getChar (row, col) board = board.[row].[col]
然后像这样使用它:
board |> getChar (1, 3)
这等同于以您当前使用的board.[1, 3]
表示形式进行array2d
。
然后印刷电路板变得非常容易:
for row in board do
printfn "%s" row
由于字符串是不可变的,因此更改板中的项目会有些困难,但是您可以为“使用旧字符串的内容制作新字符串,但该索引处的替换字符除外”定义辅助函数:
let replaceAt idx (ch : char) (s : string) =
let len = s.Length
let before = s.Substring(0, idx)
let after = if idx >= len then "" else s.Substring(idx+1, len-idx-1)
sprintf "%s%c%s" before ch after
用法:
"*1*2*3*4*5*" |> replaceAt 1 'X' // Returns "*X*2*3*4*5*"
因此要将第1行第3行的项目替换为“ X”,您可以这样做:
board.[1] <- board.[1] |> replaceAt 3 'X'
或者,如果您选择 not 来对您的阵列进行突变,而不是为每个板状态创建一个新的阵列,那么您可以使用以下辅助函数来实现:
let replaceItemInArray idx (newItem : 'T) (arr : 'T []) =
arr |> Array.mapi (fun i oldItem -> if i = idx then newItem else oldItem)
let updateBoard newItem (row, col) oldBoard =
let oldRowContents = oldBoard.[row]
let newRowContents = oldRowContents |> replaceAt col newItem
oldBoard |> replaceItemInArray row newRowContents
如果您对我使用的Array.mapi
函数感到好奇,请its documentation is here。