package logic import ( "errors" "fmt" ) type Score struct { values [13]int names [13]string } func NewScore() Score { return Score{values: [13]int{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, names: [13]string{"Aces", "Twos", "Threes", "Fours", "Fives", "Sixes", "ThreeOfAKind", "FourOfAKind", "FullHouse", "SmallStraight", "LargeStraight", "Yahtzee", "Chance"}} } func (s Score) bonus() int { sum := s.values[0] + s.values[1] + s.values[2] sum += s.values[3] + s.values[4] + s.values[5] if sum >= 63 { return 35 } return 0 } func (s Score) Score() (res int) { for _, v := range s.values { if v > 0 { res += v } } res += s.bonus() return } func (s Score) String() string { str := "Score:\n" for i, v := range s.values { p := "" if v < 0 { p = "" } else { p = fmt.Sprintf("%d", v) } str += fmt.Sprintf("%s: %s\n", s.names[i], p) if i == 5 { str += fmt.Sprintf("Bonus: %d\n\n", s.bonus()) } } return str } func (s *Score) Insert(d Dices, pos int) (int, error) { if pos < 0 || pos > 12 { return 0, errors.New("Index out of range") } if s.values[pos] == -1 { switch pos { case 6: if d.IsThreeOfAKind() { s.values[pos] = d.Sum(0) return s.values[pos], nil } return 0, errors.New("Not three of a kind") case 7: if d.IsFourOfAKind() { s.values[pos] = d.Sum(0) return s.values[pos], nil } return 0, errors.New("Not four of a kind") case 8: if d.IsFullHouse() { s.values[pos] = 25 return 25, nil } return 0, errors.New("Not a full house") case 9: if d.IsSmallStraight() { s.values[pos] = 30 return 30, nil } return 0, errors.New("Not a small straight") case 10: if d.IsLargeStraight() { s.values[pos] = 40 return 40, nil } return 0, errors.New("Not a large straight") case 11: if d.IsYahtzee() { s.values[pos] = 50 return 50, nil } return 0, errors.New("Not a yahtzee") case 12: s.values[pos] = d.Sum(0) return s.values[pos], nil } s.values[pos] = d.Sum(pos + 1) return s.values[pos], nil } return 0, errors.New("Already recorded") } func (s *Score) Cancel(pos int) error { if pos < 0 || pos > 12 { return errors.New("Index out of range") } if s.values[pos] == 0 { s.values[pos] = -1 return nil } return errors.New("Already recorded") }