見出し画像

cursesのキー入力

pythonのcursesライブラリでメソッドgetchを使うとキーボードから入力を受け取れる。戻り値はキャラクタコード。

ch = stdscr.getch()

Cの文字リテラルであれば、コンパイラ側ではキャラクタコードで扱ってくれるが、pythonではシングルクォーテーションでくくってもstr型になるのでキャラクタコードとは一致しない。

ch = stdscr.getch()
if ch == 'a':
    // non matching

このような場合、pythonではどうすればいいのかを調べてみると、組み込み関数ordを使って文字列をキャラクタコードに変換するようだ。

ch = stdscr.getch()
i比較 ch == ord('a'):
    // matching

ローグのコマンド処理は比較する文字が多いため、これでは効率が悪い。だからメソッドgetchで取得できたキャラクタコードのほうを文字列へ変換したい。その変換を行うのが組み込み関数chrらしい。

ch = chr(stdscr.getch())
if ch == 'a':
    // matching

ローグの場合はキャラクタコードを文字列へ変換しておくと、メソッドisalphaやisupperなども使えるので処理を書きやすくなる。

たとえば、identifyコマンドの場合、入力されたキーがアルファベットの大文字であればモンスター名を取得するけど、こういった判定でも統一的に書くことができる。

if ch.isupper():
    string = Monsters.getMonsterName(ch)

エスケープシーケンスを使うこともできるので、改行やエスケープキーの判定もできる。

ch = chr(stdscr.getch())
if ch in [ "\n", "\x1B" ]:
    // matching

ローグのキー入力処理はソースコードio.cの関数readcharにまとめられている。Cの場合はストリームを介さない低レイヤのキー入力処理を使っていて、ファイルデスクリプタから直接キャラクタコードを読み込んでいる。

--- io.c ---
114: readchar()
115: {
116:     char c;
117:     fflush(stdout);
118:     while (read(0, &c, 1) < 0)
119:         continue;
120:     return c;
121: }

これをpython式に書き直すとこうなる。stdscrは基本的にstdinが紐づけられるので、とりあえずはこれでコマンド入力することができるようになった。

def readChar():
   return chr(Global.stdscr.getch())


この記事が気に入ったらサポートをしてみませんか?