十二星座判別プログラム for MSX-BASIC

米チャさんに続け

買う前にBASIC入門の本を読んで、誕生日を入力すると星座を教えてくれる、しょうもないプログラムを作ってたんです。
それを打ちこんだら、エラーなしにちゃんと動いて(パソコンって)すごいなと思った

MSX・FAN 1991年3月号「FAN CLIP」より

 徳間書店「MSX・FAN」の投稿プログラムコーナー「ファンダム」のレジェンド、米屋のチャチャチャさんが初めて作ったプログラムは、誕生日を入力すると十二星座の何座か教えてくれるというものだったそうです。
 一見かんたんそうですが、実際に組んでみたらどんなものでしょう? そこであえて米チャさんに倣って、誕生日を入力すると何座か教えてくれるプログラムを作ってみようとおもいます。


そもそも十二星座って?

 黄道上に並ぶ12の星座を十二星座と称します。これを誕生日の星とし、その人の運命を占うみたいな考えが、占星術にはあるようです。詳しいことはおいといて、雑誌やテレビの星占いコーナーとかでよく見るあれです。1年を12の期間に分け、誕生日がそのどれにあてはまるかによって、その人の星座が決まります。具体的には以下のとおり。

おひつじ座3/21〜4/19
おうし座4/20〜5/20
ふたご座5/21〜6/21
かに座6/22〜7/22
しし座7/23〜8/22
おとめ座8/23〜9/22
てんびん座9/23〜10/23
さそり座10/24〜11/22
いて座11/23〜12/21
やぎ座12/22〜1/19
みずがめ座1/20〜2/28
うお座2/19〜2/30

 プログラムでは、入力された誕生日がどの星座に当てはまるかを判別し、何座であるか結果を返すという処理が必要です。


どうやって判別するか

 入力はかんたんに、INPUT命令を使うことにします。かんたんに組むので、誕生月と誕生日は別々に入力する仕様にしときます(おい)。
 プログラムの要となる判別処理をどう組むか。いちばん単純なのは、さきほどの早見表をばか正直にIF文に置き換えるやつでしょう。たとえばこんなあんばい。

IF 誕生月=3 AND 誕生日>=21 and 誕生日<=31 THEN PRINT“おひつじ座”
IF 誕生月=4 AND 誕生日>=1 and 誕生日<=19 THEN PRINT“おひつじ座“...

便宜上、サンプルには全角文字を使用しています。

 しかし試しに書いてみると、非常に無駄が目立ちます。ですのでもっとよい書き方を探ってみます。


もっとよい書き方

 日付は「1年のうちの何日目」と置き換えることができます。たとえば1月1日は1年の1日目、4月8日は99日目、12月24日は359日目といった具合です(閏年の場合)。こうすると月と日、ふたつの変数で扱っている日付がひとつで済む上、比較もしやすくなります。まずは「1年のうちの何日目」を求める処理を作ってみます。
 ところでここで問題になるのは閏年の扱いです。先述の早見表は平年も閏年も同じものが適用されます。ですから2月29日を含める方が何かと都合が良いので、ここでは1年を366日として、その何日目を求めることにします。

 日数は「前月までの日数の合計+当月の日付」で求められます。各月の日数を配列変数に格納しておけば、FOR〜NEXT命令を使って容易に計算できそうです。というわけで試しにこんな処理を組んでみます。

10 SCREEN1:WIDTH32:DIM MD(12)
20 FORI=0TO12:READMD(I):NEXT
30 INPUT"たんじょうづきは";M
40 IF M<=0 OR M>12 THEN 30
50 INPUT"たんじょうびは";D
60 IF D<=0 OR D>MD(M) THEN 50
70 FORI=1TOM:DT=DT+MD(I-1):NEXT
80 DT=DT+D
90 PRINT"たんじょうびまでのにっすう=";DT
100 DATA 0,31,29,31,30,31,30,31,31,30,31,30,31

 100行のDATA文は、各月の日数データです。それぞれをREAD文で配列変数MD(n)に格納しておきます(20行の処理)。1月は前月までの日数が「0」であるため、MD(0)には0も格納しておきます。

 あとは先述の計算をするだけ(70〜80行)。「-1月-9日」とか「36月259日」といったあり得ない数値が入力されるとうまく計算できないので、弾く処理も付けときました(40行と60行)。各月の日数を収めた配列変数MD(n)を使い回しているのが我ながらミソですな。

 ついでにこのプログラムを使って、さきほどの十二星座早見表も換算してしまいましょう。さっきの表は以下のように置き換えられます。

