diff --git a/internal/game/lobby.go b/internal/game/lobby.go index 3f404d6a..78ab8ac4 100644 --- a/internal/game/lobby.go +++ b/internal/game/lobby.go @@ -565,6 +565,33 @@ func handleNameChangeEvent(caller *Player, lobby *Lobby, name string) { } } +func (lobby *Lobby) calculateDrawerScore() int { + // The drawer can get points even if disconnected. But if they are + // connected, we need to ignore them when calculating their score. + var ( + playerCount int + scoreSum int + ) + for _, player := range lobby.GetPlayers() { + if player.State != Drawing && + // If the player has guessed, we want to take them into account, + // even if they aren't connected anymore. If the player is + // connected, but hasn't guessed, it is still as well, as the + // drawing must've not been good enough to be guessable. + (player.Connected || player.LastScore > 0) { + scoreSum += player.LastScore + playerCount++ + } + } + + var averageScore int + if playerCount > 0 { + averageScore = scoreSum / playerCount + } + + return averageScore +} + // advanceLobbyPredefineDrawer is required in cases where the drawer is removed // from the game. func advanceLobbyPredefineDrawer(lobby *Lobby, roundOver bool, newDrawer *Player) { @@ -578,30 +605,9 @@ func advanceLobbyPredefineDrawer(lobby *Lobby, roundOver bool, newDrawer *Player // The drawer can potentially be null if kicked or the game just started. if drawer := lobby.Drawer(); drawer != nil { - // The drawer can get points even if disconnected. But if they are - // connected, we need to ignore them when calculating their score. - var ( - playerCount int - scoreSum int - ) - for _, player := range lobby.GetPlayers() { - if player != drawer && - // If the player has guessed, we want to take them into account, - // even if they aren't connected anymore. If the player is - // connected, but hasn't guessed, it is still as well, as the - // drawing must've not been good enough to be guessable. - (player.Connected || player.LastScore > 0) { - scoreSum += player.LastScore - } - } - - var averageScore int - if playerCount > 0 { - averageScore = scoreSum / playerCount - } - - drawer.LastScore = averageScore - drawer.Score += drawer.LastScore + newDrawerScore := lobby.calculateDrawerScore() + drawer.LastScore = newDrawerScore + drawer.Score += newDrawerScore } // We need this for the next-turn / game-over event, in order to allow the diff --git a/internal/game/lobby_test.go b/internal/game/lobby_test.go index f5a6906b..13233bd2 100644 --- a/internal/game/lobby_test.go +++ b/internal/game/lobby_test.go @@ -11,6 +11,7 @@ import ( "github.com/lxzan/gws" easyjson "github.com/mailru/easyjson" "github.com/scribble-rs/scribble.rs/internal/sanitize" + "github.com/stretchr/testify/require" ) func createLobbyWithDemoPlayers(playercount int) *Lobby { @@ -381,3 +382,130 @@ func Test_kickDrawer(t *testing.T) { t.Errorf("Drawer should've been c, but was %s", lobby.Drawer().Name) } } + +func Test_calculateDrawerScore(t *testing.T) { + t.Run("only disconnected players, with score", func(t *testing.T) { + drawer := &Player{State: Drawing} + lobby := Lobby{ + players: []*Player{ + drawer, + { + Connected: false, + LastScore: 100, + }, + { + Connected: false, + LastScore: 200, + }, + }, + } + + require.Equal(t, 150, lobby.calculateDrawerScore()) + }) + t.Run("only disconnected players, with no score", func(t *testing.T) { + drawer := &Player{State: Drawing} + lobby := Lobby{ + players: []*Player{ + drawer, + { + Connected: false, + LastScore: 0, + }, + { + Connected: false, + LastScore: 0, + }, + }, + } + + require.Equal(t, 0, lobby.calculateDrawerScore()) + }) + t.Run("connected players, but no score", func(t *testing.T) { + drawer := &Player{State: Drawing} + lobby := Lobby{ + players: []*Player{ + drawer, + { + Connected: true, + LastScore: 0, + }, + { + Connected: true, + LastScore: 0, + }, + }, + } + + require.Equal(t, 0, lobby.calculateDrawerScore()) + }) + t.Run("connected players", func(t *testing.T) { + drawer := &Player{State: Drawing} + lobby := Lobby{ + players: []*Player{ + drawer, + { + Connected: true, + LastScore: 100, + }, + { + Connected: true, + LastScore: 200, + }, + }, + } + + require.Equal(t, 150, lobby.calculateDrawerScore()) + }) + t.Run("some connected players, some disconnected, some without score", func(t *testing.T) { + drawer := &Player{State: Drawing} + lobby := Lobby{ + players: []*Player{ + drawer, + { + Connected: true, + LastScore: 100, + }, + { + Connected: false, + LastScore: 200, + }, + { + Connected: true, + LastScore: 0, + }, + { + Connected: false, + LastScore: 0, + }, + }, + } + + require.Equal(t, 100, lobby.calculateDrawerScore()) + }) + t.Run("some connected players, some disconnected", func(t *testing.T) { + drawer := &Player{State: Drawing} + lobby := Lobby{ + players: []*Player{ + drawer, + { + Connected: true, + LastScore: 100, + }, + { + Connected: true, + LastScore: 200, + }, + { + Connected: false, + LastScore: 300, + }, + { + Connected: false, + LastScore: 400, + }, + }, + } + + require.Equal(t, 250, lobby.calculateDrawerScore()) + }) +}