// Copyright ©2015 The gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package internal

import (
	"math"
	"reflect"
	"testing"

	"github.com/gonum/graph"
	"github.com/gonum/graph/simple"
)

type changes struct {
	n graph.Node

	new, old []simple.Edge
}

var limitedVisionTests = []struct {
	g        *Grid
	radius   float64
	diag     bool
	remember bool

	path []graph.Node

	want []changes
}{
	{
		g: NewGridFrom(
			"*..*",
			"**.*",
			"**.*",
			"**.*",
		),
		radius:   1,
		diag:     false,
		remember: false,
		path:     []graph.Node{node(1), node(2), node(6), node(10), node(14)},

		want: []changes{
			{
				n: node(1),
				new: []simple.Edge{
					{F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(2),
				new: []simple.Edge{
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
				},
				old: nil,
			},
			{
				n: node(6),
				new: []simple.Edge{
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
				},
				old: nil,
			},
			{
				n: node(10),
				new: []simple.Edge{
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
				},
				old: nil,
			},
			{
				n: node(14),
				new: []simple.Edge{
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
					{F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)},
				},
				old: nil,
			},
		},
	},
	{
		g: NewGridFrom(
			"*..*",
			"**.*",
			"**.*",
			"**.*",
		),
		radius:   1.5,
		diag:     false,
		remember: false,
		path:     []graph.Node{node(1), node(2), node(6), node(10), node(14)},

		want: []changes{
			{
				n: node(1),
				new: []simple.Edge{
					{F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(0), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(4), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(4), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(2),
				new: []simple.Edge{
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(6),
				new: []simple.Edge{
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(10),
				new: []simple.Edge{
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
					{F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(14),
				new: []simple.Edge{
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
					{F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)},
				},
				old: nil,
			},
		},
	},
	{
		g: NewGridFrom(
			"*..*",
			"**.*",
			"**.*",
			"**.*",
		),
		radius:   1,
		diag:     false,
		remember: true,
		path:     []graph.Node{node(1), node(2), node(6), node(10), node(14)},

		want: []changes{
			{
				n: node(1),
				new: []simple.Edge{
					{F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(2),
				new: []simple.Edge{
					{F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
				},
				old: []simple.Edge{
					{F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
				},
			},
			{
				n: node(6),
				new: []simple.Edge{
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
				},
				old: []simple.Edge{
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
				},
			},
			{
				n: node(10),
				new: []simple.Edge{
					{F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
				},
				old: []simple.Edge{
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
				},
			},
			{
				n: node(14),
				new: []simple.Edge{
					{F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)},
				},
				old: []simple.Edge{
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
				},
			},
		},
	},
	{
		g: NewGridFrom(
			"*..*",
			"**.*",
			"**.*",
			"**.*",
		),
		radius:   1.5,
		diag:     false,
		remember: true,
		path:     []graph.Node{node(1), node(2), node(6), node(10), node(14)},

		want: []changes{
			{
				n: node(1),
				new: []simple.Edge{
					{F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(0), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(4), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(4), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(2),
				new: []simple.Edge{
					{F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
				},
				old: []simple.Edge{
					{F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
				},
			},
			{
				n: node(6),
				new: []simple.Edge{
					{F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
				},
				old: []simple.Edge{
					{F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
				},
			},
			{
				n: node(10),
				new: []simple.Edge{
					{F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
					{F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)},
				},
				old: []simple.Edge{
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
				},
			},
			{
				n:   node(14),
				new: nil,
				old: []simple.Edge{
					{F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
					{F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)},
				},
			},
		},
	},
	{
		g: NewGridFrom(
			"*..*",
			"**.*",
			"**.*",
			"**.*",
		),
		radius:   1,
		diag:     true,
		remember: false,
		path:     []graph.Node{node(1), node(2), node(6), node(10), node(14)},

		want: []changes{
			{
				n: node(1),
				new: []simple.Edge{
					{F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(0), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(2),
				new: []simple.Edge{
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(6),
				new: []simple.Edge{
					{F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(2), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(7), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(10),
				new: []simple.Edge{
					{F: simple.Node(6), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(6), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(11), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
					{F: simple.Node(14), T: simple.Node(11), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(14),
				new: []simple.Edge{
					{F: simple.Node(10), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(10), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
					{F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)},
				},
				old: nil,
			},
		},
	},
	{
		g: NewGridFrom(
			"*..*",
			"**.*",
			"**.*",
			"**.*",
		),
		radius:   1.5,
		diag:     true,
		remember: false,
		path:     []graph.Node{node(1), node(2), node(6), node(10), node(14)},

		want: []changes{
			{
				n: node(1),
				new: []simple.Edge{
					{F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(0), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(0), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(4), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(4), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(4), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(2),
				new: []simple.Edge{
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(2), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(6),
				new: []simple.Edge{
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(2), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(6), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(10),
				new: []simple.Edge{
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(6), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(10), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
					{F: simple.Node(14), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(14),
				new: []simple.Edge{
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(10), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
					{F: simple.Node(14), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)},
				},
				old: nil,
			},
		},
	},
	{
		g: NewGridFrom(
			"*..*",
			"**.*",
			"**.*",
			"**.*",
		),
		radius:   1,
		diag:     true,
		remember: true,
		path:     []graph.Node{node(1), node(2), node(6), node(10), node(14)},

		want: []changes{
			{
				n: node(1),
				new: []simple.Edge{
					{F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(0), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(2),
				new: []simple.Edge{
					{F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2},
					{F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
				},
				old: []simple.Edge{
					{F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)},
				},
			},
			{
				n: node(6),
				new: []simple.Edge{
					{F: simple.Node(2), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(7), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)},
				},
				old: []simple.Edge{
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
				},
			},
			{
				n: node(10),
				new: []simple.Edge{
					{F: simple.Node(6), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(11), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
					{F: simple.Node(14), T: simple.Node(11), W: math.Inf(1)},
				},
				old: []simple.Edge{
					{F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)},
				},
			},
			{
				n: node(14),
				new: []simple.Edge{
					{F: simple.Node(10), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)},
				},
				old: []simple.Edge{
					{F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(14), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
					{F: simple.Node(14), T: simple.Node(11), W: math.Inf(1)},
				},
			},
		},
	},
	{
		g: NewGridFrom(
			"*..*",
			"**.*",
			"**.*",
			"**.*",
		),
		radius:   1.5,
		diag:     true,
		remember: true,
		path:     []graph.Node{node(1), node(2), node(6), node(10), node(14)},

		want: []changes{
			{
				n: node(1),
				new: []simple.Edge{
					{F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(0), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(0), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(4), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(4), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(4), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
				},
				old: nil,
			},
			{
				n: node(2),
				new: []simple.Edge{
					{F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
				},
				old: []simple.Edge{
					{F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
				},
			},
			{
				n: node(6),
				new: []simple.Edge{
					{F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(6), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
				},
				old: []simple.Edge{
					{F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(2), W: 1},
					{F: simple.Node(1), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2},
					{F: simple.Node(2), T: simple.Node(1), W: 1},
					{F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(2), T: simple.Node(6), W: 1},
					{F: simple.Node(2), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
				},
			},
			{
				n: node(10),
				new: []simple.Edge{
					{F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(10), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
					{F: simple.Node(14), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)},
				},
				old: []simple.Edge{
					{F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(5), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2},
					{F: simple.Node(6), T: simple.Node(2), W: 1},
					{F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(6), T: simple.Node(10), W: 1},
					{F: simple.Node(6), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(2), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
				},
			},
			{
				n:   node(14),
				new: nil,
				old: []simple.Edge{
					{F: simple.Node(9), T: simple.Node(4), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(9), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(6), W: 1},
					{F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(10), T: simple.Node(14), W: 1},
					{F: simple.Node(10), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(6), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(9), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(10), W: 1},
					{F: simple.Node(14), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)},
					{F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(10), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)},
					{F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)},
				},
			},
		},
	},
}

func TestLimitedVisionGrid(t *testing.T) {
	for i, test := range limitedVisionTests {
		l := &LimitedVisionGrid{
			Grid:         test.g,
			VisionRadius: test.radius,
			Location:     test.path[0],
		}
		if test.remember {
			l.Known = make(map[int]bool)
		}
		l.Grid.AllowDiagonal = test.diag

		x, y := l.XY(test.path[0])
		for _, u := range l.Nodes() {
			ux, uy := l.XY(u)
			uNear := math.Hypot(x-ux, y-uy) <= test.radius
			for _, v := range l.Nodes() {
				vx, vy := l.XY(v)
				vNear := math.Hypot(x-vx, y-vy) <= test.radius
				if u.ID() == v.ID() && l.HasEdgeBetween(u, v) {
					t.Errorf("unexpected self edge: %v -- %v", u, v)
				}
				if !uNear && !vNear && !l.HasEdgeBetween(u, v) && couldConnectIn(l, u, v) {
					t.Errorf("unexpected pessimism: no hope in distant edge between %v and %v for test %d",
						u, v, i)
				}
				if (uNear && vNear) && l.HasEdgeBetween(u, v) != l.Grid.HasEdgeBetween(u, v) {
					t.Errorf("unrealistic optimism: disagreement about edge between %v and %v for test %d: got:%t want:%t",
						u, v, i, l.HasEdgeBetween(u, v), l.Grid.HasEdgeBetween(u, v))
				}
			}
		}

		var got []changes
		for _, n := range test.path {
			new, old := l.MoveTo(n)
			got = append(got, changes{n: n, new: asConcreteEdges(new, l), old: asConcreteEdges(old, l)})
		}
		if !reflect.DeepEqual(got, test.want) {
			t.Errorf("unexpected walk for test %d:\ngot: %+v\nwant:%+v", i, got, test.want)
		}
	}
}

func asConcreteEdges(changes []graph.Edge, in graph.Weighter) []simple.Edge {
	if changes == nil {
		return nil
	}
	we := make([]simple.Edge, len(changes))
	for i, e := range changes {
		we[i].F = e.From()
		we[i].T = e.To()
		w, ok := in.Weight(e.From(), e.To())
		if !ok && !math.IsInf(w, 1) {
			panic("unexpected invalid finite weight")
		}
		we[i].W = w
	}
	return we
}

func couldConnectIn(l *LimitedVisionGrid, u, v graph.Node) bool {
	if u.ID() == v.ID() {
		return false
	}

	ur, uc := l.RowCol(u.ID())
	vr, vc := l.RowCol(v.ID())
	if abs(ur-vr) > 1 || abs(uc-vc) > 1 {
		return false
	}
	if (ur != vr || uc != vc) && !l.Grid.AllowDiagonal {
		return false
	}

	if !l.Known[u.ID()] && !l.Known[v.ID()] {
		return true
	}
	if l.Known[u.ID()] && !l.Grid.HasOpen(u) {
		return false
	}
	if l.Known[v.ID()] && !l.Grid.HasOpen(v) {
		return false
	}

	return true
}
