Skip to content

Commit f7f478f

Browse files
committed
[feature] Add possible goal game event
1 parent 2fe048b commit f7f478f

File tree

9 files changed

+285
-151
lines changed

9 files changed

+285
-151
lines changed

internal/app/controller/engine.go

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -144,22 +144,20 @@ func (e *Engine) CommandForEvent(event *GameEvent) (command RefCommand, forTeam
144144

145145
forTeam = event.ByTeam().Opposite()
146146

147-
if e.State.Division == DivA {
148-
for _, event := range e.State.GameEvents {
149-
if event.Type == GameEventPlacementFailedByTeamInFavor {
150-
switch event.Type {
151-
case
152-
GameEventGoal,
153-
GameEventDefenderInDefenseArea,
154-
GameEventMultipleCards:
155-
default:
156-
// the placement failed by team in favor
157-
// the game is continued by the other team
158-
command = CommandIndirect
159-
forTeam = forTeam.Opposite()
160-
}
161-
return
147+
if e.State.Division == DivA && event.Type == GameEventPlacementFailedByTeamInFavor {
148+
for _, e := range e.State.GameEvents {
149+
switch e.Type {
150+
case
151+
GameEventGoal,
152+
GameEventDefenderInDefenseArea,
153+
GameEventMultipleCards:
154+
default:
155+
// the placement failed by team in favor
156+
// the game is continued by the other team
157+
command = CommandIndirect
158+
forTeam = forTeam.Opposite()
162159
}
160+
return
163161
}
164162
}
165163

@@ -178,6 +176,7 @@ func (e *Engine) CommandForEvent(event *GameEvent) (command RefCommand, forTeam
178176
case
179177
GameEventBallLeftFieldGoalLine,
180178
GameEventIndirectGoal,
179+
GameEventPossibleGoal,
181180
GameEventChippedGoal,
182181
GameEventDefenderInDefenseAreaPartially,
183182
GameEventAttackerTooCloseToDefenseArea,
@@ -682,7 +681,9 @@ func (e *Engine) processGameEvent(event *GameEvent) error {
682681

683682
if e.State.GameState() != GameStateHalted && !event.IsSkipped() && !event.IsSecondary() {
684683
teamInFavor := event.ByTeam().Opposite()
685-
if e.State.PlacementPos != nil {
684+
if event.Type == GameEventPossibleGoal {
685+
e.SendCommand(CommandHalt, "")
686+
} else if e.State.PlacementPos != nil {
686687
if e.State.TeamState[teamInFavor].CanPlaceBall {
687688
e.SendCommand(CommandBallPlacement, teamInFavor)
688689
} else if e.State.TeamState[teamInFavor.Opposite()].CanPlaceBall {

internal/app/controller/gameEvent.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const (
2323

2424
GameEventBallLeftFieldTouchLine GameEventType = "ballLeftFieldTouchLine"
2525
GameEventBallLeftFieldGoalLine GameEventType = "ballLeftFieldGoalLine"
26+
GameEventPossibleGoal GameEventType = "possibleGoal"
2627
GameEventGoal GameEventType = "goal"
2728
GameEventIndirectGoal GameEventType = "indirectGoal"
2829
GameEventChippedGoal GameEventType = "chippedGoal"
@@ -74,6 +75,7 @@ func AllGameEvents() []GameEventType {
7475
GameEventBallLeftFieldTouchLine,
7576
GameEventBallLeftFieldGoalLine,
7677
GameEventAimlessKick,
78+
GameEventPossibleGoal,
7779
GameEventGoal,
7880
GameEventIndirectGoal,
7981
GameEventChippedGoal,
@@ -229,6 +231,8 @@ func (e GameEvent) ToProto() *refproto.GameEvent {
229231
protoEvent.Event = &refproto.GameEvent_AimlessKick_{AimlessKick: e.Details.AimlessKick}
230232
case GameEventGoal:
231233
protoEvent.Event = &refproto.GameEvent_Goal_{Goal: e.Details.Goal}
234+
case GameEventPossibleGoal:
235+
protoEvent.Event = &refproto.GameEvent_PossibleGoal{PossibleGoal: e.Details.PossibleGoal}
232236
case GameEventIndirectGoal:
233237
protoEvent.Event = &refproto.GameEvent_IndirectGoal_{IndirectGoal: e.Details.IndirectGoal}
234238
case GameEventChippedGoal:
@@ -309,6 +313,7 @@ type GameEventDetails struct {
309313
BallLeftFieldTouchLine *refproto.GameEvent_BallLeftFieldEvent `json:"ballLeftFieldTouchLine,omitempty"`
310314
BallLeftFieldGoalLine *refproto.GameEvent_BallLeftFieldEvent `json:"ballLeftFieldGoalLine,omitempty"`
311315
AimlessKick *refproto.GameEvent_AimlessKick `json:"aimlessKick,omitempty"`
316+
PossibleGoal *refproto.GameEvent_Goal `json:"possibleGoal,omitempty"`
312317
Goal *refproto.GameEvent_Goal `json:"goal,omitempty"`
313318
IndirectGoal *refproto.GameEvent_IndirectGoal `json:"indirectGoal,omitempty"`
314319
ChippedGoal *refproto.GameEvent_ChippedGoal `json:"chippedGoal,omitempty"`
@@ -359,6 +364,9 @@ func (d GameEventDetails) EventType() GameEventType {
359364
if d.Goal != nil {
360365
return GameEventGoal
361366
}
367+
if d.PossibleGoal != nil {
368+
return GameEventPossibleGoal
369+
}
362370
if d.IndirectGoal != nil {
363371
return GameEventIndirectGoal
364372
}
@@ -489,6 +497,12 @@ func (d GameEventDetails) Description() string {
489497
}
490498
return ""
491499
}
500+
if d.PossibleGoal != nil {
501+
if d.PossibleGoal.ByBot != nil {
502+
return fmt.Sprintf("By bot %v", *d.PossibleGoal.ByBot)
503+
}
504+
return ""
505+
}
492506
if d.IndirectGoal != nil {
493507
if d.IndirectGoal.ByBot != nil {
494508
return fmt.Sprintf("By bot %v", *d.IndirectGoal.ByBot)
@@ -670,6 +684,7 @@ func NewGameEventDetails(event refproto.GameEvent) (d GameEventDetails) {
670684
d.BallLeftFieldTouchLine = event.GetBallLeftFieldTouchLine()
671685
d.BallLeftFieldGoalLine = event.GetBallLeftFieldGoalLine()
672686
d.AimlessKick = event.GetAimlessKick()
687+
d.PossibleGoal = event.GetPossibleGoal()
673688
d.Goal = event.GetGoal()
674689
d.IndirectGoal = event.GetIndirectGoal()
675690
d.ChippedGoal = event.GetChippedGoal()

internal/app/controller/placementPos.go

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,13 @@ func (e *Engine) BallPlacementPos() *Location {
3232
case GameEventBallLeftFieldGoalLine:
3333
if event.Details.BallLeftFieldGoalLine.Location != nil {
3434
location := mapProtoLocation(event.Details.BallLeftFieldGoalLine.Location)
35-
var x float64
36-
if e.isGoalKick(event) {
37-
x = e.Geometry.FieldLength/2 - e.Geometry.PlacementOffsetGoalLineGoalKick
38-
} else {
39-
x = e.Geometry.FieldLength/2 - e.Geometry.PlacementOffsetGoalLine
40-
}
41-
location.X = math.Copysign(x, location.X)
42-
y := e.Geometry.FieldWidth/2 - e.Geometry.PlacementOffsetTouchLine
43-
location.Y = math.Copysign(y, location.Y)
44-
return e.validateLocation(location)
35+
return e.ballPlacementLocationGoalLine(event, location)
36+
}
37+
return nil
38+
case GameEventPossibleGoal:
39+
if event.Details.PossibleGoal.Location != nil {
40+
location := mapProtoLocation(event.Details.PossibleGoal.Location)
41+
return e.ballPlacementLocationGoalLine(event, location)
4542
}
4643
return nil
4744
case GameEventAimlessKick:
@@ -108,7 +105,25 @@ func (e *Engine) BallPlacementPos() *Location {
108105
}
109106
}
110107

108+
func (e *Engine) ballPlacementLocationGoalLine(event *GameEvent, lastBallLocation *Location) *Location {
109+
var x float64
110+
if e.isGoalKick(event) {
111+
x = e.Geometry.FieldLength/2 - e.Geometry.PlacementOffsetGoalLineGoalKick
112+
} else {
113+
x = e.Geometry.FieldLength/2 - e.Geometry.PlacementOffsetGoalLine
114+
}
115+
var placementLocation Location
116+
placementLocation.X = math.Copysign(x, lastBallLocation.X)
117+
y := e.Geometry.FieldWidth/2 - e.Geometry.PlacementOffsetTouchLine
118+
placementLocation.Y = math.Copysign(y, lastBallLocation.Y)
119+
return e.validateLocation(&placementLocation)
120+
}
121+
111122
func (e *Engine) isGoalKick(event *GameEvent) bool {
123+
if event.Details.BallLeftFieldGoalLine == nil {
124+
// failed goal shot -> goal kick
125+
return true
126+
}
112127
teamInFavor := event.ByTeam().Opposite()
113128
location := mapProtoLocation(event.Details.BallLeftFieldGoalLine.Location)
114129
if e.State.TeamState[teamInFavor].OnPositiveHalf && location.X > 0 {

internal/app/controller/state.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,13 @@ func (s State) PrimaryGameEvent() (e *GameEvent) {
398398
e = nil
399399
for i := len(s.GameEvents) - 1; i >= 0; i-- {
400400
e = s.GameEvents[i]
401-
if e.Type == GameEventMultipleCards {
401+
switch e.Type {
402+
case GameEventMultipleCards:
402403
// only this event causes a penalty kick and must be prioritized.
403404
return
405+
case GameEventGoal:
406+
// Goal overrides everything else
407+
return
404408
}
405409
}
406410
return

0 commit comments

Comments
 (0)