Skip to content

Commit 9db14e2

Browse files
committed
Update README with new game statistics and enhance decision-making logic for penalty situations
1 parent fae71ac commit 9db14e2

File tree

5 files changed

+76
-23
lines changed

5 files changed

+76
-23
lines changed

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,23 @@ there are many different ways to run the base code, in the next section, we will
2323
| Summary Statistics
2424

2525
- **Game Count**: 100
26-
- **Goals**: 234 : 143 (diff: 91)
27-
- **Points**: 212 : 71 (diff: 141)
28-
- **Average Goals**: 2.34 : 1.43 (diff: 0.91)
29-
- **Average Points**: 2.12 : 0.71 (diff: 1.41)
30-
- **Win**: 65, **Draw**: 17, **Lost**: 18
31-
- **Win Rate**: 65.00%
32-
- **Expected Win Rate**: 78.31%
26+
- **Goals**: 223 : 78 (diff: 145)
27+
- **Points**: 229 : 52 (diff: 177)
28+
- **Average Goals**: 2.23 : 0.78 (diff: 1.45)
29+
- **Average Points**: 2.29 : 0.52 (diff: 1.77)
30+
- **Win**: 70, **Draw**: 19, **Lost**: 11
31+
- **Win Rate**: 70.00%
32+
- **Expected Win Rate**: 86.42%
3333

3434
| Goals Distribution
3535

3636
```mermaid
3737
xychart-beta
3838
title "Diff Goals Distribution"
39-
x-axis [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
39+
x-axis [-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8]
4040
y-axis "Percentage"
41-
bar [0,4,2,5,7,17,27,19,13,4,2]
42-
line [0,4,2,5,7,17,27,19,13,4,2]
41+
bar [0,0,0,0,1.00, 0.00, 2.00, 8.00, 19.00, 22.00, 25.00, 13.00, 5.00, 2.00, 2.00, 0.00, 1.00]
42+
line [0,0,0,0,1.00, 0.00, 2.00, 8.00, 19.00, 22.00, 25.00, 13.00, 5.00, 2.00, 2.00, 0.00, 1.00]
4343
```
4444

4545
## Quick start

src/decision_makers/decision_maker.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from src.interfaces.IDecisionMaker import IDecisionMaker
22
from .play_on_decision_maker import PlayOnDecisionMaker
33
from .set_play_decision_maker import SetPlayDecisionMaker
4+
from .penalty_decision_maker import PenaltyDecisionMaker
45
from src.interfaces.IAgent import IAgent
56
from service_pb2 import *
67

