Каждый элемент на доске всегда будет одним персонажем? Если так, то я бы порекомендовал немного изменить тип данных.
Во-первых, если каждый элемент на доске всегда будет одним символом, то имеет смысл использовать char
s, а не строки, в качестве типа данных для каждой позиции на доске, например:
let boardArray = array2D [ ['*'; '*'; '*'; '*'; '*'; '*'; '*'; '*'; '*'; '*'; '*'];
['*'; '1'; '*'; '2'; '*'; '3'; '*'; '4'; '*'; '5'; '*'];
// Etc.
]
Но есть еще лучший способ представления двумерного массива символов, подобного этому, и это в виде одномерного массива строк , где каждая строка представляет собой строку:
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'
Или, если вы выбираете , а не для изменения ваших массивов, и вместо этого создаете новый массив для каждого состояния платы, то вы сделаете это с помощью следующих вспомогательных функций:
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
, которую я использовал, , ее документация здесь .