diff --git a/game/session.go b/game/session.go index a3514bf..18e81b4 100644 --- a/game/session.go +++ b/game/session.go @@ -70,8 +70,8 @@ type GameSession struct { } type playerActionMsg struct { - PlayerName string - Action PlayerAction + PlayerID string + Action PlayerAction } func NewGameSession() *GameSession { @@ -209,12 +209,12 @@ func (s *GameSession) GetState() GameState { } } -func (s *GameSession) SubmitAction(playerName string, action PlayerAction) { - s.actionCh <- playerActionMsg{PlayerName: playerName, Action: action} +func (s *GameSession) SubmitAction(playerID string, action PlayerAction) { + s.actionCh <- playerActionMsg{PlayerID: playerID, Action: action} } // BuyItem handles shop purchases -func (s *GameSession) BuyItem(playerName string, itemIdx int) bool { +func (s *GameSession) BuyItem(playerID string, itemIdx int) bool { s.mu.Lock() defer s.mu.Unlock() if s.state.Phase != PhaseShop || itemIdx < 0 || itemIdx >= len(s.state.ShopItems) { @@ -222,7 +222,7 @@ func (s *GameSession) BuyItem(playerName string, itemIdx int) bool { } item := s.state.ShopItems[itemIdx] for _, p := range s.state.Players { - if p.Name == playerName && p.Gold >= item.Price { + if p.Fingerprint == playerID && p.Gold >= item.Price { p.Gold -= item.Price p.Inventory = append(p.Inventory, item) return true diff --git a/game/session_test.go b/game/session_test.go index fe49a6a..380a135 100644 --- a/game/session_test.go +++ b/game/session_test.go @@ -10,6 +10,7 @@ import ( func TestGetStateNoRace(t *testing.T) { s := NewGameSession() p := entity.NewPlayer("Racer", entity.ClassWarrior) + p.Fingerprint = "test-fp" s.AddPlayer(p) s.StartGame() @@ -30,7 +31,7 @@ func TestGetStateNoRace(t *testing.T) { for i := 0; i < 10; i++ { select { - case s.actionCh <- playerActionMsg{PlayerName: "Racer", Action: PlayerAction{Type: ActionWait}}: + case s.actionCh <- playerActionMsg{PlayerID: "test-fp", Action: PlayerAction{Type: ActionWait}}: default: } time.Sleep(10 * time.Millisecond) @@ -41,6 +42,7 @@ func TestGetStateNoRace(t *testing.T) { func TestSessionTurnTimeout(t *testing.T) { s := NewGameSession() p := entity.NewPlayer("test", entity.ClassWarrior) + p.Fingerprint = "test-fp" s.AddPlayer(p) s.StartFloor() diff --git a/game/turn.go b/game/turn.go index 2064f56..eb4432a 100644 --- a/game/turn.go +++ b/game/turn.go @@ -36,7 +36,7 @@ func (s *GameSession) RunTurn() { select { case msg := <-s.actionCh: s.mu.Lock() - s.actions[msg.PlayerName] = msg.Action + s.actions[msg.PlayerID] = msg.Action s.mu.Unlock() collected++ case <-timer.C: @@ -53,8 +53,8 @@ resolve: // Default action for players who didn't submit: Wait for _, p := range s.state.Players { if !p.IsOut() { - if _, ok := s.actions[p.Name]; !ok { - s.actions[p.Name] = PlayerAction{Type: ActionWait} + if _, ok := s.actions[p.Fingerprint]; !ok { + s.actions[p.Fingerprint] = PlayerAction{Type: ActionWait} } } } @@ -79,7 +79,7 @@ func (s *GameSession) resolvePlayerActions() { if p.IsOut() { continue } - action, ok := s.actions[p.Name] + action, ok := s.actions[p.Fingerprint] if !ok { continue } diff --git a/ui/model.go b/ui/model.go index b2087e1..c1c4467 100644 --- a/ui/model.go +++ b/ui/model.go @@ -172,6 +172,9 @@ func (m Model) updateTitle(msg tea.Msg) (tea.Model, tea.Cmd) { } else { m.playerName = "Adventurer" } + if m.fingerprint == "" { + m.fingerprint = fmt.Sprintf("anon-%d", time.Now().UnixNano()) + } m.screen = screenLobby m = m.withRefreshedLobby() } else if isQuit(key) { @@ -349,7 +352,7 @@ func (m Model) updateGame(msg tea.Msg) (tea.Model, tea.Cmd) { case game.PhaseCombat: isPlayerDead := false for _, p := range m.gameState.Players { - if p.Name == m.playerName && p.IsDead() { + if p.Fingerprint == m.fingerprint && p.IsDead() { isPlayerDead = true break } @@ -366,15 +369,15 @@ func (m Model) updateGame(msg tea.Msg) (tea.Model, tea.Cmd) { if m.session != nil { switch key.String() { case "1": - m.session.SubmitAction(m.playerName, game.PlayerAction{Type: game.ActionAttack, TargetIdx: m.targetCursor}) + m.session.SubmitAction(m.fingerprint, game.PlayerAction{Type: game.ActionAttack, TargetIdx: m.targetCursor}) case "2": - m.session.SubmitAction(m.playerName, game.PlayerAction{Type: game.ActionSkill, TargetIdx: m.targetCursor}) + m.session.SubmitAction(m.fingerprint, game.PlayerAction{Type: game.ActionSkill, TargetIdx: m.targetCursor}) case "3": - m.session.SubmitAction(m.playerName, game.PlayerAction{Type: game.ActionItem}) + m.session.SubmitAction(m.fingerprint, game.PlayerAction{Type: game.ActionItem}) case "4": - m.session.SubmitAction(m.playerName, game.PlayerAction{Type: game.ActionFlee}) + m.session.SubmitAction(m.fingerprint, game.PlayerAction{Type: game.ActionFlee}) case "5": - m.session.SubmitAction(m.playerName, game.PlayerAction{Type: game.ActionWait}) + m.session.SubmitAction(m.fingerprint, game.PlayerAction{Type: game.ActionWait}) } // After submitting, poll for turn resolution return m, m.pollState() @@ -401,7 +404,7 @@ func (m Model) updateShop(msg tea.Msg) (tea.Model, tea.Cmd) { case "1", "2", "3": if m.session != nil { idx := int(key.String()[0] - '1') - m.session.BuyItem(m.playerName, idx) + m.session.BuyItem(m.fingerprint, idx) m.gameState = m.session.GetState() } case "q":