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 に答える