How to access tile data?
Hi,
this is possibly a dumb question, but I'm not getting it yet :) Let's say I define grid this way:
type Cell struct {
sprite string
}
grid := tile.NewGridOf[Cell](width, height)
When iterating over the grid, like this:
grid.Each(func(point tile.Point, t tile.Tile[Cell]) {
// t.Value() returns an int16 which is 0 in all tiles, no Cell ???
})
Of course I can create another map of cells like this:
cells := make(map[tile.Point]Cell, width*height)
grid.Each(func(point tile.Point, t tile.Tile[Cell]) {
cells[point] = &Cell{"...."}
})
But that way I'd have two grids, the one provided by the tile module and my "shadow" grid holding the cell data (where I'd put things like sprites, properties etc).
What am I doing wrong?
Thanks in advance, Tom
There's a few methods you can use to manipulate the objects associated to a tile Add(), Del() and Range() (see: https://github.com/kelindar/tile/blob/master/grid.go#L369-L391)
Ah, thanks a lot, this works!
Ahm, no it doesn't :(
Here's my test program:
package main
import (
"fmt"
"github.com/kelindar/tile"
)
type Cell struct {
sprite string
}
const (
height int16 = 9
width int16 = 9
)
func main() {
tl := Cell{"topleft"}
tr := Cell{"topright"}
bl := Cell{"bottomleft"}
br := Cell{"bottomright"}
vt := Cell{"vertical"}
h := Cell{"horizontal"}
l := Cell{"lawn"}
matrix := [][]Cell{
{tl, h, h, h, h, h, h, h, tr},
{vt, l, l, l, l, l, l, l, vt},
{vt, l, l, l, l, l, l, l, vt},
{vt, l, l, l, l, l, l, l, vt},
{vt, l, l, l, l, l, l, l, vt},
{vt, l, l, l, l, l, l, l, vt},
{vt, l, l, l, l, l, l, l, vt},
{vt, l, l, l, l, l, l, l, vt},
{bl, h, h, h, h, h, h, h, br},
}
grid := tile.NewGridOf[Cell](width, height)
count := 1
grid.Each(func(point tile.Point, t tile.Tile[Cell]) {
fmt.Printf("Adding cell %d on %d,%d\n", count, point.X, point.Y)
cell := matrix[point.X][point.Y]
t.Add(cell)
count++
})
grid.Each(func(point tile.Point, t tile.Tile[Cell]) {
fmt.Println(point)
t.Range(func(cell Cell) error {
fmt.Printf("Cell pos: %d,%d (%s)\n",
point.X, point.Y, cell.sprite)
return nil
})
})
fmt.Println()
}
So, I create a 2d matrix of Cells and put them into the grid. Then I just iterate over the grid and print every cell on every grid position. Here's the output:
scip@tripod: % go run main.go
Adding cell 1 on 0,0
Adding cell 2 on 1,0
Adding cell 3 on 2,0
Adding cell 4 on 0,1
Adding cell 5 on 1,1
Adding cell 6 on 2,1
Adding cell 7 on 0,2
Adding cell 8 on 1,2
Adding cell 9 on 2,2
Adding cell 10 on 3,0
Adding cell 11 on 4,0
Adding cell 12 on 5,0
Adding cell 13 on 3,1
Adding cell 14 on 4,1
Adding cell 15 on 5,1
Adding cell 16 on 3,2
Adding cell 17 on 4,2
Adding cell 18 on 5,2
Adding cell 19 on 6,0
Adding cell 20 on 7,0
Adding cell 21 on 8,0
Adding cell 22 on 6,1
Adding cell 23 on 7,1
Adding cell 24 on 8,1
Adding cell 25 on 6,2
Adding cell 26 on 7,2
Adding cell 27 on 8,2
Adding cell 28 on 0,3
Adding cell 29 on 1,3
Adding cell 30 on 2,3
Adding cell 31 on 0,4
Adding cell 32 on 1,4
Adding cell 33 on 2,4
Adding cell 34 on 0,5
Adding cell 35 on 1,5
Adding cell 36 on 2,5
Adding cell 37 on 3,3
Adding cell 38 on 4,3
Adding cell 39 on 5,3
Adding cell 40 on 3,4
Adding cell 41 on 4,4
Adding cell 42 on 5,4
Adding cell 43 on 3,5
Adding cell 44 on 4,5
Adding cell 45 on 5,5
Adding cell 46 on 6,3
Adding cell 47 on 7,3
Adding cell 48 on 8,3
Adding cell 49 on 6,4
Adding cell 50 on 7,4
Adding cell 51 on 8,4
Adding cell 52 on 6,5
Adding cell 53 on 7,5
Adding cell 54 on 8,5
Adding cell 55 on 0,6
Adding cell 56 on 1,6
Adding cell 57 on 2,6
Adding cell 58 on 0,7
Adding cell 59 on 1,7
Adding cell 60 on 2,7
Adding cell 61 on 0,8
Adding cell 62 on 1,8
Adding cell 63 on 2,8
Adding cell 64 on 3,6
Adding cell 65 on 4,6
Adding cell 66 on 5,6
Adding cell 67 on 3,7
Adding cell 68 on 4,7
Adding cell 69 on 5,7
Adding cell 70 on 3,8
Adding cell 71 on 4,8
Adding cell 72 on 5,8
Adding cell 73 on 6,6
Adding cell 74 on 7,6
Adding cell 75 on 8,6
Adding cell 76 on 6,7
Adding cell 77 on 7,7
Adding cell 78 on 8,7
Adding cell 79 on 6,8
Adding cell 80 on 7,8
Adding cell 81 on 8,8
0,0
Cell pos: 0,0 (topleft)
1,0
2,0
Cell pos: 2,0 (vertical)
0,1
1,1
2,1
0,2
Cell pos: 0,2 (horizontal)
1,2
2,2
Cell pos: 2,2 (lawn)
3,0
4,0
5,0
Cell pos: 5,0 (vertical)
3,1
4,1
5,1
3,2
4,2
5,2
Cell pos: 5,2 (lawn)
6,0
7,0
Cell pos: 7,0 (vertical)
8,0
Cell pos: 8,0 (bottomleft)
6,1
7,1
8,1
6,2
7,2
Cell pos: 7,2 (lawn)
8,2
Cell pos: 8,2 (horizontal)
0,3
1,3
2,3
0,4
1,4
2,4
0,5
Cell pos: 0,5 (horizontal)
1,5
2,5
Cell pos: 2,5 (lawn)
3,3
4,3
5,3
3,4
4,4
5,4
3,5
4,5
5,5
Cell pos: 5,5 (lawn)
6,3
7,3
8,3
6,4
7,4
8,4
6,5
7,5
Cell pos: 7,5 (lawn)
8,5
Cell pos: 8,5 (horizontal)
0,6
1,6
2,6
0,7
Cell pos: 0,7 (horizontal)
1,7
2,7
Cell pos: 2,7 (lawn)
0,8
Cell pos: 0,8 (topright)
1,8
2,8
Cell pos: 2,8 (vertical)
3,6
4,6
5,6
3,7
4,7
5,7
Cell pos: 5,7 (lawn)
3,8
4,8
5,8
Cell pos: 5,8 (vertical)
6,6
7,6
8,6
6,7
7,7
Cell pos: 7,7 (lawn)
8,7
Cell pos: 8,7 (horizontal)
6,8
7,8
Cell pos: 7,8 (vertical)
8,8
Cell pos: 8,8 (bottomright)
As can be seen, 81 cells have been added successfuly but only a subset could be retrieved (25 cells out of 81). The other grid positions have no cells. I'd expect to be able to retrieve all 81 cells I put into the grid earlier.
PS: and there's a pattern (although I can't see which): it doesn't matter how often the latter loops runs, it's always the same grid positions without a cell. So I suspect, the t.Add(cell) doesn't work right.
Just spent a couple hours debugging the exact same issue. @TLINDEN The pattern that your seeing is that the "state" in each "page" of 3x3 tiles is stored in a map[T]uint8 this map stores the relation of state (T) to tile index in the page. The problem here is that when, like in your case, the state (the map key) is equal(==) between tile.Add() calls, the map fails to store the relation correctly but instead stores only the last tile index with the given state. (offending code)
In your case, every "page" that contains more than one instance of non-unique state like lawn, horizontal or vertical will only store one instance of the relation. That's why you're seeing irregularities in the tile.Range() function. It skips tiles because they have no state.
I solved this by making my state unique (just added a idx value) and now the map stores the relation of state to tile index correctly because each struct is considered a unique key.
@kelindar I believe a fix would be to inverse the relationship of the map from map[T]uint8 to map[uint8]T so identical state can be stored per index if a user wishes so. The only cascading change from this flip would be to potentially change the tile.Del(T) method to something like tile.Del() or tile.Clear() to avoid looping over the map to find if the state is present.
I'm happy to put a fix in if you agree with the solution.