initial framework added
[fp1415-soccerfun.git] / src / StdReferee / RefereeCoach_Rounds_Assignment.icl
diff --git a/src/StdReferee/RefereeCoach_Rounds_Assignment.icl b/src/StdReferee/RefereeCoach_Rounds_Assignment.icl
new file mode 100644 (file)
index 0000000..345b090
--- /dev/null
@@ -0,0 +1,103 @@
+implementation module RefereeCoach_Rounds_Assignment\r
+\r
+import Referee\r
+\r
+RefereeCoach_Rounds                            :: !FootballField -> Referee\r
+RefereeCoach_Rounds field              = { name                        = "RefereeCoach_Rounds"\r
+                                                                 , brain                       = { memory      = mkMemory\r
+                                                                                                         , ai          = randomlessRefereeAI (brain field)\r
+                                                                                                         }\r
+                                                                 , refActionPics       = []\r
+                                                                 }\r
+\r
+::     Memory                                          = { players                     :: ![(FootballerID, [Checkpoint])]      // players and their checkpoints\r
+                                                                 , stage                       :: !Stage                                                       // current stage of training\r
+                                                                 }\r
+::     Stage                                           = Begin | Rounds | End Success\r
+::     Checkpoint                                      = { base                        :: !Position\r
+                                                                 , distance            :: !Metre\r
+                                                                 , check                       :: !Bool\r
+                                                                 }\r
+\r
+mkMemory                                               :: Memory\r
+mkMemory                                               = { players                     = []\r
+                                                                 , stage                       = Begin\r
+                                                                 }\r
+\r
+fail                                                   :: Memory -> Memory\r
+fail memory                                            = {memory & stage = End Fail}\r
+\r
+ok                                                             :: Memory -> Memory\r
+ok memory                                              = {memory & stage = End Success}\r
+\r
+rounds                                                 :: Memory -> Memory\r
+rounds memory                                  = {memory & stage = Rounds}\r
+\r
+instance toPosition3D Checkpoint\r
+where    toPosition3D {base}   = toPosition3D base\r
+\r
+cornerCheckpoints                              :: !FootballField !Metre -> [Checkpoint]\r
+cornerCheckpoints field d              = [  { base = {px = x, py = y}, distance = d, check = False } \r
+                                                                 \\ x <- [scale -0.5 field.flength, scale  0.5 field.flength]\r
+                                                                  , y <- [scale  0.5 field.fwidth,  scale -0.5 field.fwidth ]\r
+                                                                 ]\r
+\r
+checkPoint                                             :: !Position !Checkpoint -> Checkpoint\r
+checkPoint pos checkpoint              = {checkpoint & check = checkpoint.check || dist pos checkpoint <= checkpoint.distance}\r
+\r
+checkpointsCleared                             :: ![Checkpoint] -> Bool\r
+checkpointsCleared checks              = and [check \\ {check} <- checks]\r
+\r
+distanceFromEdges                              :== m 5.0\r
+\r
+isIllegal                                              :: !FootballField !Position !Metre -> Bool\r
+isIllegal field pos distance   = point_in_rectangle ({px = scale -0.5 field.flength + distance, py = scale -0.5 field.fwidth + distance}\r
+                                                                                    ,{px = scale  0.5 field.flength - distance, py = scale  0.5 field.fwidth - distance}\r
+                                                                                    ) pos\r
+\r
+brain                                                  :: !FootballField !(!RefereeInput,!Memory) -> (!RefereeOutput,!Memory)\r
+\r
+//     Assignment has started. Locate all players and their checkpoints.\r
+brain field ({RefereeInput | team1,team2},memory=:{stage = Begin})\r
+| isEmpty players                              = verdict [TellMessage "No players selected."] (fail memory)\r
+| otherwise                                            = ([], rounds {memory & players = players})\r
+where\r
+       players                                         = [(player.playerID,cornerCheckpoints field distanceFromEdges) \\ player <- team1 ++ team2]\r
+\r
+//     Assignment is in the running stage. Monitor players and provide feedback.\r
+brain field ({RefereeInput | playingTime=time,unittime=dt,team1,team2},memory=:{players,stage = Rounds})\r
+| time <= minutes dt                   = verdict msg` (next next_memory)\r
+                                                               with\r
+                                                                       (msg`,next)     = if (all (checkpointsCleared o snd) checked) \r
+                                                                                                        ([], ok)\r
+                                                                                                        ([TellMessage "Not all checkpoints have been cleared."],fail)\r
+| isEmpty illegal_positions            = ([], next_memory)\r
+| otherwise                                            = ([TellMessage (length illegal_positions +++> " players have moved too far from edge.")], fail next_memory)\r
+where\r
+       next_memory                                     = { memory & players = checked }\r
+       checked                                         = [ (playerID, map (checkPoint pos) checkpoints) \\ (playerID,checkpoints) <- players\r
+                                                                                                                 & pos                    <- positions\r
+                                                                 ]\r
+       positions                                       = [ (find_player playerID all_players).pos       \\ (playerID,_)           <- players\r
+                                                                 ]\r
+       illegal_positions                       = [ (playerID,pos)                               \\ (playerID,_)           <- players\r
+                                                                                                                 & pos                    <- positions\r
+                                                                                                                 | isIllegal field pos distanceFromEdges\r
+                                                                 ]\r
+       all_players                                     = team1 ++ team2\r
+\r
+//     Assignment has ended. Stop training session and give final verdict.\r
+brain _ (_,memory)                             = verdict [] memory\r
+\r
+verdict                                                        :: ![RefereeAction] !Memory -> (![RefereeAction],!Memory)\r
+verdict actions memory=:{stage=End how}\r
+                                                               = (actions ++ [TellMessage msg,GameOver], memory)\r
+where\r
+       msg                                                     = if (how == Success) "Well done! Move on to next exercise."\r
+                                                                                     "Improve your assignment and try again."\r
+verdict actions memory                 = (actions ++ [GameOver], fail memory)\r
+\r
+find_player                                            :: FootballerID [Footballer] -> Footballer\r
+find_player playerID players   = case filter (identify_player playerID) players of\r
+                                                                       [player : _]    = player\r
+                                                                       no_one                  = abort ("player " <+++ playerID <+++ " lost in oblivion...")\r