From a9c160ad6a72ecc6088a6f246193ba428af15871 Mon Sep 17 00:00:00 2001 From: Patrick Fairbank Date: Fri, 20 Mar 2020 22:16:48 -0700 Subject: [PATCH] Update rules for 2020. --- game/foul.go | 2 +- game/rule.go | 61 ++++++++++++++++++++---------------- game/score.go | 8 +++++ game/score_test.go | 24 ++++++++++++++ game/test_helpers.go | 6 ++-- templates/referee_panel.html | 6 +++- 6 files changed, 75 insertions(+), 32 deletions(-) diff --git a/game/foul.go b/game/foul.go index fe28ca2..10c9b9d 100644 --- a/game/foul.go +++ b/game/foul.go @@ -18,7 +18,7 @@ func (foul *Foul) Rule() *Rule { // Returns the number of points that the foul adds to the opposing alliance's score. func (foul *Foul) PointValue() int { - if foul.Rule() == nil { + if foul.Rule() == nil || foul.Rule().IsRankingPoint { return 0 } if foul.Rule().IsTechnical { diff --git a/game/rule.go b/game/rule.go index 7ef608b..37e8365 100644 --- a/game/rule.go +++ b/game/rule.go @@ -13,35 +13,42 @@ type Rule struct { Description string } -// All rules from the 2018 game that carry point penalties. +// All rules from the 2020 game that carry point penalties. var rules = []*Rule{ - {1, "S6", false, false, "DRIVE TEAMS may not extend any body part into the CARGO Chute. Momentary encroachment into the Chute is an exception to this rule."}, + {1, "S6", false, false, "DRIVE TEAMS may not extend any body part into the LOADING BAY Chute."}, {2, "C8", false, false, "Strategies clearly aimed at forcing the opposing ALLIANCE to violate a rule are not in the spirit of FIRST Robotics Competition and not allowed."}, - {3, "G3", true, false, "During the SANDSTORM PERIOD, a ROBOT may not cross the FIELD such that its BUMPERS break the plane defined by their opponent’s CARGO SHIP LINE."}, - {4, "G4", false, false, "ROBOTS may not have greater-than-momentary or repeated control, i.e. exercise greater-than-momentary or repeated influence, of more than one (1) GAME PIECE at a time, either directly or transitively through other objects."}, - {5, "G5", false, true, "A ROBOT may not remove a GAME PIECE from an opponents’ ROCKET/CARGO SHIP."}, - {6, "G7", false, false, "ROBOTS may not intentionally eject GAME PIECES from the FIELD."}, - {7, "G8", false, false, "ROBOTS may not deliberately use GAME PIECES in an attempt to ease or amplify the challenge associated with FIELD elements."}, - {8, "G9", false, false, "No more than one ROBOT may be positioned such that its BUMPERS are completely beyond the opponent’s CARGO SHIP LINE."}, - {9, "G9", true, false, "No more than one ROBOT may be positioned such that its BUMPERS are completely beyond the opponent’s CARGO SHIP LINE."}, - {10, "G10", false, false, "No part of a ROBOT, except its BUMPERS, may be outside its FRAME PERIMETER if its BUMPERS are completely beyond its opponent’s CARGO SHIP LINE."}, - {11, "G10", true, false, "No part of a ROBOT, except its BUMPERS, may be outside its FRAME PERIMETER if its BUMPERS are completely beyond its opponent’s CARGO SHIP LINE."}, - {12, "G12", false, false, "A ROBOT may not break the vertical plane above the ALLIANCE STATION WALL or damage the SANDSTORM."}, - {13, "G13", false, false, "A ROBOT may not contact an opponent ROBOT if that opponent ROBOT’S BUMPERS are fully in their HAB ZONE."}, - {14, "G15", false, false, "DRIVE TEAMS, ROBOTS, and OPERATOR CONSOLES are prohibited from the following actions with regards to interaction with ARENA elements: grabbing, grasping, attaching to, hanging, deforming, becoming entangled, damaging, and repositioning GAME PIECE holders."}, - {15, "G16", false, true, "During Qualification MATCHES, ROBOTS may not contact opponents’ ROCKETS starting at T-minus 20s."}, - {16, "G17", false, false, "Fallen (i.e. tipped over) ROBOTS attempting to right themselves (either by themselves or with assistance from a partner ROBOT) have one ten (10) second grace period in which they may not be contacted by an opponent ROBOT."}, - {17, "G18", false, false, "ROBOTS may not pin an opponent’s ROBOT for more than five (5) seconds."}, - {18, "G18", true, false, "ROBOTS may not pin an opponent’s ROBOT for more than five (5) seconds."}, - {19, "G19", true, false, "Strategies aimed at the destruction or inhibition of ROBOTS via attachment, damage, tipping, or entanglements are not allowed."}, - {20, "G20", true, false, "Initiating deliberate or damaging contact with an opponent ROBOT on or inside the vertical extension of its FRAME PERIMETER, including transitively through a GAME PIECE, is not allowed."}, - {21, "G23", false, false, "BUMPERS must be in the BUMPER ZONE during the MATCH unless a ROBOT is completely in its HAB ZONE or supported by a ROBOT completely in its HAB ZONE."}, - {22, "G24", false, false, "ROBOTS may not extend more than 30 in (~76 cm). beyond their FRAME PERIMETER."}, - {23, "H6", false, false, "During the MATCH, DRIVERS, COACHES, and HUMAN PLAYERS may not contact anything outside the ALLIANCE STATION and TECHNICIANS may not contact anything outside their designated area."}, - {24, "H7", false, false, "During the MATCH, team members may only enter GAME PIECES on to the FIELD through their LOADING STATIONS."}, - {25, "H8", false, false, "During a MATCH, COACHES may not touch GAME PIECES unless for safety purposes."}, - {26, "H9", true, false, "During the SANDSTORM PERIOD, COACHES, DRIVERS, HUMAN PLAYERS, and any part of the OPERATOR CONSOLE may not break the vertical planes defined by the STARTING LINES, unless for safety purposes."}, - {27, "H10", true, false, "During the SANDSTORM PERIOD, COACHES, DRIVERS, and HUMAN PLAYERS may not look over the top of the ALLIANCE WALL down to the FIELD to overcome the effect of the SANDSTORM."}, + {3, "C8", true, false, "Strategies clearly aimed at forcing the opposing ALLIANCE to violate a rule are not in the spirit of FIRST Robotics Competition and not allowed."}, + {4, "G3", false, false, "During AUTO, a ROBOT’s BUMPERS may not break the plane of their ALLIANCE’s SECTOR."}, + {5, "G3", true, false, "During AUTO, a ROBOT’s BUMPERS may not break the plane of their ALLIANCE’s SECTOR."}, + {6, "G4", false, false, "During AUTO, DRIVE TEAM members in ALLIANCE STATIONS may not contact anything in front of the STARTING LINES, unless for personal or equipment safety."}, + {7, "G5", false, false, "During AUTO, DRIVE TEAMS may not directly or indirectly interact with ROBOTS or OPERATOR CONSOLES unless for personal safety, OPERATOR CONSOLE safety, or pressing an E-Stop."}, + {8, "G6", false, false, "ROBOTS may not have greater-than-momentary CONTROL of more than five (5) POWER CELLS at a time, either directly or transitively through other objects."}, + {9, "G7", false, false, "ROBOTS may not intentionally eject POWER CELLS from the FIELD other than through the POWER PORT."}, + {10, "G8", true, false, "ROBOTS may not deliberately use POWER CELLS in an attempt to ease or amplify the challenge associated with FIELD elements."}, + {11, "G9", true, false, "A ROBOT whose BUMPERS are fully contained by their SECTOR may not cause POWER CELLS to travel into or through their opponent’s SECTOR."}, + {12, "G10", true, false, "A ROBOT whose BUMPERS are intersecting the opponent’s TARGET ZONE, TRENCH RUN, or LOADING ZONE may not contact opponent ROBOTS, regardless of who initiates contact."}, + {13, "G11", true, false, "An opponent ROBOT may not contact a ROBOT whose BUMPERS are intersecting its TARGET ZONE or LOADING ZONE, regardless of who initiates contact."}, + {14, "G12", false, true, "A ROBOT may not contact the opponent’s CONTROL PANEL, either directly, or transitively through a POWER CELL, if A. the opponent ROBOT is contacting that CONTROL PANEL, and B. the opponent’s POWER PORT has reached CAPACITY."}, + {15, "G12", true, false, "A ROBOT may not contact the opponent’s CONTROL PANEL, either directly, or transitively through a POWER CELL, if A. the opponent ROBOT is contacting that CONTROL PANEL, and B. the opponent’s POWER PORT has reached CAPACITY."}, + {16, "G13", true, false, "A ROBOT may not be fully supported by a partner ROBOT unless the partner ROBOT’S BUMPERS are intersecting its RENDEZVOUS POINT."}, + {17, "G14", true, false, "During the ENDGAME, a ROBOT may not contact, either directly or transitively through a POWER CELL, an opponent ROBOT whose BUMPERS are completely contained in its RENDEZVOUS POINT and not in contact with its GENERATOR SWITCH."}, + {18, "G16", false, false, "BUMPERS must be in the BUMPER ZONE during the MATCH, unless during the ENDGAME and A. a ROBOT’s BUMPERS are intersecting its RENDEZVOUS POINT or B. a ROBOT is supported by a partner ROBOT whose BUMPERS are intersecting its RENDEZVOUS POINT."}, + {19, "G17", true, false, "ROBOT height, as measured when it’s resting normally on a flat floor, may not exceed 45 in. (~114 cm) above the carpet during the MATCH, with the exception of ROBOTS intersecting their ALLIANCE’S RENDEZVOUS POINT during the ENDGAME."}, + {20, "G18", false, false, "ROBOTS may not extend more than 12 inches (~30 cm) beyond their FRAME PERIMETER."}, + {21, "G21", false, false, "ROBOTS may not PIN an opponent’s ROBOT for more than five (5) seconds."}, + {22, "G21", true, false, "ROBOTS may not PIN an opponent’s ROBOT for more than five (5) seconds."}, + {23, "G22", true, false, "Two or more ROBOTS that appear to a REFEREE to be working together may not isolate or close off any major component of MATCH play."}, + {24, "G23", true, false, "ROBOT actions that appear to be deliberate to a REFEREE and that cause damage or inhibition via attaching, tipping, or entangling to an opponent ROBOT are not allowed."}, + {25, "G24", false, false, "A ROBOT with a COMPONENT(S) outside its FRAME PERIMETER, other than BUMPERS, may not initiate direct contact with an opponent ROBOT inside the vertical projection of its FRAME PERIMETER using that COMPONENT."}, + {26, "G25", true, false, "Regardless of intent, a ROBOT may not initiate direct contact inside the vertical projection of an opponent ROBOT’S FRAME PERIMETER that damages or functionally impairs the opponent ROBOT."}, + {27, "G26", true, false, "ROBOTS and OPERATOR CONSOLES are prohibited from the following actions with regards to interaction with ARENA elements: grabbing, grasping, attaching, deforming, becoming entangled, damaging, suspending from."}, + {28, "H5", false, false, "During the MATCH, DRIVERS, COACHES, and HUMAN PLAYERS may not contact anything outside the ALLIANCE STATION and TECHNICIANS may not contact anything outside their designated area."}, + {29, "H6", false, false, "POWER CELLS may only be introduced to the FIELD A. during TELEOP, B. by a DRIVER or HUMAN PLAYER, and C. through the LOADING BAY."}, + {30, "H7", false, false, "During a MATCH, COACHES may not touch POWER CELLS, unless for safety purposes."}, + {31, "H9", false, false, "During TELEOP, an ALLIANCE may not have more than fifteen (15) POWER CELLS in their ALLIANCE STATION."}, + {32, "H10", false, false, "POWER CELLS must be stored on the LOADING BAY racks."}, + {33, "H10", true, false, "POWER CELLS must be stored on the LOADING BAY racks."}, + {34, "H16", true, false, "DRIVE TEAMS are prohibited from the following actions with regards to interaction with ARENA elements: climbing, hanging, deforming, damaging."}, } var ruleMap map[int]*Rule diff --git a/game/score.go b/game/score.go index b641439..f741bce 100644 --- a/game/score.go +++ b/game/score.go @@ -123,6 +123,14 @@ func (score *Score) Summarize(opponentFouls []Foul) *ScoreSummary { summary.FoulPoints += foul.PointValue() } + // Check for the opponent fouls that automatically trigger a ranking point. + for _, foul := range opponentFouls { + if foul.Rule() != nil && foul.Rule().IsRankingPoint { + summary.ControlPanelRankingPoint = true + break + } + } + summary.Score = summary.AutoPoints + summary.TeleopPowerCellPoints + summary.ControlPanelPoints + summary.EndgamePoints + summary.FoulPoints diff --git a/game/score_test.go b/game/score_test.go index c09c47b..f181a36 100644 --- a/game/score_test.go +++ b/game/score_test.go @@ -126,6 +126,30 @@ func TestScoreSummaryBoundaryConditions(t *testing.T) { assert.Equal(t, false, score.Summarize(score.Fouls).EndgameRankingPoint) } +func TestScoreSummaryRankingPointFoul(t *testing.T) { + fouls := []Foul{{14, 0, 0}} + score1 := TestScore1() + score2 := TestScore2() + + summary := score1.Summarize([]Foul{}) + assert.Equal(t, 0, summary.FoulPoints) + assert.Equal(t, false, summary.ControlPanelRankingPoint) + assert.Equal(t, true, summary.EndgameRankingPoint) + summary = score1.Summarize(fouls) + assert.Equal(t, 0, summary.FoulPoints) + assert.Equal(t, true, summary.ControlPanelRankingPoint) + assert.Equal(t, true, summary.EndgameRankingPoint) + + summary = score2.Summarize([]Foul{}) + assert.Equal(t, 0, summary.FoulPoints) + assert.Equal(t, true, summary.ControlPanelRankingPoint) + assert.Equal(t, false, summary.EndgameRankingPoint) + summary = score2.Summarize(fouls) + assert.Equal(t, 0, summary.FoulPoints) + assert.Equal(t, true, summary.ControlPanelRankingPoint) + assert.Equal(t, false, summary.EndgameRankingPoint) +} + func TestScoreEquals(t *testing.T) { score1 := TestScore1() score2 := TestScore1() diff --git a/game/test_helpers.go b/game/test_helpers.go index 1170198..febad09 100644 --- a/game/test_helpers.go +++ b/game/test_helpers.go @@ -7,9 +7,9 @@ package game func TestScore1() *Score { fouls := []Foul{ - {18, 25, 150}, - {20, 1868, 0}, - {21, 25, 25.2}, + {17, 25, 150}, + {18, 1868, 0}, + {19, 25, 25.2}, } return &Score{ ExitedInitiationLine: [3]bool{true, true, false}, diff --git a/templates/referee_panel.html b/templates/referee_panel.html index aca0ca8..4ed24d3 100644 --- a/templates/referee_panel.html +++ b/templates/referee_panel.html @@ -67,7 +67,11 @@ {{end}} -
+

Note: Tooltips do not contain the entire text of the rule, and depending on the circumstances the + prescribed penalty may not be a foul or tech foul. +
+ If a rule does not appear here, it is because the penalty is either a yellow/red card or a free score for + the opponent, and should be applied directly.

Clear Foul