|
|
@@ -1,12 +1,12 @@
|
|
|
package main
|
|
|
|
|
|
import (
|
|
|
- "math"
|
|
|
"bytes"
|
|
|
"encoding/json"
|
|
|
"fmt"
|
|
|
"io/ioutil"
|
|
|
"log"
|
|
|
+ "math"
|
|
|
"net/http"
|
|
|
"os"
|
|
|
"strconv"
|
|
|
@@ -27,22 +27,36 @@ func main() {
|
|
|
flag.ParseFlags()
|
|
|
pu := make(chan *events.PlayerUpdate)
|
|
|
go subscribeToUpdate(pu)
|
|
|
- subscribeToGame(pu)
|
|
|
+ for {
|
|
|
+ subscribeToGame(pu)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
func subscribeToGame(pu chan *events.PlayerUpdate) {
|
|
|
sub := stomp.Subscribe("game")
|
|
|
|
|
|
+ gameEndChannels := make(map[int]*[]chan bool)
|
|
|
+
|
|
|
for {
|
|
|
announcement := <-sub
|
|
|
gs := new(events.GameStart)
|
|
|
json.Unmarshal(announcement.Body, &gs)
|
|
|
- log.Printf("announcement type: %v ", strconv.FormatInt(gs.GameId, 10))
|
|
|
- gameEndChan := make(chan bool)
|
|
|
+ fmt.Printf("announcement type: %v for game %v\n", gs.Type, strconv.FormatInt(gs.GameId, 10))
|
|
|
if "GAME_START" == gs.Type {
|
|
|
- go joinGame(gs.GameId, gameEndChan, pu)
|
|
|
+ names := []string{"Zeus", "Joost", "Henk", "Klaas"}
|
|
|
+ tmp := make([]chan bool, 0, len(names))
|
|
|
+ gameEndChannels[int(gs.GameId)] = &tmp
|
|
|
+ for _, name := range names {
|
|
|
+ gameEndChan := make(chan bool)
|
|
|
+ tmp := append(*gameEndChannels[int(gs.GameId)], gameEndChan)
|
|
|
+ gameEndChannels[int(gs.GameId)] = &tmp
|
|
|
+ go joinGame(gs.GameId, gameEndChan, pu, name)
|
|
|
+ }
|
|
|
} else {
|
|
|
- gameEndChan <- true
|
|
|
+ chans := gameEndChannels[int(gs.GameId)]
|
|
|
+ for _, channel := range *chans {
|
|
|
+ channel <- true
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -64,10 +78,10 @@ func subscribeToUpdate(pu chan *events.PlayerUpdate) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func joinGame(gameId int64, gameEndChan chan bool, pu chan *events.PlayerUpdate) {
|
|
|
+func joinGame(gameId int64, gameEndChan chan bool, pu chan *events.PlayerUpdate, name string) {
|
|
|
//join game
|
|
|
p := &player.Player{
|
|
|
- Id: "Zeus",
|
|
|
+ Id: name,
|
|
|
Color: "#238b02",
|
|
|
Type: 1,
|
|
|
}
|
|
|
@@ -101,30 +115,25 @@ func joinGame(gameId int64, gameEndChan chan bool, pu chan *events.PlayerUpdate)
|
|
|
fmt.Printf("My start position x %v y %v\n", p.Pos.X, p.Pos.Y)
|
|
|
resp.Body.Close()
|
|
|
|
|
|
- //determine to avoind north or south
|
|
|
- north := true
|
|
|
- if boardSummery.Finish.Y > p.Pos.Y {
|
|
|
- north = false
|
|
|
- }
|
|
|
-
|
|
|
for {
|
|
|
select {
|
|
|
case <-gameEndChan:
|
|
|
+ fmt.Println("Game ended returning")
|
|
|
return
|
|
|
case playerUpdate := <-pu:
|
|
|
if playerUpdate.GameId == gameId {
|
|
|
- players = playerUpdate.Players
|
|
|
+ /* players = playerUpdate.Players // TODO fix multi client
|
|
|
for _, pup := range players {
|
|
|
if pup.Id == p.Id {
|
|
|
p.Pos.X = pup.Pos.X
|
|
|
p.Pos.Y = pup.Pos.Y
|
|
|
fmt.Printf("Set position to x=%v y=%v\n", pup.Pos.X, pup.Pos.Y)
|
|
|
}
|
|
|
- }
|
|
|
+ }*/
|
|
|
}
|
|
|
default:
|
|
|
- move(gameId, p, players, boardSummery, north)
|
|
|
- time.Sleep(2 * time.Second)
|
|
|
+ move(gameId, p, players, boardSummery)
|
|
|
+ time.Sleep(100 * time.Millisecond)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -135,17 +144,14 @@ type viewport struct {
|
|
|
}
|
|
|
|
|
|
func getViewPort(x, y, width, height int, gameId int64, bs *board.Board) *viewport {
|
|
|
- x = max(x, 0)
|
|
|
+ x, y, width, height = board.SanitizeViewPort(bs, x, y, width, height)
|
|
|
+
|
|
|
+ /*max(x, 0)
|
|
|
x = min(x, bs.Width)
|
|
|
y = max(y, 0)
|
|
|
- y = min(y, bs.Height)
|
|
|
- if x+width > bs.Width {
|
|
|
- width = bs.Width - x
|
|
|
- }
|
|
|
- if y+height > bs.Height {
|
|
|
- height = bs.Height - x
|
|
|
- }
|
|
|
- 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)
|
|
|
+ y = min(y, bs.Height)*/
|
|
|
+
|
|
|
+ url := "http://localhost:8080/games/board/" + strconv.FormatInt(gameId, 10) + "?x=" + strconv.Itoa(x) + "&y=" + strconv.Itoa(y) + "&rows=" + strconv.Itoa(height) + "&cols=" + strconv.Itoa(width)
|
|
|
fmt.Println("getViewPort:>", url)
|
|
|
resp, _ := http.Get(url)
|
|
|
board := board.ReadJSON(x, y, resp.Body)
|
|
|
@@ -162,8 +168,8 @@ func (v viewport) Get(x, y int) board.TileType {
|
|
|
return v.Board.Get(x-v.x, y-v.y)
|
|
|
}
|
|
|
|
|
|
-const viewPortWidth = 32
|
|
|
-const viewPortHeight = 32
|
|
|
+const viewPortWidth = 1024
|
|
|
+const viewPortHeight = 1024
|
|
|
|
|
|
func max(a, b int) int {
|
|
|
if a >= b {
|
|
|
@@ -179,49 +185,84 @@ func min(a, b int) int {
|
|
|
return b
|
|
|
}
|
|
|
|
|
|
-func move(gameId int64, p *player.Player, players []*player.Player, bs *board.Board, north bool) {
|
|
|
+func move(gameId int64, p *player.Player, players []*player.Player, bs *board.Board) {
|
|
|
+ if bs.Finish.X == p.Pos.X && p.Pos.Y == bs.Finish.Y {
|
|
|
+ fmt.Println("HELP i'm finished stop me!!")
|
|
|
+ time.Sleep(1 * time.Second)
|
|
|
+ return
|
|
|
+ }
|
|
|
//determine move
|
|
|
-
|
|
|
- viewPortX := p.Pos.X - 1
|
|
|
- viewPortY := p.Pos.Y - 1
|
|
|
- if north {
|
|
|
- viewPortX = viewPortX - viewPortHeight
|
|
|
+ viewPortX := 0
|
|
|
+ viewPortY := 0
|
|
|
+ if viewPortHeight <= bs.Height || viewPortWidth <= bs.Width {
|
|
|
+ viewPortX = p.Pos.X - 1
|
|
|
+ viewPortY = p.Pos.Y - viewPortHeight/2
|
|
|
}
|
|
|
-
|
|
|
viewPort := getViewPort(viewPortX, viewPortY, viewPortWidth, viewPortHeight, gameId, bs)
|
|
|
|
|
|
- direction := "W"
|
|
|
+ //fmt.Printf("viewport x=%v y=%v width %v height %v viewport board width %v height %v\n", viewPort.x, viewPort.y, viewPort.width, viewPort.height, viewPort.Board.Width, viewPort.Board.Height)
|
|
|
|
|
|
- fmt.Printf("p.Pos.X+1 %v p.Pos.Y %v\n", p.Pos.X+1, p.Pos.Y)
|
|
|
+ direction := "E"
|
|
|
|
|
|
- if viewPort.Get(p.Pos.X+1, p.Pos.Y) != board.Rock {
|
|
|
- direction = "E"
|
|
|
- }
|
|
|
- var igloY int
|
|
|
- if bs.Finish.Y > viewPort.y {
|
|
|
- //iglo ten noorden van ons
|
|
|
+ igloY := bs.Finish.Y
|
|
|
+ if bs.Finish.Y < viewPort.y {
|
|
|
+ //iglo ten noorden van viewport
|
|
|
+ fmt.Println("iglo boven")
|
|
|
igloY = 0
|
|
|
/*for viewPort.Get(viewPort.x+viewPortWidth, igloY) == board.Rock && igloY <= viewPort.y+viewPortHeight {
|
|
|
igloY++
|
|
|
}*/
|
|
|
- } else if(bs.Finish.Y < viewPort.y+viewPortHeight) {
|
|
|
- //iglo ten zuiden van ons
|
|
|
- igloY = viewPort.Board.Height-1
|
|
|
+ } else if bs.Finish.Y > viewPort.y+viewPort.Board.Height {
|
|
|
+ //iglo ten zuiden van viewport
|
|
|
+ fmt.Println("iglo onder")
|
|
|
+ igloY = viewPort.Board.Height - 1
|
|
|
/*for viewPort.Get(viewPort.x+viewPortWidth, igloY) == board.Rock && igloY >= viewPort.y+viewPortHeight {
|
|
|
igloY--
|
|
|
}*/
|
|
|
- } else {
|
|
|
- igloY = bs.Finish.Y
|
|
|
}
|
|
|
+
|
|
|
igloX := viewPort.Board.Width
|
|
|
- calcDist(igloX, igloY, viewPort)
|
|
|
-
|
|
|
-
|
|
|
+ if viewPort.x < bs.Finish.X && viewPort.x+viewPort.Board.Width > bs.Finish.X {
|
|
|
+ igloX = bs.Finish.X
|
|
|
+ }
|
|
|
+
|
|
|
+ //fmt.Printf("Virtuele iglo geplaast op x %v y %v\n", igloX, igloY)
|
|
|
+
|
|
|
+ dist := calcDist(igloX, igloY, viewPort)
|
|
|
+
|
|
|
+ /*for i := 0;i< viewPort.Board.Height;i++ {
|
|
|
+ for j := 0;j< viewPort.Board.Width;j++ {
|
|
|
+ if(j == p.Pos.X && i == p.Pos.Y) {
|
|
|
+ fmt.Printf("X")
|
|
|
+ }
|
|
|
+ if(j == bs.Finish.X && i == bs.Finish.Y) {
|
|
|
+ fmt.Printf("I")
|
|
|
+ }
|
|
|
+ fmt.Printf("%v ", dist[(i*viewPort.Board.Width)+j])
|
|
|
+ }
|
|
|
+ fmt.Printf("\n")
|
|
|
+ }*/
|
|
|
+
|
|
|
smallestDist := math.MaxInt32
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+ if p.Pos.X+1 < viewPort.width && dist[toIndex(p.Pos.X+1, p.Pos.Y, viewPort.Board.Width)] != 0 {
|
|
|
+ direction = "E"
|
|
|
+ smallestDist = dist[toIndex(p.Pos.X+1, p.Pos.Y, viewPort.Board.Width)]
|
|
|
+ }
|
|
|
+ if p.Pos.X-1 >= 0 && dist[toIndex(p.Pos.X-1, p.Pos.Y, viewPort.Board.Width)] != 0 && smallestDist > dist[toIndex(p.Pos.X-1, p.Pos.Y, viewPort.Board.Width)] {
|
|
|
+ direction = "W"
|
|
|
+ smallestDist = dist[toIndex(p.Pos.X-1, p.Pos.Y, viewPort.Board.Width)]
|
|
|
+ }
|
|
|
+ if p.Pos.Y+1 < viewPort.height && dist[toIndex(p.Pos.X, p.Pos.Y+1, viewPort.Board.Width)] != 0 && smallestDist > dist[toIndex(p.Pos.X, p.Pos.Y+1, viewPort.Board.Width)] {
|
|
|
+ direction = "S"
|
|
|
+ smallestDist = dist[toIndex(p.Pos.X, p.Pos.Y+1, viewPort.Board.Width)]
|
|
|
+ }
|
|
|
+
|
|
|
+ if p.Pos.Y-1 >= 0 && dist[toIndex(p.Pos.X, p.Pos.Y-1, viewPort.Board.Width)] != 0 && smallestDist > dist[toIndex(p.Pos.X, p.Pos.Y-1, viewPort.Board.Width)] {
|
|
|
+ direction = "N"
|
|
|
+ smallestDist = dist[toIndex(p.Pos.X, p.Pos.Y-1, viewPort.Board.Width)]
|
|
|
+ }
|
|
|
+
|
|
|
//send move
|
|
|
url := "http://localhost:8080/games/" + strconv.FormatInt(gameId, 10) + "/move/" + p.Id + "/" + direction
|
|
|
fmt.Println("move:>", url, smallestDist)
|
|
|
@@ -231,82 +272,148 @@ func move(gameId int64, p *player.Player, players []*player.Player, bs *board.Bo
|
|
|
//update x,y
|
|
|
switch direction {
|
|
|
case "N":
|
|
|
- p.Pos.Y++
|
|
|
+ p.Pos.Y--
|
|
|
case "E":
|
|
|
p.Pos.X++
|
|
|
case "S":
|
|
|
- p.Pos.Y--
|
|
|
- case "W":
|
|
|
p.Pos.Y++
|
|
|
+ case "W":
|
|
|
+ p.Pos.X--
|
|
|
}
|
|
|
- fmt.Printf("new pos x=%v y=%v\n", p.Pos.X, p.Pos.Y)
|
|
|
+ //fmt.Printf("new pos x=%v y=%v\n", p.Pos.X, p.Pos.Y)
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
func toXy(index, boardWidth int) (x, y int) {
|
|
|
x = index % boardWidth
|
|
|
- y = (index-x)/boardWidth
|
|
|
- return x,y
|
|
|
+ y = (index - x) / boardWidth
|
|
|
+ return x, y
|
|
|
}
|
|
|
|
|
|
-func toIndex(x,y , boardWidth int) (index int) {
|
|
|
- return y*boardWidth+x
|
|
|
+func toIndex(x, y, boardWidth int) (index int) {
|
|
|
+ return y*boardWidth + x
|
|
|
}
|
|
|
|
|
|
func calcDist(igloX, igloY int, viewPort *viewport) map[int]int {
|
|
|
distance := make(map[int]int)
|
|
|
-
|
|
|
- s := stack{}
|
|
|
+
|
|
|
+ s := NewQueue()
|
|
|
index := toIndex(igloX, igloY, viewPort.Board.Width)
|
|
|
- s.Put(index)
|
|
|
+ s.Push(index)
|
|
|
distance[index] = -1
|
|
|
- for !s.Empty() {
|
|
|
- i := s.Pop()
|
|
|
+ for s.Len() != 0 {
|
|
|
+ i := s.Poll()
|
|
|
x, y := toXy(i, viewPort.Board.Width)
|
|
|
- if(x+1 < viewPort.width) {
|
|
|
+ if x+1 < viewPort.Board.Width {
|
|
|
newI := toIndex(x+1, y, viewPort.Board.Width)
|
|
|
-
|
|
|
- if(distance[newI] == 0 && viewPort.Board.Get(x+1, y) != board.Rock) {
|
|
|
- distance[newI] = distance[toIndex(x, y, viewPort.Board.Width)] + 1
|
|
|
- s.Put(newI)
|
|
|
+ if distance[newI] == 0 && viewPort.Board.Get(x+1, y) != board.Rock {
|
|
|
+ distance[newI] = max(distance[toIndex(x, y, viewPort.Board.Width)], 0) + 1
|
|
|
+ s.Push(newI)
|
|
|
}
|
|
|
}
|
|
|
- if(x-1 > 0) {
|
|
|
+ if x-1 >= 0 {
|
|
|
newI := toIndex(x-1, y, viewPort.Board.Width)
|
|
|
- if(distance[newI] == 0 && viewPort.Board.Get(x+1, y) != board.Rock) {
|
|
|
- distance[newI] = distance[toIndex(x, y, viewPort.Board.Width)] + 1
|
|
|
- s.Put(newI)
|
|
|
+ if distance[newI] == 0 && viewPort.Board.Get(x-1, y) != board.Rock {
|
|
|
+ distance[newI] = max(distance[toIndex(x, y, viewPort.Board.Width)], 0) + 1
|
|
|
+ s.Push(newI)
|
|
|
}
|
|
|
}
|
|
|
- if(y+1 < viewPort.height) {
|
|
|
+ if y+1 < viewPort.Board.Height {
|
|
|
newI := toIndex(x, y+1, viewPort.Board.Width)
|
|
|
- if(distance[newI] == 0 && viewPort.Board.Get(x+1, y) != board.Rock) {
|
|
|
- distance[newI] = distance[toIndex(x, y, viewPort.Board.Width)] + 1
|
|
|
- s.Put(newI)
|
|
|
+ if distance[newI] == 0 && viewPort.Board.Get(x, y+1) != board.Rock {
|
|
|
+ distance[newI] = max(distance[toIndex(x, y, viewPort.Board.Width)], 0) + 1
|
|
|
+ s.Push(newI)
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- if(y-1 > 0) {
|
|
|
+
|
|
|
+ if y-1 >= 0 {
|
|
|
newI := toIndex(x, y-1, viewPort.Board.Width)
|
|
|
- if(distance[newI] == 0 && viewPort.Board.Get(x+1, y) != board.Rock) {
|
|
|
- distance[newI] = distance[toIndex(x, y, viewPort.Board.Width)] + 1
|
|
|
- s.Put(newI)
|
|
|
+ if distance[newI] == 0 && viewPort.Board.Get(x, y-1) != board.Rock {
|
|
|
+ distance[newI] = max(distance[toIndex(x, y, viewPort.Board.Width)], 0) + 1
|
|
|
+ s.Push(newI)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return distance
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
type stack []int
|
|
|
|
|
|
func (s stack) Empty() bool { return len(s) == 0 }
|
|
|
func (s stack) Peek() int { return s[len(s)-1] }
|
|
|
func (s *stack) Put(i int) { (*s) = append((*s), i) }
|
|
|
func (s *stack) Pop() int {
|
|
|
- d := (*s)[len(*s)-1]
|
|
|
- (*s) = (*s)[:len(*s)-1]
|
|
|
- return d
|
|
|
+ d := (*s)[len(*s)-1]
|
|
|
+ (*s) = (*s)[:len(*s)-1]
|
|
|
+ return d
|
|
|
+}
|
|
|
+*/
|
|
|
+
|
|
|
+type queuenode struct {
|
|
|
+ data int
|
|
|
+ next *queuenode
|
|
|
+}
|
|
|
+
|
|
|
+// A go-routine safe FIFO (first in first out) data stucture.
|
|
|
+type Queue struct {
|
|
|
+ head *queuenode
|
|
|
+ tail *queuenode
|
|
|
+ count int
|
|
|
+}
|
|
|
+
|
|
|
+// Creates a new pointer to a new queue.
|
|
|
+func NewQueue() *Queue {
|
|
|
+ q := &Queue{}
|
|
|
+ return q
|
|
|
+}
|
|
|
+
|
|
|
+// Returns the number of elements in the queue (i.e. size/length)
|
|
|
+// go-routine safe.
|
|
|
+func (q *Queue) Len() int {
|
|
|
+ return q.count
|
|
|
+}
|
|
|
+
|
|
|
+// Pushes/inserts a value at the end/tail of the queue.
|
|
|
+// Note: this function does mutate the queue.
|
|
|
+// go-routine safe.
|
|
|
+func (q *Queue) Push(item int) {
|
|
|
+ n := &queuenode{data: item}
|
|
|
+
|
|
|
+ if q.tail == nil {
|
|
|
+ q.tail = n
|
|
|
+ q.head = n
|
|
|
+ } else {
|
|
|
+ q.tail.next = n
|
|
|
+ q.tail = n
|
|
|
+ }
|
|
|
+ q.count++
|
|
|
+}
|
|
|
+
|
|
|
+// Returns the value at the front of the queue.
|
|
|
+// i.e. the oldest value in the queue.
|
|
|
+// Note: this function does mutate the queue.
|
|
|
+// go-routine safe.
|
|
|
+func (q *Queue) Poll() int {
|
|
|
+
|
|
|
+ n := q.head
|
|
|
+ q.head = n.next
|
|
|
+
|
|
|
+ if q.head == nil {
|
|
|
+ q.tail = nil
|
|
|
+ }
|
|
|
+ q.count--
|
|
|
+
|
|
|
+ return n.data
|
|
|
+}
|
|
|
+
|
|
|
+// Returns a read value at the front of the queue.
|
|
|
+// i.e. the oldest value in the queue.
|
|
|
+// Note: this function does NOT mutate the queue.
|
|
|
+// go-routine safe.
|
|
|
+func (q *Queue) Peek() int {
|
|
|
+ n := q.head
|
|
|
+
|
|
|
+ return n.data
|
|
|
}
|
|
|
|
|
|
func playerJoin(p *player.Player) {
|