F # Распечатка 2D String Array - PullRequest
0 голосов
/ 25 июня 2018

Я сейчас работаю над настольной игрой под названием 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.Могу ли я работать с конверсией?Другой подход, который я должен использовать?Я серьезно неправильно понимаю использование F # для каждого цикла?

Ответы [ 2 ]

0 голосов
/ 25 июня 2018

Каждый элемент на доске всегда будет одним персонажем? Если так, то я бы порекомендовал немного изменить тип данных.

Во-первых, если каждый элемент на доске всегда будет одним символом, то имеет смысл использовать 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, которую я использовал, , ее документация здесь .

0 голосов
/ 25 июня 2018

Решается с помощью цикла 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]

Это распечатает каждый элемент в новой строке, поэтому помимо этого необходима отдельная функция для обработки пробелов.

...