Skip Navigation

Wireless・のおと

サイレックスの無線LAN 開発者が語る、無線技術についてや製品開発の秘話、技術者向け情報、新しく興味深い話題、サイレックスが提供するサービスや現状などの話題などを配信していきます。

前の記事:「Bluetooth5の補遺」へ

プログラミングのはなし

2017年4月 7日 09:15
YS
今回はプログラミングのおはなしです。
生まれて初めて自分で書いて、自分で動かしたコンピュータプログラムを覚えているでしょうか。殆どの人は覚えていないでしょうね。ひょっとしたら「コンピュータプログラムなんて書いたことがない」という読者の方もおられるかもしれませんね。
Sometimes I feel, back in the old days...
さて幸か不幸か、私は今でも「生まれて初めて動かしたコンピュータプログラム」を覚えています。図書館で借りた BASIC 言語の入門書に載っていた、単価 100 円のリンゴと単価 70 円のミカンの合計金額を表示するというプログラムです。

10 INPUT "HOW MANY APPLE", RINGO
20 INPUT "HOW MANY ORANGE", MIKAN
30 PRINT "TOTAL=";
40 PRINT RINGO * 100 + MIKAN * 70
50 GOTO 10

当時小学6年生の私はパソコンなど持っていなかったので、パソコンを置いている最寄りの大手電器店に自転車で乗り付け、店頭デモの松下 JR-200 に打ち込んで動かし「すごい!本当に動いた!」などと感動していました。当時パソコンを買うお金はないけどコンピュータを触りたくて仕方がない子供たちは、こうやって店頭デモのパソコンを恐る恐る触りながらパソコンを学んだものですが、彼等は「マイコン族」をもじって「ナイコン族」と呼ばれていました。まだ「パソコン」よりも「マイコン」の方が広く使われていた時代ですね。そういえばTVドラマ「太陽にほえろ」にもマイコンという渾名の刑事が登場していました。すっかりじじいの昔話ですね。

さて、リンゴとミカンの合計金額算出プログラムは「そんなの電卓で出来るじゃん」と一蹴されそうな「実用的」プログラムです。では、次のプログラムはどうでしょうか。

10 WIDTH 40,25:CONSOLE 0,25,0,1
20 X=20:Y=12
30 LOCATE X,Y:PRINT "●";
40 NX = X + (1-INT(RND * 3))
50 IF (NX < 0) THEN NX=0 ELSE IF (NX > 79) THEN NX=79
60 NY = Y + (1-INT(RND * 3))
70 IF (NY < 0) THEN NY=0 ELSE IF (NY > 24) THEN NY=24
80 LOCATE X,Y:PRINT " ";
90 X=NX:Y=NY
100 GOTO 30

※註:WIDTH 40,25 は「40文字x25行モード」、CONSOLE 0,25,0,1は「スクロール範囲0~25行、ファンクションキー表示なし、カラーモード」を意味する N-BASIC 固有の画面設定命令です。

このプログラムでは座標変数 X,Y に応じて丸印を描き、この●は乱数で上下左右に(画面上の表示を「食いつぶしながら」)動きます。今のパソコンなら適当に遅延を入れないと●の動きが速すぎて見えないかも知れませんが、昔の 8bit パソコンでは遅延を入れなくても●の動きは数コマ毎秒でした。
MS-BASIC の RND 関数は 0~1.0 未満の少数を返すので 3 倍して INT() で小数点を切り捨てれば 0~2 の値となり、1 からそれを引くことで -1~+1 の値にしています。
RND の直後に入っている IF 文は X, Y が画面の外へ出ないためのリミッターです。これを入れておかないと、画面領域外にはみ出したとたん BEEP 音を鳴らし「Illegal Function Call」を表示して止まってしまいます。

さて、これでもピンと来ない?乱数で●が動くのが何が面白いのって?では、判断を1行追加してみましょう。

