@@ -20,6 +20,10 @@ import (
2020 "github.com/gofrs/uuid/v5"
2121)
2222
23+ var SupportedScoreCalculations = []string {
24+ "chill" ,
25+ }
26+
2327var SupportedLanguages = map [string ]string {
2428 "english_gb" : "English (GB)" ,
2529 "english" : "English (US)" ,
@@ -282,9 +286,7 @@ func handleMessage(message string, sender *Player, lobby *Lobby) {
282286 switch CheckGuess (normInput , normSearched ) {
283287 case EqualGuess :
284288 {
285- secondsLeft := int (lobby .roundEndTime / 1000 - time .Now ().UTC ().Unix ())
286-
287- sender .LastScore = calculateGuesserScore (lobby .hintCount , lobby .hintsLeft , secondsLeft , lobby .DrawingTime )
289+ sender .LastScore = lobby .calculateGuesserScore ()
288290 sender .Score += sender .LastScore
289291
290292 sender .State = Standby
@@ -321,24 +323,6 @@ func (lobby *Lobby) wasLastDrawEventFill() bool {
321323 return isFillEvent
322324}
323325
324- func calculateGuesserScore (hintCount , hintsLeft , secondsLeft , drawingTime int ) int {
325- // The base score is based on the general time taken.
326- // The formula here represents an exponential decline based on the time taken.
327- // This way fast players get more points, however not a lot more.
328- // The bonus gained by guessing before hints are shown is therefore still somewhat relevant.
329- declineFactor := 1.0 / float64 (drawingTime )
330- baseScore := int (maxBaseScore * math .Pow (1.0 - declineFactor , float64 (drawingTime - secondsLeft )))
331-
332- // Prevent zero division panic. This could happen with two letter words.
333- if hintCount <= 0 {
334- return baseScore
335- }
336-
337- // If all hints are shown, or the word is too short to show hints, the
338- // calculation will basically always be baseScore + 0.
339- return baseScore + hintsLeft * (maxHintBonusScore / hintCount )
340- }
341-
342326func (lobby * Lobby ) isAnyoneStillGuessing () bool {
343327 for _ , otherPlayer := range lobby .players {
344328 if otherPlayer .State == Guessing && otherPlayer .Connected {
@@ -597,34 +581,12 @@ func handleNameChangeEvent(caller *Player, lobby *Lobby, name string) {
597581 }
598582}
599583
600- func (lobby * Lobby ) calculateDrawerScore () int {
601- // The drawer can get points even if disconnected. But if they are
602- // connected, we need to ignore them when calculating their score.
603- var (
604- playerCount int
605- scoreSum int
606- )
607- for _ , player := range lobby .GetPlayers () {
608- if player .State != Drawing &&
609- // Switch to spectating is only possible after score calculation, so
610- // this can't be used to manipulate score.
611- player .State != Spectating &&
612- // If the player has guessed, we want to take them into account,
613- // even if they aren't connected anymore. If the player is
614- // connected, but hasn't guessed, it is still as well, as the
615- // drawing must've not been good enough to be guessable.
616- (player .Connected || player .LastScore > 0 ) {
617- scoreSum += player .LastScore
618- playerCount ++
619- }
620- }
621-
622- var averageScore int
623- if playerCount > 0 {
624- averageScore = scoreSum / playerCount
625- }
584+ func (lobby * Lobby ) calculateGuesserScore () int {
585+ return lobby .scoreCalculation .CalculateGuesserScore (lobby )
586+ }
626587
627- return averageScore
588+ func (lobby * Lobby ) calculateDrawerScore () int {
589+ return lobby .scoreCalculation .CalculateDrawerScore (lobby )
628590}
629591
630592// advanceLobbyPredefineDrawer is required in cases where the drawer is removed
@@ -946,6 +908,7 @@ func CreateLobby(
946908 publicLobby bool ,
947909 drawingTime , rounds , maxPlayers , customWordsPerTurn , clientsPerIPLimit int ,
948910 customWords []string ,
911+ scoringCalculation ScoreCalculation ,
949912) (* Player , * Lobby , error ) {
950913 if desiredLobbyId == uuid .Nil {
951914 desiredLobbyId = uuid .Must (uuid .NewV4 ())
@@ -960,9 +923,10 @@ func CreateLobby(
960923 ClientsPerIPLimit : clientsPerIPLimit ,
961924 Public : publicLobby ,
962925 },
963- CustomWords : customWords ,
964- currentDrawing : make ([]any , 0 ),
965- State : Unstarted ,
926+ CustomWords : customWords ,
927+ currentDrawing : make ([]any , 0 ),
928+ State : Unstarted ,
929+ scoreCalculation : scoringCalculation ,
966930 }
967931
968932 if len (customWords ) > 1 {
@@ -1139,3 +1103,72 @@ func (lobby *Lobby) Shutdown() {
11391103
11401104 lobby .Broadcast (& EventTypeOnly {Type : EventTypeShutdown })
11411105}
1106+
1107+ // ScoreCalculation allows having different scoring systems for
1108+ type ScoreCalculation interface {
1109+ Identifier () string
1110+ CalculateGuesserScore (* Lobby ) int
1111+ CalculateDrawerScore (* Lobby ) int
1112+ }
1113+
1114+ type ChillScoring struct {}
1115+
1116+ func (s * ChillScoring ) Identifier () string {
1117+ return "chill"
1118+ }
1119+
1120+ func (s * ChillScoring ) CalculateGuesserScore (lobby * Lobby ) int {
1121+ return s .calculateGuesserScore (lobby .hintCount , lobby .hintsLeft , lobby .DrawingTime , lobby .roundEndTime )
1122+ }
1123+
1124+ func (s * ChillScoring ) calculateGuesserScore (
1125+ hintCount , hintsLeft , drawingTime int ,
1126+ roundEndTimeMillis int64 ,
1127+ ) int {
1128+ secondsLeft := int (roundEndTimeMillis / 1000 - time .Now ().UTC ().Unix ())
1129+
1130+ // The base score is based on the general time taken.
1131+ // The formula here represents an exponential decline based on the time taken.
1132+ // This way fast players get more points, however not a lot more.
1133+ // The bonus gained by guessing before hints are shown is therefore still somewhat relevant.
1134+ declineFactor := 1.0 / float64 (drawingTime )
1135+ baseScore := int (maxBaseScore * math .Pow (1.0 - declineFactor , float64 (drawingTime - secondsLeft )))
1136+
1137+ // Prevent zero division panic. This could happen with two letter words.
1138+ if hintCount <= 0 {
1139+ return baseScore
1140+ }
1141+
1142+ // If all hints are shown, or the word is too short to show hints, the
1143+ // calculation will basically always be baseScore + 0.
1144+ return baseScore + hintsLeft * (maxHintBonusScore / hintCount )
1145+ }
1146+
1147+ func (s * ChillScoring ) CalculateDrawerScore (lobby * Lobby ) int {
1148+ // The drawer can get points even if disconnected. But if they are
1149+ // connected, we need to ignore them when calculating their score.
1150+ var (
1151+ playerCount int
1152+ scoreSum int
1153+ )
1154+ for _ , player := range lobby .GetPlayers () {
1155+ if player .State != Drawing &&
1156+ // Switch to spectating is only possible after score calculation, so
1157+ // this can't be used to manipulate score.
1158+ player .State != Spectating &&
1159+ // If the player has guessed, we want to take them into account,
1160+ // even if they aren't connected anymore. If the player is
1161+ // connected, but hasn't guessed, it is still as well, as the
1162+ // drawing must've not been good enough to be guessable.
1163+ (player .Connected || player .LastScore > 0 ) {
1164+ scoreSum += player .LastScore
1165+ playerCount ++
1166+ }
1167+ }
1168+
1169+ if playerCount > 0 {
1170+ return scoreSum / playerCount
1171+ }
1172+
1173+ return 0
1174+ }
0 commit comments