302 lines
7.2 KiB
Go
302 lines
7.2 KiB
Go
package controller_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/iliadenisov/galaxy/internal/controller"
|
|
"github.com/iliadenisov/galaxy/internal/model/game"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestVotesByRace(t *testing.T) {
|
|
c, _ := newCache()
|
|
|
|
c.MustPlanet(R0_Planet_0_num).Size = 450.
|
|
c.MustPlanet(R0_Planet_0_num).Population = 450.
|
|
|
|
c.MustPlanet(R1_Planet_1_num).Size = 900.
|
|
c.MustPlanet(R1_Planet_1_num).Population = 900.
|
|
|
|
c.MustPlanet(R0_Planet_2_num).Size = 330.
|
|
c.MustPlanet(R0_Planet_2_num).Population = 330.
|
|
|
|
vbr := c.VotesByRace()
|
|
assert.Len(t, vbr, 2)
|
|
assert.Contains(t, vbr, Race_0_idx)
|
|
assert.Equal(t, 0.78, vbr[Race_0_idx])
|
|
assert.Contains(t, vbr, Race_1_idx)
|
|
assert.Equal(t, 0.9, vbr[Race_1_idx])
|
|
// TODO: add races without planets / dead races
|
|
}
|
|
|
|
func prepareRaces() ([]game.Race, func(u uuid.UUID) int) {
|
|
races := make([]game.Race, 20)
|
|
raceIndex := make(map[uuid.UUID]int)
|
|
for i := range len(races) {
|
|
races[i].ID = uuid.New()
|
|
races[i].VoteFor = races[i].ID
|
|
raceIndex[races[i].ID] = i
|
|
}
|
|
// 0 -> 1 -> 2 -> 3
|
|
// ^ |
|
|
// 5 -> 6 -> 4 <--'
|
|
races[0].VoteFor = races[1].ID
|
|
races[1].VoteFor = races[2].ID
|
|
races[2].VoteFor = races[3].ID
|
|
races[3].VoteFor = races[4].ID
|
|
races[4].VoteFor = races[2].ID
|
|
races[5].VoteFor = races[6].ID
|
|
races[6].VoteFor = races[4].ID
|
|
// 7 -> 10 -> 11
|
|
// ^
|
|
// 8 -> 9
|
|
races[7].VoteFor = races[10].ID
|
|
races[10].VoteFor = races[11].ID
|
|
races[8].VoteFor = races[9].ID
|
|
races[9].VoteFor = races[10].ID
|
|
// 12 -> 13
|
|
// 13 -> 12
|
|
races[12].VoteFor = races[13].ID
|
|
races[13].VoteFor = races[12].ID
|
|
// 14 -> 15 -> 16
|
|
// ^ |
|
|
// 17 <--'
|
|
races[14].VoteFor = races[15].ID
|
|
races[15].VoteFor = races[16].ID
|
|
races[16].VoteFor = races[17].ID
|
|
races[17].VoteFor = races[15].ID
|
|
// 19 -> 13
|
|
races[19].VoteFor = races[13].ID
|
|
|
|
return races, func(u uuid.UUID) int { return raceIndex[u] }
|
|
}
|
|
|
|
func TestVotingGraph(t *testing.T) {
|
|
races, raceIndex := prepareRaces()
|
|
|
|
voteNodes := controller.VotingGraph(races, raceIndex)
|
|
|
|
assert.Len(t, voteNodes, len(races))
|
|
for i := range voteNodes {
|
|
n := voteNodes[i]
|
|
switch i {
|
|
case 0:
|
|
assert.Equal(t, voteNodes[1], n.Next)
|
|
case 1:
|
|
assert.Equal(t, voteNodes[2], n.Next)
|
|
case 2:
|
|
assert.Equal(t, voteNodes[3], n.Next)
|
|
case 3:
|
|
assert.Equal(t, voteNodes[4], n.Next)
|
|
case 4:
|
|
assert.Equal(t, voteNodes[2], n.Next)
|
|
case 5:
|
|
assert.Equal(t, voteNodes[6], n.Next)
|
|
case 6:
|
|
assert.Equal(t, voteNodes[4], n.Next)
|
|
case 7:
|
|
assert.Equal(t, voteNodes[10], n.Next)
|
|
case 8:
|
|
assert.Equal(t, voteNodes[9], n.Next)
|
|
case 9:
|
|
assert.Equal(t, voteNodes[10], n.Next)
|
|
case 10:
|
|
assert.Equal(t, voteNodes[11], n.Next)
|
|
case 11:
|
|
assert.Nil(t, n.Next)
|
|
case 12:
|
|
assert.Equal(t, voteNodes[13], n.Next)
|
|
case 13:
|
|
assert.Equal(t, voteNodes[12], n.Next)
|
|
case 14:
|
|
assert.Equal(t, voteNodes[15], n.Next)
|
|
case 15:
|
|
assert.Equal(t, voteNodes[16], n.Next)
|
|
case 16:
|
|
assert.Equal(t, voteNodes[17], n.Next)
|
|
case 17:
|
|
assert.Equal(t, voteNodes[15], n.Next)
|
|
case 18:
|
|
assert.Nil(t, n.Next)
|
|
case 19:
|
|
assert.Equal(t, voteNodes[13], n.Next)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestVotingChains(t *testing.T) {
|
|
races, raceIndex := prepareRaces()
|
|
nodes := controller.VotingGraph(races, raceIndex)
|
|
|
|
vc := controller.VotingChains(nodes)
|
|
|
|
assert.Len(t, vc, 7)
|
|
for i := range vc {
|
|
n := vc[i]
|
|
switch i {
|
|
case 0:
|
|
assert.Len(t, n, 3)
|
|
assert.Equal(t, 2, n[0].ID)
|
|
assert.Equal(t, 3, n[1].ID)
|
|
assert.Equal(t, 4, n[2].ID)
|
|
assert.True(t, n[0].Ally)
|
|
assert.True(t, n[1].Ally)
|
|
assert.True(t, n[2].Ally)
|
|
case 1:
|
|
assert.Len(t, n, 2)
|
|
assert.Equal(t, 0, n[0].ID)
|
|
assert.Equal(t, 1, n[1].ID)
|
|
assert.False(t, n[0].Ally)
|
|
assert.False(t, n[1].Ally)
|
|
case 2:
|
|
assert.Len(t, n, 2)
|
|
assert.Equal(t, 5, n[0].ID)
|
|
assert.Equal(t, 6, n[1].ID)
|
|
assert.False(t, n[0].Ally)
|
|
assert.False(t, n[1].Ally)
|
|
case 3:
|
|
assert.Len(t, n, 3)
|
|
assert.Equal(t, 7, n[0].ID)
|
|
assert.Equal(t, 10, n[1].ID)
|
|
assert.Equal(t, 11, n[2].ID)
|
|
assert.False(t, n[0].Ally)
|
|
assert.False(t, n[1].Ally)
|
|
assert.False(t, n[2].Ally)
|
|
case 4:
|
|
assert.Len(t, n, 4)
|
|
assert.Equal(t, 8, n[0].ID)
|
|
assert.Equal(t, 9, n[1].ID)
|
|
assert.Equal(t, 10, n[2].ID)
|
|
assert.Equal(t, 11, n[3].ID)
|
|
assert.False(t, n[0].Ally)
|
|
assert.False(t, n[1].Ally)
|
|
assert.False(t, n[2].Ally)
|
|
assert.False(t, n[3].Ally)
|
|
case 5:
|
|
assert.Len(t, n, 2)
|
|
assert.Equal(t, 12, n[0].ID)
|
|
assert.Equal(t, 13, n[1].ID)
|
|
assert.True(t, n[0].Ally)
|
|
assert.True(t, n[1].Ally)
|
|
case 6:
|
|
assert.Len(t, n, 3)
|
|
assert.Equal(t, 15, n[0].ID)
|
|
assert.Equal(t, 16, n[1].ID)
|
|
assert.Equal(t, 17, n[2].ID)
|
|
assert.True(t, n[0].Ally)
|
|
assert.True(t, n[1].Ally)
|
|
assert.True(t, n[2].Ally)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGroupVotes(t *testing.T) {
|
|
races, raceIndex := prepareRaces()
|
|
raceVotes := make(map[int]float64)
|
|
// [1] = 0.24
|
|
raceVotes[0] = 0.11
|
|
raceVotes[1] = 0.13
|
|
|
|
// [2,3,4] = 0.69
|
|
raceVotes[2] = 0.22
|
|
raceVotes[3] = 0.23
|
|
raceVotes[4] = 0.24
|
|
|
|
// [6] = 0.71
|
|
raceVotes[5] = 0.35
|
|
raceVotes[6] = 0.36
|
|
|
|
// [11] = 0.843
|
|
raceVotes[7] = 0.41
|
|
raceVotes[9] = 0.42
|
|
raceVotes[10] = 0.013
|
|
|
|
// [12,13] = 0.52
|
|
raceVotes[12] = 0.52
|
|
raceVotes[13] = 0.
|
|
|
|
// [14] = 1.04
|
|
raceVotes[14] = 1.04
|
|
|
|
// [15,16,17] = 2.49
|
|
raceVotes[15] = 1.15
|
|
raceVotes[16] = 0.16
|
|
raceVotes[17] = 1.18
|
|
|
|
// [18] = 3.18
|
|
raceVotes[18] = 3.18
|
|
|
|
// [19] = 0.019
|
|
raceVotes[19] = 0.019
|
|
|
|
calc := controller.GroupVotes(raceVotes, controller.VotingGraph(races, raceIndex))
|
|
|
|
assert.Len(t, calc, 9)
|
|
for i := range calc {
|
|
vg := calc[i]
|
|
switch i {
|
|
case 0:
|
|
assert.ElementsMatch(t, []int{2, 3, 4}, vg.RaceIndex)
|
|
assert.Equal(t, 0.69, vg.Sum)
|
|
case 4:
|
|
assert.ElementsMatch(t, []int{12, 13}, vg.RaceIndex)
|
|
assert.Equal(t, 0.52, vg.Sum)
|
|
case 5:
|
|
assert.ElementsMatch(t, []int{15, 16, 17}, vg.RaceIndex)
|
|
assert.InDelta(t, 2.49, vg.Sum, 0.001)
|
|
default:
|
|
assert.Len(t, vg.RaceIndex, 1)
|
|
switch ri := vg.RaceIndex[0]; ri {
|
|
case 1:
|
|
assert.Equal(t, 0.24, vg.Sum)
|
|
case 6:
|
|
assert.Equal(t, 0.71, vg.Sum)
|
|
case 11:
|
|
assert.Equal(t, 0.843, vg.Sum)
|
|
case 14:
|
|
assert.Equal(t, 1.04, vg.Sum)
|
|
case 18:
|
|
assert.Equal(t, 3.18, vg.Sum)
|
|
case 19:
|
|
assert.Equal(t, 0.019, vg.Sum)
|
|
default:
|
|
assert.Failf(t, "unexpected group", "id=%v sum=%f", vg.RaceIndex, vg.Sum)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestVotingWinners(t *testing.T) {
|
|
gameVotes := 100.0
|
|
var vg []*controller.VoteGroup
|
|
var winners []int
|
|
|
|
vg = []*controller.VoteGroup{
|
|
{Sum: 4.0, RaceIndex: []int{0}},
|
|
{Sum: 66.65, RaceIndex: []int{1, 2}},
|
|
{Sum: 5.0, RaceIndex: []int{3}},
|
|
{Sum: 25.0, RaceIndex: []int{4, 5, 6}},
|
|
}
|
|
winners = controller.VotingWinners(vg, gameVotes)
|
|
assert.Len(t, winners, 0)
|
|
|
|
vg = []*controller.VoteGroup{
|
|
{Sum: 4.0, RaceIndex: []int{0}},
|
|
{Sum: 66.666666666666666, RaceIndex: []int{1, 2}},
|
|
{Sum: 5.0, RaceIndex: []int{3}},
|
|
{Sum: 22.0, RaceIndex: []int{4, 5, 6}},
|
|
}
|
|
winners = controller.VotingWinners(vg, gameVotes)
|
|
assert.ElementsMatch(t, winners, []int{1, 2})
|
|
|
|
vg = []*controller.VoteGroup{
|
|
{Sum: 4.0, RaceIndex: []int{0}},
|
|
{Sum: 3.33, RaceIndex: []int{1, 2}},
|
|
{Sum: 66.67, RaceIndex: []int{3}},
|
|
{Sum: 25.0, RaceIndex: []int{4, 5, 6}},
|
|
}
|
|
winners = controller.VotingWinners(vg, gameVotes)
|
|
assert.ElementsMatch(t, winners, []int{3})
|
|
}
|