Skip to content

Instantly share code, notes, and snippets.

@bunker-inspector
Created December 2, 2019 00:02
Show Gist options
  • Save bunker-inspector/2ba75aaa6da15889a887a5eb3b7e2b0f to your computer and use it in GitHub Desktop.
Save bunker-inspector/2ba75aaa6da15889a887a5eb3b7e2b0f to your computer and use it in GitHub Desktop.
Slackbot functions I wrote at Streamlabs for setting up games of "Secret Hitler" since we could never do it correctly.
package mugman
import (
"bytes"
"fmt"
slackbot "github.com/BeepBoopHQ/go-slackbot"
"github.com/nlopes/slack"
"math/rand"
"strings"
"time"
"unicode"
)
type Party int
const (
LIBERAL Party = iota
FASCIST
)
type Player struct {
Party Party
IsHitler bool
Channel string
User string
}
var players map[string]Player = make(map[string]Player)
var game_started bool = false
var sh_start_channel string = ""
func GetJoinResponse(evt *slack.MessageEvent) string {
if sh_start_channel == "" {
return "Game not started. Say !restart in a channel to start"
}
joining := evt.User
if sh_start_channel == evt.Channel {
return "DM me"
}
num_players := len(players)
if num_players >= 10 {
return "There are already 10 players. Say !start to start"
}
_, ok := players[joining]
if ok {
return fmt.Sprintf("<@%s> is already playing. %d players.", joining, num_players)
} else {
players[joining] = Player{Channel: evt.Channel, User: evt.User}
}
evt.Channel = sh_start_channel
return fmt.Sprintf("<@%s> joined. %d players.", joining, num_players+1)
}
func GetLiberals(num_players int) []Player {
var to_create int
if num_players == 10 {
to_create = 6
} else if num_players >= 8 {
to_create = 5
} else {
to_create = 4
}
var libs []Player
for i := 0; i < to_create; i++ {
libs = append(libs, Player{Party: LIBERAL, IsHitler: false})
}
return libs
}
func GetFascists(num_players int) []Player {
var to_create int
if num_players >= 9 {
to_create = 3
} else {
to_create = 2
}
var facs []Player
facs = append(facs, Player{Party: FASCIST, IsHitler: true})
for i := 0; i < to_create; i++ {
facs = append(facs, Player{Party: FASCIST, IsHitler: false})
}
return facs
}
func GameStart(bot *slackbot.Bot, evt *slack.MessageEvent) string {
num_players := len(players)
if num_players < 7 {
return "You need at least 7 players to begin"
}
facs := GetFascists(num_players)
libs := GetLiberals(num_players)
all_roles := append(libs, facs...)
var roles_randomized []Player
rand.Seed(time.Now().UTC().UnixNano())
for _, i := range rand.Perm(len(all_roles)) {
roles_randomized = append(roles_randomized, all_roles[i])
}
var facs_users []Player
var libs_users []Player
var hitler Player
i := 0
for k := range players {
assigned_role := roles_randomized[i]
assigned_role.Channel = players[k].Channel
assigned_role.User = players[k].User
players[k] = assigned_role
if assigned_role.Party == FASCIST {
if assigned_role.IsHitler {
hitler = assigned_role
} else {
facs_users = append(facs_users, assigned_role)
}
} else {
libs_users = append(libs_users, assigned_role)
}
i++
}
var buffer bytes.Buffer
for user := range facs_users {
buffer.WriteString(fmt.Sprintf("<@%s> ", facs_users[user].User))
}
fasc_user_list := buffer.String()
for user := range facs_users {
evt.Channel = facs_users[user].Channel
bot.Reply(
evt,
fmt.Sprintf("You are a fascist. The fascists are %s . <@%s> is Hitler.", fasc_user_list, hitler.User),
slackbot.WithoutTyping,
)
}
for user := range libs_users {
evt.Channel = libs_users[user].Channel
bot.Reply(evt, "You are a liberal", slackbot.WithoutTyping)
}
evt.Channel = hitler.Channel
bot.Reply(evt, "You are hitler", slackbot.WithoutTyping)
evt.Channel = sh_start_channel
game_started = true
return "The game has begun. You should have received your roles"
}
func TrimWhiteSpace(s string) string {
return strings.Map(func(r rune) rune {
if unicode.IsSpace(r) {
return -1
}
return r
}, s)
}
func GetInspectResponse(bot *slackbot.Bot, evt *slack.MessageEvent) string {
if !game_started {
return "The game has not started. There is noone to inspect"
}
target := strings.Replace(strings.Replace(TrimWhiteSpace(strings.Split(evt.Text, " ")[1]), "<@", "", 1), ">", "", 1)
if target == evt.User {
return "You can't inspect yourself..."
}
_, ok := players[target]
if !ok {
return "That player is not in the game"
}
var target_party string
if players[target].Party == LIBERAL {
target_party = "Liberal"
} else {
target_party = "Fascist"
}
evt.Channel = players[evt.User].Channel
bot.Reply(evt, fmt.Sprintf("<@%s> is a %s", target, target_party), slackbot.WithoutTyping)
evt.Channel = sh_start_channel
return fmt.Sprintf("<@%s> inspected <@%s>", evt.User, target)
}
func GameEnd(evt *slack.MessageEvent) {
players = make(map[string]Player)
game_started = false
sh_start_channel = evt.Channel
}
func GameRestart(evt *slack.MessageEvent) string {
GameEnd(evt)
return "The game has been restarted in this channel. DM me `!join` to play"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment