mirror of
https://github.com/deunix-educ/aventuriers-des-mots.git
synced 2026-10-13 02:11:58 +02:00
Fix export on fresh clone (make import), add elision and duplicate-sentence guards, replace 14 duplicate sentences (0.5.3)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@ Jeu éducatif de français CE1–CE2 (7–9 ans), aventure 2D, hors ligne, Godot
|
|||||||
Le `Makefile` est le seul point d'entrée pour les opérations système. Tenir cette liste à jour.
|
Le `Makefile` est le seul point d'entrée pour les opérations système. Tenir cette liste à jour.
|
||||||
|
|
||||||
- `make setup` : installe l'outillage (lint, tests, modèles d'export)
|
- `make setup` : installe l'outillage (lint, tests, modèles d'export)
|
||||||
|
- `make import` : importe les ressources dans `.godot/` (deux passes ; appelé automatiquement par `run`, `test`, `validate-data`, `export-*`, `screenshot` : indispensable sur un dépôt fraîchement cloné)
|
||||||
- `make run` : lance le jeu
|
- `make run` : lance le jeu
|
||||||
- `make lint` / `make format` : analyse statique et formatage
|
- `make lint` / `make format` : analyse statique et formatage
|
||||||
- `make validate-data` : valide tous les JSON de `data/` contre leurs schémas
|
- `make validate-data` : valide tous les JSON de `data/` contre leurs schémas
|
||||||
|
|||||||
@@ -6,12 +6,21 @@ PYRIGHT := $(VENV)/bin/pyright
|
|||||||
PYTHON := $(VENV)/bin/python3
|
PYTHON := $(VENV)/bin/python3
|
||||||
GD_SOURCES := autoload scripts tests
|
GD_SOURCES := autoload scripts tests
|
||||||
|
|
||||||
.PHONY: setup run lint format validate-data test check content-review generate-dictation-audio generate-sounds export-linux export-windows package screenshot
|
.PHONY: setup import run lint format validate-data test check content-review generate-dictation-audio generate-sounds export-linux export-windows package screenshot
|
||||||
|
|
||||||
setup:
|
setup:
|
||||||
tools/setup.sh
|
tools/setup.sh
|
||||||
|
|
||||||
run:
|
# Importe les ressources (polices, SVG, audio...) dans .godot/. Indispensable
|
||||||
|
# sur un depot fraichement clone : sans cela, l'export plante ou produit un
|
||||||
|
# jeu sans theme. Deux passes : le theme n'est valide qu'une fois les polices
|
||||||
|
# importees. La premiere passe peut echouer (theme charge avant les polices) :
|
||||||
|
# son code de retour est ignore, la seconde fait foi.
|
||||||
|
import:
|
||||||
|
-@$(GODOT_BIN) --headless --path . --import >/dev/null 2>&1
|
||||||
|
$(GODOT_BIN) --headless --path . --import >/dev/null
|
||||||
|
|
||||||
|
run: import
|
||||||
$(GODOT_BIN) --path .
|
$(GODOT_BIN) --path .
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
@@ -21,10 +30,10 @@ lint:
|
|||||||
format:
|
format:
|
||||||
$(GDFORMAT) $(GD_SOURCES)
|
$(GDFORMAT) $(GD_SOURCES)
|
||||||
|
|
||||||
validate-data:
|
validate-data: import
|
||||||
$(GODOT_BIN) --headless --path . -s res://scripts/data/validate_data_cli.gd
|
$(GODOT_BIN) --headless --path . -s res://scripts/data/validate_data_cli.gd
|
||||||
|
|
||||||
test:
|
test: import
|
||||||
$(GODOT_BIN) --headless --path . -s res://addons/gut/gut_cmdln.gd -gdir=res://tests -ginclude_subdirs -gexit
|
$(GODOT_BIN) --headless --path . -s res://addons/gut/gut_cmdln.gd -gdir=res://tests -ginclude_subdirs -gexit
|
||||||
|
|
||||||
check: lint validate-data test
|
check: lint validate-data test
|
||||||
@@ -38,11 +47,11 @@ generate-dictation-audio:
|
|||||||
generate-sounds:
|
generate-sounds:
|
||||||
$(PYTHON) tools/generate_sounds.py
|
$(PYTHON) tools/generate_sounds.py
|
||||||
|
|
||||||
export-linux:
|
export-linux: import
|
||||||
mkdir -p build/linux
|
mkdir -p build/linux
|
||||||
$(GODOT_BIN) --headless --path . --export-release "Linux" build/linux/aventuriers_des_mots.x86_64
|
$(GODOT_BIN) --headless --path . --export-release "Linux" build/linux/aventuriers_des_mots.x86_64
|
||||||
|
|
||||||
export-windows:
|
export-windows: import
|
||||||
mkdir -p build/windows
|
mkdir -p build/windows
|
||||||
$(GODOT_BIN) --headless --path . --export-release "Windows" build/windows/aventuriers_des_mots.exe
|
$(GODOT_BIN) --headless --path . --export-release "Windows" build/windows/aventuriers_des_mots.exe
|
||||||
|
|
||||||
@@ -51,5 +60,5 @@ package:
|
|||||||
|
|
||||||
# Capture d'une scene dans une vraie fenetre (voir tools/screenshot.gd) :
|
# Capture d'une scene dans une vraie fenetre (voir tools/screenshot.gd) :
|
||||||
# make screenshot SCENE=res://scenes/world/world_map.tscn OUT=/tmp/map.png ARGS="CE2"
|
# make screenshot SCENE=res://scenes/world/world_map.tscn OUT=/tmp/map.png ARGS="CE2"
|
||||||
screenshot:
|
screenshot: import
|
||||||
$(GODOT_BIN) --path . -s res://tools/screenshot.gd -- $(SCENE) $(OUT) $(ARGS)
|
$(GODOT_BIN) --path . -s res://tools/screenshot.gd -- $(SCENE) $(OUT) $(ARGS)
|
||||||
|
|||||||
@@ -14,13 +14,28 @@
|
|||||||
"expected": "Les",
|
"expected": "Les",
|
||||||
"rule_id": "regle_accord_determinant"
|
"rule_id": "regle_accord_determinant"
|
||||||
},
|
},
|
||||||
{ "text": "petites", "correct": true },
|
{
|
||||||
{ "text": "fleurs", "correct": true },
|
"text": "grandes",
|
||||||
{ "text": "sont", "correct": true },
|
"correct": true
|
||||||
{ "text": "jolies.", "correct": true }
|
},
|
||||||
|
{
|
||||||
|
"text": "maisons",
|
||||||
|
"correct": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "sont",
|
||||||
|
"correct": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "anciennes.",
|
||||||
|
"correct": true
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"hint": "Cherche le nom auquel le déterminant se rapporte, même si un autre mot s'intercale.",
|
"hint": "Cherche le nom auquel le déterminant se rapporte, même si un autre mot s'intercale.",
|
||||||
"explanation": "Le déterminant se rapporte à « fleurs », qui est féminin pluriel, même si l'adjectif « petites » s'intercale : il faut écrire « Les ».",
|
"explanation": "Le déterminant se rapporte à « maisons », qui est féminin pluriel, même si l'adjectif « grandes » s'intercale : il faut écrire « Les ».",
|
||||||
"review_tags": ["pluriel", "accord_determinant"],
|
"review_tags": [
|
||||||
|
"pluriel",
|
||||||
|
"accord_determinant"
|
||||||
|
],
|
||||||
"review_status": "draft"
|
"review_status": "draft"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,17 @@
|
|||||||
"difficulty": 1,
|
"difficulty": 1,
|
||||||
"type": "multiple_choice",
|
"type": "multiple_choice",
|
||||||
"instruction": "Choisis le bon déterminant.",
|
"instruction": "Choisis le bon déterminant.",
|
||||||
"question": "... chat dort.",
|
"question": "... lapin dort.",
|
||||||
"answers": ["Le", "La"],
|
"answers": [
|
||||||
|
"Le",
|
||||||
|
"La"
|
||||||
|
],
|
||||||
"correct_answer": 0,
|
"correct_answer": 0,
|
||||||
"hint": "Le nom « chat » est masculin.",
|
"hint": "Le nom « lapin » est masculin.",
|
||||||
"explanation": "« Chat » est un nom masculin : il faut le déterminant masculin « Le ».",
|
"explanation": "« Lapin » est un nom masculin : il faut le déterminant masculin « Le ».",
|
||||||
"review_tags": ["genre", "accord_determinant"],
|
"review_tags": [
|
||||||
|
"genre",
|
||||||
|
"accord_determinant"
|
||||||
|
],
|
||||||
"review_status": "draft"
|
"review_status": "draft"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,17 @@
|
|||||||
"difficulty": 1,
|
"difficulty": 1,
|
||||||
"type": "multiple_choice",
|
"type": "multiple_choice",
|
||||||
"instruction": "Choisis le bon déterminant.",
|
"instruction": "Choisis le bon déterminant.",
|
||||||
"question": "... chats dorment.",
|
"question": "... oiseaux chantent.",
|
||||||
"answers": ["Le", "Les"],
|
"answers": [
|
||||||
|
"Le",
|
||||||
|
"Les"
|
||||||
|
],
|
||||||
"correct_answer": 1,
|
"correct_answer": 1,
|
||||||
"hint": "Le nom « chats » est au pluriel.",
|
"hint": "Le nom « oiseaux » est au pluriel.",
|
||||||
"explanation": "« Chats » est au pluriel : il faut le déterminant pluriel « Les ».",
|
"explanation": "« Oiseaux » est au pluriel : il faut le déterminant pluriel « Les ».",
|
||||||
"review_tags": ["pluriel", "accord_determinant"],
|
"review_tags": [
|
||||||
|
"pluriel",
|
||||||
|
"accord_determinant"
|
||||||
|
],
|
||||||
"review_status": "draft"
|
"review_status": "draft"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,17 @@
|
|||||||
"difficulty": 1,
|
"difficulty": 1,
|
||||||
"type": "multiple_choice",
|
"type": "multiple_choice",
|
||||||
"instruction": "Choisis le bon mot.",
|
"instruction": "Choisis le bon mot.",
|
||||||
"question": "Les ... jouent dans le jardin.",
|
"question": "Les ... courent dans la cour.",
|
||||||
"answers": ["chat", "chats"],
|
"answers": [
|
||||||
|
"enfant",
|
||||||
|
"enfants"
|
||||||
|
],
|
||||||
"correct_answer": 1,
|
"correct_answer": 1,
|
||||||
"hint": "Le déterminant « les » indique plusieurs chats.",
|
"hint": "Le déterminant « les » indique plusieurs enfants.",
|
||||||
"explanation": "Pour former le pluriel d'un nom, on ajoute un -s à la fin : « chats ».",
|
"explanation": "Pour former le pluriel d'un nom, on ajoute un -s à la fin : « enfants ».",
|
||||||
"review_tags": ["pluriel", "pluriel_nom"],
|
"review_tags": [
|
||||||
|
"pluriel",
|
||||||
|
"pluriel_nom"
|
||||||
|
],
|
||||||
"review_status": "draft"
|
"review_status": "draft"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,16 @@
|
|||||||
"difficulty": 2,
|
"difficulty": 2,
|
||||||
"type": "multiple_choice",
|
"type": "multiple_choice",
|
||||||
"instruction": "Choisis le bon mot.",
|
"instruction": "Choisis le bon mot.",
|
||||||
"question": "Le ... est sur la table.",
|
"question": "Le ... est dans le sac.",
|
||||||
"answers": ["cahier", "cahiers"],
|
"answers": [
|
||||||
|
"livre",
|
||||||
|
"livres"
|
||||||
|
],
|
||||||
"correct_answer": 0,
|
"correct_answer": 0,
|
||||||
"hint": "Le déterminant « le » indique un seul cahier.",
|
"hint": "Le déterminant « le » indique un seul livre.",
|
||||||
"explanation": "« Le » indique un seul objet : le nom reste au singulier, sans -s : « cahier ».",
|
"explanation": "« Le » indique un seul objet : le nom reste au singulier, sans -s : « livre ».",
|
||||||
"review_tags": ["pluriel_nom"],
|
"review_tags": [
|
||||||
|
"pluriel_nom"
|
||||||
|
],
|
||||||
"review_status": "draft"
|
"review_status": "draft"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,17 @@
|
|||||||
"difficulty": 3,
|
"difficulty": 3,
|
||||||
"type": "multiple_choice",
|
"type": "multiple_choice",
|
||||||
"instruction": "Choisis le bon mot.",
|
"instruction": "Choisis le bon mot.",
|
||||||
"question": "Les jolies ... sentent bon.",
|
"question": "Les belles ... brillent dans le ciel.",
|
||||||
"answers": ["fleur", "fleurs"],
|
"answers": [
|
||||||
|
"étoile",
|
||||||
|
"étoiles"
|
||||||
|
],
|
||||||
"correct_answer": 1,
|
"correct_answer": 1,
|
||||||
"hint": "Cherche le déterminant, même si un autre mot s'intercale avant le nom.",
|
"hint": "Cherche le déterminant, même si un autre mot s'intercale avant le nom.",
|
||||||
"explanation": "« Les » indique le pluriel, même si l'adjectif « jolies » s'intercale avant le nom : il faut écrire « fleurs ».",
|
"explanation": "« Les » indique le pluriel, même si l'adjectif « belles » s'intercale avant le nom : il faut écrire « étoiles ».",
|
||||||
"review_tags": ["pluriel", "pluriel_nom"],
|
"review_tags": [
|
||||||
|
"pluriel",
|
||||||
|
"pluriel_nom"
|
||||||
|
],
|
||||||
"review_status": "draft"
|
"review_status": "draft"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
"instruction": "Touche le mot qui contient une erreur, puis corrige-le.",
|
"instruction": "Touche le mot qui contient une erreur, puis corrige-le.",
|
||||||
"tokens": [
|
"tokens": [
|
||||||
{
|
{
|
||||||
"text": "Nous",
|
"text": "Ils",
|
||||||
"correct": true
|
"correct": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "allons",
|
"text": "vont",
|
||||||
"correct": true
|
"correct": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -23,11 +23,7 @@
|
|||||||
"rule_id": "regle_homophone_a_a"
|
"rule_id": "regle_homophone_a_a"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "la",
|
"text": "l'école.",
|
||||||
"correct": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "piscine.",
|
|
||||||
"correct": true
|
"correct": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"difficulty": 1,
|
"difficulty": 1,
|
||||||
"type": "multiple_choice",
|
"type": "multiple_choice",
|
||||||
"instruction": "Choisis le bon mot.",
|
"instruction": "Choisis le bon mot.",
|
||||||
"question": "Léa ... un chat.",
|
"question": "Max ... un vélo.",
|
||||||
"answers": [
|
"answers": [
|
||||||
"a",
|
"a",
|
||||||
"à"
|
"à"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
"instruction": "Touche le mot qui contient une erreur, puis corrige-le.",
|
"instruction": "Touche le mot qui contient une erreur, puis corrige-le.",
|
||||||
"tokens": [
|
"tokens": [
|
||||||
{
|
{
|
||||||
"text": "Paul",
|
"text": "Sarah",
|
||||||
"correct": true
|
"correct": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -19,11 +19,11 @@
|
|||||||
"rule_id": "regle_homophone_et_est"
|
"rule_id": "regle_homophone_et_est"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "Marie",
|
"text": "Tom",
|
||||||
"correct": true
|
"correct": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "jouent",
|
"text": "dessinent",
|
||||||
"correct": true
|
"correct": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"difficulty": 1,
|
"difficulty": 1,
|
||||||
"type": "multiple_choice",
|
"type": "multiple_choice",
|
||||||
"instruction": "Choisis le bon mot.",
|
"instruction": "Choisis le bon mot.",
|
||||||
"question": "Le chat ... noir.",
|
"question": "Le ciel ... bleu.",
|
||||||
"answers": [
|
"answers": [
|
||||||
"et",
|
"et",
|
||||||
"est"
|
"est"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"difficulty": 1,
|
"difficulty": 1,
|
||||||
"type": "multiple_choice",
|
"type": "multiple_choice",
|
||||||
"instruction": "Choisis le bon mot.",
|
"instruction": "Choisis le bon mot.",
|
||||||
"question": "... joue dehors.",
|
"question": "... chante une chanson.",
|
||||||
"answers": [
|
"answers": [
|
||||||
"On",
|
"On",
|
||||||
"Ont"
|
"Ont"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"difficulty": 1,
|
"difficulty": 1,
|
||||||
"type": "multiple_choice",
|
"type": "multiple_choice",
|
||||||
"instruction": "Choisis le bon mot.",
|
"instruction": "Choisis le bon mot.",
|
||||||
"question": "Les enfants ... faim.",
|
"question": "Les oiseaux ... froid.",
|
||||||
"answers": [
|
"answers": [
|
||||||
"on",
|
"on",
|
||||||
"ont"
|
"ont"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"difficulty": 1,
|
"difficulty": 1,
|
||||||
"type": "multiple_choice",
|
"type": "multiple_choice",
|
||||||
"instruction": "Choisis le bon mot.",
|
"instruction": "Choisis le bon mot.",
|
||||||
"question": "Les chats ... gentils.",
|
"question": "Les élèves ... contents.",
|
||||||
"answers": [
|
"answers": [
|
||||||
"son",
|
"son",
|
||||||
"sont"
|
"sont"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"difficulty": 1,
|
"difficulty": 1,
|
||||||
"type": "multiple_choice",
|
"type": "multiple_choice",
|
||||||
"instruction": "Choisis le bon mot.",
|
"instruction": "Choisis le bon mot.",
|
||||||
"question": "Paul range ... cartable.",
|
"question": "Julie ouvre ... cahier.",
|
||||||
"answers": [
|
"answers": [
|
||||||
"son",
|
"son",
|
||||||
"sont"
|
"sont"
|
||||||
|
|||||||
@@ -105,11 +105,11 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
|
|||||||
|
|
||||||
### Choix multiples
|
### Choix multiples
|
||||||
|
|
||||||
- **ce1_accord_determinant_qcm_01** (difficulte 1) : ... chat dort.
|
- **ce1_accord_determinant_qcm_01** (difficulte 1) : ... lapin dort.
|
||||||
- Reponses : Le, La
|
- Reponses : Le, La
|
||||||
- Reponse attendue : Le
|
- Reponse attendue : Le
|
||||||
- Indice : Le nom « chat » est masculin.
|
- Indice : Le nom « lapin » est masculin.
|
||||||
- Explication : « Chat » est un nom masculin : il faut le déterminant masculin « Le ».
|
- Explication : « Lapin » est un nom masculin : il faut le déterminant masculin « Le ».
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
- **ce1_accord_determinant_qcm_02** (difficulte 1) : ... fleur sent bon.
|
- **ce1_accord_determinant_qcm_02** (difficulte 1) : ... fleur sent bon.
|
||||||
- Reponses : Le, La
|
- Reponses : Le, La
|
||||||
@@ -117,11 +117,11 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
|
|||||||
- Indice : Le nom « fleur » est féminin.
|
- Indice : Le nom « fleur » est féminin.
|
||||||
- Explication : « Fleur » est un nom féminin : il faut le déterminant féminin « La ».
|
- Explication : « Fleur » est un nom féminin : il faut le déterminant féminin « La ».
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
- **ce1_accord_determinant_qcm_03** (difficulte 1) : ... chats dorment.
|
- **ce1_accord_determinant_qcm_03** (difficulte 1) : ... oiseaux chantent.
|
||||||
- Reponses : Le, Les
|
- Reponses : Le, Les
|
||||||
- Reponse attendue : Les
|
- Reponse attendue : Les
|
||||||
- Indice : Le nom « chats » est au pluriel.
|
- Indice : Le nom « oiseaux » est au pluriel.
|
||||||
- Explication : « Chats » est au pluriel : il faut le déterminant pluriel « Les ».
|
- Explication : « Oiseaux » est au pluriel : il faut le déterminant pluriel « Les ».
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
- **ce1_accord_determinant_qcm_04** (difficulte 1) : ... fleurs sentent bon.
|
- **ce1_accord_determinant_qcm_04** (difficulte 1) : ... fleurs sentent bon.
|
||||||
- Reponses : La, Les
|
- Reponses : La, Les
|
||||||
@@ -168,9 +168,9 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
|
|||||||
- Indice : Le nom « chats » est au pluriel.
|
- Indice : Le nom « chats » est au pluriel.
|
||||||
- Explication : « Chats » est au pluriel : il faut le déterminant pluriel « Les ».
|
- Explication : « Chats » est au pluriel : il faut le déterminant pluriel « Les ».
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
- **ce1_accord_determinant_correction_04** (difficulte 3) : [Le -> Les] petites fleurs sont jolies.
|
- **ce1_accord_determinant_correction_04** (difficulte 3) : [Le -> Les] grandes maisons sont anciennes.
|
||||||
- Indice : Cherche le nom auquel le déterminant se rapporte, même si un autre mot s'intercale.
|
- Indice : Cherche le nom auquel le déterminant se rapporte, même si un autre mot s'intercale.
|
||||||
- Explication : Le déterminant se rapporte à « fleurs », qui est féminin pluriel, même si l'adjectif « petites » s'intercale : il faut écrire « Les ».
|
- Explication : Le déterminant se rapporte à « maisons », qui est féminin pluriel, même si l'adjectif « grandes » s'intercale : il faut écrire « Les ».
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
|
|
||||||
### Dictees
|
### Dictees
|
||||||
@@ -198,7 +198,7 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
|
|||||||
|
|
||||||
### Choix multiples
|
### Choix multiples
|
||||||
|
|
||||||
- **ce2_a_a_qcm_01** (difficulte 1) : Léa ... un chat.
|
- **ce2_a_a_qcm_01** (difficulte 1) : Max ... un vélo.
|
||||||
- Reponses : a, à
|
- Reponses : a, à
|
||||||
- Reponse attendue : a
|
- Reponse attendue : a
|
||||||
- Indice : Essaie de remplacer par « avait ».
|
- Indice : Essaie de remplacer par « avait ».
|
||||||
@@ -253,7 +253,7 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
|
|||||||
- Indice : Essaie de remplacer par « avait ».
|
- Indice : Essaie de remplacer par « avait ».
|
||||||
- Explication : « avait » convient ici : c'est le verbe avoir, on écrit « a » sans accent.
|
- Explication : « avait » convient ici : c'est le verbe avoir, on écrit « a » sans accent.
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
- **ce2_a_a_correction_02** (difficulte 1) : Nous allons [a -> à] la piscine.
|
- **ce2_a_a_correction_02** (difficulte 1) : Ils vont [a -> à] l'école.
|
||||||
- Indice : Essaie de remplacer par « avait ».
|
- Indice : Essaie de remplacer par « avait ».
|
||||||
- Explication : « avait » ne convient pas ici : c'est le petit mot « à », avec un accent.
|
- Explication : « avait » ne convient pas ici : c'est le petit mot « à », avec un accent.
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
@@ -291,7 +291,7 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
|
|||||||
|
|
||||||
### Choix multiples
|
### Choix multiples
|
||||||
|
|
||||||
- **ce2_et_est_qcm_01** (difficulte 1) : Le chat ... noir.
|
- **ce2_et_est_qcm_01** (difficulte 1) : Le ciel ... bleu.
|
||||||
- Reponses : et, est
|
- Reponses : et, est
|
||||||
- Reponse attendue : est
|
- Reponse attendue : est
|
||||||
- Indice : Essaie de remplacer par « était ».
|
- Indice : Essaie de remplacer par « était ».
|
||||||
@@ -346,7 +346,7 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
|
|||||||
- Indice : Essaie de remplacer par « était ».
|
- Indice : Essaie de remplacer par « était ».
|
||||||
- Explication : « était » convient ici : c'est le verbe être, on écrit « est ».
|
- Explication : « était » convient ici : c'est le verbe être, on écrit « est ».
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
- **ce2_et_est_correction_02** (difficulte 1) : Paul [est -> et] Marie jouent ensemble.
|
- **ce2_et_est_correction_02** (difficulte 1) : Sarah [est -> et] Tom dessinent ensemble.
|
||||||
- Indice : Essaie de remplacer par « était ».
|
- Indice : Essaie de remplacer par « était ».
|
||||||
- Explication : « était » ne convient pas ici, mais « et puis » convient : c'est « et », qui relie deux mots.
|
- Explication : « était » ne convient pas ici, mais « et puis » convient : c'est « et », qui relie deux mots.
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
@@ -384,13 +384,13 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
|
|||||||
|
|
||||||
### Choix multiples
|
### Choix multiples
|
||||||
|
|
||||||
- **ce2_on_ont_qcm_01** (difficulte 1) : ... joue dehors.
|
- **ce2_on_ont_qcm_01** (difficulte 1) : ... chante une chanson.
|
||||||
- Reponses : On, Ont
|
- Reponses : On, Ont
|
||||||
- Reponse attendue : On
|
- Reponse attendue : On
|
||||||
- Indice : Essaie de remplacer par « avaient », ou par « il ».
|
- Indice : Essaie de remplacer par « avaient », ou par « il ».
|
||||||
- Explication : « avaient » ne convient pas ici, mais « il » convient : c'est le pronom « on ».
|
- Explication : « avaient » ne convient pas ici, mais « il » convient : c'est le pronom « on ».
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
- **ce2_on_ont_qcm_02** (difficulte 1) : Les enfants ... faim.
|
- **ce2_on_ont_qcm_02** (difficulte 1) : Les oiseaux ... froid.
|
||||||
- Reponses : on, ont
|
- Reponses : on, ont
|
||||||
- Reponse attendue : ont
|
- Reponse attendue : ont
|
||||||
- Indice : Essaie de remplacer par « avaient », ou par « il ».
|
- Indice : Essaie de remplacer par « avaient », ou par « il ».
|
||||||
@@ -477,7 +477,7 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
|
|||||||
|
|
||||||
### Choix multiples
|
### Choix multiples
|
||||||
|
|
||||||
- **ce2_son_sont_qcm_01** (difficulte 1) : Les chats ... gentils.
|
- **ce2_son_sont_qcm_01** (difficulte 1) : Les élèves ... contents.
|
||||||
- Reponses : son, sont
|
- Reponses : son, sont
|
||||||
- Reponse attendue : sont
|
- Reponse attendue : sont
|
||||||
- Indice : Essaie de remplacer par « étaient », ou par « mon ».
|
- Indice : Essaie de remplacer par « étaient », ou par « mon ».
|
||||||
@@ -495,7 +495,7 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
|
|||||||
- Indice : Essaie de remplacer par « étaient », ou par « mon ».
|
- Indice : Essaie de remplacer par « étaient », ou par « mon ».
|
||||||
- Explication : « étaient » convient ici : c'est le verbe être, on écrit « sont ».
|
- Explication : « étaient » convient ici : c'est le verbe être, on écrit « sont ».
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
- **ce2_son_sont_qcm_04** (difficulte 1) : Paul range ... cartable.
|
- **ce2_son_sont_qcm_04** (difficulte 1) : Julie ouvre ... cahier.
|
||||||
- Reponses : son, sont
|
- Reponses : son, sont
|
||||||
- Reponse attendue : son
|
- Reponse attendue : son
|
||||||
- Indice : Essaie de remplacer par « étaient », ou par « mon ».
|
- Indice : Essaie de remplacer par « étaient », ou par « mon ».
|
||||||
@@ -570,11 +570,11 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
|
|||||||
|
|
||||||
### Choix multiples
|
### Choix multiples
|
||||||
|
|
||||||
- **ce1_pluriel_nom_qcm_01** (difficulte 1) : Les ... jouent dans le jardin.
|
- **ce1_pluriel_nom_qcm_01** (difficulte 1) : Les ... courent dans la cour.
|
||||||
- Reponses : chat, chats
|
- Reponses : enfant, enfants
|
||||||
- Reponse attendue : chats
|
- Reponse attendue : enfants
|
||||||
- Indice : Le déterminant « les » indique plusieurs chats.
|
- Indice : Le déterminant « les » indique plusieurs enfants.
|
||||||
- Explication : Pour former le pluriel d'un nom, on ajoute un -s à la fin : « chats ».
|
- Explication : Pour former le pluriel d'un nom, on ajoute un -s à la fin : « enfants ».
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
- **ce1_pluriel_nom_qcm_02** (difficulte 1) : Des ... poussent dans le jardin.
|
- **ce1_pluriel_nom_qcm_02** (difficulte 1) : Des ... poussent dans le jardin.
|
||||||
- Reponses : fleur, fleurs
|
- Reponses : fleur, fleurs
|
||||||
@@ -594,11 +594,11 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
|
|||||||
- Indice : Le déterminant « des » indique plusieurs voitures.
|
- Indice : Le déterminant « des » indique plusieurs voitures.
|
||||||
- Explication : Pour former le pluriel d'un nom, on ajoute un -s à la fin : « voitures ».
|
- Explication : Pour former le pluriel d'un nom, on ajoute un -s à la fin : « voitures ».
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
- **ce1_pluriel_nom_qcm_05** (difficulte 2) : Le ... est sur la table.
|
- **ce1_pluriel_nom_qcm_05** (difficulte 2) : Le ... est dans le sac.
|
||||||
- Reponses : cahier, cahiers
|
- Reponses : livre, livres
|
||||||
- Reponse attendue : cahier
|
- Reponse attendue : livre
|
||||||
- Indice : Le déterminant « le » indique un seul cahier.
|
- Indice : Le déterminant « le » indique un seul livre.
|
||||||
- Explication : « Le » indique un seul objet : le nom reste au singulier, sans -s : « cahier ».
|
- Explication : « Le » indique un seul objet : le nom reste au singulier, sans -s : « livre ».
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
- **ce1_pluriel_nom_qcm_06** (difficulte 2) : La ... est ouverte.
|
- **ce1_pluriel_nom_qcm_06** (difficulte 2) : La ... est ouverte.
|
||||||
- Reponses : porte, portes
|
- Reponses : porte, portes
|
||||||
@@ -612,11 +612,11 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
|
|||||||
- Indice : Cherche le déterminant, même si un autre mot s'intercale avant le nom.
|
- Indice : Cherche le déterminant, même si un autre mot s'intercale avant le nom.
|
||||||
- Explication : « Les » indique le pluriel, même si l'adjectif « petits » s'intercale avant le nom : il faut écrire « chiens ».
|
- Explication : « Les » indique le pluriel, même si l'adjectif « petits » s'intercale avant le nom : il faut écrire « chiens ».
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
- **ce1_pluriel_nom_qcm_08** (difficulte 3) : Les jolies ... sentent bon.
|
- **ce1_pluriel_nom_qcm_08** (difficulte 3) : Les belles ... brillent dans le ciel.
|
||||||
- Reponses : fleur, fleurs
|
- Reponses : étoile, étoiles
|
||||||
- Reponse attendue : fleurs
|
- Reponse attendue : étoiles
|
||||||
- Indice : Cherche le déterminant, même si un autre mot s'intercale avant le nom.
|
- Indice : Cherche le déterminant, même si un autre mot s'intercale avant le nom.
|
||||||
- Explication : « Les » indique le pluriel, même si l'adjectif « jolies » s'intercale avant le nom : il faut écrire « fleurs ».
|
- Explication : « Les » indique le pluriel, même si l'adjectif « belles » s'intercale avant le nom : il faut écrire « étoiles ».
|
||||||
- Statut : draft
|
- Statut : draft
|
||||||
|
|
||||||
### Corrections de phrase
|
### Corrections de phrase
|
||||||
|
|||||||
@@ -330,3 +330,11 @@ Ajouts à l'arborescence proposée :
|
|||||||
**Addendum (0.5.1) — choix de la musique de fond** (demande utilisateur) : 5 morceaux au choix, `forest`, `marsh`, `meadow` (prairie), `river` (rivière), `night` (nuit), plus un choix « Automatique » (par défaut : forêt en CE1, marais en CE2, comme avant). Le choix est un réglage de l'appareil (`music_track` dans `user://settings.json`, valeur inconnue ramenée à « auto ») : le format des sauvegardes de profil est inchangé. Sélectionner un morceau dans les réglages le fait entendre aussitôt. Sons toujours provisoires et jamais écoutés ici.
|
**Addendum (0.5.1) — choix de la musique de fond** (demande utilisateur) : 5 morceaux au choix, `forest`, `marsh`, `meadow` (prairie), `river` (rivière), `night` (nuit), plus un choix « Automatique » (par défaut : forêt en CE1, marais en CE2, comme avant). Le choix est un réglage de l'appareil (`music_track` dans `user://settings.json`, valeur inconnue ramenée à « auto ») : le format des sauvegardes de profil est inchangé. Sélectionner un morceau dans les réglages le fait entendre aussitôt. Sons toujours provisoires et jamais écoutés ici.
|
||||||
|
|
||||||
**Correctif (0.5.2)** : les cinq morceaux de 0.5.1 étaient trop proches (même timbre de nappe + cloches, même niveau) : l'utilisateur n'a pas perçu de différence. Le changement de morceau fonctionnait (vérifié : identifiant, flux et bus corrects à chaque choix) ; seul le matériau sonore était indiscernable. Les morceaux sont désormais construits sur des styles distincts : forêt (nappe + cloches), marais (bourdon grave qui respire, rares cloches creuses), prairie (pizzicati allègres, basse sur le temps), rivière (arpège continu et lié), nuit (boîte à musique aiguë en 3 temps). Mesure objective : centroïde spectral de 220 à 1277 Hz, durée de boucle de 12 à 46 s, densité d'attaques de 3 à 36/s. Toujours jamais écouté ici.
|
**Correctif (0.5.2)** : les cinq morceaux de 0.5.1 étaient trop proches (même timbre de nappe + cloches, même niveau) : l'utilisateur n'a pas perçu de différence. Le changement de morceau fonctionnait (vérifié : identifiant, flux et bus corrects à chaque choix) ; seul le matériau sonore était indiscernable. Les morceaux sont désormais construits sur des styles distincts : forêt (nappe + cloches), marais (bourdon grave qui respire, rares cloches creuses), prairie (pizzicati allègres, basse sur le temps), rivière (arpège continu et lié), nuit (boîte à musique aiguë en 3 temps). Mesure objective : centroïde spectral de 220 à 1277 Hz, durée de boucle de 12 à 46 s, densité d'attaques de 3 à 36/s. Toujours jamais écouté ici.
|
||||||
|
|
||||||
|
## 34. Corrections du 12 octobre (version 0.5.3)
|
||||||
|
|
||||||
|
**Export cassé sur dépôt frais** : sur un clone sans `.godot/`, `make export-*` échouait (erreurs de chargement des polices et du thème, segfault de l'export, aucun binaire). Cause : le thème global est chargé au démarrage avant que les polices soient importées, donc une première passe d'import échoue ; le dépôt ne versionne pas `.godot/`. Correctif : cible `make import` (deux passes, la première tolérée en échec), prérequis de `run`, `test`, `validate-data`, `export-linux`, `export-windows`, `screenshot`. Vérifié sur un clone neuf : `make export-linux` produit un binaire qui démarre sans erreur. L'export avec Godot 4.7.2 (celui de l'utilisateur dans `~/bin`) fonctionne aussi ; le projet reste épinglé en 4.6.3 (`.godot-version`).
|
||||||
|
|
||||||
|
**Élisions** : aucune élision manquante (« le arbre ») dans les données, vérifié sur tous les JSON y compris les listes de jetons ; garde-fou permanent `tests/data/test_elision.gd` (mots à « h » aspiré et exceptions listés ; l'assertion arrière écarte « écris-la en »). Si l'élision manquante vue en jeu vient d'ailleurs que des données, il faudra l'indication de l'écran concerné.
|
||||||
|
|
||||||
|
**Phrases en double** : 14 phrases apparaissaient dans deux exercices ou dans un exercice et une dictée (ex. « Le chat dort. »). Les énoncés des QCM et corrections concernés ont été remplacés par de nouvelles phrases originales (indice et explication ajustés) ; les dictées, dont l'audio est généré, n'ont pas été touchées. Garde-fou permanent `tests/data/test_no_duplicate_sentences.gd` (phrase reconstituée en version correcte, comparée sans casse ni ponctuation).
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ config_version=5
|
|||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="Les Aventuriers des mots"
|
config/name="Les Aventuriers des mots"
|
||||||
config/version="0.5.2"
|
config/version="0.5.3"
|
||||||
run/main_scene="res://scenes/boot/boot.tscn"
|
run/main_scene="res://scenes/boot/boot.tscn"
|
||||||
config/features=PackedStringArray("4.6", "Forward Plus")
|
config/features=PackedStringArray("4.6", "Forward Plus")
|
||||||
config/icon="res://icon.svg"
|
config/icon="res://icon.svg"
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
extends GutTest
|
||||||
|
## Garde-fou orthographique sur tous les textes du jeu : « le arbre » doit
|
||||||
|
## s'ecrire « l'arbre ». Parcourt tous les JSON de data/ (chaines et listes de
|
||||||
|
## mots consecutifs) a la recherche d'une elision manquante. Les mots a « h »
|
||||||
|
## aspire et quelques exceptions legitimes sont listes ci-dessous.
|
||||||
|
|
||||||
|
const DATA_DIR := "res://data"
|
||||||
|
## Mots a « h » aspire ou vocalique sans elision : « le hibou », « le onze ».
|
||||||
|
const NO_ELISION_WORDS: Array[String] = [
|
||||||
|
"hibou",
|
||||||
|
"haie",
|
||||||
|
"haies",
|
||||||
|
"héros",
|
||||||
|
"hérisson",
|
||||||
|
"hamac",
|
||||||
|
"hanche",
|
||||||
|
"hangar",
|
||||||
|
"haricot",
|
||||||
|
"haricots",
|
||||||
|
"hasard",
|
||||||
|
"hache",
|
||||||
|
"hauteur",
|
||||||
|
"haut",
|
||||||
|
"haute",
|
||||||
|
"hautes",
|
||||||
|
"hauts",
|
||||||
|
"hall",
|
||||||
|
"hameau",
|
||||||
|
"harpe",
|
||||||
|
"hâte",
|
||||||
|
"hérissons",
|
||||||
|
"hurlement",
|
||||||
|
"huit",
|
||||||
|
"onze",
|
||||||
|
"oui",
|
||||||
|
"ouistiti",
|
||||||
|
"yaourt",
|
||||||
|
"yeux",
|
||||||
|
"ukulélé",
|
||||||
|
]
|
||||||
|
|
||||||
|
## (*UCP) : \\w couvre les lettres accentuees. Motif : mot d'elision, espaces,
|
||||||
|
## puis mot a voyelle ou « h » initial ; l'assertion arriere ecarte « écris-la en ».
|
||||||
|
const PATTERN := (
|
||||||
|
"(*UCP)(?<![-\\w'’])(?i)(le|la|de|que|ne|se|me|te|je|ce)\\s+"
|
||||||
|
+ "([aeiouâàäéèêëîïôöûùüœh][\\wàâäéèêëîïôöûùüçœ]*)"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _regex := RegEx.new()
|
||||||
|
var _problems: Array[String] = []
|
||||||
|
|
||||||
|
|
||||||
|
func before_all() -> void:
|
||||||
|
_regex.compile(PATTERN)
|
||||||
|
|
||||||
|
|
||||||
|
func test_no_missing_elision_in_game_texts() -> void:
|
||||||
|
_scan_dir(DATA_DIR)
|
||||||
|
assert_eq(_problems.size(), 0, "Elisions manquantes : %s" % "\n".join(_problems))
|
||||||
|
|
||||||
|
|
||||||
|
func test_detector_catches_a_missing_elision() -> void:
|
||||||
|
_problems.clear()
|
||||||
|
_check_text("le arbre est grand", "exemple")
|
||||||
|
assert_eq(_problems.size(), 1)
|
||||||
|
_problems.clear()
|
||||||
|
_check_text("Le hibou dort. Écris-la en entier. Le onze.", "exemple")
|
||||||
|
assert_eq(_problems.size(), 0)
|
||||||
|
|
||||||
|
|
||||||
|
func _scan_dir(path: String) -> void:
|
||||||
|
var dir := DirAccess.open(path)
|
||||||
|
if dir == null:
|
||||||
|
return
|
||||||
|
for sub in dir.get_directories():
|
||||||
|
if sub != "schemas":
|
||||||
|
_scan_dir(path.path_join(sub))
|
||||||
|
for file_name in dir.get_files():
|
||||||
|
if file_name.ends_with(".json"):
|
||||||
|
_scan_file(path.path_join(file_name))
|
||||||
|
|
||||||
|
|
||||||
|
func _scan_file(path: String) -> void:
|
||||||
|
var file := FileAccess.open(path, FileAccess.READ)
|
||||||
|
var parsed: Variant = JSON.parse_string(file.get_as_text())
|
||||||
|
_scan_value(parsed, path)
|
||||||
|
|
||||||
|
|
||||||
|
func _scan_value(value: Variant, where: String) -> void:
|
||||||
|
if typeof(value) == TYPE_STRING:
|
||||||
|
_check_text(value, where)
|
||||||
|
elif typeof(value) == TYPE_DICTIONARY:
|
||||||
|
for key: Variant in value:
|
||||||
|
_scan_value(value[key], where)
|
||||||
|
elif typeof(value) == TYPE_ARRAY:
|
||||||
|
var items: Array = value
|
||||||
|
# Mots consecutifs d'une phrase decoupee en jetons.
|
||||||
|
for i in range(items.size() - 1):
|
||||||
|
if typeof(items[i]) == TYPE_STRING and typeof(items[i + 1]) == TYPE_STRING:
|
||||||
|
_check_text("%s %s" % [items[i], items[i + 1]], where)
|
||||||
|
for item: Variant in items:
|
||||||
|
_scan_value(item, where)
|
||||||
|
|
||||||
|
|
||||||
|
func _check_text(text: String, where: String) -> void:
|
||||||
|
for match in _regex.search_all(text):
|
||||||
|
var next_word := match.get_string(2).to_lower()
|
||||||
|
if NO_ELISION_WORDS.has(next_word):
|
||||||
|
continue
|
||||||
|
_problems.append("%s : « %s »" % [where, match.get_string(0)])
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://beh3tst4how7j
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
extends GutTest
|
||||||
|
## Aucune phrase ne doit apparaitre deux fois dans le jeu (exercices et
|
||||||
|
## dictees confondus) : un meme enonce revu dans deux missions est une
|
||||||
|
## redite, pas un nouvel exercice. La phrase est reconstituee en version
|
||||||
|
## correcte (blanc rempli, mot fautif corrige) puis comparee sans casse ni
|
||||||
|
## ponctuation.
|
||||||
|
|
||||||
|
const EXERCISES_DIR := "res://data/exercises"
|
||||||
|
const DICTATIONS_DIR := "res://data/dictations"
|
||||||
|
|
||||||
|
|
||||||
|
func test_no_sentence_is_used_twice() -> void:
|
||||||
|
var seen: Dictionary = {}
|
||||||
|
var duplicates: Array[String] = []
|
||||||
|
for entry in _collect_sentences():
|
||||||
|
var key := _normalize(entry["sentence"])
|
||||||
|
if seen.has(key):
|
||||||
|
duplicates.append("« %s » : %s et %s" % [entry["sentence"], seen[key], entry["id"]])
|
||||||
|
else:
|
||||||
|
seen[key] = entry["id"]
|
||||||
|
assert_eq(duplicates.size(), 0, "Phrases en double :\n%s" % "\n".join(duplicates))
|
||||||
|
assert_gt(seen.size(), 100, "le test doit avoir vu les phrases du jeu")
|
||||||
|
|
||||||
|
|
||||||
|
func _collect_sentences() -> Array[Dictionary]:
|
||||||
|
var sentences: Array[Dictionary] = []
|
||||||
|
for path in _json_files(EXERCISES_DIR):
|
||||||
|
var data := _read(path)
|
||||||
|
var sentence := ""
|
||||||
|
if data.get("type", "") == "multiple_choice":
|
||||||
|
var answers: Array = data["answers"]
|
||||||
|
sentence = str(data["question"]).replace(
|
||||||
|
"...", str(answers[int(data["correct_answer"])])
|
||||||
|
)
|
||||||
|
elif data.get("type", "") == "sentence_correction":
|
||||||
|
var words: Array[String] = []
|
||||||
|
for token: Dictionary in data["tokens"]:
|
||||||
|
words.append(token["text"] if token["correct"] else token["expected"])
|
||||||
|
sentence = " ".join(words)
|
||||||
|
if not sentence.is_empty():
|
||||||
|
sentences.append({"id": data["id"], "sentence": sentence})
|
||||||
|
for path in _json_files(DICTATIONS_DIR):
|
||||||
|
var data := _read(path)
|
||||||
|
sentences.append({"id": data["id"], "sentence": data["target_text"]})
|
||||||
|
return sentences
|
||||||
|
|
||||||
|
|
||||||
|
func _normalize(sentence: String) -> String:
|
||||||
|
var cleaned := ""
|
||||||
|
for character in sentence.to_lower():
|
||||||
|
if character.is_valid_int() or character == "'" or character == " ":
|
||||||
|
cleaned += character
|
||||||
|
elif character.to_upper() != character or "éèêàâîïôûùçœ".contains(character):
|
||||||
|
cleaned += character
|
||||||
|
else:
|
||||||
|
cleaned += " "
|
||||||
|
var parts := cleaned.split(" ", false)
|
||||||
|
return " ".join(parts)
|
||||||
|
|
||||||
|
|
||||||
|
func _json_files(path: String) -> Array[String]:
|
||||||
|
var found: Array[String] = []
|
||||||
|
var dir := DirAccess.open(path)
|
||||||
|
if dir == null:
|
||||||
|
return found
|
||||||
|
for sub in dir.get_directories():
|
||||||
|
found.append_array(_json_files(path.path_join(sub)))
|
||||||
|
for file_name in dir.get_files():
|
||||||
|
if file_name.ends_with(".json"):
|
||||||
|
found.append(path.path_join(file_name))
|
||||||
|
return found
|
||||||
|
|
||||||
|
|
||||||
|
func _read(path: String) -> Dictionary:
|
||||||
|
var file := FileAccess.open(path, FileAccess.READ)
|
||||||
|
var parsed: Variant = JSON.parse_string(file.get_as_text())
|
||||||
|
return parsed if typeof(parsed) == TYPE_DICTIONARY else {}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://cekmrk80y81fk
|
||||||
Reference in New Issue
Block a user