1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Hello World あたたたた HSP3 (Hot Soup Processor) 編

Posted at

「Hello World あたたたた」とは

「Hello World あたたたた」は、以下の記事で定義されている。
Hello World あたたたた 1日目 概要編 #HelloWorld - Qiita

以下の要件が定義されている。

・「あ」か「た」をランダムに出力する
・「あたたたた」が出たら「お前はもう死んでいる」を出力して終了する

また、以下の処理フローが指定されている。

変数 hako に空文字をセット
変数 running に true をセット
running が true なら繰り返す
    0か1をランダムに決める
    もし0なら
        変数 char に「あ」をセット
    その他なら
        変数 char に「た」をセット
    画面に char を出力
    char を hako に追加
    もし 最後の 5 文字が「あたたたた」なら
        "お前はもう死んでいる" を出力
        running に false をセット        

HSP3 (Hot Soup Processor) とは

プログラミング言語 HSP3 公式 - HSPTV!

HSP3 は、「おにたま」氏によって開発されているプログラミング言語である。
何も書かずに実行するだけでウィンドウが表示され、BASIC 的な平易な文法でスクリプトを記述できる。
文字コードは SJIS を用いる。
今回は、執筆時点で最新の HSP3.7 を用いる。

UTF-8 を用いるバージョンのランタイムもあるが、今回は用いない。

最近、インタビュー記事が公開された。
だって最高のホビーだから。プログラミング言語「HSP3」を30年開発している理由【フォーカス】 | レバテックラボ(レバテックLAB)

今回用いた機能

式と変数

HSP3 プログラミング・マニュアル → 3.6.式
HSP3 プログラミング・マニュアル → 3.8.変数

変数名 = 値

の形式で、変数に値を代入できる。
式の中で変数名を用いることで、変数の値を参照できる。

式では、以下の演算子を用いることができる。(今回用いたものだけを紹介)

演算子 意味
値1 == 値2 値1と値2が等しいかを判定する
値1 < 値2 値1が値2未満かを判定する
数値1 + 数値2 数値1と数値2の和を求める
文字列1 + 文字列2 文字列1の後ろに文字列2を結合した文字列を求める

== だけでなく、= も等しいかを判定する演算子として使用できる。

変数名 演算子= 値

と書くことで、

変数名 = 変数名 演算子 値

と書くのと同様の処理を行うことができる。
すなわち、たとえば以下の2行は同じ処理を行う。

a += 72
a = a + 72

コメント

HSP3 プログラミング・マニュアル → 3.5.コメント

文字列以外で ; を書くと、その行のそれ以降の部分がコメントになる。

マクロ定義

HSP3 プログラミング・マニュアル → 4.7.#defineマクロについて

#define 名前 置き換え先

と書くことで、「名前」を「置き換え先」に置き換えるマクロを定義できる。

より複雑なマクロ定義も可能だが、今回は用いない。

条件分岐

HSP3 プログラミング・マニュアル → 3.12.条件判断

if 式 : 式が真のとき行う処理

の形式で、条件分岐を行うことができる。
式と処理の間は : で区切る。
処理も : で区切ることで、複数の処理を記述できる。

else を用いると、式が偽のとき行う処理も記述できる。
処理と else の間も : で区切る。

if 式 : 式が真のとき行う処理 : else : 式が偽のとき行う処理

処理を {} で囲むことで、複数行に分けて記述できる。

if 式 {
	式が真のとき行う処理1
	式が真のとき行う処理2
}

条件を指定しての繰り返し

HSP3 プログラミング・マニュアル → 4.8.標準マクロ定義ファイル

whilewend マクロを用いることで、条件を指定し、その条件が満たされる間繰り返しを行うことができる。

while 式
	式が真の間繰り返す処理
wend

データの出力

HSP3 プログラミング・マニュアル → 5.3.フォントと文字表示

mes 命令でデータをウィンドウに出力できる。

mes 値

デフォルトでは、次に出力する位置は出力したデータの下に移動する。
第2引数に 1 を指定することで、次の出力を出力したデータの右にすることができる。

mes 値, 1

デフォルトの動作は「改行する」(出力位置を次の行の一番左にする) ではなく、「次の出力位置を出力したデータの下にする」である。
次のデータを一番左から出力するには、別途出力位置を左に戻さなければならない。

コンソール版のランタイムでは、出力先は標準出力となり、第2引数に 1 を指定するかどうかの差は単純な「改行する/しない」になるようである。

pos 命令で、次にデータを出力する位置を指定できる。

pos x座標, y座標

乱数の生成

rnd 関数で、整数の乱数を生成できる。
この関数は1個の引数をとり、0以上指定した値未満の乱数を生成する。

randomize 命令で、rnd 関数で生成する乱数を不定な系列にできる。
逆に、randomzie 命令を実行しない場合、実行開始時から毎回同じ乱数が生成される。

randomize
mes rnd(10) ; 0~9の乱数を生成して表示する

ウィンドウ情報の取得

HSP3 プログラミング・マニュアル → 3.16.システム変数

