diff options
Diffstat (limited to 'src/simulation')
-rw-r--r-- | src/simulation/game.js | 66 |
1 files changed, 63 insertions, 3 deletions
diff --git a/src/simulation/game.js b/src/simulation/game.js index 7a3119d..20c5e4e 100644 --- a/src/simulation/game.js +++ b/src/simulation/game.js @@ -86,6 +86,7 @@ export function create_world(size, teams) { // agents // genome // score +// games // } @@ -113,7 +114,7 @@ export function create_team(size, genome_size, n_internal) { ).slice(-1)[0]; const agents = [...Array(size)].map(_ => create_agent(genome, n_internal)); - return { agents, genome, score: 0 }; + return { agents, genome, score: 0, games: 0 }; } @@ -135,7 +136,7 @@ export function child_team(team, keep=Math.floor(team.size/2)) { const new_agents = [...Array(team.agents.length - keep)].map(_ => create_agent(genome, n_internal)); const agents = [old_agents, new_agents].flat(); - return { agents, genome, score: 0 }; + return { agents, genome, score: 0, games: 0 }; } @@ -178,9 +179,68 @@ export function finish_game(teams, game) { return game.team_indices.reduce( (acc, idx, i) => { const team = teams[idx]; - acc.splice(idx, 1, {...team, score: team.score + scores[i]}); + acc.splice(idx, 1, {...team, score: team.score + scores[i], games: team.games+1}); return acc; }, teams, ); } + + + +// epoch structure +// { +// game +// time +// teams +// } + +function random_indices(teams) { + return [...Array(teams.length - 4)].reduce( + (acc) => { + const idx = Math.floor(Math.random() * acc.length); + acc.splice(idx, 1); + return acc; + }, + teams.keys() + ); +} + +let epoch_num = 0; +export function create_epoch(teams) { + return { + game: create_game(teams, random_indices(teams)), + time: 0, + epoch: epoch_num++, // !!!! side effects !!!! + teams, + } +} + + +const GAME_STEPS = 5000 +const EPOCH_STEPS = 200 + +export function update_epoch(epoch) { + if (epoch.game.time < GAME_STEPS) { + return { ...epoch, game: step_game(epoch.game) }; + } else if (epoch.time < EPOCH_STEPS) { + return { + ...epoch, + teams: finish_game(epoch.teams, epoch.game), + game: create_game(epoch.teams, random_indices(epoch.teams)), + time: epoch.time+1 + }; + } else { + // epoch complete!! + const source_teams = epoch.teams + .map(team => { + const normalized_score = team.score/team.games; + const count = Math.ceil(16*normalized_score); + return [...Array(count > 0 ? count : 1)].map(x => team) + }) + .flat(); + const new_teams = [...Array(epoch.teams.length] + .reduce((acc) => child_team(random_choice(source_teams)), []); + return create_epoch(new_teams); + } +} |