Show match score and optionally show pip count

Resolves #1.
Resolves #2.
This commit is contained in:
Trevor Slocum 2023-11-13 19:08:26 -08:00
parent 74a1f9dcf3
commit 64a07671f6
9 changed files with 145 additions and 28 deletions

View file

@ -1,3 +1,7 @@
1.1.2:
- Show match score during matches worth more than 1 point
- Optionally show pip count
1.1.1:
- Support additional languages

View file

@ -74,14 +74,18 @@ type board struct {
opponentLabel *Label
playerLabel *Label
opponentPipCount *etk.Text
playerPipCount *etk.Text
timerLabel *etk.Text
clockLabel *etk.Text
showMenuButton *etk.Button
menuGrid *etk.Grid
highlightCheckbox *etk.Checkbox
settingsGrid *etk.Grid
showPipCountCheckbox *etk.Checkbox
highlightCheckbox *etk.Checkbox
settingsGrid *etk.Grid
matchStatusGrid *etk.Grid
@ -105,8 +109,10 @@ type board struct {
lineHeight int
lineOffset int
showPipCount bool
highlightAvailable bool
availableMoves [][]int
availableMoves [][]int
widget *BoardWidget
@ -138,6 +144,8 @@ func NewBoard() *board {
spaceHighlight: ebiten.NewImage(1, 1),
opponentLabel: NewLabel(color.RGBA{255, 255, 255, 255}),
playerLabel: NewLabel(color.RGBA{0, 0, 0, 255}),
opponentPipCount: etk.NewText("0"),
playerPipCount: etk.NewText("0"),
buttonsGrid: etk.NewGrid(),
buttonsOnlyRollGrid: etk.NewGrid(),
buttonsOnlyUndoGrid: etk.NewGrid(),
@ -159,6 +167,17 @@ func NewBoard() *board {
Mutex: &sync.Mutex{},
}
centerText := func(t *etk.Text) {
t.SetVertical(messeji.AlignCenter)
t.SetScrollBarVisible(false)
}
centerText(b.opponentPipCount)
centerText(b.playerPipCount)
b.opponentPipCount.SetHorizontal(messeji.AlignEnd)
b.playerPipCount.SetHorizontal(messeji.AlignStart)
b.bearOffOverlay = etk.NewButton(gotext.Get("Drag here to bear off"), func() error {
return nil
})
@ -179,22 +198,44 @@ func NewBoard() *board {
settingsLabel := etk.NewText(gotext.Get("Settings"))
settingsLabel.SetHorizontal(messeji.AlignCenter)
b.showPipCountCheckbox = etk.NewCheckbox(b.togglePipCountCheckbox)
b.showPipCountCheckbox.SetBorderColor(triangleA)
b.showPipCountCheckbox.SetCheckColor(triangleA)
b.showPipCountCheckbox.SetSelected(b.showPipCount)
pipCountLabel := &ClickableText{
Text: etk.NewText(gotext.Get("Show pip count")),
onSelected: func() {
b.showPipCountCheckbox.SetSelected(!b.showPipCountCheckbox.Selected())
b.togglePipCountCheckbox()
},
}
pipCountLabel.SetVertical(messeji.AlignCenter)
b.highlightCheckbox = etk.NewCheckbox(b.toggleHighlightCheckbox)
b.highlightCheckbox.SetBorderColor(triangleA)
b.highlightCheckbox.SetCheckColor(triangleA)
b.highlightCheckbox.SetSelected(b.highlightAvailable)
highlightLabel := etk.NewText(gotext.Get("Highlight legal moves"))
highlightLabel := &ClickableText{
Text: etk.NewText(gotext.Get("Highlight legal moves")),
onSelected: func() {
b.highlightCheckbox.SetSelected(!b.highlightCheckbox.Selected())
b.toggleHighlightCheckbox()
},
}
highlightLabel.SetVertical(messeji.AlignCenter)
checkboxGrid := etk.NewGrid()
checkboxGrid.SetColumnSizes(-1, -1, -1, -1, -1)
checkboxGrid.AddChildAt(b.highlightCheckbox, 0, 0, 1, 1)
checkboxGrid.AddChildAt(highlightLabel, 1, 0, 4, 1)
checkboxGrid.SetRowSizes(-1, 20, -1)
checkboxGrid.AddChildAt(b.showPipCountCheckbox, 0, 0, 1, 1)
checkboxGrid.AddChildAt(pipCountLabel, 1, 0, 4, 1)
checkboxGrid.AddChildAt(b.highlightCheckbox, 0, 2, 1, 1)
checkboxGrid.AddChildAt(highlightLabel, 1, 2, 4, 1)
b.settingsGrid.SetBackground(color.RGBA{40, 24, 9, 255})
b.settingsGrid.SetColumnSizes(20, -1, -1, 20)
b.settingsGrid.SetRowSizes(72, 72, 20, -1)
b.settingsGrid.SetRowSizes(72, 72+20+72, 20, -1)
b.settingsGrid.AddChildAt(settingsLabel, 1, 0, 2, 1)
b.settingsGrid.AddChildAt(checkboxGrid, 1, 1, 2, 1)
b.settingsGrid.AddChildAt(etk.NewBox(), 1, 2, 1, 1)
@ -255,9 +296,11 @@ func NewBoard() *board {
{
f := etk.NewFrame()
f.AddChild(b.widget)
f.AddChild(b.opponentPipCount)
f.AddChild(b.opponentLabel)
f.AddChild(b.opponentLabel)
f.AddChild(b.playerLabel)
f.AddChild(b.playerPipCount)
f.AddChild(b.uiGrid)
f.AddChild(b.bearOffOverlay)
b.frame.AddChild(f)
@ -334,6 +377,9 @@ func (b *board) fontUpdated() {
b.timerLabel.SetFont(b.fontFace, fontMutex)
b.clockLabel.SetFont(b.fontFace, fontMutex)
b.opponentPipCount.SetFont(bufferFont, fontMutex)
b.playerPipCount.SetFont(bufferFont, fontMutex)
}
func (b *board) recreateInputGrid() {
@ -550,6 +596,13 @@ func (b *board) selectResign() error {
return nil
}
func (b *board) togglePipCountCheckbox() error {
b.showPipCount = b.showPipCountCheckbox.Selected()
b.updatePlayerLabel()
b.updateOpponentLabel()
return nil
}
func (b *board) toggleHighlightCheckbox() error {
b.highlightAvailable = b.highlightCheckbox.Selected()
return nil
@ -1048,7 +1101,7 @@ func (b *board) setRect(x, y, w, h int) {
if dialogWidth > game.screenW {
dialogWidth = game.screenW
}
dialogHeight := 72 + 72 + 20 + game.scale(baseButtonHeight)
dialogHeight := 72 + 72 + 20 + 72 + 20 + game.scale(baseButtonHeight)
if dialogHeight > game.screenH {
dialogHeight = game.screenH
}
@ -1079,13 +1132,34 @@ func (b *board) setRect(x, y, w, h int) {
b.menuGrid.SetColumnSizes(-1, game.scale(10), -1, game.scale(10), -1)
b.chatGrid.SetRowSizes(-1, int(b.horizontalBorderSize)/2, inputAndButtons)
var padding int
if b.w >= 600 {
padding = 20
} else if b.w >= 400 {
padding = 12
} else if b.w >= 300 {
padding = 10
} else if b.w >= 200 {
padding = 7
} else if b.w >= 100 {
padding = 5
}
b.opponentPipCount.SetPadding(padding / 2)
b.playerPipCount.SetPadding(padding)
}
func (b *board) updateOpponentLabel() {
player := b.gameState.OpponentPlayer()
label := b.opponentLabel
label.SetText(player.Name)
var text string
if b.gameState.Points > 1 && len(player.Name) > 0 {
text = fmt.Sprintf("%s %d", player.Name, player.Points)
} else {
text = player.Name
}
label.SetText(text)
if player.Number == 1 {
label.activeColor = color.RGBA{0, 0, 0, 255}
@ -1096,7 +1170,7 @@ func (b *board) updateOpponentLabel() {
label.Text.TextField.SetForegroundColor(label.activeColor)
fontMutex.Lock()
bounds := etk.BoundString(largeFont, player.Name)
bounds := etk.BoundString(largeFont, text)
fontMutex.Unlock()
padding := 13
@ -1109,13 +1183,28 @@ func (b *board) updateOpponentLabel() {
return
}
label.SetRect(r.Inset(-padding))
if b.showPipCount {
b.opponentPipCount.SetVisible(true)
b.opponentPipCount.SetText(strconv.Itoa(b.gameState.Pips(player.Number)))
b.opponentPipCount.SetForegroundColor(label.activeColor)
b.opponentPipCount.SetRect(image.Rect(x+bounds.Dx(), y-bounds.Dy(), b.w/2-int(b.barWidth)/2, y+bounds.Dy()*2))
} else {
b.opponentPipCount.SetVisible(false)
}
}
func (b *board) updatePlayerLabel() {
player := b.gameState.LocalPlayer()
label := b.playerLabel
label.SetText(player.Name)
var text string
if b.gameState.Points > 1 && len(player.Name) > 0 {
text = fmt.Sprintf("%s %d", player.Name, player.Points)
} else {
text = player.Name
}
label.SetText(text)
if player.Number == 1 {
label.activeColor = color.RGBA{0, 0, 0, 255}
@ -1126,7 +1215,7 @@ func (b *board) updatePlayerLabel() {
label.Text.TextField.SetForegroundColor(label.activeColor)
fontMutex.Lock()
bounds := etk.BoundString(largeFont, player.Name)
bounds := etk.BoundString(largeFont, text)
defer fontMutex.Unlock()
padding := 13
@ -1139,6 +1228,15 @@ func (b *board) updatePlayerLabel() {
return
}
label.SetRect(r.Inset(-padding))
if b.showPipCount {
b.playerPipCount.SetVisible(true)
b.playerPipCount.SetText(strconv.Itoa(b.gameState.Pips(player.Number)))
b.playerPipCount.SetForegroundColor(label.activeColor)
b.playerPipCount.SetRect(image.Rect(b.innerW/2+int(b.barWidth)/2+int(b.horizontalBorderSize), y-bounds.Dy(), x, y+bounds.Dy()*2))
} else {
b.playerPipCount.SetVisible(false)
}
}
func (b *board) offsetPosition(x, y int) (int, int) {

View file

@ -36,7 +36,7 @@ import (
"golang.org/x/text/language"
)
const version = "v1.1.1"
const version = "v1.1.2"
const MaxDebug = 2
@ -1732,6 +1732,18 @@ func LoadLocale(forceLanguage *language.Tag) error {
return nil
}
type ClickableText struct {
*etk.Text
onSelected func()
}
func (t *ClickableText) HandleMouse(cursor image.Point, pressed bool, clicked bool) (handled bool, err error) {
if clicked {
t.onSelected()
}
return true, nil
}
// Short description.
var _ = gotext.Get("Play backgammon online via bgammon.org")

View file

@ -1,17 +1,21 @@
msgid ""
msgstr ""
"PO-Revision-Date: 2023-11-13 20:52+0000\n"
"Last-Translator: Trevor Slocum <trevor@rocketnine.space>\n"
"Language-Team: German <https://hosted.weblate.org/projects/bgammon/boxcars/"
"de/>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: xgotext\n"
"X-Generator: Weblate 5.2-dev\n"
msgid "%s joined the match."
msgstr ""
msgstr "%s ist dem Spiel beigetreten."
msgid "%s left the match."
msgstr ""
msgstr "%s hat das Spiel verlassen."
msgid "%s moved %s."
msgstr ""
@ -20,10 +24,10 @@ msgid "%s rolled %s."
msgstr ""
msgid "%s wins!"
msgstr ""
msgstr "%s hat gewonnen!"
msgid "Accept"
msgstr ""
msgstr "Akzeptiert"
msgid ""
"Boxcars is a client for playing backgammon via bgammon.org, a free and open "
@ -34,10 +38,10 @@ msgid "Cancel"
msgstr ""
msgid "Connect"
msgstr ""
msgstr "Verbunden"
msgid "Connecting..."
msgstr ""
msgstr "Verbinde..."
msgid "Create"
msgstr ""

View file

@ -44,7 +44,6 @@ msgid "Connecting..."
msgstr "Connexion…"
#, fuzzy
#| msgid "Create match"
msgid "Create"
msgstr "Créer une partie"

View file

@ -44,7 +44,6 @@ msgid "Connecting..."
msgstr "Kobler til …"
#, fuzzy
#| msgid "Create match"
msgid "Create"
msgstr "Opprett spill"
@ -92,7 +91,6 @@ msgid "Join match: %s"
msgstr "Ta del i spill: %s"
#, fuzzy
#| msgid "Leave Match"
msgid "Leave"
msgstr "Forlat spillet"
@ -183,3 +181,6 @@ msgstr "Det kan hende du må installere en nyere versjon av programmet."
#~ msgid "Reset"
#~ msgstr "Tilbakestill"
#~ msgid "Leave Match"
#~ msgstr "Forlat spillet"

View file

@ -45,7 +45,6 @@ msgid "Connecting..."
msgstr "Łączenie..."
#, fuzzy
#| msgid "Create match"
msgid "Create"
msgstr "Stwórz mecz"

2
go.mod
View file

@ -3,7 +3,7 @@ module code.rocket9labs.com/tslocum/boxcars
go 1.17
require (
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231113192606-4acaf3128e9b
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231114025129-328e37f9002a
code.rocket9labs.com/tslocum/etk v0.0.0-20231111061733-ffdef73ac8fb
code.rocketnine.space/tslocum/kibodo v1.0.2
code.rocketnine.space/tslocum/messeji v1.0.6-0.20231108225635-7a691903039e

4
go.sum
View file

@ -1,5 +1,5 @@
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231113192606-4acaf3128e9b h1:jD9ODLEvLxP54ZLFcbhtooUo/fbZCPM7sby9LtY4K90=
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231113192606-4acaf3128e9b/go.mod h1:NIwLSiHvXFJPJ6loPWJWb3esPaZT8Qk27hO6Tzassb4=
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231114025129-328e37f9002a h1:aTN9ywRAb52tcbXPt7u2fx3obFvkFi6uXwu2PcW49EM=
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231114025129-328e37f9002a/go.mod h1:NIwLSiHvXFJPJ6loPWJWb3esPaZT8Qk27hO6Tzassb4=
code.rocket9labs.com/tslocum/etk v0.0.0-20231111061733-ffdef73ac8fb h1:CJgcS7SZi9ICZNCs1Hz6+YpajvCHmzyqY38xl+2z8h8=
code.rocket9labs.com/tslocum/etk v0.0.0-20231111061733-ffdef73ac8fb/go.mod h1:mwrZqZLdxJhtbWKcuX3Ym06fFr1yqWH8FMXG5wHJ/KU=
code.rocketnine.space/tslocum/kibodo v1.0.2 h1:0RfvVz+IUku8MFx9wvDb+p8byns5gAjQLUo4ZenWP44=