2017-10-31 10:22:36 +00:00
|
|
|
package rpgORdie
|
|
|
|
|
|
|
|
import (
|
2017-11-02 20:32:02 +00:00
|
|
|
"fmt"
|
2017-10-31 10:22:36 +00:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/velour/catbase/bot"
|
|
|
|
"github.com/velour/catbase/bot/msg"
|
|
|
|
)
|
|
|
|
|
2017-11-02 20:32:02 +00:00
|
|
|
const (
|
|
|
|
DUDE = ":lion_face:"
|
|
|
|
BOULDER = ":full_moon:"
|
|
|
|
HOLE = ":new_moon:"
|
|
|
|
EMPTY = ":white_large_square:"
|
|
|
|
|
|
|
|
OK = iota
|
|
|
|
INVALID = iota
|
|
|
|
WIN = iota
|
|
|
|
)
|
|
|
|
|
2017-10-31 10:22:36 +00:00
|
|
|
type RPGPlugin struct {
|
2017-11-02 20:32:02 +00:00
|
|
|
Bot bot.Bot
|
|
|
|
listenFor map[string]*board
|
2017-10-31 10:22:36 +00:00
|
|
|
}
|
|
|
|
|
2017-11-02 20:32:02 +00:00
|
|
|
type board struct {
|
|
|
|
state [][]string
|
|
|
|
x, y int
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewRandomBoard() *board {
|
|
|
|
boardSize := 5
|
|
|
|
b := board{
|
|
|
|
state: make([][]string, boardSize),
|
|
|
|
x: boardSize - 1,
|
|
|
|
y: boardSize - 1,
|
|
|
|
}
|
|
|
|
for i := 0; i < boardSize; i++ {
|
|
|
|
b.state[i] = make([]string, boardSize)
|
|
|
|
for j := 0; j < boardSize; j++ {
|
|
|
|
b.state[i][j] = ":white_large_square:"
|
|
|
|
}
|
2017-10-31 10:22:36 +00:00
|
|
|
}
|
2017-11-02 20:32:02 +00:00
|
|
|
|
|
|
|
b.state[boardSize-1][boardSize-1] = DUDE
|
|
|
|
b.state[boardSize/2][boardSize/2] = BOULDER
|
|
|
|
b.state[0][0] = HOLE
|
|
|
|
|
|
|
|
return &b
|
2017-10-31 10:22:36 +00:00
|
|
|
}
|
|
|
|
|
2017-11-02 20:32:02 +00:00
|
|
|
func (b *board) toMessageString() string {
|
|
|
|
lines := make([]string, len(b.state))
|
|
|
|
for i := 0; i < len(b.state); i++ {
|
|
|
|
lines[i] = strings.Join(b.state[i], "")
|
|
|
|
}
|
|
|
|
return strings.Join(lines, "\n")
|
|
|
|
}
|
2017-10-31 10:22:36 +00:00
|
|
|
|
2017-11-02 20:32:02 +00:00
|
|
|
func (b *board) checkAndMove(dx, dy int) int {
|
|
|
|
newX := b.x + dx
|
|
|
|
newY := b.y + dy
|
2017-10-31 18:14:45 +00:00
|
|
|
|
2017-11-02 20:32:02 +00:00
|
|
|
if newX < 0 || newY < 0 || newX >= len(b.state) || newY >= len(b.state) {
|
|
|
|
return INVALID
|
|
|
|
}
|
2017-10-31 10:22:36 +00:00
|
|
|
|
2017-11-02 20:32:02 +00:00
|
|
|
if b.state[newY][newX] == HOLE {
|
|
|
|
return INVALID
|
|
|
|
}
|
|
|
|
|
|
|
|
win := false
|
|
|
|
if b.state[newY][newX] == BOULDER {
|
|
|
|
newBoulderX := newX + dx
|
|
|
|
newBoulderY := newY + dy
|
|
|
|
|
|
|
|
if newBoulderX < 0 || newBoulderY < 0 || newBoulderX >= len(b.state) || newBoulderY >= len(b.state) {
|
|
|
|
return INVALID
|
|
|
|
}
|
|
|
|
|
|
|
|
if b.state[newBoulderY][newBoulderX] != HOLE {
|
|
|
|
b.state[newBoulderY][newBoulderX] = BOULDER
|
|
|
|
} else {
|
|
|
|
win = true
|
2017-10-31 10:22:36 +00:00
|
|
|
}
|
2017-11-02 20:32:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
b.state[newY][newX] = DUDE
|
|
|
|
b.state[b.y][b.x] = EMPTY
|
|
|
|
b.x = newX
|
|
|
|
b.y = newY
|
|
|
|
|
|
|
|
if win {
|
|
|
|
return WIN
|
|
|
|
}
|
|
|
|
return OK
|
|
|
|
}
|
|
|
|
|
|
|
|
func New(b bot.Bot) *RPGPlugin {
|
2019-02-05 19:41:38 +00:00
|
|
|
rpg := &RPGPlugin{
|
2017-11-02 20:32:02 +00:00
|
|
|
Bot: b,
|
|
|
|
listenFor: map[string]*board{},
|
|
|
|
}
|
2019-02-05 19:41:38 +00:00
|
|
|
b.Register(rpg, bot.Message, rpg.message)
|
|
|
|
b.Register(rpg, bot.Reply, rpg.replyMessage)
|
|
|
|
b.Register(rpg, bot.Help, rpg.help)
|
|
|
|
return rpg
|
2017-11-02 20:32:02 +00:00
|
|
|
}
|
2017-10-31 14:07:20 +00:00
|
|
|
|
2019-02-05 19:41:38 +00:00
|
|
|
func (p *RPGPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
|
2017-11-02 20:32:02 +00:00
|
|
|
if strings.ToLower(message.Body) == "start rpg" {
|
|
|
|
b := NewRandomBoard()
|
2019-02-05 18:33:18 +00:00
|
|
|
ts, _ := p.Bot.Send(bot.Message, message.Channel, b.toMessageString())
|
2017-11-02 20:32:02 +00:00
|
|
|
p.listenFor[ts] = b
|
2019-02-05 15:54:13 +00:00
|
|
|
p.Bot.Send(bot.Reply, message.Channel, "Over here.", ts)
|
2017-10-31 18:14:45 +00:00
|
|
|
return true
|
2017-10-31 10:22:36 +00:00
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2019-02-05 19:41:38 +00:00
|
|
|
func (p *RPGPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
|
|
|
|
p.Bot.Send(bot.Message, message.Channel, "Go find a walkthrough or something.")
|
|
|
|
return true
|
2017-10-31 10:22:36 +00:00
|
|
|
}
|
|
|
|
|
2019-02-05 19:41:38 +00:00
|
|
|
func (p *RPGPlugin) replyMessage(kind bot.Kind, message msg.Message, args ...interface{}) bool {
|
|
|
|
identifier := args[0].(string)
|
2019-01-22 00:16:57 +00:00
|
|
|
if strings.ToLower(message.User.Name) != strings.ToLower(p.Bot.Config().Get("Nick", "bot")) {
|
2017-11-02 20:32:02 +00:00
|
|
|
if b, ok := p.listenFor[identifier]; ok {
|
|
|
|
|
|
|
|
var res int
|
|
|
|
|
|
|
|
if message.Body == "left" {
|
|
|
|
res = b.checkAndMove(-1, 0)
|
|
|
|
} else if message.Body == "right" {
|
|
|
|
res = b.checkAndMove(1, 0)
|
|
|
|
} else if message.Body == "up" {
|
|
|
|
res = b.checkAndMove(0, -1)
|
|
|
|
} else if message.Body == "down" {
|
|
|
|
res = b.checkAndMove(0, 1)
|
|
|
|
} else {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
switch res {
|
|
|
|
case OK:
|
2019-02-05 15:54:13 +00:00
|
|
|
p.Bot.Send(bot.Edit, message.Channel, b.toMessageString(), identifier)
|
2017-11-02 20:32:02 +00:00
|
|
|
case WIN:
|
2019-02-05 15:54:13 +00:00
|
|
|
p.Bot.Send(bot.Edit, message.Channel, b.toMessageString(), identifier)
|
|
|
|
p.Bot.Send(bot.Reply, message.Channel, "congratulations, you beat the easiest level imaginable.", identifier)
|
2017-11-02 20:32:02 +00:00
|
|
|
case INVALID:
|
2019-02-05 15:54:13 +00:00
|
|
|
p.Bot.Send(bot.Reply, message.Channel, fmt.Sprintf("you can't move %s", message.Body), identifier)
|
2017-11-02 20:32:02 +00:00
|
|
|
}
|
2017-10-31 18:14:45 +00:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|