curses
ターミナル ゲーム (Mac OSX、Python 2.6.5) のパズルに使用しています。パズルには、いくつかのダイヤルを回してロックを開くことが含まれます。私のコードは、やや単純化されています(醜さを許してください):
import curses
dial = ["| -1 |","|-1/3 |","| 0 |","| 1/2 |","| 2/3 |","| 1 |"]
clear = " "
pointer = " ^ "
subdials = [clear,clear]
d = {'d0':{},'d1':{}}
d['d0'] = {'val':2,'disp':dial[2]}
d['d1'] = {'val':2,'disp':dial[2]}
def spin(scr):
try:
curses.curs_set(0)
except:
pass
solved = 0
p = 0
subdials[p] = pointer
dials = [d['d0']['disp'],d['d1']['disp']]
maxy,maxx = scr.getmaxyx()
newscr = scr.subwin(10,51,maxy-15,0)
newscr.box(ord('|'),ord('-'))
newscr.addstr(4,8,''.join(dials))
newscr.addstr(6,8,''.join(subdials))
newscr.refresh()
while solved == 0:
r = scr.getch()
subdials[p] = clear
currd = 'd'+str(p)
if r == ord('q') or r == ord('Q'):
break
elif r == curses.KEY_LEFT:
if p > 0 and p < 2:
p -= 1
else: pass
elif r == curses.KEY_RIGHT:
if p >= 0 and p < 1:
p += 1
else: pass
elif r == curses.KEY_UP:
if d[currd]['val'] >= 0 and d[currd]['val'] < 5:
d[currd]['val'] += 1
d[currd]['disp'] = dial[d[currd]['val']]
else: pass
elif r == curses.KEY_DOWN:
if d[currd]['val'] > 0 and d[currd]['val'] <= 5:
d[currd]['val'] -= 1
d[currd]['disp'] = dial[d[currd]['val']]
else: pass
else: pass
subdials[p] = pointer
dials = [d['d0']['disp'],d['d1']['disp']]
newscr.addstr(4,8,''.join(dials))
newscr.addstr(6,8,''.join(subdials))
newscr.refresh()
if d['d0']['val'] == 5 and d['d1']['val'] == 3:
solved = 1
if solved == 0:
scr.addstr(maxy-1,0,"You can't figure out the lock.")
else:
scr.addstr(maxy-1,0,"The lock is open!")
scr.getch()
scr.clear()
return solved
def box():
solved = curses.wrapper(spin)
return solved
「ボックス」機能を終了するには、「q」を押して終了するか、パズルを解くという 2 つの方法があります。初めて curses を終了するときは (どちらの方法でも)、問題ありません。しかし、もう一度「box」を呼び出すと、すぐに問題が発生します。
まず、curses ウィンドウ内で、関数に指示されたキー入力がpass
画面にエコーされます。2 番目に、さらに悪いことに、2 度目にパズルを終了すると (終了するか勝つかのいずれかで)、電源がオフになっていないため、端末がいっぱいになり、リセットする必要がありますnoecho
。cbreak
(注: 「box」を呼び出し続けると、キー入力は curses ウィンドウ自体にエコーされなくなりますが、端末は通常に戻りません。)
私は一生、この行動の原因を突き止めることはできません。ヘルプ!