ソースを参照

First kind of working bot, bbq time!

Ronald Peterson 10 年 前
コミット
ea4b1b6611

+ 1 - 1
.gitignore

@@ -5,4 +5,4 @@ battlecamp-go-boardgenerator/battlecamp-go-boardgenerator
 *.log
 *.prof
 battlecamp-go-bot/battlecamp-go-bot
-battlecamp-go-server/battlecamp-go-server
+battlecamp-go-gameserver/battlecamp-go-gameserver

+ 1 - 1
battlecamp-go-boardgenerator/main.go

@@ -44,7 +44,7 @@ func generateBoard(w http.ResponseWriter, r *http.Request) {
 	height, _ := strconv.Atoi(r.FormValue("height"))
 	totalWidth, _ := strconv.Atoi(r.FormValue("totalWidth"))
 	totalHeight, _ := strconv.Atoi(r.FormValue("totalHeight"))
-	//log.Printf("Creating partial x=%v, y=%v, width=%v, height=%v, totalWidth=%v, totalHeight=%v", x, y, width, height, totalWidth, totalHeight)
+	log.Printf("Creating partial x=%v, y=%v, width=%v, height=%v, totalWidth=%v, totalHeight=%v", x, y, width, height, totalWidth, totalHeight)
 	b := board.NewRegion(x, y, width, height, totalWidth, totalHeight)
 	b.WriteData(w)
 }

+ 32 - 4
battlecamp-go-bot/distance_test.go

