Optimizes database request for words. Fixes highlight on words minigames. Removes the GPs from the syllables minigames.

This commit is contained in:
Dylan Sarrazyn
2024-06-04 15:38:39 +02:00
parent 9ecea21007
commit e401b68c07
10 changed files with 65 additions and 87 deletions
-4
View File
@@ -235,13 +235,9 @@ func _log_new_response(response: Dictionary, current_stimulus: Dictionary) -> vo
# Calculates the stimulus remediation score
func _get_stimulus_score(stimulus: Dictionary) -> int:
var score: int = 0
# Syllables and words
if stimulus.has("GPs"):
for gp: Dictionary in stimulus.GPs:
score += UserDataManager.get_GP_remediation_score(gp.ID)
# GPs
elif stimulus.has("ID"):
score += UserDataManager.get_GP_remediation_score(stimulus.ID)
return score
@@ -29,16 +29,8 @@ func _find_stimuli_and_distractions() -> void:
var current_lesson_stimuli: Array[Dictionary] = []
var previous_lesson_stimuli: Array[Dictionary] = []
var all_GPs: = Database.get_GP_for_lesson(lesson_nb, false, false, true, true)
var all_syllables: = Database.get_syllables_for_lesson(lesson_nb, false)
# Find the GPs for current lesson
for gp: Dictionary in all_GPs:
if gp.LessonNb == lesson_nb:
current_lesson_stimuli.append(gp)
else:
previous_lesson_stimuli.append(gp)
# Find the syllables for current lesson
for syllable: Dictionary in all_syllables:
if syllable.LessonNb == lesson_nb:
@@ -50,7 +42,7 @@ func _find_stimuli_and_distractions() -> void:
current_lesson_stimuli.shuffle()
previous_lesson_stimuli.shuffle()
# Sort for remediation TODO Voir si il faut aussi trier les stimuli de la lesson actuelle
# Sort for remediation
current_lesson_stimuli.sort_custom(_sort_scoring)
previous_lesson_stimuli.sort_custom(_sort_scoring)
@@ -93,26 +85,24 @@ func _find_stimuli_and_distractions() -> void:
for stimulus: Dictionary in stimuli:
var stimulus_distractors := []
var GPs : Array
if stimulus.has("GPs") and stimulus.GPs and stimulus.GPs.size() == 2:
GPs = stimulus.GPs
# Difficulty 1
# Any previously learned item w/ all letters different
for gp: Dictionary in all_GPs:
if gp.Grapheme != stimulus.Grapheme and gp.Phoneme != stimulus.Phoneme and (not gp.OtherPhonemes or not gp.OtherPhonemes.has(stimulus.Phoneme)):
stimulus_distractors.append(gp)
if GPs:
for syllable: Dictionary in all_syllables:
if syllable.GPs.size() < 2:
continue
if syllable.GPs[0] not in GPs and syllable.GPs[1] not in GPs:
stimulus_distractors.append(syllable)
for syllable: Dictionary in all_syllables:
var gp_found_in_stimuli: = false
for gp in syllable.GPs:
if gp in stimulus.GPs:
gp_found_in_stimuli = true
break
if not gp_found_in_stimuli:
stimulus_distractors.append(syllable)
# Higher difficulties only changes syllables distractors
if difficulty > 1 and GPs:
if difficulty > 1 and stimulus.GPs.size() == 2:
for syllable: Dictionary in all_syllables:
if syllable.GPs.size() != 2:
continue
# Difficulty 2-3
# If the item has 2 GP ('cha'), distractors should have only a single letter change ('la' or 'che')
if (syllable.GPs[0] == stimulus.GPs[0] and syllable.GPs[1] != stimulus.GPs[1]) or (syllable.GPs[0] != stimulus.GPs[0] and syllable.GPs[1] == stimulus.GPs[1]):
@@ -185,47 +175,27 @@ func _on_stimulus_pressed(stimulus : Dictionary, _node : Node) -> bool:
# Checks the answer and update scores
if _is_stimulus_right(stimulus):
if not is_highlighting:
# Checks if the stimulus is a simple GP or syllable and update the score
if stimulus.has("GPs"):
for gp in stimulus.GPs:
_update_score(gp.ID, 1)
else:
_update_score(stimulus.ID, 1)
for gp in stimulus.GPs:
_update_score(gp.ID, 1)
else:
# Handles highlight
is_highlighting = false
stimulus_found.emit()
else:
var stimulus_gps : Array[Dictionary]
var right_answer_gps : Array[Dictionary]
if stimulus.has("GPs"):
stimulus_gps = stimulus.GPs
else:
stimulus_gps = [stimulus]
var right_answer: = _get_current_stimulus()
if right_answer.has("GPs"):
right_answer_gps = right_answer.GPs
else:
right_answer_gps = [right_answer]
# Handles the right answer GPs
for i in right_answer_gps.size():
if i <= stimulus_gps.size() and stimulus_gps[i] == right_answer_gps[i]:
for i in right_answer.GPs.size():
if i <= stimulus.GPs.size() and stimulus.GPs[i] == right_answer.GPs[i]:
continue
_update_score(right_answer_gps[i].ID, -1)
_update_score(right_answer.GPs[i].ID, -1)
# Handles the pressed stimulus Gps
for i in stimulus_gps.size():
if i <= right_answer_gps.size() and stimulus_gps[i] == right_answer_gps[i]:
for i in stimulus.GPs.size():
if i <= right_answer.GPs.size() and stimulus.GPs[i] == right_answer.GPs[i]:
continue
_update_score(stimulus_gps[i].ID, -1)
print(scores)
_update_score(stimulus.GPs[i].ID, -1)
return true
+11 -7
View File
@@ -16,7 +16,6 @@ var current_gp_distractors_queue: Array[Dictionary] = []
# Find the stimuli and distractions of the minigame.
func _find_stimuli_and_distractions() -> void:
# Get the currently known words list
# TODO Mettre un minimum à 2 GPs ?
var words_list: = Database.get_words_for_lesson(lesson_nb, false, max_number_of_GPs)
if words_list.is_empty():
@@ -52,7 +51,7 @@ func _find_stimuli_and_distractions() -> void:
stimuli.append_array(current_lesson_words)
# If there are not enough stimuli from current lesson, we want at least half the target number of stimuli
var minimal_stimuli : int = floori(current_lesson_stimuli_number/2)
var minimal_stimuli : int = floori(current_lesson_stimuli_number/2.0)
if stimuli.size() < minimal_stimuli:
while stimuli.size() < minimal_stimuli:
stimuli.append(current_lesson_words.pick_random())
@@ -66,15 +65,16 @@ func _find_stimuli_and_distractions() -> void:
stimuli.append_array(previous_lesson_words)
# If there are not enough stimuli, fill the rest with current lesson
while stimuli.size() < max_progression:
stimuli.append(current_lesson_words.pick_random())
if current_lesson_words:
while stimuli.size() < max_progression:
stimuli.append(current_lesson_words.pick_random())
# Shuffle the stimuli
stimuli.shuffle()
# Find the GPs and distractors for each word
for stimulus: Dictionary in stimuli:
# stimulus["GPs"] = Database.get_GP_from_word(stimulus.ID)
stimulus.GPs = Database.get_GP_from_word(stimulus.ID as int)
var grapheme_distractions: = []
for GP in stimulus.GPs:
grapheme_distractions.append(Database.get_distractors_for_grapheme(GP.ID, lesson_nb))
@@ -97,7 +97,8 @@ func _setup_minigame() -> void:
# Setups the word progression for current progression
func _setup_word_progression() -> void:
var stimulus: = _get_current_stimulus()
max_word_progression = stimulus.GPs.size()
var GPs: = stimulus.GPs as Array
max_word_progression = GPs.size()
current_word_progression = 0
_play_stimulus()
@@ -105,6 +106,7 @@ func _setup_word_progression() -> void:
func _set_current_word_progression(p_current_word_progression: int) -> void:
current_word_progression = p_current_word_progression
is_highlighting = false
if current_word_progression == max_word_progression:
current_progression += 1
@@ -114,7 +116,9 @@ func _set_current_word_progression(p_current_word_progression: int) -> void:
func _reset_distractors_queue() -> void:
current_gp_distractors_queue = distractions[current_progression][current_word_progression].duplicate()
var current_distractors: = distractions[current_progression][current_word_progression] as Array
current_gp_distractors_queue = current_distractors.duplicate()
current_gp_distractors_queue.shuffle()
while current_gp_distractors_queue.size() > distractors_queue_size:
current_gp_distractors_queue.pop_front()
@@ -136,7 +136,6 @@ func _on_berry_eaten(berry: Berry) -> void:
if _is_GP_right(berry.gp):
_clear_berries()
_stop_highlight()
await caterpillar.eat_berry(berry)
await audio_player.play_phoneme(_get_GP().Phoneme as String)
current_word_progression += 1
@@ -9,7 +9,7 @@
[node name="CaterpillarMinigame" instance=ExtResource("1_ntn14")]
script = ExtResource("2_ycf8p")
lesson_nb = 10
lesson_nb = 12
max_number_of_lives = 5
max_progression = 5
+1 -2
View File
@@ -9,8 +9,7 @@
[node name="CrabsMinigame" instance=ExtResource("1_lbq56")]
script = ExtResource("2_gierf")
minigame_name = "crabs"
lesson_nb = 8
difficulty = 2
lesson_nb = 67
max_number_of_lives = 5
max_progression = 5
+3 -2
View File
@@ -16,8 +16,9 @@
[node name="FrogMinigame" instance=ExtResource("1_ng5er")]
script = ExtResource("2_0xg3r")
max_number_of_GPs = null
distractors_queue_size = null
max_number_of_GPs = 6
distractors_queue_size = 6
time_between_words = 3.0
minigame_name = "frog"
lesson_nb = 10
difficulty = null
+10 -2
View File
@@ -102,6 +102,15 @@ func _update_label(progress: int) -> void:
word_label.text += "_"
func _stop_highlight() -> void:
for monkey: Monkey in monkeys:
monkey.stop_highlight()
func _reset_plank_label() -> void:
word_label.text = "_".repeat(_get_current_stimulus().Word.length())
func _play_monkey_stimulus(monkey: Monkey) -> void:
var coroutine: = Coroutine.new()
@@ -114,8 +123,7 @@ func _play_monkey_stimulus(monkey: Monkey) -> void:
await coroutine.join_all()
func _get_coconut_from_monkey_to_king(monkey: Monkey) -> Coconut:
func _get_coconut_from_monkey_to_king(monkey: Monkey) -> Node2D:
monkey.stop_highlight()
await monkey.play("start_throw")
+8 -12
View File
@@ -46,14 +46,6 @@ var turtle_count: int = 0:
if turtle_count >= max_turtle_count and value < max_turtle_count:
can_spawn_turtle.emit()
turtle_count = value
var is_highlighting: bool = false:
set(value):
is_highlighting = value
for turtle: Turtle in turtles.get_children():
if is_highlighting and self._is_GP_right(turtle.gp):
turtle.highlight(true)
else:
turtle.highlight(false)
# Find and set the parameters of the minigame, like the number of lives or the victory conditions.
@@ -73,7 +65,14 @@ func _setup_minigame() -> void:
func _highlight() -> void:
is_highlighting = true
for turtle: Turtle in turtles.get_children():
if self._is_GP_right(turtle.gp):
turtle.highlight(true)
func _stop_highlight() -> void:
for turtle: Turtle in turtles.get_children():
turtle.highlight(false)
func _play_turtle_phoneme(gp: Dictionary) -> void:
@@ -153,9 +152,6 @@ func _on_island_area_entered(area: Area2D) -> void:
# Stop the spawning
spawn_timer.stop()
# Stop the highlight
is_highlighting = false
# Play the right animation
turtle.right()
+10 -5
View File
@@ -185,10 +185,10 @@ func get_syllables_for_lesson(lesson_nb: int, only_new: = false) -> Array[Dictio
return res
# TODO Gets the GP IDs for the future remediation engine
func get_words_for_lesson(lesson_nb: int, only_new: = false, min_length: = 2, max_length: = 99) -> Array:
var parameters: Array = []
var query: = "SELECT Words.ID, Words.Word, VerifiedCount.Count as GPsCount, MaxLessonNb as LessonNb
var query: = "SELECT Words.ID, Words.Word, VerifiedCount.Count as GPsCount, MaxLessonNb as LessonNb, VerifiedCount.gpsid as GPs_IDs
FROM Words
INNER JOIN
(SELECT WordID, count() as Count FROM GPsInWords
@@ -196,7 +196,7 @@ FROM Words
GROUP BY WordID
) TotalCount ON TotalCount.WordID = Words.ID
INNER JOIN
(SELECT WordID, count() as Count, max(LessonNb) as MaxLessonNb FROM GPsInWords
(SELECT WordID, count() as Count, max(LessonNb) as MaxLessonNb, group_concat(GPsInWords.GPID) as gpsid FROM GPsInWords
INNER JOIN GPsInLessons ON GPsInLessons.GPID = GPsInWords.GPID
INNER JOIN Lessons ON Lessons.ID = GPsInLessons.LessonID AND Lessons.LessonNb <= ?
GROUP BY WordID
@@ -215,9 +215,14 @@ FROM Words
parameters.append(min_length)
db.query_with_bindings(query, parameters)
var res : = db.query_result
var res: = db.query_result
# Parse the GPs IDs
for word: Dictionary in res:
word.GPs = get_GP_from_word(word.ID)
word.GPs = []
for GPID in word.GPs_IDs.split(","):
word.GPs.append({ID = int(GPID)})
word.erase("GPs_IDs")
return res