From 3667e88d9b4471ba7092b650ee12305bf08cba6f Mon Sep 17 00:00:00 2001 From: TheSaminator Date: Tue, 31 May 2022 10:17:47 -0400 Subject: [PATCH] AI fixes --- .../starshipfights/game/ai/ai_behaviors.kt | 17 ++++++++++++----- .../starshipfights/game/ai/ai_util_combat.kt | 3 ++- .../starshipfights/game/ai/ai_util_nav.kt | 4 ++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/commonMain/kotlin/starshipfights/game/ai/ai_behaviors.kt b/src/commonMain/kotlin/starshipfights/game/ai/ai_behaviors.kt index ce77d49..a89f43e 100644 --- a/src/commonMain/kotlin/starshipfights/game/ai/ai_behaviors.kt +++ b/src/commonMain/kotlin/starshipfights/game/ai/ai_behaviors.kt @@ -136,19 +136,26 @@ suspend fun AIPlayer.behave(instincts: Instincts, mySide: GlobalSide) { } else emptyList() }.associateWith { (ship, weaponId, target) -> - weaponId.expectedAdvantageFromWeaponUsage(state, ship, target) * brain[shipAttackPriority forShip target.id].signedPow(instincts[combatPrioritization]) + weaponId.expectedAdvantageFromWeaponUsage(state, ship, target) * smoothNegative(brain[shipAttackPriority forShip target.id].signedPow(instincts[combatPrioritization])) * (1 + target.calculateSuffering()).signedPow(instincts[combatPreyOnTheWeak]) }.weightedRandomOrNull() if (attackWith == null) doActions.send(PlayerAction.UseAbility(PlayerAbilityType.DonePhase(phase), PlayerAbilityData.DonePhase)) else { val (ship, weaponId, target) = attackWith - val targetPickResponse = if (ship.armaments.weaponInstances[weaponId]?.weapon is AreaWeapon) - PickResponse.Location(target.position.location) - else - PickResponse.Ship(target.id) + val targetPickResponse = when (val weaponSpec = ship.armaments.weaponInstances[weaponId]?.weapon) { + is AreaWeapon -> PickResponse.Location(ship.getWeaponPickRequest(weaponSpec).boundary.closestPointTo(target.position.location)) + else -> PickResponse.Ship(target.id) + } doActions.send(PlayerAction.UseAbility(PlayerAbilityType.UseWeapon(ship.id, weaponId), PlayerAbilityData.UseWeapon(targetPickResponse))) + + withTimeoutOrNull(50L) { getErrors.receive() }?.let { error -> + logWarning("Error when attacking target ship ID ${target.id} with weapon $weaponId of ship ID ${ship.id} - $error") + + val nextState = gameState.value + phasePipe.send(nextState.phase to (nextState.doneWithPhase != mySide && (!nextState.phase.usesInitiative || nextState.currentInitiative != mySide.other))) + } } } is GamePhase.Repair -> { diff --git a/src/commonMain/kotlin/starshipfights/game/ai/ai_util_combat.kt b/src/commonMain/kotlin/starshipfights/game/ai/ai_util_combat.kt index 8cbfc61..362e8c2 100644 --- a/src/commonMain/kotlin/starshipfights/game/ai/ai_util_combat.kt +++ b/src/commonMain/kotlin/starshipfights/game/ai/ai_util_combat.kt @@ -11,10 +11,11 @@ val combatTargetShipWeight by instinct { Random.nextDouble(0.5, 2.5) } val combatAvengeShipwrecks by instinct { Random.nextDouble(0.5, 4.5) } val combatAvengeShipWeight by instinct { Random.nextDouble(-0.5, 1.5) } -val combatPrioritization by instinct { Random.nextDouble(-1.0, 1.0) } +val combatPrioritization by instinct { Random.nextDouble(-1.5, 2.5) } val combatAvengeAttacks by instinct { Random.nextDouble(0.5, 4.5) } val combatForgiveTarget by instinct { Random.nextDouble(-1.5, 2.5) } +val combatPreyOnTheWeak by instinct { Random.nextDouble(-1.5, 2.5) } val combatFrustratedByFailedAttacks by instinct { Random.nextDouble(-2.5, 5.5) } diff --git a/src/commonMain/kotlin/starshipfights/game/ai/ai_util_nav.kt b/src/commonMain/kotlin/starshipfights/game/ai/ai_util_nav.kt index d931040..0cdbf18 100644 --- a/src/commonMain/kotlin/starshipfights/game/ai/ai_util_nav.kt +++ b/src/commonMain/kotlin/starshipfights/game/ai/ai_util_nav.kt @@ -20,11 +20,11 @@ fun ShipPosition.score(gameState: GameState, shipInstance: ShipInstance, instinc val canBeAttackedBy = ship.attackableWithDamageBy(gameState) val opportunityScore = canAttack.map { (targetId, potentialDamage) -> - brain[shipAttackPriority forShip targetId].signedPow(instincts[navTunnelVision]) * potentialDamage + smoothNegative(brain[shipAttackPriority forShip targetId]).signedPow(instincts[navTunnelVision]) * potentialDamage }.sum() + (ship.calculateSuffering() * instincts[navLustForBlood]) val vulnerabilityScore = canBeAttackedBy.map { (targetId, potentialDamage) -> - brain[shipAttackPriority forShip targetId].signedPow(instincts[navTunnelVision]) * potentialDamage + smoothNegative(brain[shipAttackPriority forShip targetId]).signedPow(instincts[navTunnelVision]) * potentialDamage }.sum() * -expm1(-ship.calculateSuffering() * instincts[navSqueamishness]) return instincts[navOptimality].pow(opportunityScore.signedPow(instincts[navAggression]) - vulnerabilityScore.signedPow(instincts[navPassivity])) -- 2.25.1