package hex import "sort" // Board is the adjacency table of one game board. ids is sorted so lookups // can binary-search it; nbr[i][d] is the index in ids of the neighbour of // ids[i] in direction d, or -1 when the board edge lies that way. // // Boards are generated by scripts/gen_board_data.py and never mutated, so // sharing *Board values is safe. type Board struct { name string ids []string nbr [][6]int qr [][2]int // axial coordinates (q, r) of ids[i], see geom.gno fence []uint8 // fenced hexsides of ids[i]: bit d for direction d (rule 35) obstacles []int // indices of the obstacle hexes (rule 36) // between lists the hex pairs an obstacle lies between for the line of // sight (rule 31), computed by the generator from the printed coordinates // and the obstacle's outline on the board image: {a, b, o} with a < b // indices in ids and o an index in obstacles, sorted by (a, b, o). between [][3]int } // Name returns the board letter, e.g. "A". func (b *Board) Name() string { return b.name } // Size returns the number of hexes. func (b *Board) Size() int { return len(b.ids) } // Index returns the position of id in the sorted id list, or -1. func (b *Board) Index(id string) int { i := sort.SearchStrings(b.ids, id) if i < len(b.ids) && b.ids[i] == id { return i } return -1 } // Has reports whether id is a hex of this board. func (b *Board) Has(id string) bool { return b.Index(id) >= 0 } // Neighbor returns the hex adjacent to id in direction d. ok is false when // id is unknown, d is invalid, or the board edge lies in that direction. func (b *Board) Neighbor(id string, d Dir) (nb string, ok bool) { i := b.Index(id) if i < 0 || !d.Valid() { return "", false } j := b.nbr[i][d] if j < 0 { return "", false } return b.ids[j], true } // Neighbors returns the six neighbours of id in direction order; an empty // string marks the board edge. An unknown id yields six empty strings. func (b *Board) Neighbors(id string) [6]string { var out [6]string i := b.Index(id) if i < 0 { return out } for d, j := range b.nbr[i] { if j >= 0 { out[d] = b.ids[j] } } return out } // Fenced reports whether a fence or hitching post (rule 35) runs along the // hexside of id in direction d, so that moving or staggering across it // costs two delay cards. func (b *Board) Fenced(id string, d Dir) bool { i := b.Index(id) if i < 0 || !d.Valid() || i >= len(b.fence) { return false } return b.fence[i]&(1<