Skip to content

Commit 9a6b36b

Browse files
Update version
1 parent 80d1d14 commit 9a6b36b

8 files changed

Lines changed: 270 additions & 3 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,21 @@ jobs:
4848
test -f public/generated/automate_packed/abi_manifest.json
4949
test -f public/generated/automate_packed_runtime.mjs
5050
test -f public/generated/automate_packed/host_shim.mjs
51+
test -f public/generated/automate_universel/browser_module.mjs
5152
5253
- name: Verifier la syntaxe JavaScript
5354
run: |
5455
node --check public/automate-core.js
5556
node --check public/app.mjs
5657
node --check public/generated/automate_packed_runtime.mjs
5758
node --check public/generated/automate_packed/host_shim.mjs
59+
node --check public/generated/automate_universel/browser_module.mjs
5860
5961
- name: Valider le moteur et le WASM
6062
run: |
6163
python tests/french_core_smoke.py
6264
node tests/core_smoke.js
65+
node tests/generated_browser_module_smoke.js
6366
node tests/packed_runtime_smoke.mjs
6467
node tests/static_site_smoke.js
6568

docs/release-checklist.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Before publishing a release:
1313
```powershell
1414
python tests\french_core_smoke.py
1515
node tests\core_smoke.js
16+
node tests\generated_browser_module_smoke.js
1617
node tests\packed_runtime_smoke.mjs
1718
node tests\static_site_smoke.js
1819
```
@@ -40,6 +41,7 @@ Before publishing a release:
4041

4142
- root URL
4243
- `public/generated/automate_packed/module.wasm`
44+
- `public/generated/automate_universel/browser_module.mjs`
4345
- `examples/*.json`
4446

4547
8. Confirm generated files are not staged:

public/automate-core.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,9 @@ function prochaineGeneration(generation, configuration, seed) {
247247
}
248248

