0

我正在为终端编写一个蛇游戏,即通过打印输出。

以下工作正常:

while status[snake_monad] do
  print to_string draw canvas, compose_all([
    frame,
    specs,
    snake_to_hash(snake[snake_monad])
  ])

  turn! snake_monad, get_dir
  move! snake_monad, specs

  sleep 0.25
end

但我当然不希望turn!ing 阻塞。所以我把它放入一个新线程并让它循环:

Thread.new do
  loop do
    turn! snake_monad, get_dir
  end
end

while status[snake_monad] do
  ...
  # no turn! here
  ...
end

这在逻辑上也有效(蛇正在转动),但输出以某种方式穿插了换行符。一旦我杀死输入线程(^C),它看起来又正常了。

那么线程为什么以及如何对我的输出产生影响呢?我该如何解决这个问题?
(我对线程知之甚少,对 ruby​​ 中的线程了解甚少。在同一个终端上同时输入和输出使事情变得更糟,我猜......)



另外(不是很重要):希望我的程序尽可能纯净,在传递所有内容的同时以非阻塞方式获取输入是否有点容易?

谢谢!

4

2 回答 2

0

您不想要非阻塞IO - 您想要无缓冲IO。

这里不需要线程 - 您只需将终端置于正确模式,然后等待主事件循环上的按键。

这是一个完全荒谬的例子。

require 'io/wait'

def ping
  term = `stty -g`
  `stty raw -echo cbreak`
  loop do
    if STDIN.ready?
      #command thy snake!
      ret = STDIN.getc 
    end
    if ret
      #process the snake command if there was one
      STDOUT.write("you told the snake to #{ret}\n")
    else
      #slither around bitin' fools and hustling apples.
    end
  end
ensure
  `stty #{term}`
end
于 2012-07-03T16:27:19.070 回答
0

我找到了一个肮脏的解决方案:

\r我只需要在函数中的每个换行符后添加一个回车符 ( ) to_string,因此在它之后打印的所有内容都将被覆盖。由于它是换行符,因此它失去了作用。现在一切似乎都很好。

但我更想知道为什么会发生这种情况并干净地修复它(如果可能的话)。

于 2012-07-03T16:27:33.353 回答