LoginSignup
22
14

More than 1 year has passed since last update.

日本語プログラミング「なでしこ3」でヘビゲーム作ってみた

Last updated at Posted at 2022-06-02

はじめに

普段の業務では使うことが無いようなプログラミング言語に触っている社員の方がいました。
「え、使わない言語を触ってどうするのか」と最初は思ったのですが、普段使わない言語に触れることで見えてくることもあるんじゃないかと柔軟に考えてみました。普段同じ言語を触ってるとその言語の常識に偏ってしまいますよね。そこから抜けるには全く別の言語に触るのが良いと思いました。

言語は前々から気になっていた日本語で書ける「なでしこ3」に興味があったので、それにすることにしました。Webブラウザ上で試せるので、ちょっと触ってみるには良い言語だと思います。

なでしこ3とは?

公式サイトより引用

「なでしこ3」は、日本語をベースに開発されたプログラミング言語です。主にWebブラウザで動かすことを目的に開発されています。ブログやWebサイトに組み込んで使えます。また、OSや環境を問わず、PC・スマホ・タブレットとさまざまな環境で動きます。作業の自動化をはじめ、趣味、教育、仕事などに利用できます。

なぜにWebブラウザで動くのかというとJavascriptベースだからみたいです。
・・・Javascriptで言語って作れるんですね!?
Javascriptは普段ただ使うだけでそこから新しい言語を作るというのは思いつきませんでした。

そして日本語で書ける素晴らしさ。
思えばプログラミングを書いてる時って英単語がほとんどで、コメントを書かなかったらほぼ英語と数字の塊ですもんね。

プラグインが色々あって、エクセル操作やデータベース操作も出来るみたいです。
エクセルとDB触れたら自動化できそうですね

GitHubのIssueも日本語です。

まずは触ってみる

HelloWorld

「こんにちは世界」と表示

表示結果
こんにちは世界

表示したい文字列を『「」』で囲んで『と表示』と書くだけ表示が出来ました。
C言語でprintfで表示させてきた自分的には衝撃的でした。
表示と書いたら表示してくれる。
そんな日本語として当たり前なことが出来るのがこの言語です。
信じられない人はぜひ試してみてください!

英語圏の人だとプログラミング言語は自然な感じなのかもしれないなと思いました。
自分は普段英語は喋らないので、printと聞いても頭の中で一度変換してしまいます。

関数を作って使ってみる

# 関数の定義
●(AとBの)乗算処理とは
	A*Bを戻すこと
ここまで

2と5の乗算処理して表示

表示結果
10

「#」はコメントです。
ここは他の言語と似た感じですね。
関数の宣言は●の後に書きます。
カッコで囲わずに「ここまで」で終わりを示します。
終わりを示さないといけない場合は基本「ここまで」で表現するようです。
「ここまで」を書くのが大変な場合は「💧(しずく)」を使うと代用できます。
色々考えられてて良いですね。

何か作ってみる

なんとなく分かってきたので、試しにヘビゲームを作ってみようと思います。
ゲームを作ると一通りの基本的な処理を使うことになると思うので、自分は新しい言語を触ったときには作るようにしてます。あとゲームを作るのは楽しいです。

今回は言語に触るのが目的なので、ゲームロジックや作る過程については触れないです。あしからず。
※長いのでコードは折りたたんでいます。公式サイトにある「なでしこ3 Web簡易エディタ」で動きます

コード
# 定数の宣言
定数 ゲーム画面=DOCUMENT
定数 フォントサイズ=「16px」
定数 文字高さマージン=20
定数 上マージン=30
定数 横マス最大数=30
定数 縦マス最大数=30
定数 マス幅=10
定数 マス高さ=10
定数 空=0
定数 壁=1
定数 ヘビ頭=2
定数 ヘビ体=3
定数 エサ=4
定数 ヘビ初期位置X=13
定数 ヘビ初期位置Y=13
定数 スコア加算値=10

# 変数の宣言
変数 スコア=0
変数 フィールド配列=空配列
変数 ヘビ配列=空配列
変数 ヘビ方向X=1
変数 ヘビ方向Y=0
変数 ゲームオーバーフラグ=偽
変数 エサ取得フラグ=偽

