種別コードを先入れ先出しするキュー Python編
以前,バージョン5のVRMスクリプトで種別コードを先入先出するキューの作例を紹介した。旧VRMスクリプトには配列変数のような概念はなかったので,32bit int型変数を3ビットずつ区切って0~7の種別コードを入れる「枠」とみなし,ビット演算によって種別コードをキューに入れたり取り出したりしていた。
Pythonにおいては,Cでいう配列変数を強化したような「リスト」というデータ形式があるので,それを使って同じことをしてみよう。リストはPython標準の型なので,VRMNX上のPythonエンジンでなくても使うことができる。
実現方法はとてもカンタン。まずは,空のリストを定義する。
TypeQueue = []
appendメソッドで,リストの末尾に要素を追加することができる。
TypeQueue.append(4) # 種別4をキューに追加
ある程度キューに溜まってきたとして,次に来る種別コードを取り出そう。pop(0)が使える。0番目(先頭)の要素を取り出し,もとのリストからは削除する。
TypeQueue = [4, 1, 3, 2] next = TypeQueue.pop(0) # nextは4, TypeQueueは[1, 3, 2]になる
とてもシンプル。
もし,リストが空のときにpopをしようとすると,IndexErrorが発生する。VRMNXでは,エラーが発生するとそのフレームで以降のスクリプトの処理を中止するようだ。(ビュワーは落ちない。)知らずに中止されては都合が悪いが,これを回避するには簡単な方法が2つある。
if TypeQueue == []: # リストが空だったときの処理 pass # 何もしないならこう書いておけばよい(行儀は悪いけど) else: # リストに中身があったときの処理 TypeQueue.pop(0) # エラーは出ない
try: next = TypeQueue.pop(0) except IndexError: # IndexErrorが出てうまくいかなかったときだけここが実行される vrmapi.LOG('Errors should never pass sliently')
2つ目の構文はtry~except節とか言って(旧VRMスクリプトと異なる)Pythonらしいスタイルのひとつである。詳しくはググってみて欲しい。
旧VRMスクリプトでやったときには,末尾に書いたように,Pythonのような高級言語ではこういうことがいっぱいできて,ビット演算なんか使うことは(少なくとも自分が使う範囲では)ないんじゃないか,と思っていたのだが,現在準備中の,踏切を動かす処理の中では早速使うことになった。VRMNXの次のアップデートを待って順次出していくので,お楽しみに。
| 固定リンク
「VRM:研究」カテゴリの記事
- VRMNXの時間系イベントが使いにくいなあと思っているアナタへ(2019.12.24)
- [VRMNX] フレーム同期の話(2019.07.18)
- [Python] リスト型をベクトルに見立てて計算したい(2019.06.16)
- VRMNXのレイヤーベース地形を使ってみよう(前編)(2019.05.18)
- [VRMNX]自動踏切モジュール(2019.01.25)
この記事へのコメントは終了しました。
コメント
POSTしてしまってから知ったのだが,
Python Tutorialによると,FIFO (First-in First-out)なキュー(待ち行列)の実装で生のリスト型を使うのは遅いので,代わりに, collections.deque 型を使うのがいいらしい。
https://docs.python.jp/3/tutorial/datastructures.html#using-lists-as-queues
https://docs.python.jp/3/library/collections.html#collections.deque
Pythonは,あんちょこな実装はやりやすいけれど,エレガントで高速な実装は他の言語と同程度の知識, 経験, 勘が必要な気がしている。Pythonはかんたんというのは半分本当,半分は嘘。
投稿: AKAGI | 2019年1月16日 (水) 00時29分