Diksam on Windowsを公開しました

Webサイトのほうで、Diksamの新バージョン、「Diksam on Windows」を公開しました。

プログラミング言語を作る/Diksam on Windows

これは、Diksamに、ウインドウを開いたり直線や円弧やビットマップを描画したりキーボードやマウスのイベントを拾う機能を加えたものです。
ただし、現状では、Windowsでしか動きません。やっぱりユーザ数が多いと思われるところから対応したいと思いますので。

サンプルプログラムとして、こんな「UFOゲーム」を作ってみました

……私と同世代の人は、こういうゲームを中学生くらいの頃にせっせと作った経験があるんじゃないでしょうか。

このゲーム(?)自体は実際のところ単なるネタですが、我々の世代は、というか少なくとも私は、最初はこういうゲームからプログラムを学びました。まあもっとも言語がBASICだけにプロになってそれがプラスになっているかどうかはわかりませんけれど*1。でも、いまどきの若い人たちには、こういうことができる手軽な言語がないよね、ということはずっと前から思っていて、そのことはかつてこのへんにも書きました。

ちょっと前、定期的に盛り上がる「初心者向けプログラミング言語は何がよいか」ネタでまた盛り上がっていましたけど、

初心者はプログラミングをどうやって学ぶと良いのだろうか?:Geekなぺーじ

昔の私が居た環境は、そもそもコマンドラインばかりで、ウィンドウを新しく出すのはブラウザのMoasicを出すか、emacsをコンソールじゃない状態で出す時だけで、それ以外は全部CUI(Character-based User Interface)でした。そういう意味で、昔はprintfだけのプログラムを作るだけでも「イメージが湧いた」のだと思います。しかし、簡単なCUIぽいプログラムを書いたとしても今は「何それ?ショボイ!!!」になるのだろうと思います。

そうですよねえ。

でも、GUIプログラミングって結構面倒なんですよね。色々おまじない的に覚えなければならないことが多いですし。

なるべくおまじないは減らしたい。でも、汎用言語としていびつになってしまうのは嫌だ、ということで、Diksamでは、以下のようにしてみました。

create_window()関数でウインドウを作る。

HSPなんかだと、なぜか最初から1枚だけウインドウが開いているようですが、これはあまりに美しくない。というわけで、Diksamでは、create_window()関数でウインドウを開くようにしました。

Window w = create_window("UFOゲーム", 800, 600, attr);

引数の意味は、前から順にタイトルバーの文字列、ウインドウの幅、高さ、最後がウインドウ属性です。

初心者からしてみれば、『「Window」って何だ?』とか、『「w」はなぜ必要なんだ?』という疑問が出てきそうですが、ウインドウをふたつ開くことを考えれば、そのへんの疑問は解決しないかなあ、と思うのですが……どうでしょうか。

また、create_window()が関数なのは、「コンストラクタ」などという謎の概念は敷居が高いだろう、と思ったからですが、そしてBrushやFontは同様に関数で作るのですが、Penはやっぱりコンストラクタを提供していたりして……すみませんこのへん統一できてないです。

いらない引数はできるだけ書かせない。

create_window()関数における最後の引数attrは、WindowAttributeクラスのオブジェクトです。このオブジェクトに設定することで、ウインドウの背景色やら表示位置やらが変更できるのですが、デフォルトでよければ、attrの代わりにnullを渡せばよいようにしています。
Cでウインドウを開こうとすると、XlibでもWindowsAPIでも、やたらたくさんの引数を渡すようになっていますが、上記程度なら扱いやすいのではないかなあ、と。attrを設定する場合も、普通にWindowAttributeクラスをnewすれば、デフォルトの値がそこに設定されています。必要な部分だけ変更すればよいわけです。

イベントドリブンでなくても書けるように。

UFOゲームのようなゲームを作るに当たっては、やっぱりゲームの処理全体をループで囲み、そのループの中で、UFOや砲台をちょっとずつ動かす、というのが、ひとまずは自然なのではないでしょうか。しかし、最近のウインドウシステムではたいていイベントドリブンがベースになってしまっていて、それだと処理が分断されてわかりにくくなってしまうように思います。そこでDiksamでは、時限メッセージループ関数timed_message_loop()と、現在押されているキーを検知する関数is_key_pressed()を用意しました。まあ、マウスの座標は依然としてイベント(メッセージ)でしか拾えないのですが。

UFOゲームのソースはこちら。どんなもんでしょうか。

それはさておき、上記「Geekなペーじ」には、

個人的には、オブジェクト指向的な「難しい」ものを最初から理解できるのだろうか?というのがいつも疑問に思えます。抽象化って凄く難しい事で、ゼロから書く手続き型プログラミングの方が「何をやってるのか?」を理解しやすいと思うのですよね。 C言語で「mainから書けば順番通りに動く」のと、JavaScriptなどで「状況がマッチすると呼び出される」というのでは、上から順番に流れていく手続き型の方が直感的だと感じています。

とも書いてあって、私はここにも同意します。

オブジェクト指向どころか構造化プログラミングも、実は初心者には理解しがたいのかもしれません。つか、今回のUFOゲームでは、私自身、gotoが使いたくなった……

http://java-house.jp/ml/archive/j-h-b/005547.html#body

そんな書き方をするのが悪いのです。
構造化プログラミングについて勉強なさったことはありますか?

行き当たりばったりの goto プログラミングをやめて、プログラム全体を
見通してみるようにすると、「オープンする」「準備できましたか?」の
処理は「エラーがなくなりまで繰り返す」という構造を持っていること
に気付けると思います。

高木さんの言うこともわかるけど、最初っからこれを想定することが、果たして自然かなあ。

Diksamにはretry文つけるかな。

*1:私について言えば、会社の新人研修でプログラミングスタイルから何からすべて矯正されました。