From e418f14f6cf2401876aaabe01c2e6bb7a4592e1b Mon Sep 17 00:00:00 2001 From: Paul Gestwicki Date: Tue, 6 Feb 2024 08:36:57 -0500 Subject: [PATCH] Refactor psuedo-enum into an enum The previous approach still referenced years as integers, but not all integers are valid years. This new approach uses an enumerated type throughout the application. --- project/common/year.gd | 62 +++++++++++++++---- project/story/demo_stories/year_bound_demo.gd | 2 +- .../story/starting_stories/big_vs_small.gd | 2 +- .../story/starting_stories/liberal_arts.gd | 2 +- project/test/unit/year_test.gd | 48 +++++++++----- project/ui/year_indicator.gd | 15 +++-- project/world/simple_story.gd | 4 +- project/world/world.gd | 11 ++-- 8 files changed, 104 insertions(+), 42 deletions(-) diff --git a/project/common/year.gd b/project/common/year.gd index 9ff1116..f82bf9e 100644 --- a/project/common/year.gd +++ b/project/common/year.gd @@ -1,20 +1,60 @@ class_name Year -enum { - Freshman, - Sophomore, - Junior, - Senior, +enum Name { + FRESHMAN, + SOPHOMORE, + JUNIOR, + SENIOR } +## Get the common English name of the academic year. +static func as_string(year:Name) -> String: + match year: + Name.FRESHMAN: + return "Freshman" + Name.SOPHOMORE: + return "Sophomore" + Name.JUNIOR: + return "Junior" + Name.SENIOR: + return "Senior" + push_error("Unmatched year: %s" % str(year)) + return "Splunge" -static func values() -> Array[int]: - return [Freshman, Sophomore, Junior, Senior] +## Determine if the given year has a next year or if it is terminal. +static func has_next(year:Name) -> bool: + return year!=Name.SENIOR -static func keys() -> Array[String]: - return ["Freshman", "Sophomore", "Junior", "Senior"] +## Get the year that comes after the given year. +## If the year doesn't have a next year, this will push an error. +static func next(year:Name) -> Name: + match year: + Name.FRESHMAN: return Name.SOPHOMORE + Name.SOPHOMORE: return Name.JUNIOR + Name.JUNIOR: return Name.SENIOR + push_error("Year does not have a next: %s" % str(year)) + # This is a meaningless return but is required for the interpreter + # to see that all code paths return a value. + return Name.FRESHMAN -static func not_in(years: Array[int]) -> Array[int]: - return Year.values().filter(func(year: int): return not years.has(year)) + +## Return the array of all the years except the given one. +static func not_year(year:Name) -> Array[Name]: + return values().filter(func(y): return y != year) + + +## Return all the years except the given ones. +static func not_years(years: Array[Name]) -> Array[Name]: + return values().filter(func(y): return not years.has(y)) + + +## Get all the possible Year values. +static func values() -> Array[Name]: + return [ + Name.FRESHMAN, + Name.SOPHOMORE, + Name.JUNIOR, + Name.SENIOR, + ] diff --git a/project/story/demo_stories/year_bound_demo.gd b/project/story/demo_stories/year_bound_demo.gd index 203c4d7..f4e8f94 100644 --- a/project/story/demo_stories/year_bound_demo.gd +++ b/project/story/demo_stories/year_bound_demo.gd @@ -2,7 +2,7 @@ extends SimpleStory var text := "This story will not be shown during the player's freshman year." -var years := Year.not_in([ Year.Freshman ]) +var years := Year.not_year(Year.Name.FRESHMAN) var options := { "This is not my freshman year": { diff --git a/project/story/starting_stories/big_vs_small.gd b/project/story/starting_stories/big_vs_small.gd index 6686b64..e9b6f0d 100644 --- a/project/story/starting_stories/big_vs_small.gd +++ b/project/story/starting_stories/big_vs_small.gd @@ -2,7 +2,7 @@ extends SimpleStory var text := '"I\'ve been thinking about college. Do you think it\'s better for me to go a [u]big[/u] school or [u]small[/u] school?"' -var years := Year.not_in([ Year.Freshman ]) +var years := Year.not_year(Year.Name.FRESHMAN) var options := { "Bigger is better": { diff --git a/project/story/starting_stories/liberal_arts.gd b/project/story/starting_stories/liberal_arts.gd index 1603437..7a7812b 100644 --- a/project/story/starting_stories/liberal_arts.gd +++ b/project/story/starting_stories/liberal_arts.gd @@ -7,7 +7,7 @@ var text := [ '"I liked some of the smaller liberal arts schools I visited, but I also liked the engineering program at the big state university."' ] -var years := [ Year.Junior, Year.Senior ] +var years := [ Year.Name.JUNIOR, Year.Name.SENIOR ] var options := { "Study liberal arts!": { diff --git a/project/test/unit/year_test.gd b/project/test/unit/year_test.gd index 80a0531..0c3de9b 100644 --- a/project/test/unit/year_test.gd +++ b/project/test/unit/year_test.gd @@ -1,19 +1,35 @@ extends GutTest -func test_year_not_in_single() -> void: - var years: Array[int] = [ Year.Freshman ] - - assert_eq(Year.not_in(years), [ Year.Sophomore, Year.Junior, Year.Senior ]) - - -func test_year_not_in_multiple() -> void: - var years: Array[int] = [ Year.Sophomore, Year.Senior ] - - assert_eq(Year.not_in(years), [ Year.Freshman, Year.Junior ]) - - -func test_year_not_in_all() -> void: - var years: Array[int] = [ Year.Freshman, Year.Sophomore, Year.Junior, Year.Senior ] - - assert_eq(Year.not_in(years), []) +func test_not_year() -> void: + assert_eq(Year.not_year(Year.Name.SOPHOMORE), + [ Year.Name.FRESHMAN, Year.Name.JUNIOR, Year.Name.SENIOR ]) + + +func test_not_years() -> void: + assert_eq(Year.not_years([Year.Name.FRESHMAN, Year.Name.SOPHOMORE]), + [ Year.Name.JUNIOR, Year.Name.SENIOR ]) + + +func test_has_next(params=use_parameters([ + [Year.Name.FRESHMAN, true], + [Year.Name.SOPHOMORE, true], + [Year.Name.JUNIOR, true], + [Year.Name.SENIOR, false] +])) -> void: + var year :Year.Name= params[0] + var expected :bool = params[1] + assert_eq(Year.has_next(year), expected, + "Expected year %s result to be %s" % [str(year), str(expected)] + ) + + +func test_next(params=use_parameters([ + [Year.Name.FRESHMAN, Year.Name.SOPHOMORE], + [Year.Name.SOPHOMORE, Year.Name.JUNIOR], + [Year.Name.JUNIOR, Year.Name.SENIOR] +])): + var year :Year.Name = params[0] + var next :Year.Name = params[1] + assert_eq(Year.next(year), next, + "Year after %s should be %s" % [str(year), str(next)]) diff --git a/project/ui/year_indicator.gd b/project/ui/year_indicator.gd index ea76680..a5cc6cf 100644 --- a/project/ui/year_indicator.gd +++ b/project/ui/year_indicator.gd @@ -8,10 +8,15 @@ var world: World: world = value world.years_changed.connect(_year_progressed) - _update_display(world.years) + _update_display(world.year) @onready var _year_name: Label = %YearName -@onready var _year_circles : Array[ProgressCircle] = [ %Year1, %Year2, %Year3, %Year4 ] +@onready var _year_circles := { + Year.Name.FRESHMAN: %Year1, + Year.Name.SOPHOMORE: %Year2, + Year.Name.JUNIOR: %Year3, + Year.Name.SENIOR: %Year4, +} @onready var _particles: CPUParticles2D = %Particles @@ -19,6 +24,6 @@ func _year_progressed(years: int) -> void: _particles.emitting = true _update_display(years) -func _update_display(years: int) -> void: - _year_circles[years].year_passed = true - _year_name.text = Year.keys()[years] +func _update_display(new_year: Year.Name) -> void: + _year_circles[new_year].year_passed = true + _year_name.text = Year.as_string(new_year) diff --git a/project/world/simple_story.gd b/project/world/simple_story.gd index dabc4c9..39d31e0 100644 --- a/project/world/simple_story.gd +++ b/project/world/simple_story.gd @@ -76,8 +76,10 @@ func run(presenter) -> void: presenter.world.end_stories.append(new_ending_possibility) +## Determine if this story is able to be selected now, +## given the world state. func is_active(world: World) -> bool: - if "years" in self and not get("years").has(world.years): + if "years" in self and not get("years").has(world.year): return false return true diff --git a/project/world/world.gd b/project/world/world.gd index d6af281..e1ac7c3 100644 --- a/project/world/world.gd +++ b/project/world/world.gd @@ -36,16 +36,15 @@ var turns := 0: if turns >= turns_per_year: turns = 0 - years += 1 + if Year.has_next(year): + year = Year.next(year) turns_changed.emit(turns) -var years := 0: +var year := Year.Name.FRESHMAN: set(value): - years = value - - if years < 4: - years_changed.emit(years) + year = value + years_changed.emit(year) ## Add all the stories in the given directory to the list