diff --git a/game/score.go b/game/score.go new file mode 100644 index 0000000..ac00af7 --- /dev/null +++ b/game/score.go @@ -0,0 +1,33 @@ +package game + +// SCORE_MAX is the highest allowed score (7 digits, 9,999,999). +// Any additions beyond this value are clamped. +const SCORE_MAX Score = 9999999 + +// Score is a running total of points earned. +// It’s a distinct type (over uint32) to prevent mixing raw integers with scores. +type Score uint32 + +// Lines adds points for clearing a number of lines at once. +// +// The formula used is: s = L^2 * 100 (where L is the number of lines cleared) +// That yields the following values: +// +// L=0 => 0 +// L=1 => 100 +// L=2 => 400 +// L=3 => 900 +// L=4 => 1600 +// +// Note: `lines` is a byte (0..255). Even at 255 the delta (255^2*100=6,502,500) +// fits comfortably in uint32 and is then clamped against SCORE_MAX on add. +func (s *Score) Lines(lines byte) { + L := uint32(lines) + s.Add(L * L * 100) +} + +// Add increases the score by num and clamps the result to SCORE_MAX. +// No effect if the score is already at SCORE_MAX +func (s *Score) Add(num uint32) { + *s = min(*s+Score(num), SCORE_MAX) +}