|
|
@@ -26,8 +26,8 @@ type req struct {
|
|
|
}
|
|
|
|
|
|
type response struct {
|
|
|
- boardTile io.ReadCloser
|
|
|
- x, y int
|
|
|
+ boardTile io.ReadCloser
|
|
|
+ x, y, width, height int
|
|
|
}
|
|
|
|
|
|
const maxIceWidth = 26
|
|
|
@@ -43,69 +43,80 @@ func NewPartial(startX, startY, width, height, totalWidth, totalHeight int) *Boa
|
|
|
}
|
|
|
|
|
|
func NewRemote(width, height int) *Board {
|
|
|
- b := &Board{
|
|
|
- Width: width,
|
|
|
- Height: height,
|
|
|
- data: make([]byte, (width*height)/4+1),
|
|
|
- }
|
|
|
+ b := newBlank(width, height)
|
|
|
|
|
|
log.Printf("Start creating board %v x %v", width, height)
|
|
|
|
|
|
regionWidth := 16
|
|
|
regionHeight := 16
|
|
|
|
|
|
- regionWidthNum := width / regionWidth
|
|
|
- regionHeightNum := height / regionHeight
|
|
|
+ regionWidthNum := (width + (regionWidth - 1)) / regionWidth
|
|
|
+ regionHeightNum := (height + (regionHeight - 1)) / regionHeight
|
|
|
|
|
|
returnChan := make(chan response)
|
|
|
|
|
|
for i := 0; i < regionWidthNum; i++ {
|
|
|
for j := 0; j < regionHeightNum; j++ {
|
|
|
+ var partialWidth, partialHeight int
|
|
|
x := i * regionWidth
|
|
|
y := j * regionHeight
|
|
|
|
|
|
+ if x+regionWidth > b.Width {
|
|
|
+ partialWidth = b.Width - x
|
|
|
+ } else {
|
|
|
+ partialWidth = regionWidth
|
|
|
+ }
|
|
|
+
|
|
|
+ if y+regionHeight > b.Height {
|
|
|
+ partialHeight = b.Height - y
|
|
|
+ } else {
|
|
|
+ partialHeight = regionHeight
|
|
|
+ }
|
|
|
+
|
|
|
region := req{
|
|
|
x: x,
|
|
|
y: y,
|
|
|
- width: regionWidth,
|
|
|
- height: regionHeight,
|
|
|
+ width: partialWidth,
|
|
|
+ height: partialHeight,
|
|
|
}
|
|
|
go b.genRegion(region, returnChan)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
answers := 0
|
|
|
+ for regionWidthNum*regionHeightNum > answers {
|
|
|
|
|
|
- for answers < regionWidthNum*regionHeightNum {
|
|
|
result := <-returnChan
|
|
|
|
|
|
- fmt.Printf("Received partial: x=%v, y=%v", result.x, result.y)
|
|
|
- for ry := 0; ry < regionHeight; ry++ {
|
|
|
- index := result.x + (result.y+ry)*b.Width
|
|
|
- fmt.Printf("index=%v\n", index)
|
|
|
- i := index / 4 // tiles per byte
|
|
|
- result.boardTile.Read(b.data[i:i+regionWidth/4])
|
|
|
- for _, v := range b.data[i:i+regionWidth/4] {
|
|
|
+ fmt.Printf("Received partial: x=%v, y=%v, width=%v, height=%v\n", result.x, result.y, result.width, result.height)
|
|
|
+ for ry := 0; ry < result.height; ry++ {
|
|
|
+ i, _ := b.xyToIndex(result.x, result.y + ry)
|
|
|
+ fmt.Printf("index=%v\n", i)
|
|
|
+ result.boardTile.Read(b.data[i : i+byteIndex(result.width)])
|
|
|
+ for _, v := range b.data[i : i+byteIndex(result.width)] {
|
|
|
fmt.Printf("%b ", v)
|
|
|
}
|
|
|
fmt.Println()
|
|
|
-
|
|
|
}
|
|
|
answers++
|
|
|
}
|
|
|
|
|
|
- igloY := rand.Intn(height-2) + 1
|
|
|
-
|
|
|
- b.Set(width-2, igloY, Iglo)
|
|
|
- b.Finish.X = width - 2
|
|
|
- b.Finish.Y = igloY
|
|
|
- b.Set(width-2, igloY-1, Water)
|
|
|
- b.Set(width-2, igloY+1, Water)
|
|
|
+ b.placeIglo()
|
|
|
log.Printf("Finished creating board %v x %v\n", width, height)
|
|
|
|
|
|
return b
|
|
|
}
|
|
|
|
|
|
+func (b *Board) placeIglo() {
|
|
|
+ b.Finish.X = b.Width - 2
|
|
|
+ b.Finish.Y = rand.Intn(b.Height-2) + 1
|
|
|
+ b.Set(b.Finish.X, b.Finish.Y, Iglo)
|
|
|
+ b.Set(b.Finish.X, b.Finish.Y-1, Water)
|
|
|
+ b.Set(b.Finish.X, b.Finish.Y+1, Water)
|
|
|
+ b.Set(b.Finish.X-1, b.Finish.Y, Water)
|
|
|
+ b.Set(b.Finish.X+1, b.Finish.Y, Water)
|
|
|
+}
|
|
|
+
|
|
|
func (b *Board) genRegion(region req, responseChan chan response) {
|
|
|
requestUrl := fmt.Sprintf("http://localhost:8081/?totalWidth=%v&totalHeight=%v&width=%v&height=%v&x=%v&y=%v", b.Width, b.Height, region.width, region.height, region.x, region.y)
|
|
|
log.Printf("Requested generation of tile with url: %v\n", requestUrl)
|
|
|
@@ -114,6 +125,8 @@ func (b *Board) genRegion(region req, responseChan chan response) {
|
|
|
result := response{
|
|
|
x: region.x,
|
|
|
y: region.y,
|
|
|
+ width: region.width,
|
|
|
+ height: region.height,
|
|
|
boardTile: resp.Body,
|
|
|
}
|
|
|
|
|
|
@@ -121,17 +134,26 @@ func (b *Board) genRegion(region req, responseChan chan response) {
|
|
|
}
|
|
|
|
|
|
func (b *Board) Set(x, y int, t TileType) {
|
|
|
- index := uint(y*b.Width + x)
|
|
|
- i := index / 4
|
|
|
- p := index % 4
|
|
|
+ i, p := b.xyToIndex(x, y)
|
|
|
b.data[i] = (b.data[i] & setMask[p]) | byte(t)<<(p<<1)
|
|
|
}
|
|
|
|
|
|
func (b *Board) Get(x, y int) TileType {
|
|
|
- index := y*b.Width + x
|
|
|
+ i, p := b.xyToIndex(x, y)
|
|
|
+ return TileType((b.data[i] & getMask[p]) >> uint(p<<1))
|
|
|
+}
|
|
|
+
|
|
|
+// Returns the index and offset inside the byte.
|
|
|
+func (b *Board) xyToIndex(x, y int) (int, uint) {
|
|
|
+ width := byteIndex(b.Width) * 4
|
|
|
+ index := y*width + x
|
|
|
i := index / 4
|
|
|
p := index % 4
|
|
|
- return TileType((b.data[i] & getMask[p]) >> uint(p<<1))
|
|
|
+ return i, uint(p)
|
|
|
+}
|
|
|
+
|
|
|
+func byteIndex(x int) int {
|
|
|
+ return (x + 3) / 4
|
|
|
}
|
|
|
|
|
|
func (b *Board) WriteData(w io.Writer) {
|
|
|
@@ -173,17 +195,20 @@ func (b *Board) String() string {
|
|
|
return buffer.String()
|
|
|
}
|
|
|
|
|
|
+func newBlank(width, height int) *Board {
|
|
|
+ return &Board{
|
|
|
+ Width: width,
|
|
|
+ Height: height,
|
|
|
+ data: make([]byte, byteIndex(width)*height),
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
func new(width, height int, r *rand.Rand) *Board {
|
|
|
return newPartial(0, 0, width, height, width, height, r)
|
|
|
}
|
|
|
|
|
|
func newPartial(startX, startY, width, height, totalWidth, totalHeight int, r *rand.Rand) *Board {
|
|
|
- b := &Board{
|
|
|
- Width: width,
|
|
|
- Height: height,
|
|
|
- data: make([]byte, (width*height)/4+1),
|
|
|
- }
|
|
|
-
|
|
|
+ b := newBlank(width, height)
|
|
|
leftLimit := (totalWidth-maxIceWidth)/2 - startX
|
|
|
rightLimit := totalWidth/2 + maxIceWidth/2 - startX
|
|
|
mid := totalWidth/2 - startX
|