-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdl1.html
256 lines (221 loc) · 9.7 KB
/
dl1.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
<!DOCTYPE html>
<!--[if IEMobile 7 ]><html class="no-js iem7"><![endif]-->
<!--[if lt IE 9]><html class="no-js lte-ie8"><![endif]-->
<!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]-->
<head>
<meta charset="utf-8">
<title>キー入力と任意位置へのテキスト表示 — Dreaming in Greater Boston</title>
<meta name="author" content="Kyos">
<!-- http://t.co/dKP3o1e -->
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/favicon.png" rel="icon">
<link href="/theme/css/main.css" media="screen, projection"
rel="stylesheet" type="text/css">
<link href="//fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic"
rel="stylesheet" type="text/css">
<link href="//fonts.googleapis.com/css?family=PT+Sans:regular,italic,bold,bolditalic"
rel="stylesheet" type="text/css">
</head>
<body>
<header role="banner"><hgroup>
<h1><a href="/">Dreaming in Greater Boston</a></h1>
</hgroup></header>
<nav role="navigation"><ul class="subscription" data-subscription="rss">
</ul>
<ul class="main-navigation">
<li><a href="/pages/about.html">About Me</a></li>
<li >
<a href="/category/blog.html">Blog</a>
</li>
<li >
<a href="/category/english.html">English</a>
</li>
<li >
<a href="/category/linux.html">Linux</a>
</li>
<li class="active">
<a href="/category/python.html">Python</a>
</li>
<li >
<a href="/category/tech.html">Tech</a>
</li>
</ul></nav>
<div id="main">
<div id="content">
<div>
<article class="hentry" role="article">
<header>
<h1 class="entry-title">キー入力と任意位置へのテキスト表示</h1>
<p class="meta">
<time datetime="2021-02-24T00:00:00-05:00" pubdate>Wed 24 February 2021</time> </p>
</header>
<div class="entry-content"><div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#org0eef26d">1. ノンブロッキングキー入力</a></li>
<li><a href="#org1f80df2">2. 任意位置への文字表示</a></li>
<li><a href="#orgb1f415a">3. 次回</a></li>
</ul>
</div>
</div>
<p>
Rogue + Wizライクプロジェクトの2回目はキー入力と画面表示です。
</p>
<div id="outline-container-org0eef26d" class="outline-2">
<h2 id="org0eef26d"><span class="section-number-2">1</span> ノンブロッキングキー入力</h2>
<div class="outline-text-2" id="text-1">
<p>
まずはリアルタイムキースキャンから。これがいきなり曲者で、簡単には実現できないようです。
</p>
<p>
Windowsではmsvcrtというライブラリを使うみたいです。msvcrt.getch()は使い勝手がよさそう。しかし私の手元にはMacしかないので、別のやり方を探してみます。検索すること数十分、いちおう標準ライブラリの(?)termiosを使うやり方がいいのかな。Stackoverflowの<a href="https://stackoverflow.com/questions/13207678/whats-the-simplest-way-of-detecting-keyboard-input-in-a-script-from-the-termina">このQ&A</a> に例が出ています。引用します。
</p>
<div class="org-src-container">
<pre class="src src-python">import termios, fcntl, sys, os
fd = sys.stdin.fileno()
oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)
oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
try:
while 1:
try:
c = sys.stdin.read(1)
if c:
print("Got character", repr(c))
except IOError: pass
finally:
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
</pre>
</div>
<p>
Windowsよりもずいぶん準備や後処理が面倒だし、tryブロックがネストしていて微妙な感じですが、試したところ十分使えそうです。これをお借りしましょう。
</p>
</div>
</div>
<div id="outline-container-org1f80df2" class="outline-2">
<h2 id="org1f80df2"><span class="section-number-2">2</span> 任意位置への文字表示</h2>
<div class="outline-text-2" id="text-2">
<p>
次は画面上の指定位置への文字表示です。昔懐かしのBASIC言語でいうところのLOCATEに相当することがしたいです。検索でだいぶ手間取りましたが、思いのほか簡単に実現できることがわかりました。ANSIエスケープシーケンスで指定するのですね。
</p>
<div class="org-src-container">
<pre class="src src-python">print(f"\033[{y};{x}H@", end='')
</pre>
</div>
<p>
これでx, yの位置にアットマーク('@')を表示します。バックスラッシュ('\')から'H'までが位置指定のエスケープシーケンスです。ここでは1文字しか表示していませんが、2文字以上の文字列を表示させることももちろんできます。
</p>
<p>
簡単な性能テストをしてみます。
</p>
<div class="org-src-container">
<pre class="src src-python">import random
import time
while True:
c = random.choice([b'1',b'2',b'3',b'4',b'5',b'6',b'7',b'8',b'9'])
start = time.time()
for y in range(25):
print(f"\033[{y};0H", end='')
line = bytearray(c*60)
print(line.decode())
delta = time.time() - start
print(f"{delta:.3f}")
</pre>
</div>
<p>
これはランダムな数字を60x25文字の表示エリアに一様に表示することを繰り返します。実際のゲームと同様にbytearrayで持つ1行ごとのデータを、文字列にデコードしながら1回のプリント文で表示しています。
</p>
<p>
実行したところ、十分に高速でした。描画しているところはほとんど見えず、実行時間は1画面あたり100分の一秒未満でした。行けそうです。
</p>
</div>
</div>
<div id="outline-container-orgb1f415a" class="outline-2">
<h2 id="orgb1f415a"><span class="section-number-2">3</span> 次回</h2>
<div class="outline-text-2" id="text-3">
<p>
次はローグライクなランダムマップの自動生成に挑戦します。ありがたいことにRoguelike Tutorialなページが <a href="http://rogueliketutorials.com/tutorials/tcod/v2/part-3/">ありました</a> ので、参考にさせていただきます。なるほど、部屋と部屋を結ぶ方法は意外と単純だったのですね。線を引くのにジェネレーターを使うのはよいアイデアと思いました。
</p>
</div>
</div>
</div>
<footer>
<p class="meta">
<span class="byline author vcard">
Posted by <span class="fn">
きょうす
</span>
</span>
<time datetime="2021-02-24T00:00:00-05:00" pubdate>Wed 24 February 2021</time> <span class="categories">
<a class='category' href='/category/python.html'>Python</a>
</span>
<span class="categories">
<a class="category" href="/tag/python.html">Python</a>, <a class="category" href="/tag/game.html">game</a> </span>
</p><div class="sharing">
</div> </footer>
</article>
</div>
<aside class="sidebar">
<section>
<h1>Recent Posts</h1>
<ul id="recent_posts">
<li class="post">
<a href="/kakutei24.html">アメリカから日本の確定申告を準備する(令和6年分)</a>
</li>
<li class="post">
<a href="/utm_ub.html">M1 MacBook上にUbuntu+RetroArchを入れる</a>
</li>
<li class="post">
<a href="/tello.html">アメリカ格安SIMをSpeedtalkからTelloに変えました</a>
</li>
<li class="post">
<a href="/improve_eng2.html">上級者向け英語学習法(実践編)</a>
</li>
<li class="post">
<a href="/improve_eng1.html">上級者向け英語学習法(考察編)</a>
</li>
</ul>
</section>
<section>
<h1>Categories</h1>
<ul id="recent_posts">
<li><a href="/category/blog.html">Blog</a></li>
<li><a href="/category/english.html">English</a></li>
<li><a href="/category/linux.html">Linux</a></li>
<li><a href="/category/python.html">Python</a></li>
<li><a href="/category/tech.html">Tech</a></li>
</ul>
</section>
<section>
<h1>Tags</h1>
<a href="/tag/blog.html">Blog</a>, <a href="/tag/amerikasheng-huo.html">アメリカ生活</a>, <a href="/tag/linux.html">Linux</a>, <a href="/tag/tech.html">Tech</a>, <a href="/tag/ying-yu.html">英語</a>, <a href="/tag/emacs.html">emacs</a>, <a href="/tag/sekiyuritei.html">セキュリティ</a>, <a href="/tag/investment.html">Investment</a>, <a href="/tag/python.html">Python</a>, <a href="/tag/english.html">English</a>, <a href="/tag/mac.html">Mac</a>, <a href="/tag/toraburu.html">トラブル</a>, <a href="/tag/game.html">game</a>, <a href="/tag/vacation.html">Vacation</a>, <a href="/tag/ying-yu-jiao-yu.html">英語教育</a>, <a href="/tag/ying-jian.html">英検</a> </section>
<section>
<h1>Social</h1>
<ul>
<li><a href="#" target="_blank">You can add links in your config file</a></li>
</ul>
</section>
<section>
<h1>Blogroll</h1>
<ul>
<li><a href="https://getpelican.com/" target="_blank">Pelican</a></li>
</ul>
</section>
</aside> </div>
</div>
<footer role="contentinfo"><p>
Copyright © 2020–2025 Kyos —
<span class="credit">Powered by <a href="http://getpelican.com">Pelican</a></span>
</p></footer>
<script src="/theme/js/modernizr-2.0.js"></script>
<script src="/theme/js/ender.js"></script>
<script src="/theme/js/octopress.js" type="text/javascript"></script>
</body>
</html>