1 implementation module RefereeCoach_Rounds_Assignment
5 RefereeCoach_Rounds :: !FootballField -> Referee
6 RefereeCoach_Rounds field = { name = "RefereeCoach_Rounds"
7 , brain = { memory = mkMemory
8 , ai = randomlessRefereeAI (brain field)
13 :: Memory = { players :: ![(FootballerID, [Checkpoint])] // players and their checkpoints
14 , stage :: !Stage // current stage of training
16 :: Stage = Begin | Rounds | End Success
17 :: Checkpoint = { base :: !Position
23 mkMemory = { players = []
27 fail :: Memory -> Memory
28 fail memory = {memory & stage = End Fail}
30 ok :: Memory -> Memory
31 ok memory = {memory & stage = End Success}
33 rounds :: Memory -> Memory
34 rounds memory = {memory & stage = Rounds}
36 instance toPosition3D Checkpoint
37 where toPosition3D {base} = toPosition3D base
39 cornerCheckpoints :: !FootballField !Metre -> [Checkpoint]
40 cornerCheckpoints field d = [ { base = {px = x, py = y}, distance = d, check = False }
41 \\ x <- [scale -0.5 field.flength, scale 0.5 field.flength]
42 , y <- [scale 0.5 field.fwidth, scale -0.5 field.fwidth ]
45 checkPoint :: !Position !Checkpoint -> Checkpoint
46 checkPoint pos checkpoint = {checkpoint & check = checkpoint.check || dist pos checkpoint <= checkpoint.distance}
48 checkpointsCleared :: ![Checkpoint] -> Bool
49 checkpointsCleared checks = and [check \\ {check} <- checks]
51 distanceFromEdges :== m 5.0
53 isIllegal :: !FootballField !Position !Metre -> Bool
54 isIllegal field pos distance = point_in_rectangle ({px = scale -0.5 field.flength + distance, py = scale -0.5 field.fwidth + distance}
55 ,{px = scale 0.5 field.flength - distance, py = scale 0.5 field.fwidth - distance}
58 brain :: !FootballField !(!RefereeInput,!Memory) -> (!RefereeOutput,!Memory)
60 // Assignment has started. Locate all players and their checkpoints.
61 brain field ({RefereeInput | team1,team2},memory=:{stage = Begin})
62 | isEmpty players = verdict [TellMessage "No players selected."] (fail memory)
63 | otherwise = ([], rounds {memory & players = players})
65 players = [(player.playerID,cornerCheckpoints field distanceFromEdges) \\ player <- team1 ++ team2]
67 // Assignment is in the running stage. Monitor players and provide feedback.
68 brain field ({RefereeInput | playingTime=time,unittime=dt,team1,team2},memory=:{players,stage = Rounds})
69 | time <= minutes dt = verdict msg` (next next_memory)
71 (msg`,next) = if (all (checkpointsCleared o snd) checked)
73 ([TellMessage "Not all checkpoints have been cleared."],fail)
74 | isEmpty illegal_positions = ([], next_memory)
75 | otherwise = ([TellMessage (length illegal_positions +++> " players have moved too far from edge.")], fail next_memory)
77 next_memory = { memory & players = checked }
78 checked = [ (playerID, map (checkPoint pos) checkpoints) \\ (playerID,checkpoints) <- players
81 positions = [ (find_player playerID all_players).pos \\ (playerID,_) <- players
83 illegal_positions = [ (playerID,pos) \\ (playerID,_) <- players
85 | isIllegal field pos distanceFromEdges
87 all_players = team1 ++ team2
89 // Assignment has ended. Stop training session and give final verdict.
90 brain _ (_,memory) = verdict [] memory
92 verdict :: ![RefereeAction] !Memory -> (![RefereeAction],!Memory)
93 verdict actions memory=:{stage=End how}
94 = (actions ++ [TellMessage msg,GameOver], memory)
96 msg = if (how == Success) "Well done! Move on to next exercise."
97 "Improve your assignment and try again."
98 verdict actions memory = (actions ++ [GameOver], fail memory)
100 find_player :: FootballerID [Footballer] -> Footballer
101 find_player playerID players = case filter (identify_player playerID) players of
102 [player : _] = player
103 no_one = abort ("player " <+++ playerID <+++ " lost in oblivion...")