forked from maiquynhtruong/algorithms-and-problems
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfinite-state-machine.java
132 lines (121 loc) · 4.66 KB
/
finite-state-machine.java
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
// https://gamedevelopment.tutsplus.com/tutorials/finite-state-machines-theory-and-implementation--gamedev-11867
public class FSM {
public State activeState;
public Ant ant;
public void setState(State newState) {
activeState = newState;
}
public void update() {
if (activeState == State.FIND_LEAF) ant.findLeaf();
else if (activeState == State.GO_HOME) ant.goHome();
else if (activeState == State.RUN_AWAY) ant.runAway();
}
}
public class Ant {
public Vector3D position;
public Vector3D velocity;
public FSM brain;
/* The "find leaf" state where the ant moves toward the leaf */
public void findLeaf() {
velocity = new Vector3D(leaf.x - position.x, leaf.y - position.y);
if (distance(leaf, this) <= 5) {
// Near the leaf so eat it and go home
eatLeaf();
brain.setState(State.GO_HOME);
}
if (distance(cursor, this) <= MOUSE_THREAD_RADIUS) {
// Cursor is near so need to run away
brain.setState(State.RUN_AWAY);
}
}
/* The "go home" state where the ant goes home */
public void goHome() {
velocity = new Vector3D(home.x - position.x, home.y - position.y);
if (distance(home, this) <= 5) {
// At home and needs to go find leaf
brain.setState(State.FIND_LEAF);
}
}
/* The "run away" state where the ant runs away from the cursor */
public void runAway() {
velocity = new Vector3D(cursor.x - position.x, cursor.y - position.y);
moveOneStep();
if (distance(cursor, this) > MOUSE_THREAT_RADIUS) {
brain.setState(State.FIND_LEAF);
}
}
/* call every game frame to determine what the ant should be doing next */
public void update() {
brain.update();
}
}
/**** Implemenation using stack **/
public class FSM {
/* The top of the stack contains the active state and transitions are handled by pushing or
popping states from the stack */
public Ant ant = new Ant();
public Stack<State> stack = new Stack<State>();
public void update() {
State activeState = stack.peek();
if (activeState == State.FIND_LEAF) ant.findLeaf();
else if (activeState == State.GO_HOME) ant.goHome();
else if (activeState == State.RUN_AWAY) ant.runAway();
}
/* A state can pop itself, which means the current state is complete and the next state in teh stack
should become active */
public State popState() {
return stack.pop();
}
/* Currently active state will change for a while, but then it pops itself from the stack,
the previously active state will take over again */
public void pushState(State state) {
if (stack.peek() != state) stack.push(state);
}
/* Also a state can pop itself and push another state, which means a full transition */
}
public class Ant {
FSM brain;
Vector3D velocity;
Vector3D position;
/* The "find leaf" state where the ant moves toward the leaf */
public void findLeaf() {
velocity = new Vector3D(leaf.x - position.x, leaf.y - position.y);
if (distance(leaf, this) <= 5) {
// Near the leaf so eat it and go home
eatLeaf();
brain.popState();
brain.pushState(State.GO_HOME);
}
if (distance(cursor, this) <= MOUSE_THREAD_RADIUS) {
// The "runAway" state is pushed on top of "findLeaf", which means
// the "findLeaf" state will be active again when "runAway" ends.
brain.pushState(State.RUN_AWAY);
}
}
/* The "go home" state where the ant goes home */
public void goHome() {
velocity = new Vector3D(home.x - position.x, home.y - position.y);
if (distance(home, this) <= 5) {
// At home and needs to go find leaf
brain.popState();
brain.pushState(State.FIND_LEAF);
}
if (distance(cursor, this) <= MOUSE_THREAD_RADIUS) {
// The "runAway" state is pushed on top of "goHome", which means
// the "goHome" state will be active again when "runAway" ends.
brain.pushState(State.RUN_AWAY);
}
}
/* The "run away" state where the ant runs away from the cursor */
public void runAway() {
velocity = new Vector3D(cursor.x - position.x, cursor.y - position.y);
moveOneStep();
if (distance(cursor, this) > MOUSE_THREAT_RADIUS) {
brain.popState();
}
}
/* call every game frame to determine what the ant should be doing next */
public void update() {
brain.update();
}
}