Support joining private matches
This commit is contained in:
parent
9266c363f2
commit
2a7fd00f41
5 changed files with 88 additions and 17 deletions
84
app.go
84
app.go
|
@ -35,6 +35,11 @@ var (
|
|||
createGamePasswordField *cview.InputField
|
||||
createGameGrid *cview.Grid
|
||||
|
||||
joinGameForm *cview.Form
|
||||
joinGameLabelField *cview.TextView
|
||||
joinGamePasswordField *cview.InputField
|
||||
joinGameGrid *cview.Grid
|
||||
|
||||
statusWriter *bufferWriter
|
||||
gameWriter *bufferWriter
|
||||
|
||||
|
@ -42,6 +47,10 @@ var (
|
|||
inputMode bool
|
||||
screenWidth int
|
||||
|
||||
showJoinGameDialog bool
|
||||
joinGameID int
|
||||
joinGameName string
|
||||
|
||||
allGames []bgammon.GameListing
|
||||
autoRefresh = true
|
||||
showCreateGameDialog bool
|
||||
|
@ -79,7 +88,7 @@ func logIn(c *Client) {
|
|||
updateFocus()
|
||||
hideCursor()
|
||||
|
||||
l(fmt.Sprintf("Connecting to %s...", c.address))
|
||||
l("*** Connecting...")
|
||||
go c.Connect()
|
||||
}
|
||||
|
||||
|
@ -115,7 +124,7 @@ func beforeFocus(p cview.Primitive) bool {
|
|||
}
|
||||
|
||||
if viewScreen == ScreenLobby {
|
||||
if showCreateGameDialog {
|
||||
if showCreateGameDialog || showJoinGameDialog {
|
||||
return p != gameList && p != gameBuffer && p != statusBuffer && p != inputField
|
||||
} else if gameInProgress {
|
||||
return p == inputField
|
||||
|
@ -141,6 +150,9 @@ func updateFocus() {
|
|||
} else if showCreateGameDialog {
|
||||
createGameForm.SetFocus(0)
|
||||
app.SetFocus(createGameForm)
|
||||
} else if showJoinGameDialog {
|
||||
joinGameForm.SetFocus(0)
|
||||
app.SetFocus(joinGameForm)
|
||||
} else if gameInProgress {
|
||||
app.SetFocus(inputField)
|
||||
} else {
|
||||
|
@ -169,6 +181,8 @@ func buildLayout() {
|
|||
if viewScreen == ScreenLobby {
|
||||
if showCreateGameDialog {
|
||||
currentScreen = createGameGrid
|
||||
} else if showJoinGameDialog {
|
||||
currentScreen = joinGameGrid
|
||||
} else if gameInProgress {
|
||||
currentScreen = confirmExit
|
||||
} else {
|
||||
|
@ -322,6 +336,7 @@ func RunApp(c *Client, b *GameBoard) error {
|
|||
|
||||
app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
||||
handleCreateGameInput := viewScreen == ScreenLobby && showCreateGameDialog
|
||||
handleJoinGameInput := viewScreen == ScreenLobby && showJoinGameDialog
|
||||
handleGameInput := viewScreen == ScreenGame && !inputMode && gameInProgress
|
||||
|
||||
switch event.Key() {
|
||||
|
@ -355,6 +370,14 @@ func RunApp(c *Client, b *GameBoard) error {
|
|||
acceptCreateGameDialog()
|
||||
}
|
||||
return nil
|
||||
} else if handleJoinGameInput {
|
||||
if app.GetFocus() == joinGameForm.GetButton(0) {
|
||||
showJoinGameDialog = false
|
||||
buildLayout()
|
||||
} else {
|
||||
board.client.Out <- []byte(fmt.Sprintf("j %d %s", joinGameID, joinGamePasswordField.GetText()))
|
||||
}
|
||||
return nil
|
||||
} else if handleGameInput {
|
||||
inputMode = true
|
||||
buildLayout()
|
||||
|
@ -362,7 +385,13 @@ func RunApp(c *Client, b *GameBoard) error {
|
|||
} else {
|
||||
selected := gameList.GetCurrentItemIndex()
|
||||
if viewScreen == ScreenLobby && len(allGames) > 0 && selected >= 0 && selected < len(allGames) {
|
||||
board.client.Out <- []byte(fmt.Sprintf("j %d", allGames[selected].ID))
|
||||
if allGames[selected].Password {
|
||||
showJoinGameDialog = true
|
||||
joinGameID = allGames[selected].ID
|
||||
buildLayout()
|
||||
} else {
|
||||
board.client.Out <- []byte(fmt.Sprintf("j %d", allGames[selected].ID))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -372,6 +401,10 @@ func RunApp(c *Client, b *GameBoard) error {
|
|||
showCreateGameDialog = false
|
||||
buildLayout()
|
||||
return nil
|
||||
} else if showJoinGameDialog {
|
||||
showJoinGameDialog = false
|
||||
buildLayout()
|
||||
return nil
|
||||
} else if !gameInProgress {
|
||||
return nil
|
||||
}
|
||||
|
@ -413,11 +446,11 @@ func RunApp(c *Client, b *GameBoard) error {
|
|||
if gameInProgress {
|
||||
switch event.Rune() {
|
||||
case 'r', 'R':
|
||||
if board.Board.NeedRoll() {
|
||||
if board.Board.MayRoll() {
|
||||
board.client.Out <- []byte("roll")
|
||||
}
|
||||
case 'k', 'K':
|
||||
if board.Board.NeedOk() {
|
||||
if board.Board.MayOK() {
|
||||
board.client.Out <- []byte("ok")
|
||||
}
|
||||
}
|
||||
|
@ -459,7 +492,13 @@ func RunApp(c *Client, b *GameBoard) error {
|
|||
}
|
||||
// TODO prompt for password when required
|
||||
entry := allGames[i]
|
||||
board.client.Out <- []byte(fmt.Sprintf("j %d", entry.ID))
|
||||
if entry.Password {
|
||||
showJoinGameDialog = true
|
||||
joinGameID = entry.ID
|
||||
buildLayout()
|
||||
} else {
|
||||
board.client.Out <- []byte(fmt.Sprintf("j %d", entry.ID))
|
||||
}
|
||||
})
|
||||
|
||||
gameListHeader := cview.NewTextView()
|
||||
|
@ -487,8 +526,8 @@ func RunApp(c *Client, b *GameBoard) error {
|
|||
})
|
||||
|
||||
createGameLabel := cview.NewTextView()
|
||||
createGameLabel.SetText("[" + colorYellow + "]Create match[-]")
|
||||
createGameLabel.SetDynamicColors(true)
|
||||
createGameLabel.SetText("[" + colorYellow + "]Create match[-]")
|
||||
|
||||
publicOption := cview.NewDropDownOption("Public")
|
||||
publicOption.SetSelectedFunc(func(index int, option *cview.DropDownOption) {
|
||||
|
@ -527,6 +566,28 @@ func RunApp(c *Client, b *GameBoard) error {
|
|||
createGameGrid.AddItem(cview.NewBox(), 1, 0, 1, 1, 0, 0, true)
|
||||
createGameGrid.AddItem(createGameForm, 1, 1, 1, 1, 0, 0, true)
|
||||
|
||||
joinGameLabelField = cview.NewTextView()
|
||||
joinGameLabelField.SetDynamicColors(true)
|
||||
joinGameLabelField.SetText("[" + colorYellow + "]Join match: " + cview.Escape(joinGameName) + "[-]")
|
||||
|
||||
joinGameForm = cview.NewForm()
|
||||
joinGameForm.AddPasswordField("Password", "", 10, '*', nil)
|
||||
joinGameForm.AddButton("Cancel", func() {
|
||||
showJoinGameDialog = false
|
||||
buildLayout()
|
||||
})
|
||||
joinGameForm.AddButton("Join", func() {
|
||||
board.client.Out <- []byte(fmt.Sprintf("j %d %s", joinGameID, joinGamePasswordField.GetText()))
|
||||
})
|
||||
joinGamePasswordField = joinGameForm.GetFormItem(0).(*cview.InputField)
|
||||
|
||||
joinGameGrid = cview.NewGrid()
|
||||
joinGameGrid.SetRows(1, -1)
|
||||
joinGameGrid.SetColumns(1, -1)
|
||||
joinGameGrid.AddItem(joinGameLabelField, 0, 0, 1, 2, 0, 0, false)
|
||||
joinGameGrid.AddItem(cview.NewBox(), 1, 0, 1, 1, 0, 0, true)
|
||||
joinGameGrid.AddItem(joinGameForm, 1, 1, 1, 1, 0, 0, true)
|
||||
|
||||
gameListGrid = cview.NewGrid()
|
||||
gameListGrid.SetRows(1, -1, 1)
|
||||
gameListGrid.AddItem(gameListHeader, 0, 0, 1, 1, 0, 0, false)
|
||||
|
@ -589,7 +650,7 @@ func UpdateGameList(ev *bgammon.EventList) {
|
|||
}
|
||||
}
|
||||
|
||||
if viewScreen == ScreenLobby && !showCreateGameDialog {
|
||||
if viewScreen == ScreenLobby && !showCreateGameDialog && !showJoinGameDialog {
|
||||
app.Draw()
|
||||
}
|
||||
}
|
||||
|
@ -607,11 +668,11 @@ func HandleEvents(c *Client, b *GameBoard) {
|
|||
if ev.Clients == 1 {
|
||||
clientsPlural = ""
|
||||
}
|
||||
gamesPlural := "s"
|
||||
matchesPlural := "es"
|
||||
if ev.Games == 1 {
|
||||
gamesPlural = ""
|
||||
matchesPlural = ""
|
||||
}
|
||||
l(fmt.Sprintf("Welcome, %s. There %s currently %d client%s playing %d game%s.", ev.PlayerName, areIs, ev.Clients, clientsPlural, ev.Games, gamesPlural))
|
||||
l(fmt.Sprintf("*** Welcome, %s. There %s %d client%s playing %d match%s.", ev.PlayerName, areIs, ev.Clients, clientsPlural, ev.Games, matchesPlural))
|
||||
case *bgammon.EventHelp:
|
||||
l(fmt.Sprintf("Help: %s", ev.Message))
|
||||
case *bgammon.EventPing:
|
||||
|
@ -632,6 +693,7 @@ func HandleEvents(c *Client, b *GameBoard) {
|
|||
if ev.Player == c.Username {
|
||||
gameInProgress = true
|
||||
showCreateGameDialog = false
|
||||
showJoinGameDialog = false
|
||||
setScreen(ScreenGame)
|
||||
} else {
|
||||
lg(fmt.Sprintf("%s joined the match.", ev.Player))
|
||||
|
|
13
board.go
13
board.go
|
@ -38,10 +38,17 @@ func NewGameBoard(client *Client) *GameBoard {
|
|||
|
||||
func (b *GameBoard) Update() {
|
||||
b.TextView.SetBytes(b.Board.BoardState(b.Board.PlayerNumber))
|
||||
if b.Board.NeedRoll() {
|
||||
if b.Board.MayRoll() {
|
||||
b.TextView.Write([]byte("\n[" + colorYellow + "][\"btnroll\"][ ROLL ][\"\"][-:-:-][\"dummy\"] [\"\"]"))
|
||||
} else if b.Board.Turn != 0 && b.Board.Turn == b.Board.PlayerNumber { // Always show OK button when it is the user's turn.
|
||||
b.TextView.Write([]byte("\n[" + colorYellow + "][\"btnok\"][ OK ][\"\"] [\"btnreset\"][ RESET ][\"\"][-:-:-][\"dummy\"] [\"\"]"))
|
||||
} else {
|
||||
b.TextView.Write([]byte("\n[" + colorYellow + "]"))
|
||||
if b.Board.MayReset() {
|
||||
b.TextView.Write([]byte("[\"btnreset\"][ RESET ][\"\"] "))
|
||||
}
|
||||
if b.Board.MayOK() {
|
||||
b.TextView.Write([]byte("[" + colorYellow + "][\"btnok\"][ OK ][\"\"] "))
|
||||
}
|
||||
b.TextView.Write([]byte(`[-:-:-]["dummy"] [""]`))
|
||||
}
|
||||
b.Highlight()
|
||||
app.Draw()
|
||||
|
|
|
@ -64,6 +64,8 @@ func (c *Client) Connect() {
|
|||
|
||||
go c.handleWrite()
|
||||
c.handleRead()
|
||||
|
||||
l("*** Disconnected.")
|
||||
}
|
||||
|
||||
func (c *Client) handleWrite() {
|
||||
|
|
2
go.mod
2
go.mod
|
@ -3,7 +3,7 @@ module code.rocket9labs.com/tslocum/bgammon-cli
|
|||
go 1.16
|
||||
|
||||
require (
|
||||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20230913074653-cf99329267a8
|
||||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20230919035705-1b65aae28720
|
||||
code.rocketnine.space/tslocum/cview v1.5.9-0.20230912025026-d5de9a7b0a6c
|
||||
github.com/gdamore/tcell/v2 v2.6.0
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
|
|
4
go.sum
4
go.sum
|
@ -1,5 +1,5 @@
|
|||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20230913074653-cf99329267a8 h1:wdSojaTDI9adSY/4exRCTwaon8BOLecQBSmvb5S4r7Q=
|
||||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20230913074653-cf99329267a8/go.mod h1:LS/m5Zq7/93dP8XJrLkL1T5ZTwtddkN8X9TyRrrdCkQ=
|
||||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20230919035705-1b65aae28720 h1:KP9x6iRfZY1KnfgdITlhpewFKKnEzYi6sNJtgaWhgj8=
|
||||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20230919035705-1b65aae28720/go.mod h1:LS/m5Zq7/93dP8XJrLkL1T5ZTwtddkN8X9TyRrrdCkQ=
|
||||
code.rocketnine.space/tslocum/cbind v0.1.5 h1:i6NkeLLNPNMS4NWNi3302Ay3zSU6MrqOT+yJskiodxE=
|
||||
code.rocketnine.space/tslocum/cbind v0.1.5/go.mod h1:LtfqJTzM7qhg88nAvNhx+VnTjZ0SXBJtxBObbfBWo/M=
|
||||
code.rocketnine.space/tslocum/cview v1.5.9-0.20230912025026-d5de9a7b0a6c h1:6PkEnjl48DmwEgGibnOTi7tZGT66HTijiLSitu4eCh8=
|
||||
|
|
Loading…
Reference in a new issue