Optimizes database request for words. Fixes highlight on words minigames. Removes the GPs from the syllables minigames.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user