Tôi đang viết một chương trình Sokoban ở Haskell bằng thư viện Gloss và tôi đạt đến điểm tôi muốn, khi người chơi đánh bại một cấp, tải ở cấp độ mới từ tệp văn bản và có chương trình tiếp tục.Làm thế nào để tránh hoạt động trong đơn nguyên IO cho toàn bộ chương trình này?
Tôi đang gặp một chút khó khăn với điều này vì những hạn chế Gloss - chiếc play
chức năng để thiết lập một trò chơi và có nó liên tục cập nhật trông như sau:
play :: forall world
. Display --^Display mode.
-> Color --^Background color.
-> Int --^Number of simulation steps to take for each second of real time.
-> world --^The initial world.
-> (world -> Picture) --^A function to convert the world a picture.
-> (Event -> world -> world) --^A function to handle input events.
-> (Float -> world -> world) --^A function to step the world one iteration.
-- It is passed the period of time (in seconds) needing to be advanced.
-> IO()
(sao chép trực tiếp từ http://hackage.haskell.org/packages/archive/gloss/1.7.4.1/doc/html/Graphics-Gloss-Interface-Pure-Game.html)
đây là world
loại I đang sử dụng:
data Game = Game
{ levelNumber :: Int,
currentLevel :: Level Square,
won :: Bool }
nơi Level
s chứa các khối ở cấp độ hiện tại. Tôi đọc trong Game
s sử dụng một cái gì đó như thế này (chưa thực sự làm một tổng quát được nêu ra, nhưng điều này về cơ bản là tất cả nó sẽ là một cuộc tranh luận với filename):
startGame = do
lvl <- readFile "levels/level001.lvl"
let lvl' = parseLevel lvl
return $ Game 1 lvl' False
Vì vậy, khó khăn của tôi là phát sinh do của các chức năng cập nhật trong play
. Tôi có thể dễ dàng chụp Game
và tạo ra Picture
(và Game
, v.v.) mà không phải đọc bất kỳ dữ liệu nào từ hệ thống tệp nếu tôi chỉ hoạt động ở một cấp, nhưng vì tôi đang tải các cấp từ tệp trong giữa trò chơi, tôi không biết cách tránh tạo ra tất cả Game
s IO Game
s của mình. Có lẽ điều này là không thể trong hoàn cảnh này, và có lẽ đó là vì một lý do chính đáng? Tôi sẽ luôn hoạt động trên Game
được lấy từ một tệp nhưng tôi không biết liệu nó có thể tránh được tại bất kỳ điểm cụ thể nào không và nếu có, tôi muốn tránh nó.
Bạn có thể sử dụng IO lười ("BOOO! HISSSSS !!!") ví dụ: với gói (directory) 'tree-tree' để tải toàn bộ cây thư mục của các tệp trò chơi trước khi gọi' play', và truyền xung quanh kiểu cây kết quả trong 'Trò chơi' của bạn. Hoặc đặt tất cả các cấp của bạn trong một tệp và thực hiện tương tự với tiêu chuẩn 'readFile'. – jberryman
Nếu không, hãy cắn và sử dụng ['Graphics.Gloss.Interface.IO.Game.playIO'] không đúng (http://hackage.haskell.org/packages/archive/gloss/latest/doc/html/Graphics- Gloss-Interface-IO-Game.html # v: playIO). Bạn vẫn có thể giữ hầu hết logic của mình trong các hàm thuần túy. – hammar
Bạn có thể cho chúng tôi thấy trình phân tích cú pháp không? Không có khả năng trở lại ví dụ như các chuỗi bình thường? –