card_id/common/game/trial.go

121 lines
2.3 KiB
Go

package game
import (
"fmt"
"sort"
"strings"
"git.tuxpa.in/a/card_id/common/errs"
"git.tuxpa.in/a/card_id/common/game/card"
"git.tuxpa.in/a/card_id/common/util"
)
type Trial struct {
Cards map[int]card.Card
SelectionState int
PendingSelection [2]int
Shown map[int]card.Card
History [][2]int
}
func NewTrial() *Trial {
return &Trial{
Cards: make(map[int]card.Card, 7),
Shown: make(map[int]card.Card, 7),
PendingSelection: [2]int{-1, -1},
}
}
func (t *Trial) SelectCard(id int) (card.Card, error) {
if id > len(t.Cards) {
return card.Card{}, errs.Invalid("index out of bounds")
}
switch t.SelectionState {
case 0: // start selection
t.SelectionState = 1
t.PendingSelection[0] = id
return t.Cards[id], nil
case 1: // complete selection
t.SelectionState = 2
t.PendingSelection[1] = id
return t.Cards[id], nil
default:
return card.Card{}, errs.Logic("bad game state")
}
}
func (t *Trial) CheckSelection() (points int, lifechange float64) {
switch t.SelectionState {
case 0, 1:
return
default:
}
defer func() {
t.SelectionState = 0
}()
lifechange = -1
c1, ok := t.Cards[t.PendingSelection[0]]
if !ok {
return
}
c2, ok := t.Cards[t.PendingSelection[1]]
if !ok {
return
}
if c1.Id == c2.Id {
if c1.Name == c2.Name {
t.Shown[t.PendingSelection[0]] = c1
t.Shown[t.PendingSelection[1]] = c2
if c1.BonusLife || c2.BonusLife {
return 10, 1
}
return 10, 0.35
}
}
t.History = append(t.History, t.PendingSelection)
t.PendingSelection = [2]int{-1, -1}
return 0, -1
}
func (t *Trial) Show() map[int]card.Card {
out := util.CopyMap(t.Shown)
for _, v := range t.PendingSelection {
if v > 0 {
out[v] = t.Cards[v]
}
}
return out
}
func (t *Trial) ShowString() string {
out := util.CopyMap(t.Shown)
for _, v := range t.PendingSelection {
if v > 0 {
out[v] = t.Cards[v]
}
}
outs := ""
for n, k := range t.CardKeys() {
piece := fmt.Sprintf("[??%d??]", n+1)
if v, ok := out[k]; ok {
piece = fmt.Sprintf("[%s]", v.Name)
}
outs = outs + piece + " "
}
return strings.TrimSpace(outs)
}
func (t *Trial) CardKeys() []int {
keys := make([]int, 0, len(t.Cards))
for k := range t.Cards {
keys = append(keys, k)
}
sort.Slice(keys, func(i, j int) bool {
return keys[i] < keys[j]
})
return keys
}