Я создаю игру под названием nim, используя haskell. Подводя итог короткой игре: позвонив nim с последующим номером до 9, я создаю игровое поле для игры:
>> nim 3
1 *
2 * *
3 * * *
1 2 3
Это работает так, как должно. Игра идет следующим образом: Вы можете удалить любое количество звезд из любой строки, но вы должны удалить как минимум 1 звезду. Вы не можете удалить звезды из ряда 1 и 2 в один и тот же ход. Человек, чтобы удалить последнюю звезду, побеждает.
Хорошо, так что игра играет должным образом, но возникает проблема, когда я печатаю доску после каждого хода.
Допустим, у меня есть доска выше, и выдается ввод для удаления1 1 (убрать 1 звезду из строки 1)
Вот что я получаю:
0
2 * *
3 * * *
1 2 3
0 все равно должно быть 1.
Это мои функции, отвечающие запечать доски putRow
принимает номер строки и количество звездочек. Эти два аргумента совпадают, но мне не повезло с изменением функции, чтобы принимать только 1.
putBoard
берет в списке, который представляет доску для игры. putBoard [1,2,3] создает доску из игры выше. Я запускаю putStr в первом элементе, а затем рекурсивно вызываю putRow в оставшейся части списка.
putRow :: Int -> Int -> IO ()
putRow row num = do putStr (show row)
putStr " "
putStrLn (concat (replicate num "* "))
putBoard :: Board -> IO ()
putBoard (x:xs) = putRow x x >> putBoard xs
putBoard [] = putStr " 1 2 3"
putBoard []
будет заменен позже, чтобы создать номера столбцов под доской, но это будет позже. На данный момент это просто строка, которая работает только с игрой с размером доски 3.
Это функция, которая обрабатывает движения, когда задан ряд и количество звездочек
move :: Board -> Int -> Int -> Board
move board row num = [update r n | (r, n) <- zip [1..] board]
where update r n = if r == row then (n - num) else n