2016年9月2日金曜日

開発環境

アルゴリズムパズル(Anany Levitin (著)、Maria Levitin (著)、黒川 洋 (翻訳)、松崎 公紀 (翻訳)、オライリージャパン)の初級パズル、31.(3つの山のトリック(The Three Pile Trick))をJavaScriptで。

コード(Emacs)

HTML5

<label for="card_num0">
  番号を入力(1-27): 
</label>
<input id="card_num0" type="number" min="1" max="27">
<div id="output0"></div>

<script src="array.js"></script>
<script src="sample31.js"></script>

JavaScript

(function () {
    'use strict';
    var cards,
        card_num,
        piles = {' 左: ': [], ' 真ん中: ':[], ' 右: ':[]},
        count,
        t = 500,
        text = document.createTextNode('含まれていた位置の数字をクリック'),
        br = document.createElement('br'),

        div_output = document.querySelector('#output0'),
        input_card_num = document.querySelector('#card_num0'),
        
        createPiles,
        trick,
        timeoutIDs = [];

    createPiles = function () {
        var text0_left = document.createTextNode(' 左: '),
            span_left = document.createElement('span'),
            text0_center = document.createTextNode(' 真ん中: '),
            span_center = document.createElement('span'),
            text0_right = document.createTextNode(' 右: '),
            span_right = document.createElement('span'),
            spans = [[text0_left, span_left],
                     [text0_center, span_center],
                     [text0_right, span_right]],
            
            i = 0,
            max = cards.length,
            createPile;

        Object.keys(piles).forEach(function (key) {
            piles[key] = [];
        });
        div_output.innerHTML = '';
        spans.forEach(function(span) {
            span[1].setAttribute('style', "font-size: xx-large");
            div_output.appendChild(span[0]);
            div_output.appendChild(span[1]);
        });
        createPile = function () {
            var r = i % 3,
                card = cards[i];

            if (r === 0) {
                span_left.innerText = card;
                piles[' 左: '].push(card);
            } else if (r === 1) {
                span_center.innerText = card;
                piles[' 真ん中: '].push(card);
            } else if (r === 2) {
                span_right.innerText = card;
                piles[' 右: '].push(card);
            }
            i += 1;
            if (i !== max) {
                timeoutIDs.push(setTimeout(createPile, t));
            } else {
                count += 1;
                spans.forEach(function (span) {
                    span[1].onclick = function () {
                        var text0 = span[0].textContent;

                        if (count === 3) {
                            div_output.innerText =
                                '選択した番号は: ' + piles[text0][4];
                        } else {
                            if (text0 === ' 左: ') {
                                cards = piles[' 真ん中: ']
                                    .concat(piles[' 左: '])
                                    .concat(piles[' 右: ']);
                            } else if (text0 === ' 右: ') {
                                cards = piles[' 左: ']
                                    .concat(piles[' 右: '])
                                    .concat(piles[' 真ん中: ']);
                            }
                            createPiles();
                        }
                    }
                });
                div_output.appendChild(br);
                div_output.appendChild(text);
            }
        };
        timeoutIDs.push(setTimeout(createPile, t));
    };
    trick = function () {
        cards = range(1, 28);
        cards.shuffle();
        div_output.innerHTML = '';
        count = 0;
        timeoutIDs.forEach(function (timeoutID) {
            clearTimeout(timeoutID);
        });
        timeoutIDs = [];
        createPiles();
    };
    input_card_num.onchange = function () {
        card_num = parseInt(input_card_num.value, 10);    
        if (typeof card_num === 'number') {
            trick();
        }
    };
}());

0 コメント:

コメントを投稿