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:
|
||||
if what == NOTIFICATION_WM_CLOSE_REQUEST:
|
||||
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
|
||||
|
||||
@onready var title: Label = %Title
|
||||
@onready var subtitle: Label = %Subtitle
|
||||
@onready var letter_grid: GridContainer = %LetterGrid
|
||||
@onready var info_text: Label = %InfoText
|
||||
|
||||
|
@ -54,6 +55,7 @@ func _ready() -> void:
|
|||
random_seed = Time.get_unix_time_from_datetime_dict(current_time)
|
||||
|
||||
title.text = "Daily " + title.text
|
||||
subtitle.text = "%d-%02d-%02d" % [current_time["year"], current_time["month"], current_time["day"]]
|
||||
else:
|
||||
title.text = "Random " + title.text
|
||||
|
||||
|
@ -62,6 +64,9 @@ func _ready() -> void:
|
|||
ended = 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):
|
||||
var letter := char("A".unicode_at(0) + i)
|
||||
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:
|
||||
var text := title.text
|
||||
var text := "%s %s\n" % [title.text, subtitle.text]
|
||||
if won:
|
||||
text += " %d/%d\n\n" % [current_guess, guess_count]
|
||||
text += "%d/%d\n\n" % [current_guess, guess_count]
|
||||
elif ended:
|
||||
text += " X/%d\n\n" % [guess_count]
|
||||
text += "X/%d\n\n" % [guess_count]
|
||||
else:
|
||||
# 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 j in range(letter_count):
|
||||
|
|
|
@ -175,7 +175,11 @@ anchor_bottom = 1.0
|
|||
layout_mode = 2
|
||||
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
|
||||
layout_mode = 2
|
||||
theme_override_fonts/font = SubResource("1")
|
||||
|
@ -183,6 +187,12 @@ text = "Gordle"
|
|||
label_settings = SubResource("LabelSettings_h2dux")
|
||||
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"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
@ -403,6 +413,7 @@ text = "Guess"
|
|||
|
||||
[node name="ShareButton" type="Button" parent="C/V/KeyboardVBox/GuessButton"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_left = 180.0
|
||||
offset_right = 283.0
|
||||
offset_bottom = 49.0
|
||||
|
@ -411,6 +422,7 @@ text = "Share"
|
|||
|
||||
[node name="CopiedText" type="Label" parent="C/V/KeyboardVBox/GuessButton"]
|
||||
modulate = Color(1, 1, 1, 0)
|
||||
layout_mode = 0
|
||||
offset_left = 126.0
|
||||
offset_top = 31.0
|
||||
offset_right = 347.0
|
||||
|
|
Loading…
Reference in a new issue