首页 > 解决方案 > 为什么这些字符打印在 putStrLn 的开头

问题描述

我试图从 G. Hutton 的 Programming In Haskell 中了解井字游戏代码。代码在文件 tictactoe.hs 中。在 Windows 上,它会在显示游戏网格的开头生成这些字符 (←[2J←[1;1H)。它不会发生在 Ubuntu 上。

←[2J←[1;1H   |   |
   |   |  
   |   |
 -----------
   |   |
   |   |
   |   |
 -----------
   |   |
   |   |
   |   |

似乎出现在这个函数中

 putGrid :: Grid -> IO ()
 putGrid =
   putStrLn . unlines . concat . interleave bar . map showRow
   where bar = [replicate ((size*4)-1) '-']

游戏的完整代码可在此处获得 https://www.cs.nott.ac.uk/~pszgmh/pih.html

标签: haskell

解决方案


这些是ANSI 转义码[wiki]。如果您在支持 ANSI 转义引号的终端中运行它,这些可以改变字符的打印方式:例如以粗体字、不同颜色等。

←[2J是终端制作出来的"\ESC[2J",这将清除屏幕,而←[1;1H将光标移动到左上角,正如维基百科页面上指定的那样:

                           缩写 姓名 影响
(……) (……) (……) (……)
CSI n ; m H CUP 光标位置 将光标移动到行n、列m。这些值从 1 开始,如果省略,则默认为 1(左上角)。序列 as是asCSI ;5H的同义词,与and相同。CSI 1;5HCSI 17;HCSI 17HCSI 17;1H
CSI n J ED 擦除显示 清除部分屏幕。如果 n 为 0(或缺失),则从光标到屏幕末尾清除。如果 n 为 1,则从光标清除到屏幕开头。如果 n 为 2,则清除整个屏幕(并在 DOS ANSI.SYS 上将光标移动到左上角)。如果 n 为 3,则清除整个屏幕并删除保存在回滚缓冲区中的所有行(此功能是为 xterm 添加的,其他终端应用程序支持)。
(……) (……) (……) (……)

因此,这用于以游戏的新状态“刷新”屏幕。为了正确渲染,您需要使用能够“理解”这些序列并正确实现这些序列的终端。


推荐阅读