在Haskell的Minesweeper克隆中管理状态

 用户gum5gltoo8 发布于 2023-01-07 10:43

为了学习Haskell,我决定制作一个Minesweeper克隆。我已经编写了一些代码,程序的主要结构已经准备就绪。它基于:

A Board,包含amount地雷的,地图fieldswidth以及height和的列表。

一个Field,包含相邻地雷的数量或一个指示字段本身是地雷的值。该Field还含有FieldStateMarkedHiddenShown)。

游戏循环如下所示:

play board = do
    -- Clear the screen
    putStrLn $ replicate 40 '\n'

    -- Show the board
    print board

    -- Get and process user input
    putStr "Command: "
    -- We are generating a new board to reflect the changes!
    newBoard <- parseInput board <$> getLine

    -- If the game is not ended, go to next step
    if gameEnded newBoard
    then return $ result newBoard
    else play newBoard

目前,这种方法效果很好,但我不喜欢每次转动后都必须产生一个新的事实Board。从C ++这样的命令性语言来看,它看起来效率很低,您只需要对现有的电路板进行改动即可。

要点:

这是正确的方法吗?

编译器会优化它吗?

leftaroundab.. 5

当然,完全更换电路板并非最佳选择,但您的想法也不一定像您想象的那样糟糕。如果Board使用[[FieldState]]-2D网格,则更新单个单元格实际上会重用大多数行(这种工作无需考虑,并且非常安全,因为 Haskell纯粹是起作用的):对于n × n网格,复杂度为On),仅比您查找任何给定字段所需的常数差。对于Minesweeper这样的游戏,绝对不会有任何问题。

对于性能更关键的事情,有一些专用的数组类型可以同时进行O(1)中单个字段(在IOor或STmonad中)的查找和更新。对于与您的应用程序类似的应用程序来说,它可能是最合适的(尽管社区中存在某种趋势,宁愿围绕更低级别,更优化的向量类型编写您的抽象)。Data.Array.MArray

1 个回答
  • 当然,完全更换电路板并非最佳选择,但您的想法也不一定像您想象的那样糟糕。如果Board使用[[FieldState]]-2D网格,则更新单个单元格实际上会重用大多数行(这种工作无需考虑,并且非常安全,因为 Haskell纯粹是起作用的):对于n × n网格,复杂度为On),仅比您查找任何给定字段所需的常数差。对于Minesweeper这样的游戏,绝对不会有任何问题。

    对于性能更关键的事情,有一些专用的数组类型可以同时进行O(1)中单个字段(在IOor或STmonad中)的查找和更新。对于与您的应用程序类似的应用程序来说,它可能是最合适的(尽管社区中存在某种趋势,宁愿围绕更低级别,更优化的向量类型编写您的抽象)。Data.Array.MArray

    2023-01-07 10:46 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有