{"id":399,"date":"2022-03-02T15:39:10","date_gmt":"2022-03-02T06:39:10","guid":{"rendered":"http:\/\/www.amano-lab.cs.gunma-u.ac.jp\/HP\/?page_id=399"},"modified":"2022-03-02T23:26:13","modified_gmt":"2022-03-02T14:26:13","slug":"oda-masaya","status":"publish","type":"page","link":"https:\/\/ama.inf.gunma-u.ac.jp\/amano-lab\/index.php\/oda-masaya\/","title":{"rendered":"\u5c0f\u7530 \u7406\u77e2"},"content":{"rendered":"\n<p>\u5929\u91ce\u7814B4<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">\u79fb\u52d5\u969c\u5bb3\u7269\u3042\u308a\u30b9\u30cd\u30fc\u30af\u30b2\u30fc\u30e0<\/h2>\n\n\n\n<p>\u79fb\u52d5\u3059\u308b\u969c\u5bb3\u7269\u3092\u8ffd\u52a0\u3057\u305f\u30b9\u30cd\u30fc\u30af\u30b2\u30fc\u30e0\u3067\u3059\uff0eWeb\u516c\u958b\u7528\u306bJavascript\u3067\u66f8\u304d\u76f4\u3057\u307e\u3057\u305f\uff0e<\/p>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">\u64cd\u4f5c<\/h3>\n\n\n\n<figure class=\"wp-block-table is-style-regular\"><table><tbody><tr><td>\u30ad\u30fc\u30dc\u30fc\u30c9\u5165\u529b<\/td><td>\u884c\u52d5<\/td><\/tr><tr><td>W<\/td><td>\u4e0a\u3078\u79fb\u52d5<\/td><\/tr><tr><td>S<\/td><td>\u4e0b\u3078\u79fb\u52d5<\/td><\/tr><tr><td>A<\/td><td>\u5de6\u3078\u79fb\u52d5<\/td><\/tr><tr><td>D<\/td><td>\u53f3\u3078\u79fb\u52d5<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">\u30b2\u30fc\u30e0\uff08PC\u306e\u307f\uff09<\/h3>\n\n\n\n<p>\u30ad\u30fc\u30dc\u30fc\u30c9\u306e\u300cW\u300d\u300cA\u300d\u300cS\u300d\u300cD\u300d\u3067\u52d5\u304d\u307e\u3059\uff0e\u7dd1\u8272\u3068\u8d64\u8272\u304c\u300c\u30d8\u30d3\u300d\uff0c\u9752\u8272\u304c\u300c\u30a8\u30b5\u300d\uff0c\u7070\u8272\u304c\u300c\u969c\u5bb3\u7269\u300d\u3067\u3059\uff0e\u30d8\u30d3\u3092\u64cd\u4f5c\u3057\u3066\u30a8\u30b5\u3092\u98df\u3079\u308b\u3068\u30b9\u30b3\u30a2\u304c1\u4e0a\u304c\u308a\uff0c\u58c1\u3084\u969c\u5bb3\u7269\uff0c\u81ea\u5206\u306e\u4f53\u3068\u885d\u7a81\u3057\u305f\u3089\u30b2\u30fc\u30e0\u30aa\u30fc\u30d0\u30fc\u306b\u306a\u308a\u307e\u3059\uff0e\u30b2\u30fc\u30e0\u30aa\u30fc\u30d0\u30fc\u306b\u306a\u3063\u305f\u3089\u5de6\u4e0b\u306e\u30ea\u30bb\u30c3\u30c8\u30dc\u30bf\u30f3\u3092\u62bc\u3057\u3066\u304f\u3060\u3055\u3044\uff0e<\/p>\n\n\n\n<div>\u30b9\u30b3\u30a2: <p id=\"game_score\"><\/p><\/div>\n<div>\u72b6\u614b: <p id=\"game_status\"><\/p><\/div>\n<button id=\"reset_button\" type=\"button\">\u30ea\u30bb\u30c3\u30c8<\/button>\n<canvas id=\"snake_game_screen\"\/>\n<script type=\"text\/javascript\">\n<!--\n\n    \/\/ Constants\n    const NUM_DIVS = 12;\n    const INIT_SNAKE_LEN = 3;\n\n    let SCREEN_SIZE = 480;\n    if (navigator.userAgent.match(\/iPhone|Android.+Mobile\/)) SCREEN_SIZE = 240;\n\n    \/\/ Enum\n    const DIR_UP    = 0;\n    const DIR_DOWN  = 1;\n    const DIR_LEFT  = 2;\n    const DIR_RIGHT = 3;\n\n    class Screen {\n        constructor(size) {\n            this._canvas  = document.getElementById('snake_game_screen');\n            this._canvas.width  = size;\n            this._canvas.height = size;\n            this._context = this._canvas.getContext('2d');\n            this._cell_size = size \/ NUM_DIVS;\n        }\n\n        clear() {\n            this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);\n        }\n        \n        draw_border() {\n            this._context.fillStyle = 'black';\n            this._context.strokeRect(0, 0, this._canvas.width, this._canvas.height);\n        }\n\n        \/\/ h: horizontal, v: vertical\n        draw_cell(h_index, v_index, color) {\n            this._context.fillStyle = color;\n            this._context.fillRect(h_index * this._cell_size, v_index * this._cell_size, this._cell_size, this._cell_size);\n        }\n    }\n\n\n    \/*\n\n        Game\n\n    *\/\n    screen = new Screen(SCREEN_SIZE);\n    const score_display = document.getElementById('game_score');\n    const status_display = document.getElementById('game_status');\n\n    let game_ended = false;\n\n    snake_pos_list = [];\n    food_pos       = [];\n    obstacle_pos   = [];\n    obstacle_dir   = [DIR_LEFT, DIR_UP];\n\n    function init_game() {\n        snake_pos_list = [[NUM_DIVS\/2 - 1, NUM_DIVS\/2], [NUM_DIVS\/2, NUM_DIVS\/2], [NUM_DIVS\/2 + 1, NUM_DIVS\/2]];\n        place_new_food();\n        place_obstacle();\n\n        game_ended = false;\n\n        draw_all();\n\n    }\n\n    function place_new_food() {\n        empty_cells = get_empty_cells();\n\n        food_pos = empty_cells[Math.floor(Math.random() * empty_cells.length)];\n    }\n\n    function place_obstacle() {\n        empty_cells = get_empty_cells();\n\n        obstacle_pos = empty_cells[Math.floor(Math.random() * empty_cells.length)];\n        obstacle_dir = [Math.floor(Math.random() * 4), Math.floor(Math.random() * 4)];\n    }\n\n\n    function get_head_pos() {\n        return snake_pos_list.slice(-1)[0];\n    }\n\n    function get_empty_cells() {\n        l = [];\n        for(let h = 0; h < NUM_DIVS; h++) {\n            for(let v = 0; v < NUM_DIVS; v++) {\n                let is_empty = true;\n                for(let i = 0; i < snake_pos_list.length; i++) {\n                    if(snake_pos_list[i][0] === h && snake_pos_list[i][1] === v) is_empty = false;\n                }\n\n                if(is_empty) {\n                    l.push([h, v]);\n                }\n            }\n        }\n\n        return l;\n    }\n\n    function is_snake_eating() {\n        for(let i = 0; i < snake_pos_list.length; i++) {\n            if(snake_pos_list[i][0] === food_pos[0] && snake_pos_list[i][1] === food_pos[1]) return true;\n        }\n\n        return false;\n    }\n\n    function snake_collided() {\n        const head_pos = get_head_pos();\n\n        let collided = false;\n\n        \/\/ wall\n        if (head_pos[0] < 0 || NUM_DIVS <= head_pos[0] || head_pos[1] < 0 || NUM_DIVS <= head_pos[1]) collided = true;\n\n        \/\/ body and obstacle\n        for(let i = 0; i < snake_pos_list.length - 1; i++) {\n            if((head_pos[0]     === snake_pos_list[i][0] && head_pos[1]     === snake_pos_list[i][1]) || \n               (obstacle_pos[0] === snake_pos_list[i][0] && obstacle_pos[1] === snake_pos_list[i][1])) collided = true;\n        }\n        if(head_pos[0] === obstacle_pos[0] && head_pos[1] === obstacle_pos[1]) collided = true;\n\n\n        return collided;\n    }\n\n    function get_current_dir() {\n        const head_pos = get_head_pos();\n        const neck_pos = snake_pos_list.slice(-2)[0];\n\n        if(head_pos[0] < neck_pos[0]) return DIR_LEFT;\n        else if(head_pos[0] > neck_pos[0]) return DIR_RIGHT;\n        else if(head_pos[1] < neck_pos[1]) return DIR_UP;\n        else return DIR_DOWN;\n    }\n\n    function draw_all() {\n        screen.clear();\n\n        screen.draw_border()\n\n        \/\/ draw snake\n        snake_pos_list.forEach(pos => screen.draw_cell(...pos, 'green'));\n        screen.draw_cell(...get_head_pos(), 'red');\n\n        score_display.textContent  = (snake_pos_list.length - INIT_SNAKE_LEN).toString();\n\n        screen.draw_cell(...food_pos, 'blue');\n        screen.draw_cell(...obstacle_pos, 'gray');\n\n        if(game_ended) status_display.textContent = '\u30b2\u30fc\u30e0\u30aa\u30fc\u30d0\u30fc';\n        else status_display.textContent = '';\n    }\n\n    \n    \/*\n\n        Add event listeners\n\n    *\/\n    document.addEventListener('keydown', function(e) {\n        if(game_ended) return;\n\n        let dir = get_current_dir();\n\n        \/\/ up\n        if (e.code === 'KeyW' && dir !== DIR_DOWN) {\n            dir = DIR_UP;\n        } \n        \/\/ down\n        else if (e.code === 'KeyS' && dir !== DIR_UP) {\n            dir = DIR_DOWN;\n        } \n        \/\/ left\n        else if (e.code === 'KeyA' && dir !== DIR_RIGHT) {\n            dir = DIR_LEFT;\n        } \n        \/\/right\n        else if (e.code === 'KeyD' && dir !== DIR_LEFT) {\n            dir = DIR_RIGHT;\n        }\n\n        \/\/ common\n        if (e.code === 'KeyW' || e.code === 'KeyS' || e.code === 'KeyA' || e.code === 'KeyD') {\n\n            \/\/ Move snake\n            [new_h, new_v] = get_head_pos();\n\n            switch(dir) {\n                case DIR_UP:\n                    new_v--;\n                    break;\n                case DIR_DOWN:\n                    new_v++;\n                    break;\n                case DIR_LEFT:\n                    new_h--;\n                    break;\n                case DIR_RIGHT:\n                    new_h++;\n                    break;\n            }\n\n            snake_pos_list.push([new_h, new_v]);\n\n            \/\/ Move obstacle\n            const head_pos = get_head_pos();\n            if(obstacle_dir[0] === DIR_LEFT) {\n                if(obstacle_pos[0] <= 0){\n                    obstacle_pos[0]++;\n                    obstacle_dir[0] = DIR_RIGHT;\n                }\n                else obstacle_pos[0]--;\n            }\n            else {\n                if(obstacle_pos[0] >= NUM_DIVS - 1){\n                    obstacle_pos[0]--;\n                    obstacle_dir[0] = DIR_LEFT;\n                }\n                else obstacle_pos[0]++;\n            }\n            if(obstacle_dir[1] === DIR_UP) {\n                if(obstacle_pos[1] <= 0){\n                    obstacle_pos[1]++;\n                    obstacle_dir[1] = DIR_DOWN;\n                }\n                else obstacle_pos[1]--;\n            }\n            else {\n                if(obstacle_pos[1] >= NUM_DIVS - 1){\n                    obstacle_pos[1]--;\n                    obstacle_dir[1] = DIR_UP;\n                }\n                else obstacle_pos[1]++;\n            }\n\n\n            if(snake_collided()) {\n                game_ended = true;\n            }\n            else if(is_snake_eating()) {\n                place_new_food();\n            }\n            else {\n               snake_pos_list.shift();\n            }\n\n            draw_all();\n        }\n\n    });\n\n    const reset_button = document.getElementById('reset_button');\n    reset_button.addEventListener('click', function() {\n        init_game(); \n    });\n\n\n    init_game();\n\n\n\/\/--><\/script>\n\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u5929\u91ce\u7814B4 \u79fb\u52d5\u969c\u5bb3\u7269\u3042\u308a\u30b9\u30cd\u30fc\u30af\u30b2\u30fc\u30e0 \u79fb [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-399","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ama.inf.gunma-u.ac.jp\/amano-lab\/index.php\/wp-json\/wp\/v2\/pages\/399","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ama.inf.gunma-u.ac.jp\/amano-lab\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ama.inf.gunma-u.ac.jp\/amano-lab\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ama.inf.gunma-u.ac.jp\/amano-lab\/index.php\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/ama.inf.gunma-u.ac.jp\/amano-lab\/index.php\/wp-json\/wp\/v2\/comments?post=399"}],"version-history":[{"count":0,"href":"https:\/\/ama.inf.gunma-u.ac.jp\/amano-lab\/index.php\/wp-json\/wp\/v2\/pages\/399\/revisions"}],"wp:attachment":[{"href":"https:\/\/ama.inf.gunma-u.ac.jp\/amano-lab\/index.php\/wp-json\/wp\/v2\/media?parent=399"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}