Advertisement
Guest User

Untitled

a guest
May 24th, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 8.39 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "context"
  5.     //"fmt"
  6.     "net/http"
  7.     "strings"
  8.     "gopkg.in/telegram-bot-api.v4"
  9. )
  10.  
  11. var (
  12.     BotToken   = "XXX"
  13.     WebhookURL = "https://525f2cb5.ngrok.io"
  14. )
  15.  
  16. type Bag struct {
  17.     items []string
  18. }
  19.  
  20. type Player struct {
  21.     bag    *Bag
  22.     roomID int
  23. }
  24.  
  25. type Room struct {
  26.     description     string
  27.     quest           string
  28.     items           []string
  29.     nearRooms       map[string]int
  30.     canGo           string
  31.     wellcomeMessage string
  32.     isOpen          bool
  33. }
  34.  
  35. type Game struct {
  36.     player Player
  37.     rooms  []*Room
  38. }
  39.  
  40. type GameBot struct {
  41.     bot         *tgbotapi.BotAPI
  42.     activeGames map[int]*Game
  43. }
  44.  
  45. func NewGameBot() (*GameBot, error) {
  46.     bot, err := tgbotapi.NewBotAPI(BotToken)
  47.     if err != nil {
  48.         return nil, err
  49.     }
  50.  
  51.     _, err = bot.SetWebhook(tgbotapi.NewWebhook(WebhookURL))
  52.     if err != nil {
  53.         return nil, err
  54.     }
  55.     activeGames := make(map[int]*Game)
  56.  
  57.     return &GameBot{bot, activeGames}, nil
  58. }
  59.  
  60.  
  61. func contains(slice []string, word string) (int, bool) {
  62.     for i, w := range slice {
  63.         if w == word {
  64.             return i, true
  65.         }
  66.     }
  67.     return 0, false
  68. }
  69.  
  70. func (t *GameBot) execUpdate(update tgbotapi.Update) {
  71.     user := update.Message.From
  72.     command := update.Message.Text
  73.  
  74.     switch {
  75.     case strings.Contains(command, "/start"):
  76.         t.Start(user, update)
  77.     case strings.Contains(command, "/reset"):
  78.         t.Reset(user, update)
  79.     case strings.Contains(command, "осмотреться"):
  80.         t.LookAround(user, update)
  81.     case strings.Contains(command, "идти"):
  82.         t.Go(command[9:], user, update)
  83.     case strings.Contains(command, "одеть"):
  84.         t.Equip(command[11:], user, update)
  85.     case strings.Contains(command, "взять"):
  86.         t.Take(command[11:], user, update)
  87.     case strings.Contains(command, "применить"):
  88.         t.Apply(command[19:], user, update)
  89.     default:
  90.         t.bot.Send(tgbotapi.NewMessage(
  91.             update.Message.Chat.ID,
  92.             "неизвестная команда",
  93.         ))
  94.     }
  95. }
  96.  
  97. func MakeNewGame() *Game {
  98.     player := Player{nil, 0}
  99.  
  100.     rooms := []*Room{
  101.         {
  102.             "ты находишься на кухне, на столе чай",
  103.             "надо собрать рюкзак и идти в универ",
  104.             []string{},
  105.             map[string]int{
  106.                 "коридор": 1,
  107.             },
  108.             "коридор",
  109.             "кухня, ничего интересного",
  110.             true,
  111.         },
  112.         {
  113.             "ничего интересного",
  114.             "",
  115.             []string{},
  116.             map[string]int{
  117.                 "кухня":   0,
  118.                 "комната": 2,
  119.                 "улица":   3,
  120.             },
  121.             "кухня, комната, улица",
  122.             "ничего интересного",
  123.             true,
  124.         },
  125.         {
  126.             "на столе: ключи, конспекты, на стуле - рюкзак",
  127.             "",
  128.             []string{
  129.                 "ключи",
  130.                 "конспекты",
  131.                 "рюкзак",
  132.             },
  133.             map[string]int{
  134.                 "коридор": 1,
  135.             },
  136.             "коридор",
  137.             "ты в своей комнате",
  138.             true,
  139.         },
  140.         {
  141.             "на улице весна",
  142.             "",
  143.             []string{},
  144.             map[string]int{
  145.                 "домой": 1,
  146.             },
  147.             "домой",
  148.             "на улице весна",
  149.             false,
  150.         },
  151.     }
  152.  
  153.     return &Game{player, rooms}
  154. }
  155.  
  156. func startGameBot(ctx context.Context) error {
  157.     t, err := NewGameBot()
  158.     if err != nil {
  159.         return err
  160.     }
  161.  
  162.     updates := t.bot.ListenForWebhook("/")
  163.  
  164.     go http.ListenAndServe(":8080", nil)
  165.  
  166.     for update := range updates {
  167.         t.execUpdate(update)
  168.     }
  169.     return nil
  170. }
  171.  
  172. func main() {
  173.     err := startGameBot(context.Background())
  174.     if err != nil {
  175.         panic(err)
  176.     }
  177. }
  178. func (t *GameBot) Start(user *tgbotapi.User, update tgbotapi.Update) {
  179.     t.activeGames[user.ID] = MakeNewGame()
  180.     t.bot.Send(tgbotapi.NewMessage(
  181.         update.Message.Chat.ID,
  182.         "добро пожаловать в игру!",
  183.     ))
  184. }
  185.  
  186. func (t *GameBot) Reset(user *tgbotapi.User, update tgbotapi.Update) {
  187.     delete(t.activeGames, user.ID)
  188.     game := MakeNewGame()
  189.     t.activeGames[user.ID] = game
  190.     t.bot.Send(tgbotapi.NewMessage(
  191.         update.Message.Chat.ID,
  192.         "состояние игры сброшено",
  193.     ))
  194. }
  195.  
  196. func (t *GameBot) LookAround(user *tgbotapi.User, update tgbotapi.Update) {
  197.     game := t.activeGames[user.ID]
  198.     room := game.rooms[game.player.roomID]
  199.     answer := room.description
  200.  
  201.     if game.player.bag != nil {
  202.         if strings.Contains(room.quest, "собрать рюкзак и ") {
  203.             room.quest = strings.Replace(room.quest, "собрать рюкзак и ", "", -1)
  204.         } else if strings.Contains(room.quest, "собрать рюкзак и ") {
  205.             room.quest = strings.Replace(room.quest, "собрать рюкзак", "", -1)
  206.         }
  207.     }
  208.  
  209.     if room.quest != "" {
  210.         answer += ", " + room.quest
  211.     }
  212.     answer += "."
  213.     if len(room.nearRooms) > 0 {
  214.         answer += " можно пройти - " + room.canGo
  215.         answer += "."
  216.     }
  217.     t.bot.Send(tgbotapi.NewMessage(
  218.         update.Message.Chat.ID,
  219.         answer,
  220.     ))
  221. }
  222.  
  223. func (t *GameBot) Go(roomName string, user *tgbotapi.User, update tgbotapi.Update) {
  224.     game := t.activeGames[user.ID]
  225.     room := game.rooms[game.player.roomID]
  226.     roomID, ok := room.nearRooms[roomName]
  227.  
  228.     if !ok {
  229.         t.bot.Send(tgbotapi.NewMessage(
  230.             update.Message.Chat.ID,
  231.             "нет пути в "+roomName,
  232.         ))
  233.         return
  234.     }
  235.  
  236.     newRoom := game.rooms[roomID]
  237.     if newRoom.isOpen {
  238.         game.player.roomID = roomID
  239.         answer := newRoom.wellcomeMessage + "."
  240.         if len(newRoom.nearRooms) > 0 {
  241.             answer += " можно пройти - " + newRoom.canGo
  242.             answer += "."
  243.         }
  244.         t.bot.Send(tgbotapi.NewMessage(
  245.             update.Message.Chat.ID,
  246.             answer,
  247.         ))
  248.     } else {
  249.         t.bot.Send(tgbotapi.NewMessage(
  250.             update.Message.Chat.ID,
  251.             "дверь закрыта",
  252.         ))
  253.     }
  254. }
  255.  
  256. func (t *GameBot) Equip(itemName string, user *tgbotapi.User, update tgbotapi.Update) {
  257.     game := t.activeGames[user.ID]
  258.     room := game.rooms[game.player.roomID]
  259.     if itemName == "рюкзак" {
  260.         i, ok := contains(room.items, itemName)
  261.         if ok {
  262.             game.player.bag = new(Bag)
  263.  
  264.         }
  265.         room.items = append(room.items[:i], room.items[i+1:]...)
  266.         room.description = strings.Replace(room.description, ", на стуле - рюкзак", "", -1)
  267.         t.bot.Send(tgbotapi.NewMessage(
  268.             update.Message.Chat.ID,
  269.             "вы одели: "+itemName,
  270.         ))
  271.     }
  272. }
  273.  
  274. func (t *GameBot) Take(itemName string, user *tgbotapi.User, update tgbotapi.Update) {
  275.     game := t.activeGames[user.ID]
  276.     room := game.rooms[game.player.roomID]
  277.  
  278.     if game.player.bag != nil {
  279.         i, ok := contains(room.items, itemName)
  280.         if ok {
  281.             game.player.bag.items = append(game.player.bag.items, itemName)
  282.         } else {
  283.             t.bot.Send(tgbotapi.NewMessage(
  284.                 update.Message.Chat.ID,
  285.                 "нет такого",
  286.             ))
  287.             return
  288.         }
  289.         room.items = append(room.items[:i], room.items[i+1:]...)
  290.  
  291.         lastIndex := strings.LastIndex(room.description, itemName) + len(itemName)
  292.         if lastIndex < len(room.description) && room.description[lastIndex:lastIndex+1] == "," {
  293.             room.description = strings.Replace(room.description, " "+itemName+",", "", -1)
  294.         } else {
  295.             room.description = strings.Replace(room.description, " "+itemName, "", -1)
  296.         }
  297.  
  298.         if len(room.items) == 0 {
  299.             room.description = "пустая комната"
  300.         }
  301.  
  302.         t.bot.Send(tgbotapi.NewMessage(
  303.             update.Message.Chat.ID,
  304.             "предмет добавлен в инвентарь: "+itemName,
  305.         ))
  306.     } else {
  307.         t.bot.Send(tgbotapi.NewMessage(
  308.             update.Message.Chat.ID,
  309.             "некуда класть",
  310.         ))
  311.     }
  312. }
  313.  
  314. func (t *GameBot) Apply(args string, user *tgbotapi.User, update tgbotapi.Update) {
  315.     game := t.activeGames[user.ID]
  316.     room := game.rooms[game.player.roomID]
  317.  
  318.     ar := strings.Split(args, " ")
  319.  
  320.     ok := false
  321.     if game.player.bag != nil {
  322.         _, ok = contains(game.player.bag.items, ar[0])
  323.     }
  324.     if !ok {
  325.         t.bot.Send(tgbotapi.NewMessage(
  326.             update.Message.Chat.ID,
  327.             "нет предмета в инвентаре - "+ar[0],
  328.         ))
  329.         return
  330.     }
  331.  
  332.     if ar[1] != "дверь" {
  333.         t.bot.Send(tgbotapi.NewMessage(
  334.             update.Message.Chat.ID,
  335.             "не к чему применить",
  336.         ))
  337.         return
  338.     }
  339.     if args == "ключи дверь" {
  340.         // Ищем комнату с дверью
  341.         haveDoor := false
  342.         var closedRoomID int
  343.         for _, roomID := range room.nearRooms {
  344.             if !game.rooms[roomID].isOpen {
  345.                 haveDoor = true
  346.                 closedRoomID = roomID
  347.                 break
  348.             }
  349.         }
  350.         if haveDoor {
  351.             game.rooms[closedRoomID].isOpen = true
  352.  
  353.             t.bot.Send(tgbotapi.NewMessage(
  354.                 update.Message.Chat.ID,
  355.                 "дверь открыта",
  356.             ))
  357.         } else {
  358.             t.bot.Send(tgbotapi.NewMessage(
  359.                 update.Message.Chat.ID,
  360.                 "здесь нет дверей",
  361.             ))
  362.         }
  363.     }
  364. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement