-
Notifications
You must be signed in to change notification settings - Fork 0
/
template.pcsp
277 lines (249 loc) · 16.5 KB
/
template.pcsp
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
// NOTE: This will only produce probabilities of goal when the away team attacks while the home team defends
// A similar pcsp file will have to be generated from the home team POV to meaningfully compare which team has the higher chance of scoring during an attack
// Position of players in grid
// Left, LeftRight, and CenterLeft etc.
#define L 6;
#define LR 7;
#define CL 8;
#define C 9;
#define CR 10;
#define RL 11;
#define R 12;
#define PENALTY_KICK 0;
#define FREE_KICK 1;
#define DEF_LINE 0;
#define MID_DEF_LINE 1;
#define MID_LINE 2;
#define MID_FOR_LINE 3;
#define FOR_LINE 4;
// Added: Maximum number of BackwardPasses allowed
#define BACKWARDPASS_MAX 3;
// Arrays for tracking yellow/red cards
var defendersCards = [-1(6), 0(7), -1(6)];
var midfieldersDefCards = [-1(6), 0(7), -1(6)];
var midfieldersCards = [-1(6), 0(7), -1(6)];
var midfieldersForCards = [-1(6), 0(7), -1(6)];
var forwardsCards = [-1(6), 0(7), -1(6)];
// Grid of eligible positions that can receive the ball
// This will change based on the previous position and the action taken
// 1 means the position is eligible to receive the ball
// 0 means the position is not eligible to receive the ball
// See Individual Positions section for more info
var pos = [-1(6), 0, 0, 0, 1, 0, 0, 0, -1(6)];
// If the ball is in the air
var inAir = false;
// Boolean flags to define extra levels
__flags__
// Danger level for the attacking team
// The lower the value, the lesser the danger
var danger = 0;
// Number of BackwardPasses
var backwardPassCount = 0;
// Actions based on FIFA player ratings
// ShortPass, LongPass, LongShot, Finishing, Volley, and Header
enum {SP, LP, LS, FI, VO, HD, BP};
// Soccer field grid
// 1 means there is a player in that position
// 0 means there is no player in that position
__grid__
///////////// AWAY TEAM PLAYERS (Attacking Team) /////////////
// The parameters represent the probabilities specific to the player
// The gurad only allows eligible players to get the ball, see Individual Positions section for more info
// For example keepers can only ShortPass or LongPass
// Here 64, 64 represents the FIFA ShortPass and LongPass ratings for this particular player
AtkKep = __AtkKep__;
// Here for the defenders, the first 3 parameters are with respect to the ShortPass, LongPass, and prob. to lose the ball respectively
// The prob. to lose the ball for the attacking team's defenders was calculated based on the defending team forward's player ratings
// In particular, the probability to lose the ball was a weighted combination of the standing tackle, sliding tackle, and interception FIFA player ratings of the forwards
AtkDef = __AtkDef__;
// Similar to defenders, midfielders and forwards have their own specific parameters
// See their processes below for more information on what those parameters are
// The prob. to lose for the attacking team's midfielders is based on the defending team's midfielders
// The prob. to lose for the attacking team's forwards is based on the defending team's defenders
__AtkMid__
AtkFor = __AtkFor__;
///////////// HOME TEAM PLAYERS (Defending Team) /////////////
// Home team defenders, midfielders and forwards are already implicitly "defending" via the prob. to lose the ball parameter
DefKep = __DefKep__;
///////////// Individual Positions /////////////
// There is a guard to every action (e.g., shortPass) a player can take
// The guard makes sure that there are players eligible to receive the ball should that action happen
// Furthermore, based on the type of action taken, only some players will be eligible to receive the ball
// E.g., If a defender at L does a shortPass, the midfielder at R should not be able to receive it
// The eligible players are updated with UpdatePos
Kep_1(i, j, p) = [atkDefPos[p-2] == 1 || atkDefPos[p-1] == 1 || atkDefPos[p] == 1 || atkDefPos[p+1] == 1 || atkDefPos[p+2] == 1]shortPass -> pcase {
i: pass -> UpdatePos(p, SP); AtkDef
100-i: intercepted{danger = 5;} -> Skip
} [] [atkDefPos[p-6] == 1 || atkDefPos[p-5] == 1 || atkDefPos[p-4] == 1 || atkDefPos[p-3] == 1 || atkDefPos[p+3] == 1 || atkDefPos[p+4] == 1 || atkDefPos[p+5] == 1 || atkDefPos[p+6] == 1]longPass -> pcase {
j: pass -> UpdatePos(p, LP); AtkDef
100-j: intercepted{danger = 5;} -> Skip
};
Def(i, j, k, p, fk) = [isMidDefOccupied && atkMidDefPos[p-2] == 1 || atkMidDefPos[p-1] == 1 || atkMidDefPos[p] == 1 || atkMidDefPos[p+1] == 1 || atkMidDefPos[p+2] == 1]shortPass -> pcase {
i: pass -> UpdatePos(p, SP); AtkMidDef
k: FoulAndCardsCheck(fk, p, DEF_LINE, FREE_KICK, 4, SP); AtkMidDef
} [] [isMidDefOccupied && atkMidDefPos[p-6] == 1 || atkMidDefPos[p-5] == 1 || atkMidDefPos[p-4] == 1 || atkMidDefPos[p-3] == 1 || atkMidDefPos[p+3] == 1 || atkMidDefPos[p+4] == 1 || atkMidDefPos[p+5] == 1 || atkMidDefPos[p+6] == 1]longPass -> pcase {
j: pass -> UpdatePos(p, LP); AtkMidDef
k: FoulAndCardsCheck(fk, p, DEF_LINE, FREE_KICK, 4, LP); AtkMidDef
} [] [!isMidDefOccupied && atkMidPos[p-2] == 1 || atkMidPos[p-1] == 1 || atkMidPos[p] == 1 || atkMidPos[p+1] == 1 || atkMidPos[p+2] == 1]shortPass -> pcase {
i: pass -> UpdatePos(p, SP); AtkMid
k: FoulAndCardsCheck(fk, p, DEF_LINE, FREE_KICK, 4, SP); AtkMid
} [] [!isMidDefOccupied && atkMidPos[p-6] == 1 || atkMidPos[p-5] == 1 || atkMidPos[p-4] == 1 || atkMidPos[p-3] == 1 || atkMidPos[p+3] == 1 || atkMidPos[p+4] == 1 || atkMidPos[p+5] == 1 || atkMidPos[p+6] == 1]longPass -> pcase {
j: pass -> UpdatePos(p, LP); AtkMid
k: FoulAndCardsCheck(fk, p, DEF_LINE, FREE_KICK, 4, LP); AtkMid
};
Mid(i, j, k, l, p, fk) = [isMidForOccupied && atkMidForPos[p-2] == 1 || atkMidForPos[p-1] == 1 || atkMidForPos[p] == 1 || atkMidForPos[p+1] == 1 || atkMidForPos[p+2] == 1]shortPass -> pcase {
i: pass -> UpdatePos(p, SP); AtkMidFor
l: FoulAndCardsCheck(fk, p, MID_LINE, FREE_KICK, 3, SP); AtkMidFor
}[] [isMidForOccupied && atkMidForPos[p-6] == 1 || atkMidForPos[p-5] == 1 || atkMidForPos[p-4] == 1 || atkMidForPos[p-3] == 1 || atkMidForPos[p+3] == 1 || atkMidForPos[p+4] == 1 || atkMidForPos[p+5] == 1 || atkMidForPos[p+6] == 1]longPass -> pcase {
j: pass{inAir = true;} -> UpdatePos(p, LP); AtkMidFor
l: FoulAndCardsCheck(fk, p, MID_LINE, FREE_KICK, 3, LP); AtkMidFor
} [] [!isMidForOccupied && atkForPos[p-2] == 1 || atkForPos[p-1] == 1 || atkForPos[p] == 1 || atkForPos[p+1] == 1 || atkForPos[p+2] == 1]shortPass -> pcase {
i: pass -> UpdatePos(p, SP); AtkFor
l: FoulAndCardsCheck(fk, p, MID_LINE, FREE_KICK, 3, SP); AtkFor
}[] [!isMidForOccupied && atkForPos[p-6] == 1 || atkForPos[p-5] == 1 || atkForPos[p-4] == 1 || atkForPos[p-3] == 1 || atkForPos[p+3] == 1 || atkForPos[p+4] == 1 || atkForPos[p+5] == 1 || atkForPos[p+6] == 1]longPass -> pcase {
j: pass{inAir = true;} -> UpdatePos(p, LP); AtkFor
l: FoulAndCardsCheck(fk, p, MID_LINE, FREE_KICK, 3, LP); AtkFor
} [] [defKepPos[C] == 1]longShot -> pcase {
k: shoot -> UpdatePos(p, LS); DefKep
l: FoulAndCardsCheck(fk, p, MID_LINE, FREE_KICK, 3, LS); DefKep
} [] [!isMidDefOccupied && (backwardPassCount < BACKWARDPASS_MAX) && (atkDefPos[p-2] == 1 || atkDefPos[p-1] == 1 || atkDefPos[p] == 1 || atkDefPos[p+1] == 1 || atkDefPos[p+2] == 1)]backwardPass -> pcase {
i: pass -> UpdatePos(p, BP); AtkDef
l: tackled{danger = 3;} -> Skip
} [] [isMidDefOccupied && (backwardPassCount < BACKWARDPASS_MAX) && (atkMidDefPos[p-2] == 1 || atkMidDefPos[p-1] == 1 || atkMidDefPos[p] == 1 || atkMidDefPos[p+1] == 1 || atkMidDefPos[p+2] == 1)]backwardPass -> pcase {
i: pass -> UpdatePos(p, BP); AtkMidDef
l: tackled{danger = 3;} -> Skip
};
MidDef(i, j, k, l, p, fk) = [atkMidPos[p-2] == 1 || atkMidPos[p-1] == 1 || atkMidPos[p] == 1 || atkMidPos[p+1] == 1 || atkMidPos[p+2] == 1]shortPass -> pcase {
i: pass -> UpdatePos(p, SP); AtkMid
l: FoulAndCardsCheck(fk, p, MID_DEF_LINE, FREE_KICK, 3, SP); AtkMid
} [] [atkMidPos[p-6] == 1 || atkMidPos[p-5] == 1 || atkMidPos[p-4] == 1 || atkMidPos[p-3] == 1 || atkMidPos[p+3] == 1 || atkMidPos[p+4] == 1 || atkMidPos[p+5] == 1 || atkMidPos[p+6] == 1]longPass -> pcase {
j: pass{inAir = true;} -> UpdatePos(p, LP); AtkMid
l: FoulAndCardsCheck(fk, p, MID_DEF_LINE, FREE_KICK, 3, LP); AtkMid
} [] [defKepPos[C] == 1]longShot -> pcase {
k: shoot -> UpdatePos(p, LS); DefKep
l: FoulAndCardsCheck(fk, p, MID_DEF_LINE, FREE_KICK, 3, LS); DefKep
} [] [(backwardPassCount < BACKWARDPASS_MAX) && (atkDefPos[p-2] == 1 || atkDefPos[p-1] == 1 || atkDefPos[p] == 1 || atkDefPos[p+1] == 1 || atkDefPos[p+2] == 1)]backwardPass -> pcase {
i: pass -> UpdatePos(p, BP); AtkDef
l: tackled{danger = 3;} -> Skip
};
MidFor(i, j, k, l, p, fk) = [atkForPos[p-2] == 1 || atkForPos[p-1] == 1 || atkForPos[p] == 1 || atkForPos[p+1] == 1 || atkForPos[p+2] == 1]shortPass -> pcase {
i: pass -> UpdatePos(p, SP); AtkFor
l: FoulAndCardsCheck(fk, p, MID_FOR_LINE, FREE_KICK, 3, SP); AtkFor
} [] [atkForPos[p-6] == 1 || atkForPos[p-5] == 1 || atkForPos[p-4] == 1 || atkForPos[p-3] == 1 || atkForPos[p+3] == 1 || atkForPos[p+4] == 1 || atkForPos[p+5] == 1 || atkForPos[p+6] == 1]longPass -> pcase {
j: pass{inAir = true;} -> UpdatePos(p, LP); AtkFor
l: FoulAndCardsCheck(fk, p, MID_FOR_LINE, FREE_KICK, 3, LP); AtkFor
} [] [defKepPos[C] == 1]longShot -> pcase {
k: shoot -> UpdatePos(p, LS); DefKep
l: FoulAndCardsCheck(fk, p, MID_FOR_LINE, FREE_KICK, 3, LS); DefKep
} [] [(backwardPassCount < BACKWARDPASS_MAX) && (atkMidPos[p-2] == 1 || atkMidPos[p-1] == 1 || atkMidPos[p] == 1 || atkMidPos[p+1] == 1 || atkMidPos[p+2] == 1)]backwardPass -> pcase {
i: pass -> UpdatePos(p, BP); AtkMid
l: tackled{danger = 3;} -> Skip
};
For(i, j, k, l, m, p, pk) = [defKepPos[C] == 1]finish -> pcase {
i: shoot -> UpdatePos(p, FI); DefKep
m: FoulAndCardsCheck(pk, p, FOR_LINE, PENALTY_KICK, 2, FI); DefKep
} [] [defKepPos[C] == 1]longShot -> pcase {
j: shoot -> UpdatePos(p, LS); DefKep
m: FoulAndCardsCheck(pk, p, FOR_LINE, PENALTY_KICK, 2, LS); DefKep
} [] [defKepPos[C] == 1 && inAir == true]volley -> pcase {
k: shoot -> UpdatePos(p, VO); DefKep
m: FoulAndCardsCheck(pk, p, FOR_LINE, PENALTY_KICK, 2, VO); DefKep
} [] [defKepPos[C] == 1 && inAir == true]header -> pcase {
l: shoot -> UpdatePos(p, HD); DefKep
m: FoulAndCardsCheck(pk, p, FOR_LINE, PENALTY_KICK, 2, HD); DefKep
} [] [!isMidForOccupied && (backwardPassCount < BACKWARDPASS_MAX) && (atkMidPos[p-2] == 1 || atkMidPos[p-1] == 1 || atkMidPos[p] == 1 || atkMidPos[p+1] == 1 || atkMidPos[p+2] == 1)]backwardPass -> pcase {
i: pass -> UpdatePos(p, BP); AtkMid
m: FoulAndCardsCheck(pk, p, FOR_LINE, PENALTY_KICK, 2, FI); DefKep
} [] [isMidForOccupied && (backwardPassCount < BACKWARDPASS_MAX) && (atkMidForPos[p-2] == 1 || atkMidForPos[p-1] == 1 || atkMidForPos[p] == 1 || atkMidForPos[p+1] == 1 || atkMidForPos[p+2] == 1)]backwardPass -> pcase {
i: pass -> UpdatePos(p, BP); AtkMidFor
m: FoulAndCardsCheck(pk, p, FOR_LINE, PENALTY_KICK, 2, FI); DefKep
};
Kep_2(i, p) = attemptSave -> pcase {
i: save{danger = 1;} -> Skip
100-i: concede -> Skip
};
// Added: process for fouls and yellow, red cards
FoulAndCardsCheck(aggressionDifference, playerPosition, linePosition, isPenaltyOrFreeKick, dangerLevel, actionType) = case {
aggressionDifference < -40: // red card issued to player
EjectPlayer()
aggressionDifference < -30: // yellow card issued to player
IssueYellowCard(playerPosition, linePosition) []
[defendersCards[L] > 0 || defendersCards[LR] > 0 || defendersCards[CL] > 0 || defendersCards[C] > 0 || defendersCards[CR] > 0 || defendersCards[RL] > 0 || defendersCards[R] > 0 ||
midfieldersDefCards[L] > 0 || midfieldersDefCards[LR] > 0 || midfieldersDefCards[CL] > 0 || midfieldersDefCards[C] > 0 || midfieldersDefCards[CR] > 0 || midfieldersDefCards[RL] > 0 || midfieldersDefCards[R] > 0 ||
midfieldersCards[L] > 0 || midfieldersCards[LR] > 0 || midfieldersCards[CL] > 0 || midfieldersCards[C] > 0 || midfieldersCards[CR] > 0 || midfieldersCards[RL] > 0 || midfieldersCards[R] > 0 ||
midfieldersForCards[L] > 0 || midfieldersForCards[LR] > 0 || midfieldersForCards[CL] > 0 || midfieldersForCards[C] > 0 || midfieldersForCards[CR] > 0 || midfieldersForCards[RL] > 0 || midfieldersForCards[R] > 0 ||
forwardsCards[L] > 0 || forwardsCards[L] > 0 || forwardsCards[L] > 0 || forwardsCards[L] > 0 || forwardsCards[L] > 0 || forwardsCards[L] > 0 || forwardsCards[L] > 0]
EjectPlayer()
aggressionDifference > 20: // foul committed by opposing team; get free kick or penalty kick
UpdatePos(playerPosition, actionType)
default: // player is tackled and loses possession of ball
tackled { danger = dangerLevel; } -> Stop
};
// Added: send player away because of red card/2 yellow cards issued
EjectPlayer() = Stop;
// Added: process for issuing yellow card
IssueYellowCard(playerPosition, linePosition) = case {
linePosition == DEF_LINE: {defendersCards[playerPosition] = defendersCards[playerPosition] + 1;} -> Skip
linePosition == MID_DEF_LINE: {midfieldersDefCards[playerPosition] = midfieldersDefCards[playerPosition] + 1;} -> Skip
linePosition == MID_LINE: {midfieldersCards[playerPosition] = midfieldersCards[playerPosition] + 1;} -> Skip
linePosition == MID_FOR_LINE: {midfieldersForCards[playerPosition] = midfieldersForCards[playerPosition] + 1;} -> Skip
linePosition == FOR_LINE: {forwardsCards[playerPosition] = forwardsCards[playerPosition] + 1;} -> Skip
default: Skip
};
// Added: cases for BackwardPass
UpdatePos(p, e) = case {
p == L:
case {
e == SP: {pos[L] = 1; pos[LR] = 1; pos[CL] = 1; pos[C] = 0; pos[CR] = 0; pos[RL] = 0; pos[R] = 0;} -> Skip
e == LP: {pos[L] = 0; pos[LR] = 0; pos[CL] = 0; pos[C] = 1; pos[CR] = 1; pos[RL] = 1; pos[R] = 1;} -> Skip
e == BP: {pos[L] = 1; pos[LR] = 1; pos[CL] = 1; pos[C] = 0; pos[CR] = 0; pos[RL] = 0; pos[R] = 0; backwardPassCount = backwardPassCount + 1;} -> Skip
default: {pos[L] = 0; pos[LR] = 0; pos[CL] = 0; pos[C] = 1; pos[CR] = 0; pos[RL] = 0; pos[R] = 0;} -> Skip
}
p == LR:
case {
e == SP: {pos[L] = 1; pos[LR] = 1; pos[CL] = 1; pos[C] = 1; pos[CR] = 0; pos[RL] = 0; pos[R] = 0;} -> Skip
e == LP: {pos[L] = 0; pos[LR] = 0; pos[CL] = 0; pos[C] = 0; pos[CR] = 1; pos[RL] = 1; pos[R] = 1;} -> Skip
e == BP: {pos[L] = 1; pos[LR] = 1; pos[CL] = 1; pos[C] = 1; pos[CR] = 0; pos[RL] = 0; pos[R] = 0; backwardPassCount = backwardPassCount + 1;} -> Skip
default: {pos[L] = 0; pos[LR] = 0; pos[CL] = 0; pos[C] = 1; pos[CR] = 0; pos[RL] = 0; pos[R] = 0;} -> Skip
}
p == CL:
case {
e == SP: {pos[L] = 1; pos[LR] = 1; pos[CL] = 1; pos[C] = 1; pos[CR] = 1; pos[RL] = 0; pos[R] = 0;} -> Skip
e == LP: {pos[L] = 0; pos[LR] = 0; pos[CL] = 0; pos[C] = 0; pos[CR] = 0; pos[RL] = 1; pos[R] = 1;} -> Skip
e == BP: {pos[L] = 1; pos[LR] = 1; pos[CL] = 1; pos[C] = 1; pos[CR] = 1; pos[RL] = 0; pos[R] = 0; backwardPassCount = backwardPassCount + 1;} -> Skip
default: {pos[L] = 0; pos[LR] = 0; pos[CL] = 0; pos[C] = 1; pos[CR] = 0; pos[RL] = 0; pos[R] = 0;} -> Skip
}
p == C:
case {
e == SP: {pos[L] = 0; pos[LR] = 1; pos[CL] = 1; pos[C] = 1; pos[CR] = 1; pos[RL] = 1; pos[R] = 0;} -> Skip
e == LP: {pos[L] = 1; pos[LR] = 0; pos[CL] = 0; pos[C] = 0; pos[CR] = 0; pos[RL] = 0; pos[R] = 1;} -> Skip
e == BP: {pos[L] = 0; pos[LR] = 1; pos[CL] = 1; pos[C] = 1; pos[CR] = 1; pos[RL] = 1; pos[R] = 0; backwardPassCount = backwardPassCount + 1;} -> Skip
default: {pos[L] = 0; pos[LR] = 0; pos[CL] = 0; pos[C] = 1; pos[CR] = 0; pos[RL] = 0; pos[R] = 0;} -> Skip
}
p == CR:
case {
e == SP: {pos[L] = 0; pos[LR] = 0; pos[CL] = 1; pos[C] = 1; pos[CR] = 1; pos[RL] = 1; pos[R] = 1;} -> Skip
e == LP: {pos[L] = 1; pos[LR] = 1; pos[CL] = 0; pos[C] = 0; pos[CR] = 0; pos[RL] = 0; pos[R] = 0;} -> Skip
e == BP: {pos[L] = 0; pos[LR] = 0; pos[CL] = 1; pos[C] = 1; pos[CR] = 1; pos[RL] = 1; pos[R] = 1; backwardPassCount = backwardPassCount + 1;} -> Skip
default: {pos[L] = 0; pos[LR] = 0; pos[CL] = 0; pos[C] = 1; pos[CR] = 0; pos[RL] = 0; pos[R] = 0;} -> Skip
}
p == RL:
case {
e == SP: {pos[L] = 0; pos[LR] = 0; pos[CL] = 0; pos[C] = 1; pos[CR] = 1; pos[RL] = 1; pos[R] = 1;} -> Skip
e == LP: {pos[L] = 1; pos[LR] = 1; pos[CL] = 1; pos[C] = 0; pos[CR] = 0; pos[RL] = 0; pos[R] = 0;} -> Skip
e == BP: {pos[L] = 0; pos[LR] = 0; pos[CL] = 0; pos[C] = 1; pos[CR] = 1; pos[RL] = 1; pos[R] = 1; backwardPassCount = backwardPassCount + 1;} -> Skip
default: {pos[L] = 0; pos[LR] = 0; pos[CL] = 0; pos[C] = 1; pos[CR] = 0; pos[RL] = 0; pos[R] = 0;} -> Skip
}
default:
case {
e == SP: {pos[L] = 0; pos[LR] = 0; pos[CL] = 0; pos[C] = 0; pos[CR] = 1; pos[RL] = 1; pos[R] = 1;} -> Skip
e == LP: {pos[L] = 1; pos[LR] = 1; pos[CL] = 1; pos[C] = 1; pos[CR] = 0; pos[RL] = 0; pos[R] = 0;} -> Skip
default: {pos[L] = 0; pos[LR] = 0; pos[CL] = 0; pos[C] = 1; pos[CR] = 0; pos[RL] = 0; pos[R] = 0;} -> Skip
}
};
#define Goal0 danger <= 0;
#define Goal1 danger <= 1;
#define Goal2 danger <= 2;
#define Goal3 danger <= 3;
#define Goal4 danger <= 4;
#assert AtkKep |= F G Goal0 with prob;