Show a graph of the game on the Winner popup
The Winner popup now shows every player's score after each song as a step line, with the winning score marked, and three facts under it: the longest streak, the longest standstill and the song most players scored on. The data comes from the points each song already records, through the new ScoreHistory. The popup grows to 1600x920 with the graph across the full width, so a 60-song game with five players stays readable. Reset points now starts a new game: it clears the points on the songs and the graph starts after the song that was playing. Songs already on the server at startup count as an earlier game. The screenshot tour has a long five-player game, and only the Winner popup differs from before.
This commit is contained in:
1 parent
b40b160fde
commit
e1e05f3904
21 files changed
+2461
-182
No files matched your search
+73
-1
@@ -47,6 +47,8 @@ const POPUPS: Array[Array] = [
|
||||
]
|
||||
|
||||
var _main: Control
|
||||
var _scores_before_win: Array[int] = []
|
||||
var _winning_score_before_win: int = 0
|
||||
|
||||
|
||||
func _init(main: Control) -> void:
|
||||
@@ -104,6 +106,30 @@ static func soundtrack_statistics() -> Array[Dictionary]:
|
||||
return statistics
|
||||
|
||||
|
||||
## Who scored on each song of a 60-song game to 20 points, the same on every run: the
|
||||
## third of [param players] wins on the last song, nobody scores on songs 21–27 and the
|
||||
## others stay below 20. Needs at least three players.
|
||||
static func long_game(players: Array[PlayerObject]) -> Array:
|
||||
var random: RandomNumberGenerator = RandomNumberGenerator.new()
|
||||
random.seed = 7
|
||||
var winner: int = 2
|
||||
var scores: Array[int] = []
|
||||
scores.resize(players.size())
|
||||
var song_scorers: Array = []
|
||||
for song: int in 60:
|
||||
var scorers: Array[String] = []
|
||||
for index: int in players.size():
|
||||
var limit: int = 19 if index == winner else 18
|
||||
var chance: float = 0.36 if index == winner else 0.2 + 0.02 * index
|
||||
if song < 59 && (song < 20 || song >= 27) && scores[index] < limit \
|
||||
&& random.randf() < chance:
|
||||
scorers.append(players[index].id)
|
||||
scores[index] += 1
|
||||
song_scorers.append(scorers)
|
||||
song_scorers[59].append(players[winner].id)
|
||||
return song_scorers
|
||||
|
||||
|
||||
## The pictures in [constant CHARACTERS_DIR], sorted by name.
|
||||
static func character_names() -> Array[String]:
|
||||
var names: Array[String] = []
|
||||
@@ -221,6 +247,24 @@ func run(on_state: Callable) -> void:
|
||||
_main.show_tab(&"quiz")
|
||||
await _settle()
|
||||
|
||||
# Last, as it adds players: a long game with five players on the Winner popup
|
||||
for player_name: String in ["Lucca", "Frog", "Robo"]:
|
||||
_add_player(player_name)
|
||||
await _settle()
|
||||
var players: Array[PlayerObject] = Settings.player_array
|
||||
var song_scorers: Array = long_game(players)
|
||||
var history: ScoreHistory = ScoreHistory.from_songs(players, song_scorers)
|
||||
for player: PlayerObject in players:
|
||||
player.player_score = history.final_score(player.id)
|
||||
Settings.winning_score = 20
|
||||
var winner_popup: WinnerPopup = _node("WinnerPopup")
|
||||
winner_popup.show_winner(players[2])
|
||||
winner_popup.show_history(history)
|
||||
await _settle()
|
||||
await on_state.call("popup_WinnerWindow_long_game", winner_popup)
|
||||
winner_popup.close()
|
||||
await _settle()
|
||||
|
||||
|
||||
## Returns where every Control and Window in [param subtree] is on screen, keyed by its
|
||||
## path from [param main]: [code]{"rect": [x, y, width, height], "visible": bool}[/code].
|
||||
@@ -328,13 +372,41 @@ func _open_popup(popup_name: String) -> Node:
|
||||
"CharacterSelectPopup":
|
||||
popup.show_grid("Crono")
|
||||
"WinnerPopup":
|
||||
popup.show_winner(Settings.player_array[0])
|
||||
_show_winner_after_a_game(popup)
|
||||
_:
|
||||
popup.open()
|
||||
return popup
|
||||
|
||||
|
||||
## Shows the Winner popup after a whole game, so the graph has something to show. The
|
||||
## scores are put back afterwards by [method _close_popup].
|
||||
func _show_winner_after_a_game(popup: WinnerPopup) -> void:
|
||||
_scores_before_win = []
|
||||
for player: PlayerObject in Settings.player_array:
|
||||
_scores_before_win.append(player.player_score)
|
||||
var crono: PlayerObject = Settings.player_array[0]
|
||||
var marle: PlayerObject = Settings.player_array[1]
|
||||
var song_scorers: Array = []
|
||||
for song: int in range(1, 17):
|
||||
var scorers: Array[String] = []
|
||||
if song in [2, 4, 5, 10, 11, 12, 13, 16]:
|
||||
scorers.append(crono.id)
|
||||
if song in [1, 3, 10, 14, 15]:
|
||||
scorers.append(marle.id)
|
||||
song_scorers.append(scorers)
|
||||
crono.player_score = 8
|
||||
marle.player_score = 5
|
||||
_winning_score_before_win = Settings.winning_score
|
||||
Settings.winning_score = 8
|
||||
popup.show_winner(crono)
|
||||
popup.show_history(ScoreHistory.from_songs(Settings.player_array, song_scorers))
|
||||
|
||||
|
||||
func _close_popup(popup: Node) -> void:
|
||||
if popup is WinnerPopup:
|
||||
Settings.winning_score = _winning_score_before_win
|
||||
for i: int in _scores_before_win.size():
|
||||
Settings.player_array[i].player_score = _scores_before_win[i]
|
||||
if popup is BasePopup:
|
||||
popup.close()
|
||||
else:
|
||||
|
||||
Reference in new issue
Block a user