RosettaCodeData/Task/Set-puzzle/Go/set-puzzle.go

75 lines
1.7 KiB
Go

package main
import (
"fmt"
"math/rand"
"time"
)
const (
number = [3]string{"1", "2", "3"}
color = [3]string{"red", "green", "purple"}
shade = [3]string{"solid", "open", "striped"}
shape = [3]string{"oval", "squiggle", "diamond"}
)
type card int
func (c card) String() string {
return fmt.Sprintf("%s %s %s %s",
number[c/27],
color[c/9%3],
shade[c/3%3],
shape[c%3])
}
func main() {
rand.Seed(time.Now().Unix())
game("Basic", 9, 4)
game("Advanced", 12, 6)
}
func game(level string, cards, sets int) {
// create deck
d := make([]card, 81)
for i := range d {
d[i] = card(i)
}
var found [][3]card
for len(found) != sets {
found = found[:0]
// deal
for i := 0; i < cards; i++ {
j := rand.Intn(81 - i)
d[i], d[j] = d[j], d[i]
}
// consider all triplets
for i := 2; i < cards; i++ {
c1 := d[i]
for j := 1; j < i; j++ {
c2 := d[j]
l3:
for _, c3 := range d[:j] {
for f := card(1); f < 81; f *= 3 {
if (c1/f%3 + c2/f%3 + c3/f%3) % 3 != 0 {
continue l3 // not a set
}
}
// it's a set
found = append(found, [3]card{c1, c2, c3})
}
}
}
}
// found the right number
fmt.Printf("%s game. %d cards, %d sets.\n", level, cards, sets)
fmt.Println("Cards:")
for _, c := range d[:cards] {
fmt.Println(" ", c)
}
fmt.Println("Sets:")
for _, s := range found {
fmt.Printf(" %s\n %s\n %s\n",s[0],s[1],s[2])
}
}