Actualmente estoy desarrollando un sistema GOAP en Java. Se puede encontrar una explicación de GOAP en http://web.media.mit.edu/~jorkin/goap.html . Esencialmente, está usando A * para trazar entre las acciones que mutan el estado mundial.
Para proporcionar una oportunidad justa para que se ejecuten todas las acciones y objetivos, estoy usando una función heurística para estimar el costo de hacer algo. ¿Cuál es la mejor manera de estimar este costo para que sea comparable a todos los demás costos?
Como ejemplo, estimar el costo de escapar de un enemigo en lugar de atacarlo: ¿cómo debe calcularse el costo para que sea comparable?
java
ai
path-finding
fullwall
fuente
fuente
Respuestas:
Para que todos los costos sean comparables, solo necesita usar la misma heurística para todas las acciones. Por ejemplo, todas las acciones tienen una lista de resultados potenciales y todos los resultados tienen un cierto valor para la entidad.
Por ejemplo, hay una piscina profunda con agua, y la entidad tiene sed. Así que miramos una acción que el grupo tiene disponible para satisfacer esa necesidad:
Primero, las prioridades de la entidad asociadas con estos lugares, podría llamarlos modificadores. Algunos de estos cambiarán con el tiempo y dependerán de la entidad. Por ejemplo, una hormiga podría preocuparse menos por mantenerse con vida y más por las preocupaciones de la colonia. O si una entidad ha pasado un tiempo sin beber, la prioridad de satisfacer la sed puede anular a otras.
Prioridades de la entidad :
Satisfacer la sed: 40
Mantenerse seco: 10
Mantenerse vivo: 100
Entonces, qué representa la ubicación:
Ubicación : piscina
Acción : recoger agua
* Posibles resultados: * :
satisfacer la sed - (-95)
Mojarse - 10
ahogarse - 1
Entonces podríamos calcular el costo de acción en: (40 * -95) + (10 * 10) + (100 * 1) = -3600
Donde recoger agua de un río furioso podría verse así:
Ubicación : Río enfurecido
Acción : Recoger agua
* Resultados potenciales: * :
Satisfacer la sed - (-95)
Mojarse - 90
Ahogarse - 60
(40 * -95) + (10 * 90) + (100 * 60) = 3100
Por lo tanto, es claramente una mejor opción para recoger agua de la piscina. Tal vez si el río furioso fuera la única opción, la entidad esperaría hasta que su prioridad de satisfacer la sed fuera muy alta antes de probar el río.
Es posible que desee mantener las cosas mucho más simples al comenzar. Solo tiene algunas variables que pueden aplicarse más globalmente. Como mantenerse vivo, satisfacer necesidades. En tu ejemplo de lucha o huida, deberías darle a cada entidad una calificación de combate, para que puedan clasificarse efectivamente contra la otra entidad con fines de puntuación.
fuente
Lo sé, lo sé, ha pasado bastante tiempo.
De hecho, en GOAP implementado en 2005 por Jeff Orkin en FEAR (y reutilizado en las secuelas, extensión y ... Shadow Of Mordor), las acciones tienen costos fijos, que van desde 0.5 a 8. En general, el costo de atacar es mucho más caro que el costo de defender. Se puede acceder a estos costos en la base de datos de juegos del Free FEAR SDK (2008); aquí están:
{{Animate, 1}, {Attack, 6}, {AttackBurstLimited, 5}, {AttackCrouch, 5}, {AttackFromAmbush, 4}, {AttackFromArmored, 4}, {AttackFromArmoredBounded, 4}, {AttackFromArmoredBounded, 4}, {AttackFromCover, 4}, { AttackFromVehicle, 1}, {AttackFromView, 4.5}, {AttackGrenadeFromCover, 2}, {AttackLunge3D, 1}, {AttackLungeMelee, 1}, {AttackLungeSuicide, 1}, {AttackLungeUncloaked, 1}, {AttackMelee, 3 }L, {AttackMelee, 3}, {Attack 1}, {AttackMeleeUncloaked, 3}, {AttackReady, 7}, {AttackTurret, 6}, {AttackTurretCeiling, 6}, {BlindFireFromCover, 2}, {Charge, 1}, {DeathOnVehicle, 1}, {DismountNodeUncloaked, 1} , {DismountVehicle, 1}, {DodgeCovered, 1}, {DodgeOnVehicle, 1}, {DodgeRoll, 2}, {DodgeRollParanoid, 2}, {DodgeShuffle, 3}, {DrawWeapon, 1}, {EscapeDanger, 0.5}, { FaceNode, 1}, {FlushOutWithGrenade, 3}, {Follow, 3}, {FollowHeavyArmor, 2}, {FollowPlayer, 2}, {FollowPlayerFidget, 1.8},{FollowWaitAtNode, 4}, {GetOutOfTheWay, 1}, {GotoNode, 1}, {GotoNode3D, 1}, {GotoNodeDirect, 1}, {GotoNodeOfType, 1}, {GotoTarget, 4}, {GotoTarget3D, 4}, {GotoT , 8}, {GotoValidPosition, 1}, {HolsterWeapon, 1}, {Idle, 2}, {IdleFidget, 1}, {IdleOnVehicle, 1}, {IdleTurret, 2}, {InspectDisturbance, 2}, {InstantDeath, 1 }, {InstantDeathKnockDown, 1}, {KnockDownBullet, 2}, {KnockDownExplosive, 2}, {KnockDownMelee, 2}, {LongRecoilBullet, 3}, {LongRecoilExplosive, 3}, {LongRecoilHelmetPiercing, 3}, {LongRecoilMe, 3, {LongRecoilMe, {LookAtDisturbance, 1.5}, {LookAtDisturbanceFromView, 3}, {LopeToTargetUncloaked, 1}, {MountNodeUncloaked, 1}, {MountVehicle, 1}, {ReactToDanger, 1}, {Reload, 5}, {ReloadCovered, 1}, {Reloch , 5}, {ShortRecoilMelee, 4}, {Aturdido, 1}, {SuppressionFire, 2}, {SuppressionFireFromCover, 1}, {SurveyArea, 1},{TraverseBlockedDoor, 1}, {TraverseLink, 2}, {TraverseLinkUncloaked, 1}, {Uncover, 1}, {UseSmartObjectNode, 3}, {UseSmartObjectNodeMounted, 1}}
Pero no es el caso en todas las implementaciones de GOAP y, por ejemplo, los Tomb Raiders tienen costos variables (por ejemplo, la distancia para una acción Goto).
Las acciones también tienen condiciones previas y algunas acciones se deben jugar a pesar de la arquitectura GOAP (por ejemplo, reproducir una animación "aturdida" en reacción que disminuye rápidamente la salud, a pesar del objetivo "Kill Enemy" y el plan que GOAP regresa para satisfacer ese objetivo). En su ejemplo, es decir, huir frente a atacar, el nivel de salud puede ser una condición previa (y no es necesario tener costos variables).
O bien, una función miembro Check_Costs () se ejecuta antes que nada, según las prioridades de Michael, y devuelve el costo dinámico.
Ahora, tenga en cuenta que en Shadow Of Mordor los desarrolladores de juegos intentaron jugar con los costos de las acciones para influir en lo que se ejecutaría en la pantalla. Resulta que no es tan fácil e incluso la acción barata no aparece tan a menudo: la IA en un juego apoya al jugador; si el jugador no hace lo que se espera, la IA solo lo admitirá y ... lo que aparecerá en la pantalla no será el diseño del juego esperado.
fuente