ginfo 関数で、ウィンドウに関する情報を取得できる。
この関数は1個の引数をとり、取得する情報を指定する。

また、この関数で取得できる情報を取得するマクロもある。
今回は、以下のマクロを使用した。

マクロ 内容
ginfo_winx ウィンドウのクライアント領域の横幅
ginfo_mesx 前回出力したデータの横幅
ginfo_cx 次にデータを出力する位置のx座標
ginfo_cy 次にデータを出力する位置のy座標

部分文字列の取得

strmid 関数を用いて、文字列から部分文字列を取得できる。
この関数は、以下の形式で用いる。

strmid(抜き出し元の文字列を格納した変数, 抜き出しを開始する位置, 抜き出すバイト数)

第1引数は変数でなければならず、文字列を直接指定するとエラーになった。
第2引数は、0-origin で抜き出しを開始する位置を指定することができ、-1 を指定すると文字列の右端から第3引数で指定したバイト数を抜き出す。
第3引数は、文字数ではなくバイト数を指定する。標準では SJIS を使用するので、全角文字は2バイトである。

プログラム

標準ランタイム版

hwa.hsp
#define true 1
#define false 0

randomize

hako = ""
running = true
while running == true
	if rnd(2) == 0 : char = "あ" : else : char = "た"
	mes char, 1
	if ginfo_winx < ginfo_cx + ginfo_mesx : mes "" : pos 0, ginfo_cy
	hako += char
	if strmid(hako, -1, 10) == "あたたたた" {
		mes ""
		pos 0, ginfo_cy
		mes "お前はもう死んでいる"
		running = false
	}
wend

コンソール版

HSP3 プログラミング・マニュアル → 5.14.コンソール版HSP

スクリプトの先頭に

#runtime "hsp3cl"

を追加し、ウィンドウ関係の命令をコメントアウトすることで、ウィンドウのかわりにコンソールで動作させることができる。

hwa_cl.hsp
#runtime "hsp3cl"

#define true 1
#define false 0

randomize

hako = ""
running = true
while running == true
	if rnd(2) == 0 : char = "あ" : else : char = "た"
	mes char, 1
	;if ginfo_winx < ginfo_cx + ginfo_mesx : mes "" : pos 0, ginfo_cy
	hako += char
	if strmid(hako, -1, 10) == "あたたたた" {
		mes ""
		;pos 0, ginfo_cy
		mes "お前はもう死んでいる"
		running = false
	}
wend

実行結果例

標準ランタイム版

HSPスクリプトエディタでスクリプトを開き、F5 キーを押すことで、スクリプトをコンパイルして実行できる。
同じスクリプトを繰り返し実行する際は、F6 キーを押すことで、コンパイルを省略して実行のみを行うことができる。

標準ランタイム版の実行結果例 1
標準ランタイム版の実行結果例 2
標準ランタイム版の実行結果例 3

コンソール版

コンソール版も、標準ランタイム版と同様にHSPスクリプトエディタから実行できる。
このとき、自動で終了時キーが押されるのを待機してくれるようである。

コンソール版の実行結果例

「HSP → 実行ファイル自動作成」メニューで実行ファイルを作成し、コマンド プロンプトから実行することもできる。
このときは、終了時のキー押下待機は行われないようである。

コンソール版の実行結果例 (連続実行)

プログラムのポイント

ここでは、今回作成したプログラムの中で、特に自明ではない点を紹介する。

char の出力

mes char, 1
if ginfo_winx < ginfo_cx + ginfo_mesx : mes "" : pos 0, ginfo_cy

mes 命令で、変数 char に格納した文字列を出力する。
このとき、第2引数に 1 を指定し、この後右に続けて出力できるようにする。

続いて、標準ランタイムでは自動で折り返されず、何もしないと右からはみ出してしまうことがあるので、次の出力がはみ出しそうだったら次の行に移る処理を行う。
具体的には、「次に今と同じデータを出力したら右にはみ出してしまう」場合、「出力位置を次の行の一番左にする」処理を行う。
mes で空文字列を出力することで出力位置を次の行に移し、続いて pos を用いて出力位置を一番左に移す。

接尾辞の判定と条件を満たした際の処理

if strmid(hako, -1, 10) == "あたたたた" {
	mes ""
	pos 0, ginfo_cy
	mes "お前はもう死んでいる"
	running = false
}

strmid を用いて hako の右の文字列を取り出し、「あたたたた」と比較する。
処理フローでは「5文字」との指定だが、今回は全角文字のみを扱うので、SJIS ではこれは「10バイト」となる。

接尾辞が指定のものだったら、改行し、「お前はもう死んでいる」を出力する。
この「改行する」というのは要件や処理フローには書かれていないが、「処理結果のイメージ」で改行されているのでそれに合わせる。
この改行処理は、右端での折り返し処理と同様に「次の行に移る」「一番左に移る」処理からなる。

おわりに

HSP3 で「Hello World あたたたた」を実装することができた。
今回の題材では、HSP3 のGUIが簡単に作れるという強みは活かせなかった。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?