Skip to content

Commit

Permalink
Add direction and move (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
kelindar authored Dec 29, 2021
1 parent 24b670a commit 6006843
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 35 deletions.
20 changes: 14 additions & 6 deletions path_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,24 +94,32 @@ func BenchmarkPath(b *testing.B) {
}
})

b.Run("6144x6144", func(b *testing.B) {
m := NewGrid(6144, 6144)
b.Run("3069x3069", func(b *testing.B) {
m := NewGrid(3069, 3069)
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
m.Path(At(0, 0), At(380, 380), costOf)
m.Path(At(0, 0), At(700, 700), costOf)
}
})

b.Run("6147x6147", func(b *testing.B) {
m := NewGrid(6147, 6147)
b.Run("3072x3072", func(b *testing.B) {
m := NewGrid(3072, 3072)
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
m.Path(At(0, 0), At(380, 380), costOf)
m.Path(At(0, 0), At(700, 700), costOf)
}
})

b.Run("6144x6144", func(b *testing.B) {
m := NewGrid(6144, 6144)
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
m.Path(At(0, 0), At(380, 380), costOf)
}
})
}

// BenchmarkAround/3r-8 352876 3355 ns/op 385 B/op 1 allocs/op
Expand Down
70 changes: 70 additions & 0 deletions point.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,35 @@ func (p Point) WithinSize(size Point) bool {
return p.X >= 0 && p.Y >= 0 && p.X < size.X && p.Y < size.Y
}

// Move moves a point by one in the specified direction.
func (p Point) Move(direction Direction) Point {
return p.MoveBy(direction, 1)
}

// MoveBy moves a point by n in the specified direction.
func (p Point) MoveBy(direction Direction, n int16) Point {
switch direction {
case North:
return Point{p.X, p.Y + n}
case NorthEast:
return Point{p.X + n, p.Y + n}
case East:
return Point{p.X + n, p.Y}
case SouthEast:
return Point{p.X + n, p.Y - n}
case South:
return Point{p.X, p.Y - n}
case SouthWest:
return Point{p.X - n, p.Y - n}
case West:
return Point{p.X - n, p.Y}
case NorthWest:
return Point{p.X - n, p.Y + n}
default:
return p
}
}

// DistanceTo calculates manhattan distance to the other point
func (p Point) DistanceTo(other Point) uint32 {
return abs(int32(p.X)-int32(other.X)) + abs(int32(p.Y)-int32(other.Y))
Expand Down Expand Up @@ -231,3 +260,44 @@ func (r *Rect) Size() Point {
Y: r.Max.Y - r.Min.Y,
}
}

// -----------------------------------------------------------------------------

// Diretion represents a direction
type Direction byte

// Various directions
const (
North Direction = iota
NorthEast
East
SouthEast
South
SouthWest
West
NorthWest
)

// String returns a string representation of a direction
func (v Direction) String() string {
switch v {
case North:
return "🡱N"
case NorthEast:
return "🡵NE"
case East:
return "🡲E"
case SouthEast:
return "🡶SE"
case South:
return "🡳S"
case SouthWest:
return "🡷SW"
case West:
return "🡰W"
case NorthWest:
return "🡴NW"
default:
return ""
}
}
94 changes: 65 additions & 29 deletions point_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,42 @@ import (
"github.com/stretchr/testify/assert"
)

/*
cpu: Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
BenchmarkPoint/within-8 1000000000 0.2697 ns/op 0 B/op 0 allocs/op
BenchmarkPoint/within-rect-8 1000000000 0.2928 ns/op 0 B/op 0 allocs/op
BenchmarkPoint/interleave-8 1000000000 0.8242 ns/op 0 B/op 0 allocs/op
*/
func BenchmarkPoint(b *testing.B) {
p := At(10, 20)
b.Run("within", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
p.Within(At(0, 0), At(100, 100))
}
})

b.Run("within-rect", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
p.WithinRect(NewRect(0, 0, 100, 100))
}
})

b.Run("interleave", func(b *testing.B) {
out := int32(0)
p := At(8191, 8191)
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
out = p.Interleave()
}
assert.NotZero(b, out)
})
}

func TestPoint(t *testing.T) {
p := At(10, 20)
p2 := At(2, 2)
Expand Down Expand Up @@ -37,35 +73,35 @@ func TestMorton(t *testing.T) {
assert.Equal(t, p, deinterleavePoint(67108863))
}

// BenchmarkPoint/within-8 1000000000 0.220 ns/op 0 B/op 0 allocs/op
// BenchmarkPoint/within-rect-8 1000000000 0.219 ns/op 0 B/op 0 allocs/op
// BenchmarkPoint/interleave-8 1000000000 0.657 ns/op 0 B/op 0 allocs/op
func BenchmarkPoint(b *testing.B) {
p := At(10, 20)
b.Run("within", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
p.Within(At(0, 0), At(100, 100))
}
})
func TestDirection(t *testing.T) {
for i := 0; i < 8; i++ {
dir := Direction(i)
assert.NotEmpty(t, dir.String())
}
}

b.Run("within-rect", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
p.WithinRect(NewRect(0, 0, 100, 100))
}
})
func TestDirection_Empty(t *testing.T) {
dir := Direction(9)
assert.Empty(t, dir.String())
}

b.Run("interleave", func(b *testing.B) {
out := int32(0)
p := At(8191, 8191)
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
out = p.Interleave()
}
assert.NotZero(b, out)
})
func TestMove(t *testing.T) {
tests := []struct {
dir Direction
out Point
}{
{North, Point{X: 0, Y: 1}},
{South, Point{X: 0, Y: -1}},
{East, Point{X: 1, Y: 0}},
{West, Point{X: -1, Y: 0}},
{NorthEast, Point{X: 1, Y: 1}},
{NorthWest, Point{X: -1, Y: 1}},
{SouthEast, Point{X: 1, Y: -1}},
{SouthWest, Point{X: -1, Y: -1}},
{Direction(99), Point{}},
}

for _, tc := range tests {
assert.Equal(t, tc.out, Point{}.Move(tc.dir), tc.dir.String())
}
}

0 comments on commit 6006843

Please sign in to comment.