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}) }