main.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. package main
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io/ioutil"
  7. "log"
  8. "net/http"
  9. "os"
  10. "strconv"
  11. "time"
  12. "battlecamp-go/board"
  13. "battlecamp-go/events"
  14. "battlecamp-go/flag"
  15. "battlecamp-go/game"
  16. "battlecamp-go/player"
  17. "battlecamp-go/stomp"
  18. )
  19. func main() {
  20. initLogging()
  21. log.Println("Game bot version 0.1")
  22. flag.ParseFlags()
  23. pu := make(chan *events.PlayerUpdate)
  24. go subscribeToUpdate(pu)
  25. subscribeToGame(pu)
  26. }
  27. func subscribeToGame(pu chan *events.PlayerUpdate) {
  28. sub := stomp.Subscribe("game")
  29. for {
  30. announcement := <-sub
  31. gs := new(events.GameStart)
  32. json.Unmarshal(announcement.Body, &gs)
  33. log.Printf("announcement type: %v ", strconv.FormatInt(gs.GameId, 10))
  34. gameEndChan := make(chan bool)
  35. if "GAME_START" == gs.Type {
  36. go joinGame(gs.GameId, gameEndChan, pu)
  37. } else {
  38. gameEndChan <- true
  39. }
  40. }
  41. }
  42. func subscribeToUpdate(pu chan *events.PlayerUpdate) {
  43. sub := stomp.Subscribe("update")
  44. for {
  45. announcement := <-sub
  46. if "vnd.battlecamp.player" == announcement.ContentType {
  47. p := new(player.Player)
  48. json.Unmarshal(announcement.Body, &p)
  49. playerJoin(p)
  50. } else {
  51. pue := new(events.PlayerUpdate)
  52. json.Unmarshal(announcement.Body, &pue)
  53. pu <- pue
  54. }
  55. }
  56. }
  57. func joinGame(gameId int64, gameEndChan chan bool, pu chan *events.PlayerUpdate) {
  58. //join game
  59. p := &player.Player{
  60. Id: "Zeus",
  61. Color: "#238b02",
  62. Type: 1,
  63. }
  64. players := make([]*player.Player, 5)
  65. //retrieve finish
  66. gameUrl := "http://localhost:8080/games/" + strconv.FormatInt(gameId, 10)
  67. fmt.Println("getGame:>", gameUrl)
  68. resp, _ := http.Get(gameUrl)
  69. g := new(game.Game)
  70. b, _ := ioutil.ReadAll(resp.Body)
  71. json.Unmarshal(b, &g)
  72. boardSummery := g.Board
  73. fmt.Printf("Finish x=%v y=%v\n", boardSummery.Finish.X, boardSummery.Finish.Y)
  74. //join the game
  75. url := "http://localhost:8080/games/" + strconv.FormatInt(gameId, 10) + "/join"
  76. jsonStr, _ := json.Marshal(p)
  77. req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
  78. req.Header.Set("Content-Type", "application/json")
  79. client := &http.Client{}
  80. resp, err := client.Do(req)
  81. if err != nil {
  82. panic(err)
  83. }
  84. v, _ := ioutil.ReadAll(resp.Body)
  85. json.Unmarshal(v, p) //Set my location in the player
  86. fmt.Printf("My start position x %v y %v\n", p.Pos.X, p.Pos.Y)
  87. resp.Body.Close()
  88. //determine to avoind north or south
  89. north := true
  90. if boardSummery.Finish.Y > p.Pos.Y {
  91. north = false
  92. }
  93. for {
  94. select {
  95. case <-gameEndChan:
  96. return
  97. case playerUpdate := <-pu:
  98. if playerUpdate.GameId == gameId {
  99. players = playerUpdate.Players
  100. for _, pup := range players {
  101. if pup.Id == p.Id {
  102. p.Pos.X = pup.Pos.X
  103. p.Pos.Y = pup.Pos.Y
  104. fmt.Printf("Set position to x=%v y=%v\n", pup.Pos.X, pup.Pos.Y)
  105. }
  106. }
  107. }
  108. default:
  109. move(gameId, p, players, boardSummery, north)
  110. time.Sleep(2 * time.Second)
  111. }
  112. }
  113. }
  114. type viewport struct {
  115. x,y,width,height int
  116. Board *board.Board
  117. }
  118. func getViewPort(x, y, width, height int, gameId int64, bs *board.Board) *viewport {
  119. x = max(x, 0)
  120. x = min(x, bs.Width)
  121. y = max(y, 0)
  122. y = min(y, bs.Height)
  123. if x + width > bs.Width {
  124. width = bs.Width - x
  125. }
  126. if y + height > bs.Height {
  127. height = bs.Height - x
  128. }
  129. url := "http://localhost:8080/games/board/" + strconv.FormatInt(gameId, 10) + "?x=" + strconv.Itoa(x) + "&y=" + strconv.Itoa(y) + "&rows=" + strconv.Itoa(width) + "&cols=" + strconv.Itoa(height)
  130. fmt.Println("getViewPort:>", url)
  131. resp, _ := http.Get(url)
  132. board := board.ReadJSON(x, y, resp.Body)
  133. return &viewport{
  134. x:x,
  135. y:y,
  136. width:width,
  137. height:height,
  138. Board:board,
  139. }
  140. }
  141. func (v viewport) Get(x, y int) board.TileType {
  142. fmt.Printf("retrieving from viewport x %v y %v position in viewport x %v y %v", x, y, x-v.x, y-v.y)
  143. return v.Board.Get(x-v.x,y-v.y)
  144. }
  145. const viewPortWidth = 32
  146. const viewPortHeight = 32
  147. func max(a, b int) int {
  148. if a >= b {
  149. return a
  150. }
  151. return b
  152. }
  153. func min(a, b int) int {
  154. if a <= b {
  155. return a
  156. }
  157. return b
  158. }
  159. func move(gameId int64, p *player.Player, players []*player.Player, bs *board.Board, north bool) {
  160. //determine move
  161. viewPortX := p.Pos.X-1
  162. viewPortY := p.Pos.Y-1
  163. if north {
  164. viewPortX = viewPortX-viewPortHeight
  165. }
  166. viewPort := getViewPort(viewPortX, viewPortY, viewPortWidth, viewPortHeight, gameId, bs)
  167. direction := "W"
  168. fmt.Printf("p.Pos.X+1 %v p.Pos.Y %v\n", p.Pos.X+1, p.Pos.Y)
  169. if viewPort.Get(p.Pos.X+1, p.Pos.Y) != board.Rock {
  170. direction = "E"
  171. }
  172. //send move
  173. url := "http://localhost:8080/games/" + strconv.FormatInt(gameId, 10) + "/move/" + p.Id + "/" + direction
  174. fmt.Println("move:>", url)
  175. http.Post(url, "text/plain", nil)
  176. //update x,y
  177. switch direction {
  178. case "N":
  179. p.Pos.Y++
  180. case "E":
  181. p.Pos.X++
  182. case "S":
  183. p.Pos.Y--
  184. case "W":
  185. p.Pos.Y++
  186. }
  187. fmt.Printf("new pos x=%v y=%v\n", p.Pos.X, p.Pos.Y)
  188. }
  189. func playerJoin(p *player.Player) {
  190. }
  191. func initLogging() {
  192. logFile, err := os.Create("server.log")
  193. if err == nil {
  194. log.SetOutput(logFile)
  195. } else {
  196. log.Println("ERROR: Cannot open log file, using console.")
  197. log.Printf("%v=n", err)
  198. }
  199. }