249249
function genererUnivers(configurationBrute) {
250+
if (window.AutomaginariumUniversVivant?.generer_univers_detaille) {
251+
return window.AutomaginariumUniversVivant.generer_univers_detaille(configurationBrute);
252+
}
250253
const configuration = normaliserConfiguration(configurationBrute);
251254
const lignes = [creerGenerationInitiale(configuration)];
252255
const sorties = [lignes[0].map((value) => (
@@ -446,6 +449,9 @@ function encodeList(values) {
446449
}
447450

448451
function formStateToConfig(formState, currentConfig = {}) {
452+
if (window.AutomaginariumUniversVivant?.etat_formulaire_vers_configuration) {
453+
return window.AutomaginariumUniversVivant.etat_formulaire_vers_configuration(formState, currentConfig);
454+
}
449455
const inputAlphabet = parseCommaList(formState.alphabetInput, [0, 1]);
450456
const outputAlphabet = parseCommaList(formState.alphabetOutput, inputAlphabet);
451457
let neighborhood = Number(formState.neighborhood || 3);
@@ -490,6 +496,13 @@ function formStateToConfig(formState, currentConfig = {}) {
490496
}
491497

492498
function configToFormState(config) {
499+
if (window.AutomaginariumUniversVivant?.configuration_vers_etat_formulaire) {
500+
const formState = window.AutomaginariumUniversVivant.configuration_vers_etat_formulaire(config);
501+
return {
502+
...formState,
503+
json: JSON.stringify({ ...config, numero_regle: String(config.numero_regle || 0n) }, null, 2),
504+
};
505+
}
493506
return {
494507
name: config.nom || "",
495508
alphabetInput: encodeList(config.alphabet_entree || [0, 1]),
@@ -527,6 +540,9 @@ function individuMutationDepuis(configurationBrute, tauxSur1000, graine) {
527540
}
528541

529542
function populationInitiale(configBase, taille, graine) {
543+
if (window.AutomaginariumUniversVivant?.population_initiale) {
544+
return window.AutomaginariumUniversVivant.population_initiale(configBase, taille, graine);
545+
}
530546
const gen = mulberry32(graine);
531547
const population = [];
532548
const config = normaliserConfiguration(configBase);
@@ -550,6 +566,9 @@ function selectionTournoi(scores, tailleTournoi, graine) {
550566
}
551567

552568
function nouvelleGeneration(population, scores, tauxMutationSur1000, graine) {
569+
if (window.AutomaginariumUniversVivant?.nouvelle_generation) {
570+
return window.AutomaginariumUniversVivant.nouvelle_generation(population, scores, tauxMutationSur1000, graine);
571+
}
553572
const gen = mulberry32(graine);
554573
const nouvelle = [];
555574
const meilleurIdx = scores.reduce((best, score, idx) => (score > scores[best] ? idx : best), 0);
@@ -719,6 +738,9 @@ function evaluerPopulation(population, poidsObj = {}) {
719738
}
720739

721740
function presetPoidsGenetique(nom) {
741+
if (window.AutomaginariumUniversVivant?.preset_poids_genetique) {
742+
return window.AutomaginariumUniversVivant.preset_poids_genetique(nom);
743+
}
722744
const presets = {
723745
beau: { symetrie: 8, densite: 5, stabilite: 3, oscillation: 2, complexite: 4, croissance: 1 },
724746
chaotique: { symetrie: 1, densite: 3, stabilite: 1, oscillation: 2, complexite: 9, croissance: 2 },
@@ -730,6 +752,9 @@ function presetPoidsGenetique(nom) {
730752
}
731753

732754
function appliquerPerturbation(univers, evenement) {
755+
if (window.AutomaginariumUniversVivant?.appliquer_perturbation) {
756+
return window.AutomaginariumUniversVivant.appliquer_perturbation(univers, evenement);
757+
}
733758
const { cx, cy, rayon, force, type, graine } = evenement;
734759
const { configuration, lignes, sorties } = univers;
735760
const nouvelleLignes = lignes.map((ligne) => [...ligne]);
@@ -830,6 +855,9 @@ function randomRuleNumber(max, seed = Date.now() >>> 0) {
830855
}
831856

832857
function hudRuleLabel(ruleState) {
858+
if (window.AutomaginariumUniversVivant?.etiquette_regle_hud) {
859+
return window.AutomaginariumUniversVivant.etiquette_regle_hud(ruleState);
860+
}
833861
const neighborhood = Number(ruleState.neighborhood || 3);
834862
const channels = Number(ruleState.channels || 1);
835863
const ruleMode = ruleState.ruleMode || "table";
@@ -1078,6 +1106,9 @@ const construireUniversVivant = buildSemanticCoreV1;
10781106
const sourceUniversVivant = semanticCoreSource;
10791107

10801108
function ruleSpaceLabel(configuration) {
1109+
if (window.AutomaginariumUniversVivant?.etiquette_espace_regles) {
1110+
return window.AutomaginariumUniversVivant.etiquette_espace_regles(configuration);
1111+
}
10811112
const { s, k, t, m, maxRule } = ruleConfiguration(configuration);
10821113
return `${t}^(${m}·${s}^${k}) = ${maxRule} regles possibles`;
10831114
}
@@ -1096,6 +1127,9 @@ function toutesClesVoisinage(alphabet, taille) {
10961127
}
10971128

10981129
function validerConfiguration(configurationBrute) {
1130+
if (window.AutomaginariumUniversVivant?.valider_configuration) {
1131+
return window.AutomaginariumUniversVivant.valider_configuration(configurationBrute);
1132+
}
10991133
const config = normaliserConfiguration(configurationBrute);
11001134
const erreurs = [];
11011135
const avertissements = [];

requirements-build.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
multilingualprogramming[wasm]==0.6.0
1+
multilingualprogramming[wasm]==0.8.0

scripts/build_wasm_bundle.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,11 @@ def build_french_core() -> None:
7171
"resumer_univers_vivant,construire_univers_vivant,source_univers_vivant,"
7272
"resumer_configuration,resumer_transition,decrire_configuration,signaux_transition,"
7373
"table_wolfram,table_totalistique,assurer_configuration_rendable,"
74-
"construire_configuration_regle_generee"
74+
"construire_configuration_regle_generee,"
75+
"etat_formulaire_vers_configuration,configuration_vers_etat_formulaire,"
76+
"valider_configuration,etiquette_espace_regles,etiquette_regle_hud,"
77+
"generer_univers_detaille,population_initiale,nouvelle_generation,"
78+
"preset_poids_genetique,appliquer_perturbation"
7579
),
7680
"--out",
7781
str(RICH_BROWSER / "browser_module.mjs"),

src/automate_universel.multi

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ def generer_univers_detaille(configuration_brute):
458458
soit lignes = []
459459
soit sorties = []
460460
lignes.append(creer_generation_initiale(configuration))
461-
sorties.append([[valeur] pour valeur dans lignes[0]])
461+
sorties.append([[valeur pour _ dans range(configuration["nombre_canaux_sortie"])] pour valeur dans lignes[0]])
462462
pour rang dans range(1, configuration["hauteur"]):
463463
soit detail = prochaine_generation_detaillee(lignes[rang - 1], configuration, rang)
464464
lignes.append(detail["generation"])
@@ -737,6 +737,17 @@ def preset_fitness_oscillant():
737737
retour [4, 5, 3, 9, 5, 1]
738738

739739

740+
def preset_poids_genetique(nom):
741+
soit presets = {
742+
"beau": {"symetrie": 8, "densite": 5, "stabilite": 3, "oscillation": 2, "complexite": 4, "croissance": 1},
743+
"chaotique": {"symetrie": 1, "densite": 3, "stabilite": 1, "oscillation": 2, "complexite": 9, "croissance": 2},
744+
"stable": {"symetrie": 3, "densite": 4, "stabilite": 9, "oscillation": 1, "complexite": 5, "croissance": 0},
745+
"croissance": {"symetrie": 2, "densite": 3, "stabilite": 0, "oscillation": 1, "complexite": 3, "croissance": 9},
746+
"oscillant": {"symetrie": 4, "densite": 5, "stabilite": 3, "oscillation": 9, "complexite": 5, "croissance": 1},
747+
}
748+
retour presets.get(nom, presets["beau"])
749+
750+
740751
def etiquette_regle_hud(etat_regle):
741752
soit voisinage = int(etat_regle.get("neighborhood", 3))
742753
soit canaux = int(etat_regle.get("channels", 1))
@@ -1107,6 +1118,57 @@ def decrementer_masque_gel(masque_gel):
11071118
retour masque_nouveau
11081119

11091120

1121+
def appliquer_perturbation(univers, evenement):
1122+
soit cx = int(evenement.get("cx", 0))
1123+
soit cy = int(evenement.get("cy", 0))
1124+
soit rayon = int(evenement.get("rayon", 1))
1125+
soit force = float(evenement.get("force", 0.5))
1126+
soit type_perturbation = evenement.get("type", "pulse")
1127+
soit graine = int(evenement.get("graine", 1))
1128+
soit configuration = univers["configuration"]
1129+
soit lignes = univers["lignes"]
1130+
soit sorties = univers.get("sorties", None)
1131+
soit nouvelles_lignes = [list(ligne) pour ligne dans lignes]
1132+
soit nouvelles_sorties = [[list(cellule) pour cellule dans ligne] pour ligne dans sorties] si sorties != None sinon None
1133+
soit generateur = random.Random(graine)
1134+
soit alphabet = configuration.get("alphabet_sortie", configuration.get("alphabet_entree", [0, 1]))
1135+
1136+
pour y dans range(max(0, cy - rayon), min(configuration["hauteur"], cy + rayon + 1)):
1137+
pour x dans range(max(0, cx - rayon), min(configuration["largeur"], cx + rayon + 1)):
1138+
soit dx = x - cx
1139+
soit dy = y - cy
1140+
soit distance = ((dx * dx) + (dy * dy)) ** 0.5
1141+
si distance > rayon:
1142+
continuer
1143+
soit intensite = max(0.0, 1.0 - (distance / (rayon + 1)))
1144+
soit probabilite = force * intensite
1145+
si generateur.random() >= probabilite:
1146+
continuer
1147+
1148+
si type_perturbation == "pulse":
1149+
nouvelles_lignes[y][x] = generateur.choice(alphabet)
1150+
sinon si type_perturbation == "effacer" ou type_perturbation == "geler":
1151+
nouvelles_lignes[y][x] = alphabet[0] si len(alphabet) > 0 sinon 0
1152+
sinon si type_perturbation == "inverser":
1153+
soit index = alphabet.index(nouvelles_lignes[y][x]) si nouvelles_lignes[y][x] dans alphabet sinon -1
1154+
nouvelles_lignes[y][x] = alphabet[(index + 1) % len(alphabet)] si index >= 0 sinon alphabet[1] si len(alphabet) > 1 sinon alphabet[0]
1155+
sinon si type_perturbation == "attirer":
1156+
nouvelles_lignes[y][x] = alphabet[len(alphabet) // 2]
1157+
sinon si type_perturbation == "muter":
1158+
soit index_mutation = alphabet.index(nouvelles_lignes[y][x]) si nouvelles_lignes[y][x] dans alphabet sinon -1
1159+
si index_mutation >= 0:
1160+
soit index_suivant = (index_mutation + 1) % len(alphabet)
1161+
nouvelles_lignes[y][x] = alphabet[index_mutation - 1] si generateur.random() < 0.5 et index_mutation > 0 sinon alphabet[index_suivant]
1162+
sinon:
1163+
nouvelles_lignes[y][x] = alphabet[1] si len(alphabet) > 1 sinon alphabet[0]
1164+
1165+
retour {
1166+
"configuration": configuration,
1167+
"lignes": nouvelles_lignes,
1168+
"sorties": nouvelles_sorties,
1169+
}
1170+
1171+
11101172
def variance_densite(historique_densites):
11111173
"""Returns variance of densities across generation history."""
11121174
si len(historique_densites) < 2:

tests/core_smoke.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,36 @@ function testGeneratedLivingUniverseModulePrecedence() {
345345
effectiveGenerator: `generated-${generator}`,
346346
};
347347
},
348+
etat_formulaire_vers_configuration(formState) {
349+
return { nom: `generated ${formState.name}`, generatedFormConfig: true };
350+
},
351+
configuration_vers_etat_formulaire(config) {
352+
return { name: `generated ${config.nom}`, generatedFormState: true };
353+
},
354+
valider_configuration() {
355+
return { valide: true, erreurs: [], avertissements: ["generated"] };
356+
},
357+
etiquette_espace_regles() {
358+
return "generated rule space";
359+
},
360+
etiquette_regle_hud() {
361+
return "generated hud";
362+
},
363+
generer_univers_detaille(config) {
364+
return { configuration: config, lignes: [["generated"]], sorties: [[["generated"]]] };
365+
},
366+
population_initiale(_config, taille) {
367+
return Array.from({ length: taille }, (_, index) => ({ generatedPopulation: index }));
368+
},
369+
nouvelle_generation(population) {
370+
return [{ generatedNextPopulation: population.length }];
371+
},
372+
preset_poids_genetique(nom) {
373+
return { generatedPreset: nom };
374+
},
375+
appliquer_perturbation(univers, evenement) {
376+
return { ...univers, generatedPerturbation: evenement.type };
377+
},
348378
};
349379

350380
const config = {
@@ -374,6 +404,16 @@ function testGeneratedLivingUniverseModulePrecedence() {
374404
const built = AutomaginariumCore.buildGeneratedRuleConfig(config, "wolfram", 90);
375405
assert.equal(built.effectiveGenerator, "generated-wolfram");
376406
assert.equal(built.config.generatedRuleConfig, true);
407+
assert.equal(AutomaginariumCore.formStateToConfig({ name: "Form" }).generatedFormConfig, true);
408+
assert.equal(AutomaginariumCore.configToFormState(config).generatedFormState, true);
409+
assert.equal(AutomaginariumCore.validerConfiguration(config).avertissements[0], "generated");
410+
assert.equal(AutomaginariumCore.ruleSpaceLabel(config), "generated rule space");
411+
assert.equal(AutomaginariumCore.hudRuleLabel({}), "generated hud");
412+
assert.equal(AutomaginariumCore.genererUnivers(config).lignes[0][0], "generated");
413+
assert.equal(AutomaginariumCore.populationInitiale(config, 3, 1).length, 3);
414+
assert.equal(AutomaginariumCore.nouvelleGeneration([{ a: 1 }, { b: 2 }], [1, 2], 50, 1)[0].generatedNextPopulation, 2);
415+
assert.equal(AutomaginariumCore.presetPoidsGenetique("stable").generatedPreset, "stable");
416+
assert.equal(AutomaginariumCore.appliquerPerturbation({ configuration: config, lignes: [], sorties: [] }, { type: "pulse" }).generatedPerturbation, "pulse");
377417
} finally {
378418
global.AutomaginariumUniversVivant = previousGenerated;
379419
}

0 commit comments

Comments
 (0)