JavaScriptのクロージャを使って抽選マシンを実装してみた

こちらは[qnote Advent Calendar](http://qiita.com/advent-calendar/2015/qnote) 12日目の記事となります。


今回は超ライトなお遊び記事です！

JavaScriptで、クロージャを使ったお手軽抽選マシンを実装してみました。
放り込んだ賞品をランダムで抽出、残量管理も行います。

# 実装
こんな感じでサクッと。
シンプルですね。

```js:lottery_machine.html
<html>
<head>
    <script type="text/javascript">
        // 抽選マシン
        var lotteryMachine = (function() {
            // クロージャによるプライベート変数＆関数群
            // 賞品リスト
            var prizes = {};
            // メッセージを表示します
            var showMessage = function(message) {
                var messageContainer = document.getElementById("message");
                var now = new Date();
                messageContainer.value = "[" + now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds() + "] "
                        + message
                        + "\n" + messageContainer.value;
            };
            // 賞品の合計数を取得します
            var getTotalAmount = function() {
                var totalAmount = 0;
                for (var name in prizes) {
                    totalAmount += prizes[name];
                }
                return totalAmount;
            };
            // 外部からは↓のオブジェクトのみ利用可能
            return {
                // 抽選を実行します
                draw: function() {
                    var totalAmount = getTotalAmount();
                    if (totalAmount <= 0) {
                        showMessage("賞品が残ってないよー");
                        return;
                    }
                    var randnum = Math.random() * totalAmount;
                    for (var name in prizes) {
                        randnum -= prizes[name];
                        if (randnum <= 0) {
                            prizes[name]--;
                            showMessage(name + "が出ました！抽選機には" + getTotalAmount() + "本の賞品が残っています。");
                            return;
                        }
                    }
                },
                // 賞品を追加します
                addPrize: function (name, amount) {
                    if (undefined === prizes[name]) {
                        prizes[name] = 0;
                    }
                    prizes[name] += amount;
                    showMessage(name + "を追加しました。抽選機には" + getTotalAmount() + "本の賞品が入っています。");
                }
            };
        })();
    </script>
    <style type="text/css">
        body {
            padding: 10px;
        }
        div,textarea {
            background-color: antiquewhite;
            padding: 10px;
            margin: 10px;
            border-radius: 5px
        }
        textarea#message {
            width: 400px;
            height: 300px;
        }
        button {
            border: solid 1px;
            border-radius: 5px;
            padding: 5px;
            background-color: white;
        }
    </style>
</head>
<body>
<h3>抽選機コントロール</h3>
<div>
    <button onclick="lotteryMachine.addPrize('1等', 1);">1等を補充</button><br />
    <button onclick="lotteryMachine.addPrize('2等', 1);">2等を補充</button><br />
    <button onclick="lotteryMachine.addPrize('3等', 1);">3等を補充</button><br />
    <button onclick="lotteryMachine.addPrize('4等', 1);">4等を補充</button><br />
    <button onclick="lotteryMachine.addPrize('5等', 1);">5等を補充</button><br />
    <button onclick="lotteryMachine.addPrize('6等', 1);">6等を補充</button><br />
    <button onclick="lotteryMachine.draw();">抽選！</button>
</div>
<h3>メッセージエリア</h3>
<textarea id="message" readonly></textarea>
</body>
</html>
```

# デモ
下記URLにデモを設置しました。
http://ijorutools.parseapp.com/lottery_machine.html
（[デモサーバはParseで立てています♪](http://qiita.com/Ijoru/items/1735dc34d6f36b2ce987)）

# まとめ
JSたまーに書くと頭の体操になって楽しいです。
他の言語とは言語自体の設計が違うので、それもまた楽しい。
個人的に型指定は欲しいけど、ライトな言語だとしょうがないのかな？

ってな感じで、プログラムは仕事だけで触るんじゃなく、ぜひプログラム自体に興味を持って、遊びの一環として使ってみてください。

あと、どの言語でもそうですが、メソッドのpublic/privateの定義はしっかり行いましょう。
触られたくない部分は隠蔽することで、コードの可読性が全く変わってきます。