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 Lives int SelectionState int PendingSelection [2]int Shown map[int]card.Card History [][2]int } func NewTrial(lives int) *Trial { return &Trial{ Lives: lives, 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") } if t.Lives == 0 { return card.Card{}, errs.Logic("game over") } 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() bool { switch t.SelectionState { case 0, 1: return false default: } defer func() { t.SelectionState = 0 }() c1, ok := t.Cards[t.PendingSelection[0]] if !ok { return false } c2, ok := t.Cards[t.PendingSelection[1]] if !ok { return false } if c1.Id == c2.Id { if c1.Name == c2.Name { t.Shown[t.PendingSelection[0]] = c1 t.Shown[t.PendingSelection[1]] = c2 return true } } t.History = append(t.History, t.PendingSelection) t.PendingSelection = [2]int{-1, -1} t.Lives = t.Lives - 1 return false } 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 _, k := range t.CardKeys() { piece := "[???]" 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 }