-
Notifications
You must be signed in to change notification settings - Fork 0
/
finite_state_machine.py
167 lines (122 loc) · 4 KB
/
finite_state_machine.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
from enum import Enum, auto
import time
class State():
def __init__(self):
self.state_finished = False
def _enter_state(self) -> None:
pass
def _exit_state(self) -> None:
print("exiting")
class FiniteStateMachine():
def __init__(self) -> None:
self.state = State()
def change_state(self, new_state: State):
if isinstance(self.state, State):
self.state._exit_state()
new_state._enter_state()
state = new_state
class EnemyWanderState(State):
def __init__(self) -> None:
super().__init__()
self.actor = Enemy()
class Enemy(FiniteStateMachine):
def __init__(self) -> None:
super().__init__()
self.max_speed = 40
self.acceleration = 50
goblin = Enemy()
goblin.change_state(EnemyWanderState())
################################ Variante 2 ###############################################
class Emily():
def __init__(self):
self.current_state = 'init'
self.prev_state = ''
self.new_state = ''
self.running_count = 0
def update_state(self):
if self.new_state != '':
if self.new_state != self.current_state:
init_method = "_init_" + self.new_state
end_method = "_end_" + self.current_state
self.if_has_method_call_it(end_method)
self.prev_state = self.current_state
self.current_state = self.new_state
self.new_state = ''
self.if_has_method_call_it(init_method)
else:
self.new_state = ''
def if_has_method_call_it(self, method: str):
if hasattr(self, method) and callable(getattr(self, method)):
method = getattr(self, method)
method()
def process_state(self):
self.if_has_method_call_it('_' + self.current_state)
def _init(self):
self.new_state = "running"
print("Example init")
def _init_running(self):
print("Entering run mode")
def _running(self):
print("I am running so fast rn ngl")
self.running_count += 1
if self.running_count >= 10:
self.new_state = "stopped"
def _end_running(self):
print("Okay, slowing down now, ending running")
def _init_stopped(self):
print("System has stopped")
""" il_gatto = Emily()
for i in range(12):
il_gatto.process_state()
il_gatto.update_state() """
################################ Variante 3 ###############################################
class States(Enum):
IDLE = auto()
CHASE = auto()
ATTACK = auto()
DEATH = auto()
class GameObject:
def __init__(self):
self.__state = States.IDLE
def set_state(self, state):
self.__state = state
def get_state(self):
return self.__state
class Entity(GameObject):
def __init__(self):
super().__init__()
self.__health = 100
def sub_health(self):
self.__health -= 20
def get_health(self):
return self.__health
def set_health(self, health):
self.__health = health
player = Entity()
player.set_state(States.ATTACK)
enemy = Entity()
enemy.set_state(States.CHASE)
while False:
if player.get_state() == States.ATTACK:
print("player attacking!")
enemy.sub_health()
if enemy.get_state() != States.ATTACK:
enemy.set_state(States.ATTACK)
if enemy.get_health() <= 0:
enemy.set_state(States.DEATH)
print("enemy died")
break
elif player.get_state() == States.DEATH:
print("player died")
break
if enemy.get_state() == States.ATTACK:
print("enemy attacking!")
player.sub_health()
if player.get_health() <= 0:
player.set_state(States.DEATH)
print("player died")
break
time.sleep(1)
""" print("------------------------------")
print("player's health ", player.get_health())
print("enemy's health ", enemy.get_health()) """