diff --git a/assets/trivial-bigger-staggered.txt b/assets/trivial-bigger-staggered.txt new file mode 100644 index 0000000..033fe5f --- /dev/null +++ b/assets/trivial-bigger-staggered.txt @@ -0,0 +1,5 @@ +### ### +### ### +# # +#### ## +#### ## diff --git a/io/reader/text.go b/io/reader/text.go index d7a23c0..5b71a91 100644 --- a/io/reader/text.go +++ b/io/reader/text.go @@ -67,7 +67,7 @@ func (r *TextReader) Read(filename string) (*maze.Maze, error) { ret.Nodes = append(ret.Nodes, node) nodesByCoord[coords] = node - r.lookupNeighbourAbove(&lines, node, &nodesByCoord) + r.lookupNeighbourAbove(&lines, node, &nodesByCoord, ret) if left_char == r.PathChar && right_char == r.WallChar || above_char == r.PathChar && (left_char == r.PathChar || right_char == r.PathChar) { r.lookupNeighbourLeft(&line, node, &nodesByCoord) @@ -84,7 +84,7 @@ func (r *TextReader) Read(filename string) (*maze.Maze, error) { if char == r.PathChar { coords := maze.Coordinates{X: x, Y: y} node := maze.NewNode(coords) - r.lookupNeighbourAbove(&lines, node, &nodesByCoord) + r.lookupNeighbourAbove(&lines, node, &nodesByCoord, ret) ret.Nodes = append(ret.Nodes, node) break } @@ -93,17 +93,33 @@ func (r *TextReader) Read(filename string) (*maze.Maze, error) { return ret, nil } -func (r *TextReader) lookupNeighbourAbove(lines *[]string, node *maze.Node, nodesByCoord *map[maze.Coordinates]*maze.Node) { +func (r *TextReader) lookupNeighbourAbove(lines *[]string, node *maze.Node, nodesByCoord *map[maze.Coordinates]*maze.Node, m *maze.Maze) { for y := node.Coords.Y - 1; y >= 0; y-- { - if (*lines)[y][node.Coords.X] == r.WallChar { - break - } - neighbour, ok := (*nodesByCoord)[maze.Coordinates{X: node.Coords.X, Y: y}] + if ok { node.Up = neighbour neighbour.Down = node + break } + + if y > 0 && (*lines)[y][node.Coords.X] == r.WallChar { + y++ + if y == node.Coords.Y { + break + } + coords := maze.Coordinates{X: node.Coords.X, Y: y} + new_node := maze.NewNode(coords) + r.lookupNeighbourLeft(&(*lines)[y], new_node, nodesByCoord) + r.lookupNeighbourRight(&(*lines)[y], new_node, nodesByCoord) + (*nodesByCoord)[coords] = new_node + m.Nodes = append(m.Nodes, new_node) + + node.Up = new_node + new_node.Down = node + break + } + } } @@ -121,3 +137,18 @@ func (r *TextReader) lookupNeighbourLeft(line *string, node *maze.Node, nodesByC } } } + +func (r *TextReader) lookupNeighbourRight(line *string, node *maze.Node, nodesByCoord *map[maze.Coordinates]*maze.Node) { + for x := node.Coords.X + 1; x < len(*line); x++ { + if (*line)[x] == r.WallChar { + panic(fmt.Sprintf("Found no node before wall while looking to the right at neighbours of node %v", node)) + } + + neighbour, ok := (*nodesByCoord)[maze.Coordinates{X: x, Y: node.Coords.Y}] + if ok { + node.Right = neighbour + neighbour.Left = node + break + } + } +} diff --git a/io/reader/text_test.go b/io/reader/text_test.go index 4b77a2a..8386db7 100644 --- a/io/reader/text_test.go +++ b/io/reader/text_test.go @@ -131,6 +131,78 @@ func TestTextReadTrivialBigger(t *testing.T) { } } +func TestTextReadTrivialBiggerStaggered(t *testing.T) { + /* trivial-bigger-staggered.txt + ### ### + ### ### + # # + #### ## + #### ## + + Nodes are + ###0### + ### ### + #1 243# + #### ## + ####5## + */ + fmt.Println("---------- STAGGERED ----------") + nodes := make([]*maze.Node, 6) + + nodes[0] = maze.NewNode(maze.Coordinates{X: 3, Y: 0}) + + nodes[1] = maze.NewNode(maze.Coordinates{X: 1, Y: 2}) + nodes[2] = maze.NewNode(maze.Coordinates{X: 3, Y: 2}) + nodes[3] = maze.NewNode(maze.Coordinates{X: 5, Y: 2}) + + nodes[4] = maze.NewNode(maze.Coordinates{X: 4, Y: 2}) + + nodes[5] = maze.NewNode(maze.Coordinates{X: 4, Y: 4}) + + nodes[0].Down = nodes[2] + + nodes[1].Right = nodes[2] + + nodes[2].Up = nodes[0] + nodes[2].Left = nodes[1] + nodes[2].Right = nodes[4] + + nodes[3].Left = nodes[4] + + nodes[4].Down = nodes[5] + nodes[4].Left = nodes[2] + nodes[4].Right = nodes[3] + + nodes[5].Up = nodes[4] + + reader := TextReader{ + PathChar: ' ', + WallChar: '#', + } + + filename := "../../assets/trivial-bigger-staggered.txt" + got, err := reader.Read(filename) + utils.Check(err, "Couldn't create maze from %q", filename) + + if len(nodes) != len(got.Nodes) { + t.Fatalf("Didn't get the same size of nodes: %v, want %v", len(got.Nodes), len(nodes)) + } + + for _, node := range got.Nodes { + fmt.Println(node) + } + + for i, got := range got.Nodes { + expected := nodes[i] + + checkNode(t, i, got, expected, "") + checkNode(t, i, got.Left, expected.Left, "left") + checkNode(t, i, got.Right, expected.Right, "Right") + checkNode(t, i, got.Up, expected.Up, "Up") + checkNode(t, i, got.Down, expected.Down, "Down") + } +} + func checkNode(t *testing.T, i int, got *maze.Node, expected *maze.Node, side string) { if expected == nil { return