// Copyright (c) 2016 Florian Fischer. All rights reserved. // Use of this source code is governed by a MIT license found in the LICENSE file. package logic import ( "fmt" ) var ScoreNames = [13]string{"Aces", "Twos", "Threes", "Fours", "Fives", "Sixes", "ThreeOfAKind", "FourOfAKind", "FullHouse", "SmallStraight", "LargeStraight", "Yahtzee", "Chance"} var ScorePositions = map[string]int{ "Aces": 0, "Twos": 1, "Threes": 3, "Fours": 4, "Fives": 5, "Sixes": 6, "ThreeOfAKind": 6, "FourOfAKind": 7, "FullHouse": 8, "SmallStraight": 9, "LargeStraight": 10, "Yahtzee": 11, "Chance": 12, } type Score []int func NewScore() Score { d := [13]int{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} return d[:] } func (s Score) bonus() int { sum := s[0] + s[1] + s[2] sum += s[3] + s[4] + s[5] if sum >= 63 { return 35 } return 0 } func (s Score) Score() (res int) { for _, v := range s { if v > 0 { res += v } } res += s.bonus() return } func (s Score) String() string { str := "" for i, v := range s { p := "" if v < 0 { p = "" } else { p = fmt.Sprintf("%d", v) } str += fmt.Sprintf("%s: %s\n", ScoreNames[i], p) if i == 5 { str += fmt.Sprintf("Bonus: %d\n\n", s.bonus()) } } str += fmt.Sprintf("Total: %d\n", s.Score()) return str } func (s_ *Score) Insert(d Dice, pos int) (int, error) { s := *s_ if pos < 0 || pos > 12 { return 0, fmt.Errorf("Position %d out of range", pos) } if s[pos] == -1 { switch pos { case 6: if d.IsThreeOfAKind() { s[pos] = d.Sum(0) return s[pos], nil } return 0, fmt.Errorf("%v is not %s", d, ScoreNames[pos]) case 7: if d.IsFourOfAKind() { s[pos] = d.Sum(0) return s[pos], nil } return 0, fmt.Errorf("%v is not %s", d, ScoreNames[pos]) case 8: if d.IsFullHouse() { s[pos] = 25 return 25, nil } return 0, fmt.Errorf("%v is not %s", d, ScoreNames[pos]) case 9: if d.IsSmallStraight() { s[pos] = 30 return 30, nil } return 0, fmt.Errorf("%v is not %s", d, ScoreNames[pos]) case 10: if d.IsLargeStraight() { s[pos] = 40 return 40, nil } return 0, fmt.Errorf("%v is not %s", d, ScoreNames[pos]) case 11: if d.IsYahtzee() { s[pos] = 50 return 50, nil } return 0, fmt.Errorf("%v is not %s", d, ScoreNames[pos]) case 12: s[pos] = d.Sum(0) return s[pos], nil } s[pos] = d.Sum(pos + 1) return s[pos], nil } return 0, fmt.Errorf("%s (%d) is already recorded", ScoreNames[pos], pos+1) } func (s_ *Score) Cancel(pos int) error { s := *s_ if pos < 0 || pos > 12 { return fmt.Errorf("Position %d out of range", pos) } if s[pos] == -1 { s[pos] = 0 return nil } return fmt.Errorf("%s (%d) is already recorded", ScoreNames[pos], pos+1) }