1
0
mirror of https://github.com/maaslalani/gambit.git synced 2024-11-24 08:22:12 +02:00
gambit/server/game.go

119 lines
2.7 KiB
Go
Raw Normal View History

package server
import (
"fmt"
"strings"
tea "github.com/charmbracelet/bubbletea"
"github.com/maaslalani/gambit/game"
)
// NoteMsg is a message that is sent to the client when a message is added to
// the game.
type NoteMsg string
// SharedGame is a game that is shared between players. It wraps gambit bubble
// tea model and synchronizes messages among players and server.
type SharedGame struct {
2022-02-15 04:35:07 +02:00
player *Player
game *game.Game
note string
turn bool
observer bool
whiteToMove *bool
sync chan tea.Msg
}
// NewSharedGame creates a new shared game for a player.
func NewSharedGame(p *Player, sync chan tea.Msg, roomTurn *bool, turn, observer bool, pos string) *SharedGame {
g := game.NewGameWithPosition(pos)
g.SetFlipped(!turn)
r := &SharedGame{
2022-02-15 04:35:07 +02:00
player: p,
game: g,
turn: turn,
observer: observer,
whiteToMove: roomTurn,
sync: sync,
}
return r
}
// Init implements bubble tea model.
func (r *SharedGame) Init() tea.Cmd {
return nil
}
// SendMsg sends a message to the room.
func (r *SharedGame) SendMsg(msg tea.Msg) {
go func() {
r.sync <- msg
}()
}
// Update implements bubble tea model.
func (r *SharedGame) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmds []tea.Cmd
switch msg := msg.(type) {
case game.NotifyMsg:
if !r.observer && r.turn != msg.Turn {
r.SendMsg(game.MoveMsg{From: msg.From, To: msg.To})
if msg.Checkmate {
r.SendMsg(NoteMsg(fmt.Sprintf("%s wins!", r.player)))
}
}
case game.MoveMsg:
2022-02-15 03:21:12 +02:00
g, cmd := r.game.Update(msg)
r.game = g.(*game.Game)
cmds = append(cmds, cmd)
case NoteMsg:
r.note = string(msg)
return r, nil
case tea.MouseMsg:
2022-02-15 04:35:07 +02:00
if !r.observer && r.turn == *r.whiteToMove {
if msg.Type != tea.MouseLeft {
return r, nil
}
2022-02-15 03:21:12 +02:00
g, cmd := r.game.Update(msg)
cmds = append(cmds, cmd)
2022-02-15 03:21:12 +02:00
r.game = g.(*game.Game)
}
case tea.KeyMsg:
switch msg.String() {
case "ctrl+c", "q":
2022-02-15 03:21:12 +02:00
g, cmd := r.game.Update(msg)
r.game = g.(*game.Game)
cmds = append(cmds, cmd)
cmds = append(cmds, tea.Quit)
case "ctrl+f":
2022-02-15 03:21:12 +02:00
g, cmd := r.game.Update(msg)
cmds = append(cmds, cmd)
2022-02-15 03:21:12 +02:00
r.game = g.(*game.Game)
default:
2022-02-15 04:35:07 +02:00
if !r.observer && r.turn == *r.whiteToMove {
2022-02-15 03:21:12 +02:00
g, cmd := r.game.Update(msg)
cmds = append(cmds, cmd)
2022-02-15 03:21:12 +02:00
r.game = g.(*game.Game)
}
}
default:
2022-02-15 04:35:07 +02:00
if !r.observer && r.turn == *r.whiteToMove {
2022-02-15 03:21:12 +02:00
g, cmd := r.game.Update(msg)
cmds = append(cmds, cmd)
2022-02-15 03:21:12 +02:00
r.game = g.(*game.Game)
}
}
return r, tea.Batch(cmds...)
}
// View implements bubble tea model.
func (r *SharedGame) View() string {
s := strings.Builder{}
2022-02-15 03:21:12 +02:00
s.WriteString(r.game.View())
if r.note != "" {
s.WriteString("\n")
s.WriteString(r.note)
}
return s.String()
}