119 lines
2.3 KiB
Go
119 lines
2.3 KiB
Go
package rps
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"git.kill0.net/chill9/beepboop/lib"
|
|
)
|
|
|
|
type (
|
|
Game struct {
|
|
rules [][]string
|
|
emojiMap map[string]string
|
|
}
|
|
)
|
|
|
|
type InvalidChoiceError struct {
|
|
s string
|
|
}
|
|
|
|
func (e InvalidChoiceError) Error() string {
|
|
return fmt.Sprintf("%q is an invalid choice", e.s)
|
|
}
|
|
|
|
var (
|
|
RulesRps [][]string = [][]string{
|
|
{"rock", "scissors", "crushes"},
|
|
{"paper", "rock", "covers"},
|
|
{"scissors", "paper", "cuts"},
|
|
}
|
|
|
|
EmojiMapRps map[string]string = map[string]string{
|
|
"rock": "🪨️",
|
|
"paper": "📝",
|
|
"scissors": "✂️",
|
|
}
|
|
|
|
RulesRpsls [][]string = [][]string{
|
|
{"rock", "scissors", "crushes"},
|
|
{"rock", "lizard", "crushes"},
|
|
{"paper", "rock", "covers"},
|
|
{"paper", "spock", "disproves"},
|
|
{"scissors", "paper", "cuts"},
|
|
{"scissors", "lizard", "decapitates"},
|
|
{"lizard", "paper", "eats"},
|
|
{"lizard", "spock", "poisons"},
|
|
{"spock", "scissors", "smashes"},
|
|
{"spock", "rock", "vaporizes"},
|
|
}
|
|
|
|
EmojiMapRpsls map[string]string = map[string]string{
|
|
"rock": "🪨️",
|
|
"paper": "📝",
|
|
"scissors": "✂️",
|
|
"lizard": "🦎",
|
|
"spock": "🖖",
|
|
}
|
|
)
|
|
|
|
func NewGame(rules [][]string, emojiMap map[string]string) *Game {
|
|
return &Game{rules: rules, emojiMap: emojiMap}
|
|
}
|
|
|
|
func (g *Game) Rand() string {
|
|
return lib.MapRandKey(g.emojiMap)
|
|
}
|
|
|
|
func (g *Game) Play(c1, c2 string) (string, error) {
|
|
var b strings.Builder
|
|
|
|
if !g.Valid(c1) {
|
|
return "", InvalidChoiceError{s: c1}
|
|
}
|
|
if !g.Valid(c2) {
|
|
return "", InvalidChoiceError{s: c2}
|
|
}
|
|
|
|
fmt.Fprintf(&b, "%s v %s: ", g.emojiMap[c1], g.emojiMap[c2])
|
|
|
|
for _, rule := range g.rules {
|
|
verb := rule[2]
|
|
|
|
if c1 == c2 {
|
|
fmt.Fprintf(&b, "draw")
|
|
return b.String(), nil
|
|
}
|
|
|
|
if c1 == rule[0] && c2 == rule[1] {
|
|
fmt.Fprintf(&b, "%s %s %s", c1, verb, c2)
|
|
return b.String(), nil
|
|
} else if c2 == rule[0] && c1 == rule[1] {
|
|
fmt.Fprintf(&b, "%s %s %s", c2, verb, c1)
|
|
return b.String(), nil
|
|
}
|
|
}
|
|
|
|
return b.String(), nil
|
|
}
|
|
|
|
func (g *Game) Valid(c string) bool {
|
|
_, ok := g.emojiMap[c]
|
|
return ok
|
|
}
|
|
|
|
func Play(rules [][]string, c1, c2 string) string {
|
|
for _, rule := range rules {
|
|
if c1 == c2 {
|
|
return "draw"
|
|
}
|
|
|
|
if c1 == rule[0] && c2 == rule[1] {
|
|
return fmt.Sprintf("%s %s %s", c1, rule[2], c2)
|
|
} else if c2 == rule[0] && c1 == rule[1] {
|
|
return fmt.Sprintf("%s %s %s", c2, rule[2], c1)
|
|
}
|
|
}
|
|
return ""
|
|
}
|