●フィールド初期化処理とは
 Yを0から(縦マス最大数-1)まで繰り返す
  フィールド配列[Y]=空配列
  Xを0から(横マス最大数-1)まで繰り返す
   Yで条件分岐
    0ならば、フィールド配列[Y][X]=壁💧
    (縦マス最大数-1)ならば、フィールド配列[Y][X]=壁💧
    違えば、
     Xで条件分岐
      0ならば、フィールド配列[Y][X]=壁💧
      (横マス最大数-1)ならば、フィールド配列[Y][X]=壁💧
      違えば、フィールド配列[Y][X]=空💧
     ここまで
    ここまで
   ここまで
  ここまで
 ここまで
ここまで

●ヘビ消去処理とは
 ヘビ配列を反復
  変数 ヘビ位置X=対象["X"]
  変数 ヘビ位置Y=対象["Y"]
  フィールド配列[ヘビ位置Y][ヘビ位置X]=空。
 ここまで
ここまで

●ヘビ配置処理とは
 ヘビ配列を反復
  変数 ヘビ位置X=対象["X"]
  変数 ヘビ位置Y=対象["Y"]
  フィールド配列[ヘビ位置Y][ヘビ位置X]=対象["T"]。
 ここまで
ここまで

●ヘビ初期化処理とは
 ヘビ配列=空配列
 ヘビ要素={
  "T":ヘビ頭
  "X":ヘビ初期位置X
  "Y":ヘビ初期位置Y
 }
 ヘビ配列にヘビ要素を配列追加。
 ヘビ配置処理。
ここまで

●(TXとTYの)当たり判定処理とは
 フィールド配列[TY][TX]で条件分岐
  壁ならば、
   ゲームオーバーフラグ=真。💧
  ヘビ体ならば、
   ゲームオーバーフラグ=真。💧
  エサならば、
   エサ取得フラグ=真。
   スコア=スコア+スコア加算値。
   エサ位置設定処理💧
 ここまで
ここまで

●ヘビ移動処理とは
 変数 移動地点X=0。
 変数 移動地点Y=0。
 ヘビ配列を反復
  もし、対象["T"]がヘビ頭ならば、
   移動地点X=対象["X"]+ヘビ方向X。
   移動地点Y=対象["Y"]+ヘビ方向Y。
   対象["T"]=ヘビ体。
  ここまで
 ここまで
 移動地点Xと移動地点Yの当たり判定処理。
 ヘビ消去処理。
 もし、ゲームオーバーフラグが偽ならば、
  変数 ヘビ要素={
   "T":ヘビ頭
   "X":移動地点X
   "Y":移動地点Y
  }
  ヘビ配列にヘビ要素を配列追加。
 ここまで
 もし、エサ取得フラグが真ならば、
  # 真の場合は消さないので体が伸びる
  エサ取得フラグ=偽。
 違えば、
  ヘビ配列の0を配列削除。
 ここまで
 ヘビ配置処理。
ここまで

●エサ位置設定処理とは
 変数 設定完了済=偽
 (設定完了済=偽)の間、
  変数 位置X=(横マス最大数の乱数)
  変数 位置Y=(縦マス最大数の乱数)
  もし、(フィールド配列[位置Y][位置X]=空)ならば、
   フィールド配列[位置Y][位置X]=エサ
   設定完了済=真
  ここまで
 ここまで
ここまで

●初期化処理とは
 # フィールドの用意
 フィールド初期化処理。
 # ヘビ頭の初期位置
 ヘビ初期化処理。
 # エサの初期位置(ランダム)
 エサ位置設定処理。
ここまで

●スコア表示処理とは
 黒色に塗色設定。
 「{フォントサイズ} sans-serif」に描画フォント設定。
 [0,文字高さマージン]へ「スコア:{スコア}」を文字描画。
ここまで

●操作方法表示処理とは
 黒色に塗色設定。
 「{フォントサイズ} sans-serif」に描画フォント設定。
 変数 表示位置Y=縦マス最大数*マス高さ+上マージン+文字高さマージン
 [0,表示位置Y]へ「w、a、s、dキー:進む方向を変える」を文字描画。
