「人間はJavascriptにいずれ負ける」ことを実感するツールを作った

「人間はJavascriptにいずれ負ける」ことを実感するツールを作った:


はじめに

この記事は、JavaScript Advent Calendar 2018の18日目の記事です。


ゲームを作りました

これはJavascriptの速さを身をもって体験ができるアプリです。
アプリと言うかゲームですね。

Javascriptよりも早く、ターゲットに到達するのを競うものです。



hvsj.gif


上の画像でなんとなく雰囲気わかる方もいるかも知れませんが、
緑の円よりも早く、もう一つの円に到達する(マウスオーバーする)ことを繰り返します。

プレイする


技術的な話

実装には、D3.jsともはや化石と化しそうなjqueryを使用しています。

(といっても、d3の要素はほぼないです)

このゲームは主に以下のクラスで動いています。

  • Targetクラス・・・みんなが追いかける丸
  • Trackerクラス・・・我々と戦う緑の丸
  • Navigatorクラス・・・今の現状を教えてくれるヤツ
Github - ソースコード


Trackerクラス(緑の丸)の動き

じつは、この緑の丸は「ターゲットの位置が何処にあるかわかっていません」

人間と戦うに当たり、イーブンな土台に上げるためにあえてそうしています。

まず、相手との距離をスコア化します。

(近いと減る、遠いと増える、みたいな)

Trackerクラス全16方向(東西南北とその間、さらに北北西などの方位も)に試しに動いてみて、

Navigatorクラスに対して「どの方向に動いたやつが一番スコアが良かった?」と聞いて、それで一番スコアの良い(相手との距離が一番縮まる)方向に動きます。

それを定期的に続けることで
「何処にいるかは知らないけど、こっちにいったら近づいてる」

という情報のフィードバックをずっと得ながら移動していきます。

イメージで言うとドラゴンボールに出てくる「ドラゴンレーダー」のような動きでしょうか

        this.forwardMaster = { 
            // 上段 (北西・北・北東) 
            7: {x: -1, y: -1}, 
            8: {x: 0, y: -1}, 
            9: {x: 1, y: -1}, 
 
            // 中段 (西・ニュートラル・東) 
            4: {x: -1, y: 0}, 
            5: {x: 0, y: 0}, 
            6: {x: 1, y: 0}, 
 
            // 下段 (南西・南・南東) 
            1: {x: -1, y: 1}, 
            2: {x: 0, y: 1}, 
            3: {x: 1, y: 1}, 
 
            // 北北西と北北東 
            10: {x: -1, y: -2}, 
            11: {x: 1, y: -2}, 
 
            // 西北西と東北東 
            12: {x: -2, y: -1}, 
            13: {x: 2, y: -1}, 
 
            // 西南西と東南東 
            14: {x: -2, y: 1}, 
            15: {x: 2, y: 1}, 
 
            // 南南西と南南東 
            16: {x: -1, y: 2}, 
            17: {x: 1, y: 2} 
 
        }; 
 
    /** 
     * 移動スコアを計算する 
     * @param forward 
     * @returns {number} 
     */ 
    Tracker.prototype.mathScore = function (forward) { 
        var i; 
        var count = 0; 
        var sum = 0; 
 
        while (this.history[forward].queue.length > this.step * 2) { 
            this.history[forward].queue.shift(); 
        } 
 
        // その方向の要素を全て洗う 
        for (i in this.history[forward].queue) { 
            sum += this.history[forward].queue[i].line; 
            count++; 
        } 
 
        // 最後の要素だけをもう一回 
        sum += this.history[forward].queue[i].line; 
        count++; 
 
        // 指数移動平均スコアを求める 
        return (sum / count); 
    }; 


実際には計算が早くなってるわけではない

ネタバレしてしまうと、setTimeoutの感覚がどんどん早くなっていっているだけです。

そうです、「待ってもらっていただけ」です


筆者のスコア

作った人間はこれが限界でした。



スクリーンショット 2018-12-16 15.35.43.png



おわりに

本当は、強化学習機能を搭載して、

「このスコアの並びだったらだいたいこれぐらいの距離だな・・・」

という一気にジャンプする機能を付けたかったのですが、それはまたの機会に。

ていうか、Advent Calendarの記事がこんなのでいいのだろうか・・・

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)