@@ -8,13 +8,13 @@ import (
 
 func TestDistance(t *testing.T) {
 
-	data := []byte{0x00, 0x00, 0xAA, 0x00,
+	data := []byte{0x00, 0x00, 0x55, 0x00,
 		0x00, 0x00, 0x00, 0x00,
-		0x00, 0xAA, 0xAA, 0xAA,
+		0x00, 0x55, 0x55, 0x55,
 		0x00, 0x00, 0x00, 0x00}
 	b := board.NewPreset(16, 4, data)
 	b.Finish = board.Coordinate{
-		X: 16,
+		X: 15,
 		Y: 0,
 	}
 
@@ -28,7 +28,35 @@ func TestDistance(t *testing.T) {
 	dist := calcDist(b.Finish.X, b.Finish.Y, &viewport)
 	for i := 0;i< b.Height;i++ {
 		for j := 0;j< b.Width;j++ {
-			fmt.Printf("%v ", dist[i*b.Height+j])
+			fmt.Printf("%v ",  dist[(i*b.Width)+j])
+		}
+		fmt.Printf("\n")
+	}
+}
+
+func TestDistance2(t *testing.T) {
+
+	data := []byte{0x00, 0x00, 0x55, 0x00,
+		0x00, 0x00, 0x00, 0x00,
+		0x00, 0x55, 0x55, 0x55,
+		0x00, 0x00, 0x00, 0x00}
+	b := board.NewPreset(16, 4, data)
+	b.Finish = board.Coordinate{
+		X: 10,
+		Y: 1,
+	}
+
+	viewport := viewport{
+		x:      0,
+		y:      0,
+		width:  16,
+		height: 4,
+		Board:  b,
+	}
+	dist := calcDist(b.Finish.X, b.Finish.Y, &viewport)
+	for i := 0;i< b.Height;i++ {
+		for j := 0;j< b.Width;j++ {
+			fmt.Printf("%v ",  dist[(i*b.Width)+j])
 		}
 		fmt.Printf("\n")
 	}

+ 199 - 92
battlecamp-go-bot/main.go

@@ -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) {

+ 2 - 2
battlecamp-go-gameserver/gameserver/gameserver.go

@@ -67,8 +67,8 @@ func serveGames(gameServer GameServer) {
 	}
 }
 
-func (games GameServer) AddGame(x, y int) *game.Game {
-	game := game.NewGame(x, y) // TODO
+func (games GameServer) AddGame(width, height int) *game.Game {
+	game := game.NewGame(width, height) // TODO
 	addGame := addGameChan{
 		game: game,
 		id:   make(chan int64),

+ 14 - 14
battlecamp-go-gameserver/gameserver/urlrouter.go

@@ -57,16 +57,16 @@ func listGames(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
 }
 
 func createGame(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
-	xString := ps.ByName("cols")
-	yString := ps.ByName("rows")
+	widthString := ps.ByName("cols")
+	heightString := ps.ByName("rows")
 	var game *game.Game
 
-	log.Println("Creating new game...")
+	log.Printf("Creating new game %vx%v", widthString, heightString)
 
-	if xString != "" && yString != "" {
-		x, _ := strconv.Atoi(xString)
-		y, _ := strconv.Atoi(yString)
-		game = gameServer.AddGame(x, y)
+	if widthString != "" && heightString != "" {
+		width, _ := strconv.Atoi(widthString)
+		height, _ := strconv.Atoi(heightString)
+		game = gameServer.AddGame(width, height)
 	} else {
 		game = gameServer.AddGame(56, 35)
 	}
@@ -145,19 +145,19 @@ func showBoard(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
 	w.Header().Set("Content-Type", "application/json")
 	xString := req.FormValue("x")
 	yString := req.FormValue("y")
-	colsString := req.FormValue("cols")
-	rowsString := req.FormValue("rows")
+	widthString := req.FormValue("cols")
+	heightString := req.FormValue("rows")
 
 	id, _ := strconv.ParseInt(ps.ByName("boardid"), 10, 64)
 	b := gameServer.GetGame(id).Board
 
-	if xString != "" && yString != "" && colsString != "" && rowsString != "" {
+	if xString != "" && yString != "" && widthString != "" && heightString != "" {
 		x, _ := strconv.Atoi(xString)
 		y, _ := strconv.Atoi(yString)
-		cols, _ := strconv.Atoi(colsString)
-		rows, _ := strconv.Atoi(rowsString)
-		b.WriteJSON(w, x, y, cols, rows)
-	} else if xString != "" || yString != "" || colsString != "" || rowsString != "" {
+		width, _ := strconv.Atoi(widthString)
+		height, _ := strconv.Atoi(heightString)
+		b.WriteJSON(w, x, y, width, height)
+	} else if xString != "" || yString != "" || widthString != "" || heightString != "" {
 		http.Error(w, "Bad request", http.StatusBadRequest)
 	} else {
 		b.WriteJSON(w, 0, 0, b.Width, b.Height)

+ 31 - 29
board/board.go

@@ -152,7 +152,7 @@ func worker(workChan chan *work, responseChan chan *response) {
 		responseChan <- &response{
 			x:         w.x,
 			y:         w.y,
-			width:     partialHeight,
+			width:     partialWidth, //hier zat de bug dat het bord er gaar uit zag
 			height:    partialHeight,
 			boardTile: r,
 		}
@@ -165,7 +165,6 @@ func (b *Board) Set(x, y int, t TileType) {
 }
 
 func (b *Board) Get(x, y int) TileType {
-	fmt.Printf("get x %v y %v boardsize %v", x, y, len(b.data))
 	i, p := b.xyToIndex(x, y)
 	return TileType((b.data[i] & getMask[p]) >> uint(p<<1))
 }
@@ -191,13 +190,15 @@ func (b *Board) WriteData(w io.Writer) {
 	}
 }
 
-func (b *Board) WriteJSON(w io.Writer, startCol, startRow, cols, rows int) {
-	sc, sr, cols, rows := sanitizeViewPort(b, startCol, startRow, cols, rows)
-	fmt.Fprintf(w, "{\"x\":%v,\"y\":%v,\"rows\":%v,\"cols\":%v,\"tiles\":[", sc, sr, cols, rows)
+func (b *Board) WriteJSON(w io.Writer, startWidth, startHeight, width, height int) {
+//	log.Printf("x:%v,y:%v,rows:%v,cols:%v", startWidth, startHeight, height, width)
+	sc, sr, width, height := SanitizeViewPort(b, startWidth, startHeight, width, height)
+//	log.Printf("x:%v,y:%v,rows:%v,cols:%v", sc, sr, height, width)
+	fmt.Fprintf(w, "{\"x\":%v,\"y\":%v,\"rows\":%v,\"cols\":%v,\"tiles\":[", sc, sr, height, width)
 
-	for y := startRow; y < sr+rows; y++ {
-		for x := startCol; x < sc+cols; x++ {
-			if !(x == startCol && y == startRow) {
+	for y := startHeight; y < sr+height; y++ {
+		for x := startWidth; x < sc+width; x++ {
+			if !(x == startWidth && y == startHeight) {
 				w.Write([]byte{','})
 			}
 			t := &jsonTile{x, y, b.Get(x, y).Name(), ""}
@@ -267,7 +268,8 @@ func newRegion(startX, startY, width, height, totalWidth, totalHeight int, r *ra
 	leftLimit := (totalWidth-maxIceWidth)/2 - startX
 	rightLimit := totalWidth/2 + maxIceWidth/2 - startX
 	mid := totalWidth/2 - startX
-
+	
+	log.Printf("Creating new region width %v height %v", width, height)
 	for y := 0; y < height; y++ {
 		for x := 0; x < width; x++ {
 			switch {
@@ -284,34 +286,34 @@ func newRegion(startX, startY, width, height, totalWidth, totalHeight int, r *ra
 	return b
 }
 
-func sanitizeViewPort(b *Board, startCol, startRow, cols, rows int) (int, int, int, int) {
-	if startCol > b.Width {
-		startCol = b.Width
+func SanitizeViewPort(b *Board, startWidth, startHeight, width, height int) (int, int, int, int) {
+	if startWidth > b.Width {
+		startWidth = b.Width
 	}
-	if startCol < 0 {
-		cols += startCol
-		startCol = 0
+	if startWidth < 0 {
+//		width += startWidth
+		startWidth = 0
 	}
-	if startRow > b.Height {
-		startRow = b.Height
+	if startHeight > b.Height {
+		startHeight = b.Height
 	}
-	if startRow < 0 {
-		rows += startRow
-		startRow = 0
+	if startHeight < 0 {
+//		height += startHeight
+		startHeight = 0
 	}
-	if startCol+cols > b.Width {
-		cols = b.Width - startCol
+	if startWidth+width > b.Width {
+		width = b.Width - startWidth
 	}
-	if startRow+rows > b.Height {
-		rows = b.Height - startRow
+	if startHeight+height > b.Height {
+		height = b.Height - startHeight
 	}
-	if cols < 0 {
-		cols = 0
+	if width < 0 {
+		width = 0
 	}
-	if rows < 0 {
-		rows = 0
+	if height < 0 {
+		height = 0
 	}
-	return startCol, startRow, cols, rows
+	return startWidth, startHeight, width, height
 }
 
 func abs(a int) int {

+ 2 - 2
game/game.go

@@ -21,12 +21,12 @@ type Game struct {
 	Winner    *player.Player `json:"winner,omitempty"`
 }
 
-func NewGame(cols, rows int) *Game {
+func NewGame(width, height int) *Game {
 	createTime := time.Now().Unix()
 
 	game := &Game{
 		StartTime: createTime,
-		Board:     board.NewRemote(cols, rows),
+		Board:     board.NewRemote(width, height),
 		Players:   make([]*player.Player, 0),
 	}