ここまで

●ゲームオーバー表示処理とは
 もし、ゲームオーバーフラグが偽ならば、
  偽を戻すこと。
 ここまで
 赤色に塗色設定。
 「{フォントサイズ} sans-serif」に描画フォント設定。
 変数 表示位置Y=縦マス最大数*マス高さ+上マージン+文字高さマージン*2。
 [0,表示位置Y]へ「ゲームオーバー!」を文字描画。
ここまで

●フィールド表示処理とは
 1に線太設定。
 Yを0から(縦マス最大数-1)まで繰り返す
  Xを0から(横マス最大数-1)まで繰り返す
   もし、フィールド配列[Y][X]が空でなければ、
    フィールド配列[Y][X]で条件分岐
     壁ならば、
      黒色に線色設定。灰色に塗色設定。💧
     ヘビ頭ならば、
      オリーブ色に線色設定。オリーブ色に塗色設定。💧
     ヘビ体ならば、
      緑色に線色設定。緑色に塗色設定。💧
     エサならば、
      赤色に線色設定。赤色に塗色設定。💧
     ここまで
     [(X*マス幅),(Y*マス高さ)+上マージン,マス幅,マス高さ]へ四角描画。
   ここまで
  ここまで
 ここまで
ここまで

# 表示処理
●表示処理とは
 ゲーム画面に描画クリア。
 スコア表示処理。
 フィールド表示処理。
 操作方法表示処理。
 ゲームオーバー表示処理。
ここまで

# 入力処理
ゲーム画面のキー押した時には
 押されたキーで条件分岐
  「w」ならば、
	  ヘビ方向X=0。ヘビ方向Y=-1。💧
  「a」ならば、
	  ヘビ方向X=-1。ヘビ方向Y=0。💧
  「s」ならば、
	  ヘビ方向X=0。ヘビ方向Y=1。💧
  「d」ならば、
	  ヘビ方向X=1。ヘビ方向Y=0。💧
  「q」ならば、
   ゲームオーバーフラグ=真。💧
 ここまで
ここまで

●更新待機処理とは
 もし、(スコア<30)ならば、
  0.5秒待つ。
 違えば、もし、(スコア<50)ならば、
  0.4秒待つ。
 違えば、もし、(スコア<100)ならば、
  0.3秒待つ。
 違えば、もし、(スコア<150)ならば、
  0.2秒待つ。
 違えば、
  0.1秒待つ。
 ここまで
ここまで

●ループ処理とは
 変数 ループ中=真。
 (ループ中=真)の間、
  ヘビ移動処理。
  表示処理。
  もし、ゲームオーバーフラグが真ならば、
   ループ中=偽
  ここまで
  更新待機処理。
 ここまで
ここまで

# メイン処理
●メイン処理とは
 初期化処理。
 ループ処理。
ここまで

メイン処理。

表示結果
スクリーンショット 2022-06-01 090458.png

「定数」と書いて定数を宣言できます。
defineと書いて定数を宣言してたのを思い出しました。
変数もそのまま「変数」と書いて宣言が出来ます。
説明が要らない気がしてきました。

ネストが深いと「ここまで」をたくさん書くことになります。
ネストを浅くしたくなりますね。

描画はメソッドが用意されていたので簡単に描画することが出来ました。
少ないコードで書けて良いです。

おわりに

なでしこ3に触ってみて、忘れていた技術に触れる楽しさを思い出しました。
必要かどうかとかではなく、純粋に楽しめると自然とそれについて知りたくなりますし、手も進むと思います。
今回、一番の発見はそれでした。

それぞれの言語に長所があって、その長所に注目すると楽しめるのかもしれないです。
例えば、なでしこ3は型を宣言しない言語なので、変数の扱いの難しさがありますが、型を宣言しないことで気軽に宣言できるので書きやすくなる面もあると思いました。その辺りは表裏一体で捉え方で変わってくるような気がします。

最後まで読んでいただきありがとうございました。

参考

22
14
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
22
14