File size: 6,060 Bytes
09a6f7f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
/**
* @classdesc Class that handles the simulation.
*/
class Game {
/**
* @constructor
* @param agents {{morphologies: Array, policies: Array, positions: Array}} - Morphologies, policies and positions of the agents
* @param cppn_input_vector {Array} - 3-dimensional array that encodes the CPPN
* @param water_level {number}
* @param creepers_width {number}
* @param creepers_height {number}
* @param creepers_spacing {number}
* @param smoothing {number}
* @param creepers_type {boolean}
* @param ground {Array} - List of points {x, y} composing the ground
* @param ceiling {Array} - List of points {x, y} composing the ceiling
* @param align_terrain {Object}
*/
constructor(agents, cppn_input_vector, water_level, creepers_width, creepers_height,
creepers_spacing, smoothing, creepers_type, ground, ceiling, align_terrain) {
this.run_fps = 60;
this.obs = [];
this.rewards = [];
this.initWorld(agents, cppn_input_vector, water_level, creepers_width, creepers_height, creepers_spacing, smoothing,
creepers_type, ground, ceiling, align_terrain);
this.running = false;
}
/**
* Initializes the environment.
* @param agents {{morphologies: Array, policies: Array, positions: Array}} - Morphologies, policies and positions of the agents
* @param cppn_input_vector {Array} - 3-dimensional array that encodes the CPPN
* @param water_level {number}
* @param creepers_width {number}
* @param creepers_height {number}
* @param creepers_spacing {number}
* @param smoothing {number}
* @param creepers_type {boolean}
* @param ground {Array} - List of points {x, y} composing the ground
* @param ceiling {Array} - List of points {x, y} composing the ceiling
* @param align_terrain {Object}
*/
initWorld(agents, cppn_input_vector, water_level, creepers_width, creepers_height, creepers_spacing,
smoothing, creepers_type, ground, ceiling, align_terrain) {
this.env = new MultiAgentsContinuousParkour(
agents,
3,
smoothing,
200,
90,
20,
creepers_type,
ground,
ceiling,
align_terrain);
this.env.set_environment(cppn_input_vector, water_level, creepers_width, creepers_height, creepers_spacing, smoothing, creepers_type);
let step_rets = this.env.reset();
this.obs.push([...step_rets.map(e => e[0])]);
this.rewards.push([...step_rets.map(e => e[1])]);
}
/**
* Pauses the simulation.
*/
pause(){
clearInterval(this.runtime);
this.running = false;
}
/**
* Runs the simulation.
* @returns {Promise<void>}
*/
async run(){
// Loads the policy for each agent before launching the simulation
for(let agent of window.game.env.agents){
if(agent.policy.path != null){
agent.model = await tf.loadGraphModel(agent.policy.path + '/model.json');
}
else{
agent.model = null;
}
}
// Creates a repeated interval over time
this.runtime = setInterval(() => {
this.play();
}, 1000 / this.run_fps);
this.running = true;
}
/**
*
* @param agents {{morphologies: Array, policies: Array, positions: Array}} - Morphologies, policies and positions of the agents
* @param cppn_input_vector {Array} - 3-dimensional array that encodes the CPPN
* @param water_level {number}
* @param creepers_width {number}
* @param creepers_height {number}
* @param creepers_spacing {number}
* @param smoothing {number}
* @param creepers_type {boolean}
* @param ground {Array} - List of points {x, y} composing the ground
* @param ceiling {Array} - List of points {x, y} composing the ceiling
* @param align_terrain {Object}
*/
reset(agents, cppn_input_vector, water_level, creepers_width, creepers_height,
creepers_spacing, smoothing, creepers_type, ground, ceiling, align_terrain){
this.pause();
let zoom = window.game.env.zoom;
let scroll = [...window.game.env.scroll];
this.initWorld(agents, cppn_input_vector, water_level, creepers_width, creepers_height, creepers_spacing, smoothing,
creepers_type, ground, ceiling, align_terrain);
// Keeps the previous zoom and scroll
window.game.env.set_zoom(zoom);
window.game.env.set_scroll(null, scroll[0], scroll[1]);
this.env.render();
}
/**
* Plays one simulation step.
*/
play() {
// Gets the actions to execute for each agent
for(let agent of window.game.env.agents){
let state = this.obs[this.obs.length - 1][agent.id];
// Generates the actions thanks to the agent's policy model
if(agent.model != null){
let envState = tf.tensor(state,[1, state.length]);
let inputs = {
"Placeholder_1:0": envState
};
let output = 'main/mul:0'
agent.actions = agent.model.execute(inputs, output).arraySync()[0];
}
// Generates random actions
else /*if(agent.policy.name == "random")*/{
agent.actions = Array.from({length: agent.agent_body.get_action_size()}, () => Math.random() * 2 - 1);
}
// Generates motionless actions
/*else{
agent.actions = Array.from({length: agent.agent_body.get_action_size()}, () => 0);
}*/
}
// Runs one step and stores the resulted states for each agent
let step_rets = this.env.step();
this.obs.push([...step_rets.map(e => e[0])]);
this.rewards.push([...step_rets.map(e => e[1])]);
this.env.render();
}
}
|