JScript 覚書（実践編その壱）

この記事は、[富士通ソーシアルサイエンスラボラトリ Advent Calendar 2019](http://qiita.com/advent-calendar/2019/ssl)の 3 日目の記事です。

# はじめに

@GORO_Nekoです。ご存知の方ご無沙汰してます。初めての方お初にお目にかかります。

えーっと、先にお断りをば一言。

以下は、自分が所属する会社の意向を反映したものでもスタンスを示すものでもなく、単なる一個人の趣味の活動から産まれた記述です。

# JScriptって知ってます？

知らない方、まず[こちらの記事](https://qiita.com/GORO_Neko/items/0be4ddc3b40094d0006f)をご覧ください。

てぇわけでこの記事、じつは単品記事じゃなくて上で紹介した記事「JScript 覚書」の続編デス。

前の記事で「JScript とは何か」および「JScript で Windows の標準入力・標準出力・標準エラー出力を利用する方法」を紹介してみたつもりでいたのですが、読み返してみるとなんか座りが悪い。

使い方の説明として、若干コードも載っけてみたけど、どうも中途半端に感じちゃったんですよね。

てなわけで、もう少し意味のあるコードを記載して、「JScript で Windows の標準入力・標準出力・標準エラー出力を利用する方法」をコードを通して再解説しようと思います。

# 数あてゲームを作ってみる

正式名称かどうか実はよくわかっていませんが「数あてゲーム」ってありますよね？

コンピュータが考えた数値がいくつか、言い当てるゲーム。

人間が「コンピュータが考えた数は、xxx だろ？」とキーボードを通して通知すると、コンピュータが「もっと大きな数」「もっと小さな数」「あたり！」を答えるアレです。

以下、JScript で実装した数あてゲームのソースコードを掲載します（注意: 入力内容のチェック等エラーチェック処理ちゃんとやってません(:p ）。

コード中のコメント等を読んで「JScript で Windows の標準入力・標準出力・標準エラー出力を利用する方法」を体感してみてください（体感してもらえるといいなぁ）。

``` kaduate.js

// 0 ～ 999 の数字を一つ生成
var random_no = Math.floor(Math.random() * 1000);

// 人間が打ち込んだ数値を読み取る変数を用意する
var input_number = 0;

// 人間が行った発言回数を記録するカウンタを用意する
var cnt = 0;

// 発言数の上限を定義する
var MAX_CNT = 20;

// あたり判定フラグを用意する
var hit_flg = false;

// コンピュータが返すメッセージ文字列を定義する
var OOKII  = "大きいです。";
var TIISAI = "小さいです。";
var ATARI  = "あたりです。";

// コンピュータが返すメッセージの格納変数を用意する
var pcAns = "";

// 開始メッセージを出力する
WScript.StdOut.WriteLine("0～999の数字を入力してください。");
WScript.StdOut.WriteLine("私の考えた数より大きい数だった場合「大きいです。」");
WScript.StdOut.WriteLine("私の考えた数より小さい数だった場合「小さいです。」");
WScript.StdOut.WriteLine("私の考えた通りの数だった場合「あたりです。」とお答えします。");

while(cnt < MAX_CNT){

	// ユーザに入力を促す
	WScript.StdOut.WriteLine("数を入力して[Enter]キーを押してください。");

	// 標準入力に入力された情報を読み取る
	input_number = WScript.StdIn.ReadLine();

	//当たりはずれを判定する
	if(random_no < input_number){
		pcAns = OOKII;
	}else if(random_no > input_number){
		pcAns = TIISAI;
	}else{
		pcAns = ATARI;
		hit_flg = true;
	}

	// 結果表示
	WScript.StdOut.WriteLine(pcAns);

	// 状態確認処理
	if(true == hit_flg){
		// ループを脱出する
		break;
	}else{
		// 入力数カウンタをカウントアップしてループ処理を続ける
		cnt++;
	}

}

// 終了処理
if(true == hit_flg){
	WScript.StdOut.WriteLine("おめでとうございます。" + (cnt + 1) + "回で正解です。");
}else{
	WScript.StdOut.WriteLine("残念。" + MAX_CNT + "回以内で正解できませんでした。");
}

```

先の記事で解説していますが、一応上記のコードの実行方法を書きます。

上記コードを "kaduate.js" ファイルに書き込んだとします。

その場合、実行方法は以下のようになります。

```
x:\> cscript kaduate.js
```

cscript にマイクロソフトのロゴを出させたくない場合は以下の通り。

```
x:\> cscript /nologo kaduate.js
```

うまく動きましたでしょうか？

なお、いつものごとく Ruby で書くとこんな感じ…かな？

``` kaduate.rb

require 'readline'

#
# 注意:
# windows OS 上で実行する場合は、管理者モードで起動し、以下のコマンドを実行したCMD上で実行すること
# > chcp 650001
# このコード自体はエンコード UTF-8 でファイル化して実行のこと
#

# 0 ～ 999 の数字を一つ生成
random_no = Random.new.rand(0..999)

# 人間が打ち込んだ数値を読み取る変数を用意する
input_number = 0;

# 人間が行った発言回数を記録するカウンタを用意する
cnt = 0;

# 発言数の上限を定義する
MAX_CNT = 20;

# あたり判定フラグを用意する
hit_flg = false;

# コンピュータが返すメッセージ文字列を定義する
OOKII  = '大きいです。'
TIISAI = '小さいです。'
ATARI  = 'あたりです。'

# コンピュータが返すメッセージの格納変数を用意する
pcAns = "";

# 開始メッセージを出力する
p '0～999の数字を入力してください。'
p '私の考えた数より大きい数だった場合「大きいです。」'
p '私の考えた数より小さい数だった場合「小さいです。」'
p '私の考えた通りの数だった場合「あたりです。」とお答えします。'

while cnt < MAX_CNT do

    # ユーザに入力を促す
    p '数を入力して[Enter]キーを押してください。'

    # 標準入力に入力された情報を読み取る
    input_number = Readline.readline.to_i
    # 当たりはずれを判定する
    if random_no < input_number then
        pcAns = OOKII
    elsif random_no > input_number then
        pcAns = TIISAI
    else
        pcAns = ATARI
        hit_flg = true
    end

    # 結果表示
    p pcAns

    # 状態確認処理
    if true == hit_flg then
        # ループを脱出する
        break
    else
        # 入力数カウンタをカウントアップしてループ処理を続ける
        cnt = cnt + 1
    end

end

# 終了処理
if true == hit_flg then
    p 'おめでとうございます。' + (cnt + 1).to_s + '回で正解です。'
else
    p '残念。' + MAX_CNT.to_s + '回以内で正解できませんでした。'
end
```

では、また。

※ 追記（2019/12/23）

[続編]
(https://qiita.com/GORO_Neko/items/e863e940285e97158a88)書きました。