みずがめ座20日目〜49日目
うお座50日目〜80日目
おひつじ座81日目〜111日目
おうし座112日目〜141日目
ふたご座142日目〜173日目
かに座174日目〜204日目
しし座205日目〜235日目
おとめ座236日目〜266日目
てんびん座267日目〜294日目
さそり座295日目〜326日目
いて座327日目〜356日目
やぎ座357日目〜366日目,1日目〜19日目

判別してみよう

 誕生日と星座早見表を日数に置き換えることができました。さっきのプログラムで求めた誕生日までの日数が、変換した早見表のどの期間にあてはまるかを調べれば、どの星座であるかを判別できます。
 期間末日は次の星座に変わる前の日です。計算式では「誕生日の日数≧期間初日AND誕生日の日数<次の星座の初日」と、等号不等号を使って書けば、末日のデータを省けます。一応日数のデータと星座の名前も、てきとうな配列変数を用意して代入しておきましょう。

やぎ座の扱いをどうするか

 ここで問題になるのはやぎ座です。なぜなら年をまたぐから。さきほどの早見表に従えば、誕生日が357日目から366日目までか、または誕生日が1日目〜20日目の間か、という処理が必要になります。
 しかしこう考えることもできます。「みずがめ座からいて座のどれにも該当しなければやぎ座」。11星座以外だったら残りはやぎ座しかないという、いわば消去法です。この方式なら、やぎ座用に年またぎを考慮した判定処理を用意せずに済みます。
 ですので判定処理は11星座分だけ調べればよいということになります。

 ついでに荒井はやぎ座な。


しょうもないプログラム〜いよいよ組んでみる

 以上を踏まえて組んでみたのが以下のプログラムです。

10 SCREEN1:WIDTH32:DIM MD(12),DS(12),H$(12)
20 M=0:D=0:DT=0:H=0
30 FORI=0TO12:READMD(I):NEXT
40 FORI=1TO12:READDS(I):NEXT
50 FORI=1TO12:READH$(I):NEXT
60 INPUT"たんじょうづきは";M
70 IF M<=0 OR M>12 THEN 60
80 INPUT"たんじょうびは";D
90 IF D<=0 OR D>MD(M) THEN 80
100 FORI=1TOM:DT=DT+MD(I-1):NEXT
110 DT=DT+D
120 PRINT"たんじょうびまでのにっすう=";DT
130 FOR I=1 TO 11
140 IF DT>=DS(I) AND DT<DS(I+1) THEN H=I:GOTO 170
150 NEXT I
160 H=12
170 PRINT H$(H);"ざ です“
180 END
190 DATA 0,31,29,31,30,31,30,31,31,30,31,30,31
200 DATA 20,50,81,112,142,174,205,236,267,295,327,357
210 DATAみずがめ,うお,おひつじ,おうし,ふたご,かに,しし,おとめ,てんびん,さそり,いて,やぎ

 肝心の判別処理は、130行から150行です。配列変数DS(n)は、各星座の期間初日の日数です。これとFOR〜NEXTループを使用することで、IF文を1行だけで済ませています。160行はそのどれでもなかったらやぎ座であるという処理です。星座名は配列変数H$(n)に格納しており、引数nによって星座を表すという仕組みです。


使い方

十二星座判別プログラム
数字以外を入力するとRedo from startと表示されるのはMSXの仕様です。

 RUNで実行すると、誕生月と誕生日を入力するよう求められます。それぞれ数値で入力してください。入力すると誕生日までの日数とともに、誕生日の星座を教えてくれます。
 実行するたびにプログラムが終了します。リトライ時は再びRUNしてください。


まとめ

 プログラムはもっと短くできますが、さしあたり核心部分の処理は完成しました。ですのでこれでできあがり、ということにしておきます。無駄な処理を省いたり、データリード処理を工夫したり、マルチステートメントを多用すれば、1画面に収められるでしょう。
 米チャさんは、自分で作ったプログラムが実際に動いたことに感動して、その後プログラミングの道を邁進することとなります。かんたんなことをするプログラムでも、きちんと動かすためにはアルゴリズムを編み出したり、相応の工夫をする必要があります。「車輪の再発明」であっても、実際に自分で頭を使って手を動かして作ってみることには、十分に意味があるとおもうのです。


変数表

MD(n):各月の日数
DS(12):各星座初日の日数
H$(n):星座の名前
M:誕生月
D:誕生日
DT:誕生日の日数
H:星座の番号
(1:みずがめ,2:うお,3:おひつじ,4:おうし,5:ふたご,6:かに,7:しし,8:おとめ,9:てんびん,10:さそり,11:いて,12:やぎ)

文頭に戻る目次に戻るトップページに戻る