From f728cc0b276e5e0366f41c263730269c0fe793c6 Mon Sep 17 00:00:00 2001 From: Ugo Date: Wed, 9 Oct 2019 22:37:54 +0200 Subject: [PATCH] changed to vue --- index.html | 38 ++++++++- js/controls.js | 1 + js/rl.js | 3 + js/view.js | 208 ++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 246 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 29024ee..7a6284e 100644 --- a/index.html +++ b/index.html @@ -3,11 +3,15 @@ + + + + RL exhibit - prototype -
+
+
+ + + + + + + + + + + + + + + + +
+ - + + diff --git a/js/controls.js b/js/controls.js index 6824b3e..da715cb 100644 --- a/js/controls.js +++ b/js/controls.js @@ -32,6 +32,7 @@ function key_callback(e) { ret = machine.step(tmp); } update_agent(machine.state, true); + // show_q_table(); } document.addEventListener('keydown', key_callback); diff --git a/js/rl.js b/js/rl.js index 521926f..5577f42 100644 --- a/js/rl.js +++ b/js/rl.js @@ -20,6 +20,7 @@ class RL_machine { this.episode = 0; this.epsilon = epsilon; this.score = 0; + this.running = false; } reset_machine(){ this.q_table = this.q_table.map((c) => c.map((a) => a.fill(0))); @@ -58,6 +59,7 @@ class RL_machine { return new_state; } run(episodes, max_steps_per_episode=10000){ + this.running = true; for (var i = 0; i < episodes; i++) { for (var j = 0; j < max_steps_per_episode; j++) { if (this.auto_step() != 1) { @@ -66,6 +68,7 @@ class RL_machine { } this.new_episode(); } + this.running = false; } } diff --git a/js/view.js b/js/view.js index 689cbca..1e64d57 100644 --- a/js/view.js +++ b/js/view.js @@ -105,9 +105,7 @@ function draw_agent(state) { break; } if (animate){ - console.log(fun); this.todos.push(fun); - console.log(this.todos); } else { this.todos = []; this.target_x = undefined; @@ -255,3 +253,209 @@ window.addEventListener('resize', function() { draw_map(map) draw_agent(machine.state) + +// New + +app = new Vue({ + el: '#app', + data: { + width: 0, + height: 0, + q_table: machine.q_table, + maze: maze, + state: {x:0,y:0}, + state_tween: new TimelineLite(), + }, + created() { + // Resize handler + window.addEventListener('resize', this.handleResize) + this.handleResize(); + // State wrapper + var s = machine.state; + var $this = this; + this.state = this.s2p(s); + Object.defineProperty(machine, 'state', { + get: function() { return this._state }, + set: function(ne) { this._state=ne; $this.handleState(this._state); } + }); + machine.state = s; + }, + destroyed() { + window.removeEventListener('resize', this.handleResize) + }, + computed: { + stage_config: function () { + return { + width: this.width, + height: this.height, + } + }, + mini_map_config: function () { + return { + // x: this.stage_config.width * 0.5 - (Math.round(maze.width * this.base_size)/2), + // y: this.stage_config.height * 0.5 - (Math.round(maze.height * this.base_size)/2), + x:this.width-(Math.round(maze.width * this.base_size)*0.2)-30, + y:30, + scale:{ + x: 0.2, + y: 0.2 + } + } + }, + local_layer: function () { + return { + x: this.width/2, + y: this.height/2, + scale:{ + x: 2, + y: 2 + } + } + }, + map_config: function () { + return { + x: this.base_size*(this.maze.width-this.state.x), + y: this.base_size*(this.maze.height-this.state.y), + offset: { + x: this.base_size*this.maze.width+this.base_size/2, + y: this.base_size*this.maze.height+this.base_size/2, + } + } + }, + agent_config: function () { + return { + sides: 5, + radius: this.base_size / 3, + fill: '#00D2FF', + stroke: 'black', + strokeWidth: this.strokeW, + offset: { + x: -this.base_size / 2, + y: -this.base_size / 2 + }, + } + }, + base_size: function () { + return Math.min(this.stage_config.height * 0.9 / this.maze.height, this.stage_config.width * 0.6 / this.maze.width); + }, + strokeW: function () { + return this.base_size / 50; + }, + }, + methods: { + s2p: function(state){ + return { + x: (state%this.maze.width), + y: Math.floor(state/this.maze.width), + } + }, + p2s: function(x,y){ + return x+y*this.maze.width; + }, + handleResize: function() { + this.width = window.innerWidth; + this.height = window.innerHeight; + }, + handleState: function(s) { + if (!machine.running){ + this.state_tween.to(this.state, 0.2, { x: this.s2p(s).x, y: this.s2p(s).y }); + } else { + this.state = this.s2p(s); + } + // this.hidden_state = s; + }, + get_grid_line_config: function (idx, y=false) { + var offset = this.strokeW/2; + if (y){ + var points = [-offset, Math.round(idx * this.base_size), this.base_size * this.maze.width + offset,Math.round(idx * this.base_size)]; + } else { + var points = [Math.round(idx * this.base_size), -offset, Math.round(idx * this.base_size), this.base_size * this.maze.height + offset]; + } + return { + points: points, + stroke: '#ddd', + strokeWidth: this.strokeW, + } + }, + get_agent_config: function () { + return{ + ...this.agent_config, + x: this.base_size*this.state.x, + y: this.base_size*this.state.y, + } + }, + get_tile_type: function (state){ + var pos = this.s2p(state); + if (pos.y > maze.height){ + return null; + } else if (pos.x > maze.width){ + return null; + } else { + return maze.map[pos.y][pos.x]; + } + }, + in_plus: function (pos1, pos2) { + if (Math.abs(pos1.x-pos2.x) + Math.abs(pos1.y-pos2.y) < 2) { + return true; + } + return false; + }, + get_tile_config: function (i, t_type, local=false) { + var pos = this.s2p(i); + var over = {}; + + // not in plus + if (local) { + if (!this.in_plus(this.s2p(i),{x:Math.round(this.state.x),y:Math.round(this.state.y)})) { + over = { + opacity: 0, + fill: "#eee" + }; + } else if (i != this.p2s(Math.round(this.state.x),Math.round(this.state.y))) { + over = { + opacity: 1, + fill: "#eee" + }; + } + } + const layout = { + x: this.base_size * pos.x, + y: this.base_size * pos.y, + width: this.base_size, + height: this.base_size, + stroke: '#ddd', + strokeWidth: this.strokeW, + }; + switch (t_type) { + case tile.regular: + return { + ...layout, + fill: '#fff', + opacity: 1, + ...over, + } + case tile.end: + return { + ...layout, + fill: '#0eb500', + opacity: 1, + ...over, + } + case tile.start: + return { + ...layout, + fill: '#ff0008', + opacity: 1, + ...over, + } + case tile.dangerous: + return { + ...layout, + fill: '#FF7B17', + opacity: 1, + ...over, + } + } + } + }, +})