gordle/src/Main.gd

176 lines
4.5 KiB
GDScript3
Raw Normal View History

2022-02-20 17:30:03 -05:00
extends Control
2022-02-20 14:35:55 -05:00
const letter_count := 5
const guess_count := 6
const Letter = preload("res://src/Letter.tscn")
export var color_incorrect: Color = Color()
export var color_misplaced: Color = Color()
export var color_correct: Color = Color()
# An array of arrays of the letter nodes
var letters := []
2022-02-20 15:55:10 -05:00
var target_word: String
var current_guess: int
2022-02-23 23:31:14 -05:00
var ended: bool
var input_guess: String
2022-02-20 15:55:10 -05:00
2022-02-20 17:30:03 -05:00
onready var error_text_color_default = $C/V/V/ErrorText.get("custom_colors/font_color")
2022-02-23 23:31:14 -05:00
2022-02-20 14:35:55 -05:00
func _ready() -> void:
for _i in range(guess_count):
var letter_array := []
for _j in range(letter_count):
var letter := Letter.instance()
letter_array.append(letter)
2022-02-20 17:30:03 -05:00
$C/V/LetterGrid.add_child(letter)
2022-02-20 14:35:55 -05:00
letters.append(letter_array)
2022-02-20 15:55:10 -05:00
2022-02-23 23:31:14 -05:00
var random_seed = null
if Global.daily_mode:
var current_time := OS.get_datetime_from_unix_time(OS.get_unix_time())
current_time["hour"] = 0
current_time["minute"] = 0
current_time["second"] = 0
random_seed = OS.get_unix_time_from_datetime(current_time)
$C/V/Title.text = "Daily " + $C/V/Title.text
else:
$C/V/Title.text = "Random " + $C/V/Title.text
2022-02-23 20:36:35 -05:00
2022-02-23 23:31:14 -05:00
target_word = Global.generate_word(letter_count, random_seed)
2022-02-20 15:55:10 -05:00
current_guess = 0
2022-02-23 23:31:14 -05:00
ended = false
2022-02-20 15:55:10 -05:00
2022-02-24 00:23:47 -05:00
func type_letter(letter: String) -> void:
if ended or input_guess.length() >= 5:
return
var index := input_guess.length()
letter = letter[0]
input_guess += letter
var letter_instance := letters[current_guess][index] as ColorRect
letter_instance.get_node("Label").text = letter
2022-02-20 15:55:10 -05:00
func backspace() -> void:
if ended or input_guess.length() <= 0:
return
input_guess = input_guess.substr(0, input_guess.length() - 1)
var index := input_guess.length()
var letter_instance := letters[current_guess][index] as ColorRect
letter_instance.get_node("Label").text = ""
func _unhandled_key_input(event: InputEventKey) -> void:
if event.is_pressed():
var scancode = event.get_scancode()
if scancode >= KEY_A and scancode <= KEY_Z:
var letter := OS.get_scancode_string(scancode)
type_letter(letter)
get_tree().set_input_as_handled()
elif scancode == KEY_BACKSPACE:
backspace()
get_tree().set_input_as_handled()
elif scancode == KEY_ENTER:
guess_entered()
get_tree().set_input_as_handled()
2022-02-20 15:55:10 -05:00
func _on_GuessButton_pressed() -> void:
guess_entered()
2022-02-20 15:55:10 -05:00
func guess_entered() -> void:
2022-02-20 15:55:10 -05:00
if current_guess >= guess_count:
return
input_guess = input_guess.to_upper()
if input_guess.length() != letter_count:
2022-02-20 17:30:03 -05:00
show_error("Word must be five characters.")
2022-02-20 15:55:10 -05:00
return
if not Global.is_valid_word(input_guess):
show_error("Not a recognized word.")
return
2022-02-20 15:55:10 -05:00
var letters_remaining = []
for letter in target_word:
letters_remaining.append(letter)
2022-02-20 17:30:03 -05:00
hide_error()
2022-02-20 15:55:10 -05:00
# Mark all greens
for i in range(letter_count):
var guess_letter := input_guess[i]
2022-02-20 15:55:10 -05:00
var target_letter := target_word[i]
var letter_instance := letters[current_guess][i] as ColorRect
letter_instance.get_node("Label").text = guess_letter
if guess_letter == target_letter:
letter_instance.color = color_correct
# Remove that one letter from remaining letters (is there a function for this?)
for j in range(letters_remaining.size()):
if letters_remaining[j] == guess_letter:
letters_remaining.remove(j)
break
# Mark all yellows (and grays)
for i in range(letter_count):
var letter_instance := letters[current_guess][i] as ColorRect
if letter_instance.color == color_correct:
# Ignore things that are already green
continue
var guess_letter := input_guess[i]
2022-02-20 15:55:10 -05:00
var found := false
for j in range(letters_remaining.size()):
if letters_remaining[j] == guess_letter:
found = true
letters_remaining.remove(j)
break
if found:
letter_instance.color = color_misplaced
else:
letter_instance.color = color_incorrect
current_guess += 1
2022-02-20 17:30:03 -05:00
var won := false
if input_guess == target_word:
2022-02-20 17:30:03 -05:00
ended = true
won = true
elif current_guess >= guess_count:
ended = true
input_guess = ""
2022-02-20 17:30:03 -05:00
if ended:
find_node("GuessButton").disabled = true
if won:
show_error("Congrats! You won!", Color(0.4, 0.9, 0.6))
else:
show_error("Game Over. The word was %s" % target_word, error_text_color_default)
func show_error(text: String, color = null):
$C/V/V/ErrorText.text = text
if typeof(color) == TYPE_COLOR:
$ErrorFadeOut.stop()
$C/V/V/ErrorText.add_color_override("font_color", color)
else:
$ErrorFadeOut.play("ErrorFadeOut")
func hide_error():
$C/V/V/ErrorText.text = ""
$ErrorFadeOut.stop()
2022-02-23 23:31:14 -05:00
func _on_MenuButton_pressed() -> void:
# TODO check if game is in progress and show confirmation popup
var error := get_tree().change_scene("res://src/Menu.tscn")
assert(not error)