【问题标题】:Take input from user until tic-tac-toe game ends接受用户输入直到井字游戏结束
【发布时间】:2015-09-19 17:04:58
【问题描述】:

所以我通过CIS194 大约有八周的时间,我正在用 Haskell 制作一个超级简单的井字游戏。我已经把大部分游戏逻辑都搞定了,但我对用户输入部分感到困惑。

到目前为止,只是为了检查所有内容,我有一个糟糕的系统来硬编码用户和计算机的动作。

putStrLn "Welcome to tic tac toe. Where do you want to move first?"

let board1 = emptyBoard
putStrLn (show board1)
loc1 <- getLine
let moveLoc1 = read loc1
let board2 = findAndReplace board1 (Left moveLoc1) (Right O)

...

let board7 = makeXMove board6
putStrLn (show board7)
loc4 <- getLine
let moveLoc4 = read loc4
let board8 = findAndReplace board7 (Left moveLoc4) (Right O)


putStrLn (show board8)

不过,我的目标是接受用户输入,检查游戏是否结束,让计算机移动,检查游戏是否结束,如果没有则重复。在命令式语言中,我会在 while 循环中包装这样的内容,但我不确定如何在 Haskell 中解决这个问题。

从我在网上看到的情况来看,有很多东西听起来可能会有所帮助,但我不知道从哪里开始。例如,我也在看this example,我听说过很多关于Monads 和State 的信息,但是有没有什么介绍性的文献可以让我了解整个事情?

我目前所有的代码都可以在on github找到。

基本上我的问题是如何在游戏结束之前询问用户输入,并在游戏结束时停止询问他们?

【问题讨论】:

  • 在 Haskell 中,您通常在这种情况下使用递归。
  • 如何沿递归传递游戏板? main 函数中的递归是如何工作的?
  • @2016rshah 递归可以是基于值的。编写一个函数来产生一个调用自身的 IO 操作,或者只是再次引用 main

标签: haskell state monads


【解决方案1】:

你将棋盘传递给递归调用

player :: Board -> IO ()
player board1 = do
    putStrLn (show board1)
    loc1 <- getLine
    let moveLoc1 = read loc1
    let board2 = findAndReplace board1 (Left moveLoc1) (Right O)
    if over board2                    -- check to see if the game is over and we should stop recursing
    then putStrLn (outcome board2)    -- what to do when the game is over
    else computer board2              -- recurse for the other player if the game isn't over
--       |        ^-- the state of the board being passed to the recursive call
--       ^----------- the recursive call to the other player


computer :: Board -> IO ()
computer board1 = do
    let board2 = makeXMove board1
    if over board2                    -- check to see if the game is over and we should stop recursing
    then putStrLn (outcome board2)    -- what to do when the game is over
    else player board2                -- recurse for the other player if the game isn't over
--       |        ^-- the state of the board being passed to the recursive call
--       ^----------- the recursive call to the other player

您需要填写检测游戏何时结束的函数over :: Board -&gt; Bool 和描述游戏结果的outcome :: Board -&gt; String。你会在玩家开始游戏时先用

main = do
    putStrLn "Welcome to tic tac toe. Where do you want to move first?"
    player emptyBoard

playercomputer 中有很多代码重复。对自己来说,一个很好的挑战是弄清楚如何摆脱重复的代码。你能改变player,让它不知道computer,反之亦然,然后让两个player互相对战(可能稍微修改一下,以区分哪个是X,哪个是O )?

【讨论】:

  • 这个解决方案现在非常有意义,非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-12
  • 2019-08-17
  • 1970-01-01
相关资源
最近更新 更多