10 WIDTH 40,25:CONSOLE 0,25,0,1
20 X=20:Y=12
30 LOCATE X,Y:PRINT "●";
40 NX = X + (1-INT(RND * 3))
50 IF (NX < 0) THEN NX=0 ELSE IF (NX > 79) THEN NX=79
60 NY = Y + (1-INT(RND * 3))
70 IF (NY < 0) THEN NY=0 ELSE IF (NY > 24) THEN NY=24
75 IF PEEK(&HF300+NY*120+NX) <> 32 THEN GOTO 40
80 LOCATE X,Y:PRINT " ";
90 X=NX:Y=NY
100 GOTO 30

こうすると●は画面上を「食いつぶしながら」ではなく、画面上の空白を縫って動くようになります。PEEK 云々というのは N-BASIC / PC-8001 特有のやりかたで、画面表示情報を保持している VRAM 領域に直接アクセスして画面上の情報を拾ってくるものです。ASCII コード 32 = ホワイトスペース、<> は MS-BASIC における不等号表記。
標準 BASIC では LOCATE と PRINT で位置指定・表示はできても、表示済みの情報を拾う方法はありません(※註)。当時 8bit パソコンを設計していた人たちは、それをゲームプログラムに使うという意識はあまり持っていなかったようですね。

※註:画面と同じ情報量(40x25)の配列を定義して「画面表示のコピー」を維持する方法もありますが、当時の 8bit BASIC パソコンの多くではメモリを節約するため、PEEK などを使って VRAM を読む実装がポピュラーでした。富士通 FM シリーズではキャラクタコード VRAM を持たずフルグラフィックしかも画面はサブ CPU 制御下なので、こういうところで NEC に水を開けられて歯噛みしたものです...。

さて「●が画面上の空白を縫って動く」ということは、これは「乱数アルゴリズムによる迷路脱出プログラム」として動かすことができます。もっとも「ゴールに向かって動く」という明確なアルゴリズムを入れていないため、あらぬ方向へ行ったり来たりを繰り返すので、乱数「だけ」で●が迷路を脱出するのを眺めているのはイライラするだけで楽しくはないかも知れません。
では、どうすれば良いでしょう?たとえば「障害物に当たるまでは直進し、突き当たるたび右90度に回頭する」というアルゴリズムは組めるでしょうか?「分岐点を覚えておいて、一度通った道は二度と通らない」アルゴリズムは組めるでしょうか。乱数ではなく、キー入力に基づいて動くようにすれば「自キャラ」ができますし、乱数で動く「敵キャラ」とキー入力で動く「自キャラ」の2つを動かせば「迷路型ゲーム」の基本形です。どうでしょう、これならワクワクしてきませんか?...してこない?こんな事やってるよりオンラインゲームでガチャ引きでもやってたほうが面白い...かなぁ?

Those were the days of my life
こういうものを見て「すごい!僕もこれをやってみたい!」とワクワクするか、「それが一体何の役に立つの?」「そんなのお金出せばもっと良いのが手に入るじゃん」とシラけた顔をするかが「オタク」と「一般人」の分水嶺になるのでしょう。「オタク」という人種は物事の仕組みを知りたくて仕方がない人種で、時計だろうがカメラだろうがTVだろうが分解したくてたまらないし、分解したらもう一度組み立てて自分オリジナルのモノを作りたくてたまらない人種なのです。たとえそれが既に世の中に存在して、お金を出せば簡単に手に入るようなものであっても。

まとめ
1980 年代の 8bit BASIC パソコンの能力など、今から思えば「パーソナル・コンピュータ」の名を冠したことが恥ずかしくなるくらいに貧弱です。リンゴとミカンの合計金額を計算するのも迷路を抜けるのも、プログラムなんぞ組んでいる間に自分でやったほうが「結果としては」早いでしょう。
でも「迷路を抜けるにはこうすれば良いんじゃないか?」と思い付き、それをプログラムコードとして打ち込み、それを走らせた結果迷路脱出が早くなれば「やった!」という気になりますし、袋小路をぐるぐる無限ループしてしまえば「どうすれば袋小路にハマらないで済むようになる?」と更に考えることができます。
それを「楽しい」と思えるか、「過程なんてどうでもいいから、さっさと結果だけくれよ」と思うかが、「ものづくり」を楽しめるか・ただの作業になるかの違いではないかと思います。

次の記事:「クラスとテンプレートのはなし」へ

ページの先頭へ戻る

最新の記事

カテゴリ

バックナンバー