Skip to content

Commit

Permalink
Remove lobby.drawer as it can be inferred from player states
Browse files Browse the repository at this point in the history
This leaves us with one field less that we have to keep consistent.
This will cost us some more CPU cycles, but is worth it.
  • Loading branch information
Bios-Marcel committed Aug 24, 2023
1 parent 56e97d8 commit f3d8ee5
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 27 deletions.
2 changes: 0 additions & 2 deletions internal/game/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ type Lobby struct {

// Whether the game has started, is ongoing or already over.
State State
// drawer references the Player that is currently drawing.
drawer *Player
// Owner references the Player that currently owns the lobby.
// Meaning this player has rights to restart or change certain settings.
Owner *Player
Expand Down
38 changes: 22 additions & 16 deletions internal/game/lobby.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func (lobby *Lobby) HandleEvent(eventType string, payload []byte, player *Player
return fmt.Errorf("word choice was %d, but should've been >= 0 and < %d", chosenIndex, len(lobby.wordChoice))
}

if player == lobby.drawer {
if player.State == Drawing {
lobby.selectWord(chosenIndex)

wordHintData := &Event{Type: EventTypeUpdateWordHint, Data: lobby.wordHints}
Expand Down Expand Up @@ -479,7 +479,7 @@ func kickPlayer(lobby *Lobby, playerToKick *Player, playerToKickIndex int) {
}
}

if lobby.drawer == playerToKick {
if playerToKick.State == Drawing {
newDrawer, roundOver := determineNextDrawer(lobby)
lobby.players = append(lobby.players[:playerToKickIndex], lobby.players[playerToKickIndex+1:]...)
lobby.Broadcast(&EventTypeOnly{Type: EventTypeDrawerKicked})
Expand All @@ -491,7 +491,6 @@ func kickPlayer(lobby *Lobby, playerToKick *Player, playerToKickIndex int) {
otherPlayer.LastScore = 0
}
lobby.scoreEarnedByGuessers = 0
lobby.drawer = nil

advanceLobbyPredefineDrawer(lobby, roundOver, newDrawer)
} else {
Expand All @@ -508,6 +507,15 @@ func kickPlayer(lobby *Lobby, playerToKick *Player, playerToKickIndex int) {
}
}

func (lobby *Lobby) Drawer() *Player {
for _, player := range lobby.players {
if player.State == Drawing {
return player
}
}
return nil
}

func calculateVotesNeededToKick(playerToKick *Player, lobby *Lobby) int {
connectedPlayerCount := lobby.GetConnectedPlayerCount()

Expand Down Expand Up @@ -569,14 +577,14 @@ func advanceLobbyPredefineDrawer(lobby *Lobby, roundOver bool, newDrawer *Player
}

// The drawer can potentially be null if kicked or the game just started.
if lobby.drawer != nil {
if drawer := lobby.Drawer(); drawer != nil {
if lobby.scoreEarnedByGuessers <= 0 {
lobby.drawer.LastScore = 0
drawer.LastScore = 0
} else {
// Average score, but minus one player, since the own score is 0 and doesn't count.
playerCount := lobby.GetConnectedPlayerCount()
// If the drawer isn't connected though, we mustn't subtract from the count.
if lobby.drawer.Connected {
if drawer.Connected {
playerCount--
}

Expand All @@ -585,8 +593,8 @@ func advanceLobbyPredefineDrawer(lobby *Lobby, roundOver bool, newDrawer *Player
averageScore = lobby.scoreEarnedByGuessers / playerCount
}

lobby.drawer.LastScore = averageScore
lobby.drawer.Score += lobby.drawer.LastScore
drawer.LastScore = averageScore
drawer.Score += drawer.LastScore
}
}

Expand Down Expand Up @@ -617,7 +625,6 @@ func advanceLobbyPredefineDrawer(lobby *Lobby, roundOver bool, newDrawer *Player
if roundOver {
// Game over
if lobby.Round == lobby.Rounds {
lobby.drawer = nil
lobby.State = GameOver

for _, player := range lobby.players {
Expand All @@ -643,8 +650,7 @@ func advanceLobbyPredefineDrawer(lobby *Lobby, roundOver bool, newDrawer *Player
}

lobby.ClearDrawing()
lobby.drawer = newDrawer
lobby.drawer.State = Drawing
newDrawer.State = Drawing
lobby.State = Ongoing
lobby.wordChoice = GetRandomWords(3, lobby)

Expand All @@ -663,7 +669,7 @@ func advanceLobbyPredefineDrawer(lobby *Lobby, roundOver bool, newDrawer *Player
},
})

lobby.WriteObject(lobby.drawer, &Event{Type: EventTypeYourTurn, Data: lobby.wordChoice})
lobby.WriteObject(newDrawer, &Event{Type: EventTypeYourTurn, Data: lobby.wordChoice})
}

// advanceLobby will either start the game or jump over to the next turn.
Expand All @@ -677,7 +683,7 @@ func advanceLobby(lobby *Lobby) {
// is over.
func determineNextDrawer(lobby *Lobby) (*Player, bool) {
for index, player := range lobby.players {
if player == lobby.drawer {
if player.State == Drawing {
// If we have someone that's drawing, take the next one
for i := index + 1; i < len(lobby.players); i++ {
player := lobby.players[i]
Expand Down Expand Up @@ -957,8 +963,8 @@ func (lobby *Lobby) OnPlayerConnectUnsynchronized(player *Player) {
// This state is reached if the player reconnects before having chosen a word.
// This can happen if the player refreshes his browser page or the socket
// loses connection and reconnects quickly.
if lobby.drawer == player && lobby.CurrentWord == "" {
lobby.WriteObject(lobby.drawer, &Event{Type: EventTypeYourTurn, Data: lobby.wordChoice})
if player.State == Drawing && lobby.CurrentWord == "" {
lobby.WriteObject(player, &Event{Type: EventTypeYourTurn, Data: lobby.wordChoice})
}

// The player that just joined already has the most up-to-date data due
Expand Down Expand Up @@ -1020,7 +1026,7 @@ func (lobby *Lobby) JoinPlayer(playerName string) *Player {
}

func (lobby *Lobby) canDraw(player *Player) bool {
return lobby.drawer == player && lobby.CurrentWord != ""
return player.State == Drawing && lobby.CurrentWord != "" && lobby.State == Ongoing
}

var connectionCharacterReplacer = strings.NewReplacer(" ", "", "-", "", "_", "")
Expand Down
18 changes: 9 additions & 9 deletions internal/game/lobby_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,35 +324,35 @@ func Test_kickDrawer(t *testing.T) {
t.Errorf("Couldn't start lobby: %s", err)
}

if lobby.drawer == nil {
if lobby.Drawer() == nil {
t.Error("Drawer should've been a, but was nil")
}

if lobby.drawer != marcel {
t.Errorf("Drawer should've been a, but was %s", lobby.drawer.Name)
if lobby.Drawer() != marcel {
t.Errorf("Drawer should've been a, but was %s", lobby.Drawer().Name)
}

lobby.Synchronized(func() {
advanceLobby(lobby)
})

if lobby.drawer == nil {
if lobby.Drawer() == nil {
t.Error("Drawer should've been b, but was nil")
}

if lobby.drawer != kevin {
t.Errorf("Drawer should've been b, but was %s", lobby.drawer.Name)
if lobby.Drawer() != kevin {
t.Errorf("Drawer should've been b, but was %s", lobby.Drawer().Name)
}

lobby.Synchronized(func() {
kickPlayer(lobby, kevin, 1)
})

if lobby.drawer == nil {
if lobby.Drawer() == nil {
t.Error("Drawer should've been c, but was nil")
}

if lobby.drawer != chantal {
t.Errorf("Drawer should've been c, but was %s", lobby.drawer.Name)
if lobby.Drawer() != chantal {
t.Errorf("Drawer should've been c, but was %s", lobby.Drawer().Name)
}
}

0 comments on commit f3d8ee5

Please sign in to comment.