Introducció a les Màquines d'Estats Finits
Les màquines d'estats finits (FSM, per les seves sigles en anglès) són un model matemàtic utilitzat per dissenyar lògica de control en sistemes on el comportament es pot descriure en termes d'estats i transicions entre aquests estats. En el context dels videojocs, les FSM són àmpliament utilitzades per gestionar el comportament dels personatges no jugadors (NPCs).
Conceptes Clau
- Estat: Representa una situació o condició específica en la qual es troba el sistema en un moment donat.
- Transició: El canvi d'un estat a un altre, sovint desencadenat per un esdeveniment o condició.
- Esdeveniment: Una acció o condició que provoca una transició entre estats.
- Acció: Una operació que es realitza quan es produeix una transició o quan es manté un estat.
Exemple de FSM
Considerem un NPC que patrulla una àrea. Els estats possibles podrien ser:
- Patrullar
- Perseguir
- Atacar
- Fugir
Les transicions entre aquests estats es podrien desencadenar per esdeveniments com veure un enemic, ser atacat, o perdre de vista l'enemic.
Implementació d'una FSM
Pseudocodi
A continuació, es presenta un exemple de pseudocodi per implementar una FSM per un NPC que patrulla i persegueix enemics:
state = "Patrullar" while (true): if state == "Patrullar": patrullar() if veure_enemic(): state = "Perseguir" elif state == "Perseguir": perseguir() if perdre_enemic(): state = "Patrullar" elif enemic_a_proper(): state = "Atacar" elif state == "Atacar": atacar() if enemic_fugir(): state = "Perseguir" elif enemic_mort(): state = "Patrullar"
Implementació en Codi (Python)
class NPC: def __init__(self): self.state = "Patrullar" def veure_enemic(self): # Lògica per detectar enemic pass def perdre_enemic(self): # Lògica per perdre de vista l'enemic pass def enemic_a_proper(self): # Lògica per determinar si l'enemic és a prop pass def enemic_fugir(self): # Lògica per determinar si l'enemic fuig pass def enemic_mort(self): # Lògica per determinar si l'enemic és mort pass def patrullar(self): print("Patrullant...") def perseguir(self): print("Perseguint l'enemic...") def atacar(self): print("Atacant l'enemic...") def actualitzar(self): if self.state == "Patrullar": self.patrullar() if self.veure_enemic(): self.state = "Perseguir" elif self.state == "Perseguir": self.perseguir() if self.perdre_enemic(): self.state = "Patrullar" elif self.enemic_a_proper(): self.state = "Atacar" elif self.state == "Atacar": self.atacar() if self.enemic_fugir(): self.state = "Perseguir" elif self.enemic_mort(): self.state = "Patrullar" # Exemple d'ús npc = NPC() while True: npc.actualitzar()
Exercicis Pràctics
Exercici 1: Implementar una FSM per un NPC que patrulla i fuig
Descripció: Implementa una FSM per un NPC que patrulla una àrea i fuig quan veu un enemic.
Solució:
class NPC: def __init__(self): self.state = "Patrullar" def veure_enemic(self): # Lògica per detectar enemic pass def perdre_enemic(self): # Lògica per perdre de vista l'enemic pass def patrullar(self): print("Patrullant...") def fugir(self): print("Fugint...") def actualitzar(self): if self.state == "Patrullar": self.patrullar() if self.veure_enemic(): self.state = "Fugir" elif self.state == "Fugir": self.fugir() if self.perdre_enemic(): self.state = "Patrullar" # Exemple d'ús npc = NPC() while True: npc.actualitzar()
Exercici 2: Afegir un estat de "Buscar" a la FSM
Descripció: Afegiu un estat de "Buscar" a la FSM de l'exemple anterior, on l'NCP buscarà l'enemic durant un temps abans de tornar a patrullar.
Solució:
class NPC: def __init__(self): self.state = "Patrullar" self.temps_buscar = 0 def veure_enemic(self): # Lògica per detectar enemic pass def perdre_enemic(self): # Lògica per perdre de vista l'enemic pass def patrullar(self): print("Patrullant...") def fugir(self): print("Fugint...") def buscar(self): print("Buscant l'enemic...") self.temps_buscar -= 1 def actualitzar(self): if self.state == "Patrullar": self.patrullar() if self.veure_enemic(): self.state = "Fugir" elif self.state == "Fugir": self.fugir() if self.perdre_enemic(): self.state = "Buscar" self.temps_buscar = 5 # Temps de buscar elif self.state == "Buscar": self.buscar() if self.temps_buscar <= 0: self.state = "Patrullar" # Exemple d'ús npc = NPC() while True: npc.actualitzar()
Errors Comuns i Consells
- No gestionar correctament les transicions: Assegureu-vos que totes les transicions entre estats estan ben definides i que no hi ha bucles infinits.
- No actualitzar els estats correctament: Verifiqueu que els estats es canvien només quan es compleixen les condicions adequades.
- No implementar accions per a cada estat: Cada estat ha de tenir una acció associada que es realitzi mentre l'NCP es troba en aquest estat.
Conclusió
Les màquines d'estats finits són una eina poderosa per gestionar el comportament dels NPCs en videojocs. Amb una comprensió clara dels conceptes bàsics i una implementació acurada, podeu crear comportaments complexos i realistes per als vostres personatges. En el següent tema, explorarem els arbres de decisió, una altra tècnica important per a la presa de decisions en IA per a videojocs.
IA per a Videojocs
Mòdul 1: Introducció a la IA en Videojocs
Mòdul 2: Navegació en Videojocs
Mòdul 3: Presa de Decisions
Mòdul 4: Aprenentatge Automàtic
- Introducció a l'Aprenentatge Automàtic
- Xarxes Neuronals en Videojocs
- Aprenentatge per Reforç
- Implementació d'un Agent d'Aprenentatge
Mòdul 5: Integració i Optimització
Mòdul 6: Projectes Pràctics
- Projecte 1: Implementació de Navegació Bàsica
- Projecte 2: Creació d'un NPC amb Presa de Decisions
- Projecte 3: Desenvolupament d'un Agent amb Aprenentatge Automàtic