From 6139db889dd3ab98611ac683c5eaa42ad15d4b3a Mon Sep 17 00:00:00 2001 From: Ryan Cavicchioni Date: Thu, 15 Sep 2022 09:32:37 -0500 Subject: [PATCH] Refactor RPS/RPSLS --- bot/rps.go | 58 ++++++++-------------------------------------- bot/rpsls.go | 58 ++++++++-------------------------------------- lib/rand.go | 6 +++++ lib/rps/rps.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 97 deletions(-) create mode 100644 lib/rps/rps.go diff --git a/bot/rps.go b/bot/rps.go index 2524ce7..9ce5deb 100644 --- a/bot/rps.go +++ b/bot/rps.go @@ -5,43 +5,14 @@ import ( "strings" "git.kill0.net/chill9/beepboop/lib" + "git.kill0.net/chill9/beepboop/lib/rps" "github.com/bwmarrin/discordgo" ) -const ( - Rock = iota - Paper - Scissors - Lizard - Spock -) - -var ( - rpsVictoryMap map[int][]int = map[int][]int{ - Rock: {Scissors}, - Paper: {Rock}, - Scissors: {Paper}, - } - - rpsChoiceMap map[string]int = map[string]int{ - "rock": Rock, - "paper": Paper, - "scissors": Scissors, - } - - rpsEmojiMap map[int]string = map[int]string{ - Rock: "🪨️", - Paper: "📝", - Scissors: "✂️", - } -) - func (b *Bot) RpsCommand() CommandFunc { return func(args []string, m *discordgo.MessageCreate) error { var ( - bc, pc int - be, pe string - c string + bc, pc, be, pe string ) if len(args) != 1 { @@ -51,33 +22,22 @@ func (b *Bot) RpsCommand() CommandFunc { return nil } - c = strings.ToLower(args[0]) + pc = strings.ToLower(args[0]) - pc, ok := rpsChoiceMap[c] // player's choice + _, ok := rps.EmojiMapRps[pc] // player's choice if !ok { b.Session.ChannelMessageSend( m.ChannelID, "help: `!rps (rock | paper | scissors)`", ) - } - - bc = lib.MapRand(rpsChoiceMap) // bot's choice - pe = rpsEmojiMap[pc] // player's emoji - be = rpsEmojiMap[bc] // bot's emoji - - if bc == pc { - b.Session.ChannelMessageSend(m.ChannelID, fmt.Sprintf( - "%s v %s: draw", be, pe, - )) - return nil - } else if lib.Contains(rpsVictoryMap[bc], pc) { - b.Session.ChannelMessageSend(m.ChannelID, fmt.Sprintf( - "%s v %s: %s wins", be, pe, lib.MapKey(rpsChoiceMap, bc), - )) return nil } + bc = lib.MapRandKey(rps.EmojiMapRps) // bot's choice + pe = rps.EmojiMapRps[pc] // player's emoji + be = rps.EmojiMapRps[bc] // bot's emoji + b.Session.ChannelMessageSend(m.ChannelID, fmt.Sprintf( - "%s v %s: %s wins", be, pe, lib.MapKey(rpsChoiceMap, pc), + "%s v %s: %s", pe, be, rps.Play(rps.RulesRps, bc, pc), )) return nil } diff --git a/bot/rpsls.go b/bot/rpsls.go index 5c3bc09..a0e244f 100644 --- a/bot/rpsls.go +++ b/bot/rpsls.go @@ -5,77 +5,39 @@ import ( "strings" "git.kill0.net/chill9/beepboop/lib" + "git.kill0.net/chill9/beepboop/lib/rps" "github.com/bwmarrin/discordgo" ) -var ( - rpslsVictoryMap map[int][]int = map[int][]int{ - Rock: {Scissors, Lizard}, - Paper: {Rock, Spock}, - Scissors: {Paper, Lizard}, - Lizard: {Paper, Spock}, - Spock: {Scissors, Rock}, - } - - rpslsChoiceMap map[string]int = map[string]int{ - "rock": Rock, - "paper": Paper, - "scissors": Scissors, - "lizard": Lizard, - "spock": Spock, - } - - rpslsEmojiMap map[int]string = map[int]string{ - Rock: "🪨️", - Paper: "📝", - Scissors: "✂️", - Lizard: "🦎", - Spock: "🖖", - } -) - func (b *Bot) RpslsCommand() CommandFunc { return func(args []string, m *discordgo.MessageCreate) error { var ( - bc, pc int - be, pe string - c string + bc, pc, be, pe string ) if len(args) != 1 { b.Session.ChannelMessageSend( - m.ChannelID, "help: `!rpsls (rock | paper | scissors | lizard | spock )`", + m.ChannelID, "help: `!rpsls (rock | paper | scissors | lizard | spock)`", ) return nil } - c = strings.ToLower(args[0]) + pc = strings.ToLower(args[0]) - pc, ok := rpslsChoiceMap[c] // player's choice + _, ok := rps.EmojiMapRpsls[pc] // player's choice if !ok { b.Session.ChannelMessageSend( m.ChannelID, "help: `!rpsls (rock | paper | scissors | lizard | spock)`", ) - } - - bc = lib.MapRand(rpslsChoiceMap) // bot's choice - pe = rpslsEmojiMap[pc] // player's emoji - be = rpslsEmojiMap[bc] // bot's emoji - - if bc == pc { - b.Session.ChannelMessageSend(m.ChannelID, fmt.Sprintf( - "%s v %s: draw", be, pe, - )) - return nil - } else if lib.Contains(rpslsVictoryMap[bc], pc) { - b.Session.ChannelMessageSend(m.ChannelID, fmt.Sprintf( - "%s v %s: %s wins", be, pe, lib.MapKey(rpslsChoiceMap, bc), - )) return nil } + bc = lib.MapRandKey(rps.EmojiMapRpsls) // bot's choice + pe = rps.EmojiMapRpsls[pc] // player's emoji + be = rps.EmojiMapRpsls[bc] // bot's emoji + b.Session.ChannelMessageSend(m.ChannelID, fmt.Sprintf( - "%s v %s: %s wins", be, pe, lib.MapKey(rpslsChoiceMap, pc), + "%s v %s: %s", pe, be, rps.Play(rps.RulesRpsls, bc, pc), )) return nil } diff --git a/lib/rand.go b/lib/rand.go index c88f55b..5562d26 100644 --- a/lib/rand.go +++ b/lib/rand.go @@ -49,3 +49,9 @@ func MapRand[K comparable, V any](m map[K]V) V { } panic("unreachable") } + +func MapRandKey[K comparable, V any](m map[K]V) K { + keys := MapKeys(m) + n := rand.Intn(len(m)) + return keys[n] +} diff --git a/lib/rps/rps.go b/lib/rps/rps.go new file mode 100644 index 0000000..814d45d --- /dev/null +++ b/lib/rps/rps.go @@ -0,0 +1,62 @@ +package rps + +import ( + "fmt" +) + +type ( + Game struct { + rules [][]string + emojiMap map[string]string + } +) + +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 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 "" +}