mirror of
https://github.com/knight0zh/aoi.git
synced 2026-02-03 23:55:09 +08:00
162 lines
3.1 KiB
Go
162 lines
3.1 KiB
Go
package aoi
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/stretchr/testify/assert"
|
|
"math/rand"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func Test_FindQuadrant(t *testing.T) {
|
|
aoi := NewQuadTree(0, 0, 100)
|
|
tree := aoi.(*QuadTree)
|
|
tree.cutNode()
|
|
|
|
tests := []struct {
|
|
x, y float64
|
|
want int
|
|
}{
|
|
{
|
|
x: 49.9, y: 49.9, want: leftUp,
|
|
},
|
|
{
|
|
x: 50, y: 50, want: rightDown,
|
|
},
|
|
{
|
|
x: 49.9, y: 50, want: leftDown,
|
|
},
|
|
{
|
|
x: 50, y: 49.9, want: rightUp,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
d := tree.findSonQuadrant(tt.x, tt.y)
|
|
assert.Equal(t, tt.want, d)
|
|
}
|
|
|
|
// 再次分割
|
|
tree.Child[rightUp].cutNode()
|
|
tests2 := []struct {
|
|
x, y float64
|
|
want int
|
|
}{
|
|
{
|
|
x: 74.9, y: 24.9, want: leftUp,
|
|
},
|
|
{
|
|
x: 75, y: 25, want: rightDown,
|
|
},
|
|
{
|
|
x: 74.9, y: 25, want: leftDown,
|
|
},
|
|
{
|
|
x: 75, y: 24.9, want: rightUp,
|
|
},
|
|
}
|
|
for _, tt := range tests2 {
|
|
d := tree.Child[rightUp].findSonQuadrant(tt.x, tt.y)
|
|
assert.Equal(t, tt.want, d)
|
|
}
|
|
}
|
|
|
|
func Test_NeedCut(t *testing.T) {
|
|
aoi := NewQuadTree(0, 0, 100)
|
|
tree := aoi.(*QuadTree)
|
|
|
|
tree.maxCap = 2 // 超过两人节点分裂
|
|
assert.Equal(t, false, tree.needCut())
|
|
tree.Add(60.9, 24.9, "player1")
|
|
|
|
assert.Equal(t, false, tree.needCut())
|
|
tree.Add(25, 25, "player2")
|
|
|
|
assert.Equal(t, true, tree.needCut())
|
|
}
|
|
|
|
func TestNode_Search(t *testing.T) {
|
|
aoi := NewQuadTree(0, 0, 100)
|
|
tree := aoi.(*QuadTree)
|
|
tree.maxCap = 2 // 超过两人节点分裂
|
|
tree.radius = 5
|
|
|
|
tree.Add(60.9, 24.9, "player1")
|
|
tree.Add(25, 25, "player2")
|
|
|
|
// 查询player1附近
|
|
entities := tree.Search(60.9, 24.9)
|
|
assert.Equal(t, 2, len(entities), "player1 player2")
|
|
|
|
// 当出现第三个玩家超过节点最大容量产生分裂
|
|
tree.Add(99, 24, "player3")
|
|
|
|
// 查询player1附近
|
|
entities = tree.Search(60.9, 24.9)
|
|
assert.Equal(t, 2, len(entities), "player1 player3")
|
|
|
|
// 添加第四个玩家
|
|
tree.Add(72, 23, "player4")
|
|
|
|
// 查询player1附近
|
|
entities = tree.Search(60.9, 24.9)
|
|
assert.Equal(t, 2, len(entities), "player1 player4")
|
|
|
|
// 查询player2附近
|
|
entities = tree.Search(25, 25)
|
|
assert.Equal(t, 1, len(entities), "player2")
|
|
|
|
// 添加第五个玩家
|
|
tree.Add(49.9, 49.9, "player5")
|
|
|
|
// 查询player2附近
|
|
entities = tree.Search(25, 25)
|
|
assert.Equal(t, 2, len(entities), "player2 player5")
|
|
|
|
// 移除player5
|
|
tree.Delete(49.9, 49.9, "player5")
|
|
|
|
// 查询player2附近
|
|
entities = tree.Search(25, 25)
|
|
assert.Equal(t, 1, len(entities), "player2")
|
|
}
|
|
|
|
func BenchmarkQuadtree(b *testing.B) {
|
|
var wg sync.WaitGroup
|
|
aoi := NewQuadTree(0, 0, 1024)
|
|
tree := aoi.(*QuadTree)
|
|
rand.Seed(time.Now().UnixNano())
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
wg.Add(30000)
|
|
for j := 0; j < 10000; j++ {
|
|
go func() {
|
|
tree.Add(
|
|
float64(rand.Intn(10)*10+rand.Intn(10)),
|
|
float64(rand.Intn(10)*10+rand.Intn(10)),
|
|
fmt.Sprintf("player%d", rand.Intn(100)),
|
|
)
|
|
wg.Done()
|
|
}()
|
|
|
|
go func() {
|
|
tree.Delete(
|
|
float64(rand.Intn(10)*10+rand.Intn(10)),
|
|
float64(rand.Intn(10)*10+rand.Intn(10)),
|
|
fmt.Sprintf("player%d", rand.Intn(100)),
|
|
)
|
|
wg.Done()
|
|
}()
|
|
|
|
go func() {
|
|
tree.Search(
|
|
float64(rand.Intn(10)*10+rand.Intn(10)),
|
|
float64(rand.Intn(10)*10+rand.Intn(10)),
|
|
)
|
|
wg.Done()
|
|
}()
|
|
}
|
|
}
|
|
}
|