summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-11-12 03:17:24 -0600
committersanine <sanine.not@pm.me>2023-11-12 03:17:24 -0600
commite3a042a7a5c041dad63255965576346377e4f823 (patch)
tree7a03757bdddc6678e6f2411bd6cdb581ecdae3d7 /src
parent661847f269030c0cbaa681e2d4697873f891cdec (diff)
implement epoch updates
Diffstat (limited to 'src')
-rw-r--r--src/simulation/game.js66
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);
+ }
+}