package game_test import ( "slices" "testing" "github.com/iliadenisov/galaxy/internal/model/game" "github.com/stretchr/testify/assert" ) var ( attacker = game.ShipType{ ShipTypeReport: game.ShipTypeReport{ Name: "Attacker", Drive: 8, Armament: 1, Weapons: 8, Shields: 8, Cargo: 0, }, } defender = game.ShipType{ ShipTypeReport: game.ShipTypeReport{ Name: "Defender", Drive: 1, Armament: 1, Weapons: 1, Shields: 1, Cargo: 0, }, } ship = game.ShipType{ ShipTypeReport: game.ShipTypeReport{ Name: "Ship", Drive: 10, Armament: 1, Weapons: 10, Shields: 10, Cargo: 0, }, } ) func TestDestructionProbability(t *testing.T) { probability := game.DestructionProbability(ship.Weapons, 1, ship.Shields, 1, ship.EmptyMass()) assert.Equal(t, .5, probability) undefeatedShip := ship undefeatedShip.Shields = 55 probability = game.DestructionProbability(ship.Weapons, 1, undefeatedShip.Shields, 1, undefeatedShip.EmptyMass()) assert.LessOrEqual(t, probability, 0.) disruptiveShip := ship disruptiveShip.Weapons = 40 probability = game.DestructionProbability(disruptiveShip.Weapons, 1, ship.Shields, 1, ship.EmptyMass()) assert.GreaterOrEqual(t, probability, 1.) } func TestEffectiveDefence(t *testing.T) { assert.Equal(t, 10., game.EffectiveDefence(ship.Shields, 1, ship.EmptyMass())) attackerEffectiveDefence := game.EffectiveDefence(attacker.Shields, 1, attacker.EmptyMass()) defenderEffectiveDefence := game.EffectiveDefence(defender.Shields, 1, defender.EmptyMass()) // attacker's effective shields must be 'just' 4 times greater than defender's assert.InDelta(t, defenderEffectiveDefence*4, attackerEffectiveDefence, 0) } func TestCollectPlanetGroups(t *testing.T) { g := newGame() assert.NoError(t, g.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_0_num, 10)) // 0 assert.NoError(t, g.CreateShips(Race_0_idx, ShipType_Cruiser, R0_Planet_0_num, 3)) // 1 assert.NoError(t, g.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_0_num, 3)) // 2 g.ShipGroups[2].StateInSpace = &game.InSpace{Origin: 2, Range: 1.23} // 2 -> In_Space assert.NoError(t, g.CreateShips(Race_0_idx, ShipType_Cruiser, R0_Planet_0_num, 1)) // 3 g.ShipGroups[3].Destination = R1_Planet_1_num // 3 -> Planet_1 assert.NoError(t, g.CreateShips(Race_1_idx, Race_1_Gunship, R1_Planet_1_num, 15)) // 4 g.ShipGroups[4].Destination = R0_Planet_0_num // 4 -> Planet_0 cacheShipGroupRaceID := make(map[int]int) cacheShipClass := make(map[int]*game.ShipType) planetGroups := game.CollectPlanetGroups(g, cacheShipGroupRaceID, cacheShipClass) for pl := range planetGroups { switch pl { case R0_Planet_0_num: assert.Equal(t, 3, len(planetGroups[pl])) assert.Contains(t, planetGroups[pl], 0) assert.Contains(t, planetGroups[pl], 1) assert.Contains(t, planetGroups[pl], 4) default: assert.Fail(t, "planet #%d should not contain groups for battle", pl) } } assert.Len(t, cacheShipGroupRaceID, 4) assert.Contains(t, cacheShipGroupRaceID, 0) assert.Contains(t, cacheShipGroupRaceID, 1) assert.Contains(t, cacheShipGroupRaceID, 3) assert.Contains(t, cacheShipGroupRaceID, 4) assert.Equal(t, Race_0_idx, cacheShipGroupRaceID[0]) assert.Equal(t, Race_0_idx, cacheShipGroupRaceID[1]) assert.Equal(t, Race_0_idx, cacheShipGroupRaceID[3]) assert.Equal(t, Race_1_idx, cacheShipGroupRaceID[4]) assert.Len(t, cacheShipClass, 4) // all registered ship classes for all In_Orbit ship groups cacheRelation := game.CacheRelations(g, cacheShipGroupRaceID) assert.Len(t, cacheRelation, 2) assert.Len(t, cacheRelation[Race_0_idx], 1) assert.Len(t, cacheRelation[Race_1_idx], 1) assert.Equal(t, game.RelationWar, cacheRelation[Race_0_idx][Race_1_idx]) assert.Equal(t, game.RelationPeace, cacheRelation[Race_1_idx][Race_0_idx]) assert.Empty(t, cacheRelation[Race_0_idx][Race_0_idx]) assert.Empty(t, cacheRelation[Race_1_idx][Race_1_idx]) } func TestFilterBattleOpponents(t *testing.T) { g := newGame() assert.NoError(t, g.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_0_num, 1)) // 0 assert.NoError(t, g.CreateShips(Race_0_idx, ShipType_Cruiser, R0_Planet_0_num, 1)) // 1 assert.NoError(t, g.CreateShips(Race_1_idx, Race_1_Gunship, R1_Planet_1_num, 15)) // 2 undefeatedShip := ship undefeatedShip.Shields = 100 assert.NoError(t, g.CreateShipType(Race_1.Name, undefeatedShip.Name, undefeatedShip.Drive, undefeatedShip.Weapons, undefeatedShip.Shields, undefeatedShip.Cargo, int(undefeatedShip.Armament))) assert.NoError(t, g.CreateShips(Race_1_idx, undefeatedShip.Name, R1_Planet_1_num, 1)) // 3 cacheShipGroupRaceID := make(map[int]int) cacheShipClass := make(map[int]*game.ShipType) cacheProbability := make(map[int]map[int]float64) cacheRelation := make(map[int]map[int]game.Relation) game.CollectPlanetGroups(g, cacheShipGroupRaceID, cacheShipClass) cacheRelation[Race_0_idx] = make(map[int]game.Relation) cacheRelation[Race_1_idx] = make(map[int]game.Relation) cacheRelation[Race_0_idx][Race_1_idx] = game.RelationPeace cacheRelation[Race_1_idx][Race_0_idx] = game.RelationWar assert.False(t, game.FilterBattleOpponents(g, 0, 2, cacheShipGroupRaceID, cacheRelation, cacheShipClass, cacheProbability)) assert.Contains(t, cacheProbability, 0) assert.Contains(t, cacheProbability[0], 2) assert.InDelta(t, 0.396222, cacheProbability[0][2], 0.0000001) assert.False(t, game.FilterBattleOpponents(g, 2, 0, cacheShipGroupRaceID, cacheRelation, cacheShipClass, cacheProbability)) assert.Contains(t, cacheProbability, 2) assert.Contains(t, cacheProbability[2], 0) assert.InDelta(t, 0.495, cacheProbability[2][0], 0.0001) // Test: same owner assert.True(t, game.FilterBattleOpponents(g, 0, 0, cacheShipGroupRaceID, cacheRelation, cacheShipClass, cacheProbability)) assert.True(t, game.FilterBattleOpponents(g, 0, 1, cacheShipGroupRaceID, cacheRelation, cacheShipClass, cacheProbability)) assert.True(t, game.FilterBattleOpponents(g, 1, 0, cacheShipGroupRaceID, cacheRelation, cacheShipClass, cacheProbability)) // Test: reace reations cacheRelation[Race_1_idx][Race_0_idx] = game.RelationPeace assert.True(t, game.FilterBattleOpponents(g, 0, 2, cacheShipGroupRaceID, cacheRelation, cacheShipClass, cacheProbability)) assert.True(t, game.FilterBattleOpponents(g, 2, 0, cacheShipGroupRaceID, cacheRelation, cacheShipClass, cacheProbability)) cacheRelation[Race_1_idx][Race_0_idx] = game.RelationWar assert.LessOrEqual(t, game.DestructionProbability(Cruiser.Weapons, 1, undefeatedShip.Shields, 1, undefeatedShip.EmptyMass()), 0.) assert.True(t, game.FilterBattleOpponents(g, 1, 3, cacheShipGroupRaceID, cacheRelation, cacheShipClass, cacheProbability)) assert.NotContains(t, cacheProbability[1], 3) } func TestSlicesDeleteFunc(t *testing.T) { type Container struct { S []int } c := Container{S: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}} r1 := slices.DeleteFunc(c.S, func(e int) bool { return e%2 != 0 }) assert.Len(t, r1, 5) for i := range r1 { assert.Equal(t, i*2, r1[i], "elem #%d", i) assert.Equal(t, i*2, c.S[i], "elem #%d", i) } assert.Len(t, c.S, 10) for i := len(r1); i < len(c.S); i++ { assert.Equal(t, 0, c.S[i], "elem #%d", i) } }