175 lines
5.2 KiB
GDScript
175 lines
5.2 KiB
GDScript
extends Minigame
|
|
class_name WordsMinigame
|
|
|
|
# Define the maximum number of GP inside each words
|
|
@export var max_number_of_GPs: int = 6
|
|
# Define the size of the distractor queue for each GP
|
|
@export var distractors_queue_size: int = 6
|
|
|
|
var current_word_progression: int = 0: set = _set_current_word_progression
|
|
var max_word_progression: int = 0
|
|
|
|
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
|
|
var words_list: = Database.get_words_for_lesson(lesson_nb, false, max_number_of_GPs)
|
|
if words_list.is_empty():
|
|
return
|
|
var current_lesson_words: = []
|
|
var previous_lesson_words: = []
|
|
|
|
for word: Dictionary in words_list:
|
|
if word.LessonNb == lesson_nb:
|
|
current_lesson_words.append(word)
|
|
else:
|
|
previous_lesson_words.append(word)
|
|
|
|
# Shuffle everything
|
|
current_lesson_words.shuffle()
|
|
previous_lesson_words.shuffle()
|
|
|
|
# If there is no previous stimuli, only adds from current lesson
|
|
if previous_lesson_words.is_empty():
|
|
while stimuli.size() < max_progression:
|
|
stimuli.append(current_lesson_words.pick_random())
|
|
else:
|
|
if not current_lesson_words.is_empty():
|
|
# If there are more stimuli in current lesson than needed
|
|
if current_lesson_words.size() >= current_lesson_stimuli_number:
|
|
for i in current_lesson_stimuli_number:
|
|
stimuli.append(current_lesson_words[i])
|
|
else:
|
|
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)
|
|
if stimuli.size() < minimal_stimuli:
|
|
while stimuli.size() < minimal_stimuli:
|
|
stimuli.append(current_lesson_words.pick_random())
|
|
|
|
# Gets other stimuli from previous errors or lessons
|
|
# TODO Handle remediation engine
|
|
var spaces_left : int = max_progression - stimuli.size()
|
|
if previous_lesson_words.size() >= spaces_left:
|
|
for i in max_progression - stimuli.size():
|
|
stimuli.append(previous_lesson_words[i])
|
|
else:
|
|
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())
|
|
|
|
# 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.Word)
|
|
var grapheme_distractions: = []
|
|
for GP in stimulus.GPs:
|
|
grapheme_distractions.append(Database.get_distractors_for_grapheme(GP.Grapheme, lesson_nb))
|
|
distractions.append(grapheme_distractions)
|
|
|
|
print(stimulus)
|
|
|
|
|
|
# Launch the minigame
|
|
func _start() -> void:
|
|
if stimuli.is_empty():
|
|
_win()
|
|
return
|
|
_setup_word_progression()
|
|
|
|
|
|
# Find and set the parameters of the minigame, like the number of lives or the victory conditions.
|
|
func _setup_minigame() -> void:
|
|
super()
|
|
|
|
|
|
# Setups the word progression for current progression
|
|
func _setup_word_progression() -> void:
|
|
var stimulus: = _get_current_stimulus()
|
|
max_word_progression = stimulus.GPs.size()
|
|
current_word_progression = 0
|
|
|
|
_play_stimulus()
|
|
|
|
|
|
func _set_current_word_progression(p_current_word_progression: int) -> void:
|
|
current_word_progression = p_current_word_progression
|
|
|
|
if current_word_progression == max_word_progression:
|
|
current_progression += 1
|
|
else:
|
|
@warning_ignore("redundant_await")
|
|
await _on_current_word_progression_changed()
|
|
|
|
|
|
func _reset_distractors_queue() -> void:
|
|
current_gp_distractors_queue = distractions[current_progression][current_word_progression].duplicate()
|
|
current_gp_distractors_queue.shuffle()
|
|
while current_gp_distractors_queue.size() > distractors_queue_size:
|
|
current_gp_distractors_queue.pop_front()
|
|
|
|
|
|
# Gets the previous stimulus which is already found
|
|
func _get_previous_stimulus() -> Dictionary:
|
|
if stimuli.size() == 0 or current_progression == 0:
|
|
return {}
|
|
return stimuli[(current_progression-1) % stimuli.size()]
|
|
|
|
|
|
# Get the current stimulus which needs to be found to increase progression
|
|
func _get_current_stimulus() -> Dictionary:
|
|
if stimuli.size() == 0:
|
|
return {}
|
|
return stimuli[current_progression % stimuli.size()]
|
|
|
|
|
|
# Get the distractors for current word
|
|
func _get_current_distractors() -> Array:
|
|
return distractions[current_progression]
|
|
|
|
|
|
# Get the current GP to find
|
|
func _get_GP() -> Dictionary:
|
|
var stimulus: = _get_current_stimulus()
|
|
if not stimulus or not stimulus.has("GPs"):
|
|
return {}
|
|
return stimulus.GPs[current_word_progression]
|
|
|
|
|
|
# Get a random distractor for the current GP
|
|
func _get_distractor() -> Dictionary:
|
|
if current_gp_distractors_queue.is_empty():
|
|
_reset_distractors_queue()
|
|
return current_gp_distractors_queue.pop_front()
|
|
|
|
|
|
# Check if the provided GP is the expected answer
|
|
func _is_GP_right(gp: Dictionary) -> bool:
|
|
return gp == _get_GP()
|
|
|
|
|
|
# ------------- UI Callbacks ------------- #
|
|
|
|
|
|
func _play_stimulus() -> void:
|
|
await audio_player.play_word(_get_current_stimulus().Word)
|
|
|
|
|
|
# -------------- CONNECTIONS -------------- #
|
|
|
|
|
|
func _on_current_word_progression_changed() -> void:
|
|
_reset_distractors_queue()
|
|
|
|
|
|
func _on_current_progression_changed() -> void:
|
|
if current_progression >= max_progression:
|
|
return
|
|
_setup_word_progression()
|