Create simple word encoding scheme and display in game
This commit is contained in:
parent
0f8c97dca5
commit
a7e83622d2
3 changed files with 89 additions and 5 deletions
|
@ -65,3 +65,70 @@ func is_valid_word(word: String) -> bool:
|
||||||
func _notification(what: int) -> void:
|
func _notification(what: int) -> void:
|
||||||
if what == NOTIFICATION_WM_CLOSE_REQUEST:
|
if what == NOTIFICATION_WM_CLOSE_REQUEST:
|
||||||
get_tree().quit()
|
get_tree().quit()
|
||||||
|
|
||||||
|
|
||||||
|
## Returns the number of 1 bits in an integer
|
||||||
|
func popcnt(num: int) -> int:
|
||||||
|
# Is this already implemented somewhere?
|
||||||
|
var count := 0
|
||||||
|
for i in range(64):
|
||||||
|
if num & (1 << i):
|
||||||
|
count += 1
|
||||||
|
return count
|
||||||
|
|
||||||
|
|
||||||
|
## Encodes a word using a very basic "encryption" method. Returns -1 if invalid word
|
||||||
|
func encode_word(word: String) -> int:
|
||||||
|
if word.length() != 5:
|
||||||
|
return -1
|
||||||
|
word = word.to_upper()
|
||||||
|
|
||||||
|
# Encode word in base 26
|
||||||
|
var num := 0
|
||||||
|
for i in range(word.length()):
|
||||||
|
var letter_ind := word[i].unicode_at(0) - 65 # 65 = ascii "A"
|
||||||
|
if letter_ind < 0 or letter_ind >= 26:
|
||||||
|
return -1
|
||||||
|
num += letter_ind * (26 ** i)
|
||||||
|
# Add an offset so that "aaaaa" isn't just zeroes
|
||||||
|
num += 123456
|
||||||
|
|
||||||
|
# Shuffle bits around
|
||||||
|
# uvwxyz -> vuxwzy -> zyvuxw
|
||||||
|
num = ((num & 0xf0f0f0) >> 4) | ((num & 0x0f0f0f) << 4)
|
||||||
|
num = ((num & 0xffff00) >> 8) | ((num & 0x0000ff) << 16)
|
||||||
|
# Count bits and add as checksum
|
||||||
|
var bits := popcnt(num)
|
||||||
|
num = num | (bits << 24)
|
||||||
|
|
||||||
|
return num
|
||||||
|
|
||||||
|
|
||||||
|
## Decodes an encoded word. Returns an empty string if invalid
|
||||||
|
func decode_word(encoded_word: int) -> String:
|
||||||
|
var bits := encoded_word >> 24
|
||||||
|
var num := encoded_word & 0xffffff
|
||||||
|
|
||||||
|
# Verify bit count
|
||||||
|
if popcnt(num) != bits:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
# Unshuffle bits
|
||||||
|
num = ((num << 8) & 0xffff00) | ((num >> 16) & 0x0000ff)
|
||||||
|
num = ((num << 4) & 0xf0f0f0) | ((num >> 4) & 0x0f0f0f)
|
||||||
|
|
||||||
|
num -= 123456
|
||||||
|
|
||||||
|
if num < 0 or num >= (26 ** 5): # (26 ** 5) - 1 = "zzzzz"
|
||||||
|
# Someone is trying to be sneaky! Or more likely I just messed up.
|
||||||
|
return ""
|
||||||
|
|
||||||
|
# Decode base 26 word
|
||||||
|
var word := ""
|
||||||
|
for i in range(5):
|
||||||
|
var letter_ind := num % 26
|
||||||
|
word += char(letter_ind + 65) # 65 = ascii "A"
|
||||||
|
@warning_ignore("integer_division")
|
||||||
|
num = num / 26
|
||||||
|
|
||||||
|
return word
|
||||||
|
|
13
src/main.gd
13
src/main.gd
|
@ -21,6 +21,7 @@ var won: bool
|
||||||
var input_guess: String
|
var input_guess: String
|
||||||
|
|
||||||
@onready var title: Label = %Title
|
@onready var title: Label = %Title
|
||||||
|
@onready var subtitle: Label = %Subtitle
|
||||||
@onready var letter_grid: GridContainer = %LetterGrid
|
@onready var letter_grid: GridContainer = %LetterGrid
|
||||||
@onready var info_text: Label = %InfoText
|
@onready var info_text: Label = %InfoText
|
||||||
|
|
||||||
|
@ -54,6 +55,7 @@ func _ready() -> void:
|
||||||
random_seed = Time.get_unix_time_from_datetime_dict(current_time)
|
random_seed = Time.get_unix_time_from_datetime_dict(current_time)
|
||||||
|
|
||||||
title.text = "Daily " + title.text
|
title.text = "Daily " + title.text
|
||||||
|
subtitle.text = "%d-%02d-%02d" % [current_time["year"], current_time["month"], current_time["day"]]
|
||||||
else:
|
else:
|
||||||
title.text = "Random " + title.text
|
title.text = "Random " + title.text
|
||||||
|
|
||||||
|
@ -62,6 +64,9 @@ func _ready() -> void:
|
||||||
ended = false
|
ended = false
|
||||||
won = false
|
won = false
|
||||||
|
|
||||||
|
if not Global.daily_mode:
|
||||||
|
subtitle.text = String.num_int64(Global.encode_word(target_word), 16)
|
||||||
|
|
||||||
for i in range(0, 26):
|
for i in range(0, 26):
|
||||||
var letter := char("A".unicode_at(0) + i)
|
var letter := char("A".unicode_at(0) + i)
|
||||||
var keyboard_button: Button = keyboard_vbox.find_child("Button" + letter)
|
var keyboard_button: Button = keyboard_vbox.find_child("Button" + letter)
|
||||||
|
@ -219,14 +224,14 @@ func _on_ButtonBksp_pressed() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _on_share_button_pressed() -> void:
|
func _on_share_button_pressed() -> void:
|
||||||
var text := title.text
|
var text := "%s %s\n" % [title.text, subtitle.text]
|
||||||
if won:
|
if won:
|
||||||
text += " %d/%d\n\n" % [current_guess, guess_count]
|
text += "%d/%d\n\n" % [current_guess, guess_count]
|
||||||
elif ended:
|
elif ended:
|
||||||
text += " X/%d\n\n" % [guess_count]
|
text += "X/%d\n\n" % [guess_count]
|
||||||
else:
|
else:
|
||||||
# Can probably bail early but I might as allow it
|
# Can probably bail early but I might as allow it
|
||||||
text += " ?/%d\n\n" % [guess_count]
|
text += "?/%d\n\n" % [guess_count]
|
||||||
|
|
||||||
for i in range(current_guess):
|
for i in range(current_guess):
|
||||||
for j in range(letter_count):
|
for j in range(letter_count):
|
||||||
|
|
|
@ -175,7 +175,11 @@ anchor_bottom = 1.0
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
theme_override_constants/separation = 20
|
theme_override_constants/separation = 20
|
||||||
|
|
||||||
[node name="Title" type="Label" parent="C/V"]
|
[node name="Header" type="VBoxContainer" parent="C/V"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_constants/separation = 0
|
||||||
|
|
||||||
|
[node name="Title" type="Label" parent="C/V/Header"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
theme_override_fonts/font = SubResource("1")
|
theme_override_fonts/font = SubResource("1")
|
||||||
|
@ -183,6 +187,12 @@ text = "Gordle"
|
||||||
label_settings = SubResource("LabelSettings_h2dux")
|
label_settings = SubResource("LabelSettings_h2dux")
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
|
|
||||||
|
[node name="Subtitle" type="Label" parent="C/V/Header"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Subtitle"
|
||||||
|
horizontal_alignment = 1
|
||||||
|
|
||||||
[node name="LetterGrid" type="GridContainer" parent="C/V"]
|
[node name="LetterGrid" type="GridContainer" parent="C/V"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
@ -403,6 +413,7 @@ text = "Guess"
|
||||||
|
|
||||||
[node name="ShareButton" type="Button" parent="C/V/KeyboardVBox/GuessButton"]
|
[node name="ShareButton" type="Button" parent="C/V/KeyboardVBox/GuessButton"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 0
|
||||||
offset_left = 180.0
|
offset_left = 180.0
|
||||||
offset_right = 283.0
|
offset_right = 283.0
|
||||||
offset_bottom = 49.0
|
offset_bottom = 49.0
|
||||||
|
@ -411,6 +422,7 @@ text = "Share"
|
||||||
|
|
||||||
[node name="CopiedText" type="Label" parent="C/V/KeyboardVBox/GuessButton"]
|
[node name="CopiedText" type="Label" parent="C/V/KeyboardVBox/GuessButton"]
|
||||||
modulate = Color(1, 1, 1, 0)
|
modulate = Color(1, 1, 1, 0)
|
||||||
|
layout_mode = 0
|
||||||
offset_left = 126.0
|
offset_left = 126.0
|
||||||
offset_top = 31.0
|
offset_top = 31.0
|
||||||
offset_right = 347.0
|
offset_right = 347.0
|
||||||
|
|
Loading…
Reference in a new issue