Moved RawMaze to reader package since it is used
mostly there
This commit is contained in:
41
io/reader/raw_maze.go
Normal file
41
io/reader/raw_maze.go
Normal file
@ -0,0 +1,41 @@
|
||||
package reader
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const CHUNK_SIZE = 8 // size of a byte
|
||||
|
||||
type RawMaze struct {
|
||||
Width, Height int
|
||||
Data [][]byte
|
||||
}
|
||||
|
||||
func (m *RawMaze) String() string {
|
||||
var ret strings.Builder
|
||||
ret.WriteString("{\n")
|
||||
ret.WriteString("\tData: \n")
|
||||
for _, line := range m.Data {
|
||||
ret.WriteRune('\t')
|
||||
ret.WriteRune('\t')
|
||||
ret.Write(line) // TODO: prolly should fix this to make it readable
|
||||
ret.WriteRune('\n')
|
||||
}
|
||||
ret.WriteString("}")
|
||||
|
||||
return ret.String()
|
||||
}
|
||||
|
||||
func (m *RawMaze) IsPath(x int, y int) bool {
|
||||
chunk_index := x / CHUNK_SIZE
|
||||
chunk_rest := x % CHUNK_SIZE
|
||||
chunk := m.Data[y][chunk_index]
|
||||
return chunk&(1<<(CHUNK_SIZE-1-chunk_rest)) != 0
|
||||
}
|
||||
|
||||
func (m *RawMaze) IsWall(x int, y int) bool {
|
||||
chunk_index := x / CHUNK_SIZE
|
||||
chunk_rest := x % CHUNK_SIZE
|
||||
chunk := m.Data[y][chunk_index]
|
||||
return chunk&(1<<(CHUNK_SIZE-1-chunk_rest)) == 0
|
||||
}
|
220
io/reader/raw_maze_test.go
Normal file
220
io/reader/raw_maze_test.go
Normal file
@ -0,0 +1,220 @@
|
||||
package reader
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestRawMazeWall(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
width, height int
|
||||
pathChar, wallChar byte
|
||||
data []string
|
||||
expected [][]bool
|
||||
}{
|
||||
{
|
||||
"Trivial",
|
||||
5, 3,
|
||||
' ', '#',
|
||||
[]string{
|
||||
"## ##",
|
||||
"# #",
|
||||
"### #",
|
||||
},
|
||||
[][]bool{
|
||||
{true, true, false, true, true},
|
||||
{true, false, false, false, true},
|
||||
{true, true, true, false, true},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Trivial Bigger",
|
||||
7, 5,
|
||||
' ', '#',
|
||||
[]string{
|
||||
"### ###",
|
||||
"### ###",
|
||||
"# #",
|
||||
"##### #",
|
||||
"##### #",
|
||||
},
|
||||
[][]bool{
|
||||
{true, true, true, false, true, true, true},
|
||||
{true, true, true, false, true, true, true},
|
||||
{true, false, false, false, false, false, true},
|
||||
{true, true, true, true, true, false, true},
|
||||
{true, true, true, true, true, false, true},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Bigger Staggered",
|
||||
7, 5,
|
||||
' ', '#',
|
||||
[]string{
|
||||
"### ###",
|
||||
"### ###",
|
||||
"# #",
|
||||
"#### ##",
|
||||
"#### ##",
|
||||
},
|
||||
[][]bool{
|
||||
{true, true, true, false, true, true, true},
|
||||
{true, true, true, false, true, true, true},
|
||||
{true, false, false, false, false, false, true},
|
||||
{true, true, true, true, false, true, true},
|
||||
{true, true, true, true, false, true, true},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Normal",
|
||||
11, 11,
|
||||
' ', '#',
|
||||
[]string{
|
||||
"##### #####",
|
||||
"# # #",
|
||||
"##### ### #",
|
||||
"# # #",
|
||||
"# # ##### #",
|
||||
"# # #",
|
||||
"### ### # #",
|
||||
"# # # #",
|
||||
"# ####### #",
|
||||
"# # #",
|
||||
"##### #####",
|
||||
},
|
||||
[][]bool{
|
||||
{true, true, true, true, true, false, true, true, true, true, true},
|
||||
{true, false, false, false, false, false, true, false, false, false, true},
|
||||
{true, true, true, true, true, false, true, true, true, false, true},
|
||||
{true, false, false, false, true, false, false, false, false, false, true},
|
||||
{true, false, true, false, true, true, true, true, true, false, true},
|
||||
{true, false, true, false, false, false, false, false, false, false, true},
|
||||
{true, true, true, false, true, true, true, false, true, false, true},
|
||||
{true, false, false, false, true, false, false, false, true, false, true},
|
||||
{true, false, true, true, true, true, true, true, true, false, true},
|
||||
{true, false, false, false, false, false, true, false, false, false, true},
|
||||
{true, true, true, true, true, false, true, true, true, true, true},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
reader := StringsReader{
|
||||
PathChar: test.pathChar,
|
||||
WallChar: test.wallChar,
|
||||
Lines: &test.data,
|
||||
}
|
||||
rawMaze, _ := reader.Read()
|
||||
for y, row := range test.expected {
|
||||
for x, expected := range row {
|
||||
if rawMaze.IsWall(x, y) != expected {
|
||||
t.Fatalf("%s: Wanted wall at (%v, %v), apparently it isn't", test.name, x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawMazePath(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
width, height int
|
||||
data [][]byte
|
||||
expected [][]bool
|
||||
}{
|
||||
{
|
||||
"Trivial",
|
||||
5, 3,
|
||||
[][]byte{
|
||||
{0b_00100_000},
|
||||
{0b_01110_000},
|
||||
{0b_00010_000},
|
||||
},
|
||||
[][]bool{
|
||||
{false, false, true, false, false},
|
||||
{false, true, true, true, false},
|
||||
{false, false, false, true, false},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Trivial Bigger",
|
||||
7, 5,
|
||||
[][]byte{
|
||||
{0b_0001000_0},
|
||||
{0b_0001000_0},
|
||||
{0b_0111110_0},
|
||||
{0b_0000010_0},
|
||||
{0b_0000010_0},
|
||||
},
|
||||
[][]bool{
|
||||
{false, false, false, true, false, false, false},
|
||||
{false, false, false, true, false, false, false},
|
||||
{false, true, true, true, true, true, false},
|
||||
{false, false, false, false, false, true, false},
|
||||
{false, false, false, false, false, true, false},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Bigger Staggered",
|
||||
7, 5,
|
||||
[][]byte{
|
||||
{0b_0001000_0},
|
||||
{0b_0001000_0},
|
||||
{0b_0111110_0},
|
||||
{0b_0000100_0},
|
||||
{0b_0000100_0},
|
||||
},
|
||||
[][]bool{
|
||||
{false, false, false, true, false, false, false},
|
||||
{false, false, false, true, false, false, false},
|
||||
{false, true, true, true, true, true, false},
|
||||
{false, false, false, false, true, false, false},
|
||||
{false, false, false, false, true, false, false},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Normal",
|
||||
11, 11,
|
||||
[][]byte{
|
||||
{0b_00000100, 0b000_00000},
|
||||
{0b_01111101, 0b110_00000},
|
||||
{0b_00000100, 0b010_00000},
|
||||
{0b_01110111, 0b110_00000},
|
||||
{0b_01010000, 0b010_00000},
|
||||
{0b_01011111, 0b110_00000},
|
||||
{0b_00010001, 0b010_00000},
|
||||
{0b_01110111, 0b010_00000},
|
||||
{0b_01000000, 0b010_00000},
|
||||
{0b_01111101, 0b110_00000},
|
||||
{0b_00000100, 0b000_00000},
|
||||
},
|
||||
[][]bool{
|
||||
{false, false, false, false, false, true, false, false, false, false, false},
|
||||
{false, true, true, true, true, true, false, true, true, true, false},
|
||||
{false, false, false, false, false, true, false, false, false, true, false},
|
||||
{false, true, true, true, false, true, true, true, true, true, false},
|
||||
{false, true, false, true, false, false, false, false, false, true, false},
|
||||
{false, true, false, true, true, true, true, true, true, true, false},
|
||||
{false, false, false, true, false, false, false, true, false, true, false},
|
||||
{false, true, true, true, false, true, true, true, false, true, false},
|
||||
{false, true, false, false, false, false, false, false, false, true, false},
|
||||
{false, true, true, true, true, true, false, true, true, true, false},
|
||||
{false, false, false, false, false, true, false, false, false, false, false},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
rawMaze := RawMaze{
|
||||
Width: test.width,
|
||||
Height: test.height,
|
||||
Data: test.data,
|
||||
}
|
||||
|
||||
for y, row := range test.expected {
|
||||
for x, expected := range row {
|
||||
if rawMaze.IsPath(x, y) != expected {
|
||||
t.Fatalf("%s: Wanted path at (%v, %v), apparently it isn't", test.name, x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
package reader
|
||||
|
||||
import "maze-solver/maze"
|
||||
|
||||
type Reader interface {
|
||||
Read() (*maze.RawMaze, error)
|
||||
Read() (*RawMaze, error)
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package reader
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"maze-solver/maze"
|
||||
"maze-solver/utils"
|
||||
)
|
||||
|
||||
@ -11,16 +10,16 @@ type StringsReader struct {
|
||||
Lines *[]string
|
||||
}
|
||||
|
||||
func (r *StringsReader) Read() (*maze.RawMaze, error) {
|
||||
func (r *StringsReader) Read() (*RawMaze, error) {
|
||||
width, height := len((*r.Lines)[0]), len(*r.Lines)
|
||||
ret := &maze.RawMaze{
|
||||
ret := &RawMaze{
|
||||
Width: width,
|
||||
Height: height,
|
||||
Data: make([][]byte, height),
|
||||
}
|
||||
|
||||
for i := 0; i < height; i++ {
|
||||
ret.Data[i] = make([]byte, width/maze.CHUNK_SIZE+1)
|
||||
ret.Data[i] = make([]byte, width/CHUNK_SIZE+1)
|
||||
}
|
||||
|
||||
for y, line := range *r.Lines {
|
||||
@ -31,7 +30,7 @@ func (r *StringsReader) Read() (*maze.RawMaze, error) {
|
||||
}
|
||||
|
||||
func (r *StringsReader) processLine(line string, dest *[]byte) {
|
||||
n_chunks := len(line)/maze.CHUNK_SIZE + 1
|
||||
n_chunks := len(line)/CHUNK_SIZE + 1
|
||||
|
||||
if len(*dest) != n_chunks {
|
||||
panic(fmt.Sprintf("The row that should receive the chunks does not have the correct length (%v, want %v)", len(*dest), n_chunks))
|
||||
@ -40,11 +39,11 @@ func (r *StringsReader) processLine(line string, dest *[]byte) {
|
||||
for i := 0; i < n_chunks; i++ {
|
||||
var chunk byte = 0 // all walls
|
||||
|
||||
end_index := utils.Min((i+1)*maze.CHUNK_SIZE, len(line))
|
||||
end_index := utils.Min((i+1)*CHUNK_SIZE, len(line))
|
||||
|
||||
for x, c := range line[i*maze.CHUNK_SIZE : end_index] {
|
||||
for x, c := range line[i*CHUNK_SIZE : end_index] {
|
||||
if c == rune(r.PathChar) {
|
||||
chunk |= 1 << (maze.CHUNK_SIZE - 1 - x)
|
||||
chunk |= 1 << (CHUNK_SIZE - 1 - x)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ package reader
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"maze-solver/maze"
|
||||
"os"
|
||||
)
|
||||
|
||||
@ -11,7 +10,7 @@ type TextReader struct {
|
||||
PathChar, WallChar byte
|
||||
}
|
||||
|
||||
func (r TextReader) Read() (*maze.RawMaze, error) {
|
||||
func (r TextReader) Read() (*RawMaze, error) {
|
||||
lines, err := getLines(r.Filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
Reference in New Issue
Block a user