@@ -18,19 +19,20 @@ class DecisionMaker(IDecisionMaker):
1819
Makes a decision for the given agent based on its role and the current game mode.
1920
If the agent is a goalie, it adds a goalie action.
2021
If the game mode is 'PlayOn', it delegates the decision to play_on_decision_maker.
21-
If the game mode is a penalty kick, it adds a penalty action.
22-
Otherwise, it adds a set play action.
22+
If the game mode is a penalty kick, it adds a penalty action using penalty_decision_maker.
23+
Otherwise, it adds a set play action using set_play_decision_maker.
2324
"""
2425
def __init__(self):
2526
self.play_on_decision_maker = PlayOnDecisionMaker()
2627
self.set_play_decision_maker = SetPlayDecisionMaker()
28+
self.penalty_decision_maker = PenaltyDecisionMaker()
2729

2830
def make_decision(self, agent: IAgent):
2931
if agent.wm.self.is_goalie:
3032
agent.add_action(PlayerAction(helios_goalie=HeliosGoalie()))
3133
elif agent.wm.game_mode_type == GameModeType.PlayOn:
3234
self.play_on_decision_maker.make_decision(agent)
3335
elif agent.wm.is_penalty_kick_mode:
34-
agent.add_action(PlayerAction(helios_penalty=HeliosPenalty()))
36+
self.penalty_decision_maker.make_decision(agent)
3537
else:
36-
agent.add_action(PlayerAction(helios_set_play=HeliosSetPlay()))
38+
self.set_play_decision_maker.make_decision(agent)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from src.interfaces.IDecisionMaker import IDecisionMaker
2+
from src.interfaces.IAgent import IAgent
3+
from service_pb2 import *
4+
5+
6+
class PenaltyDecisionMaker(IDecisionMaker):
7+
def __init__(self):
8+
pass
9+
10+
def make_decision(self, agent: IAgent):
11+
agent.add_action(PlayerAction(helios_penalty=HeliosPenalty()))

src/decision_makers/set_play_decision_maker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ class SetPlayDecisionMaker(IDecisionMaker):
77
def __init__(self):
88
pass
99

10-
def make_decision(self, agent: IAgent, wm: WorldModel):
10+
def make_decision(self, agent: IAgent):
1111
agent.add_action(PlayerAction(helios_set_play=HeliosSetPlay()))

src/strategy/formation_strategy.py

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,41 +10,81 @@
1010

1111

1212
class Situation(Enum):
13+
"""
14+
Enum class representing different game situations in a 2D soccer simulation.
15+
16+
Attributes:
17+
OurSetPlay_Situation (int): Represents a situation where our team is executing a set play.
18+
OppSetPlay_Situation (int): Represents a situation where the opposing team is executing a set play.
19+
Defense_Situation (int): Represents a defensive situation for our team.
20+
Offense_Situation (int): Represents an offensive situation for our team.
21+
PenaltyKick_Situation (int): Represents a penalty kick situation.
22+
"""
1323
OurSetPlay_Situation = 0,
1424
OppSetPlay_Situation = 1,
1525
Defense_Situation = 2,
1626
Offense_Situation = 3,
1727
PenaltyKick_Situation = 4
1828

1929
class Formation:
30+
"""
31+
A class to manage different soccer formations for various game situations.
32+
33+
Attributes:
34+
before_kick_off_formation (FormationFile): Formation used before the kick-off.
35+
defense_formation (FormationFile): Formation used during defense.
36+
offense_formation (FormationFile): Formation used during offense.
37+
goalie_kick_opp_formation (FormationFile): Formation used when the opponent's goalie kicks.
38+
goalie_kick_our_formation (FormationFile): Formation used when our goalie kicks.
39+
kickin_our_formation (FormationFile): Formation used during our team's kick-in.
40+
setplay_opp_formation (FormationFile): Formation used during the opponent's set play.
41+
setplay_our_formation (FormationFile): Formation used during our team's set play.
42+
43+
Args:
44+
path (str): The path to the directory containing the formation configuration files.
45+
logger (logging.Logger): Logger instance for logging formation-related information.
46+
"""
2047
def __init__(self, path, logger: logging.Logger):
48+
# Initialize formation files for different game situations
49+
# before_kick_off_formation: Formation used before the kick-off
2150
self.before_kick_off_formation: FormationFile = FormationFile(f'{path}/before-kick-off.conf', logger)
51+
# defense_formation: Formation used during defense
2252
self.defense_formation: FormationFile = FormationFile(f'{path}/defense-formation.conf', logger)
53+
# offense_formation: Formation used during offense
2354
self.offense_formation: FormationFile = FormationFile(f'{path}/offense-formation.conf', logger)
55+
# goalie_kick_opp_formation: Formation used when the opponent's goalie kicks
2456
self.goalie_kick_opp_formation: FormationFile = FormationFile(f'{path}/goalie-kick-opp-formation.conf', logger)
57+
# goalie_kick_our_formation: Formation used when our goalie kicks
2558
self.goalie_kick_our_formation: FormationFile = FormationFile(f'{path}/goalie-kick-our-formation.conf', logger)
59+
# kickin_our_formation: Formation used during our team's kick-in
2660
self.kickin_our_formation: FormationFile = FormationFile(f'{path}/kickin-our-formation.conf', logger)
61+
# setplay_opp_formation: Formation used during the opponent's set play
2762
self.setplay_opp_formation: FormationFile = FormationFile(f'{path}/setplay-opp-formation.conf', logger)
63+
# setplay_our_formation: Formation used during our team's set play
2864
self.setplay_our_formation: FormationFile = FormationFile(f'{path}/setplay-our-formation.conf', logger)
2965

3066
class FormationStrategy(IPositionStrategy):
3167
def __init__(self, logger: logging.Logger):
3268
self.logger = logger
3369
self.formations: dict[str, Formation] = {}
34-
self.formations['4-3-3'] = Formation('src/formations/4-3-3', logger)
35-
self.formations['4-3-3-cyrus-base'] = Formation('src/formations/4-3-3-cyrus-base', logger)
36-
self.formations['4-3-3-helios-base'] = Formation('src/formations/4-3-3-helios-base', logger)
37-
self.selected_formation_name = '4-3-3' # '4-3-3' '4-3-3-cyrus-base' '4-3-3-helios-base'
70+
71+
self._read_formations()
72+
self._set_formation(None)
3873

3974
self._poses: dict[int, Vector2D] = {(i, Vector2D(0, 0)) for i in range(11)}
4075
self.current_situation = Situation.Offense_Situation
4176
self.current_formation_file: FormationFile = self._get_current_formation().offense_formation
4277

78+
def _read_formations(self):
79+
self.formations['4-3-3'] = Formation('src/formations/4-3-3', self.logger)
80+
self.formations['4-3-3-cyrus-base'] = Formation('src/formations/4-3-3-cyrus-base', self.logger)
81+
self.formations['4-3-3-helios-base'] = Formation('src/formations/4-3-3-helios-base', self.logger)
82+
4383
def _get_current_formation(self) -> Formation:
4484
return self.formations[self.selected_formation_name]
4585

4686
def _set_formation(self, wm: WorldModel):
47-
self.selected_formation_name = '4-3-3'
87+
self.selected_formation_name = '4-3-3-cyrus-base' # '4-3-3' '4-3-3-cyrus-base' '4-3-3-helios-base'
4888

4989
def update(self, agent: IAgent):
5090
logger = agent.logger
@@ -117,13 +157,13 @@ def update(self, agent: IAgent):
117157
def get_position(self, uniform_number) -> Vector2D:
118158
return self._poses[uniform_number]
119159

120-
def get_role_name(self, uniform_number) -> int:
160+
def get_role_name(self, uniform_number) -> RoleName:
121161
return self.current_formation_file.get_role(uniform_number).name
122162

123-
def get_role_type(self, uniform_number) -> int:
163+
def get_role_type(self, uniform_number) -> RoleType:
124164
return self.current_formation_file.get_role(uniform_number).type
125165

126-
def get_role_side(self, uniform_number) -> int:
166+
def get_role_side(self, uniform_number) -> RoleSide:
127167
return self.current_formation_file.get_role(uniform_number).side
128168

129169
def get_role_pair(self, uniform_number) -> int:

0 commit comments

Comments
 (0)