initial framework added
[fp1415-soccerfun.git] / src / StdReferee / RefereeCoach_Rounds_Assignment.icl
1 implementation module RefereeCoach_Rounds_Assignment
2
3 import Referee
4
5 RefereeCoach_Rounds :: !FootballField -> Referee
6 RefereeCoach_Rounds field = { name = "RefereeCoach_Rounds"
7 , brain = { memory = mkMemory
8 , ai = randomlessRefereeAI (brain field)
9 }
10 , refActionPics = []
11 }
12
13 :: Memory = { players :: ![(FootballerID, [Checkpoint])] // players and their checkpoints
14 , stage :: !Stage // current stage of training
15 }
16 :: Stage = Begin | Rounds | End Success
17 :: Checkpoint = { base :: !Position
18 , distance :: !Metre
19 , check :: !Bool
20 }
21
22 mkMemory :: Memory
23 mkMemory = { players = []
24 , stage = Begin
25 }
26
27 fail :: Memory -> Memory
28 fail memory = {memory & stage = End Fail}
29
30 ok :: Memory -> Memory
31 ok memory = {memory & stage = End Success}
32
33 rounds :: Memory -> Memory
34 rounds memory = {memory & stage = Rounds}
35
36 instance toPosition3D Checkpoint
37 where toPosition3D {base} = toPosition3D base
38
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 ]
43 ]
44
45 checkPoint :: !Position !Checkpoint -> Checkpoint
46 checkPoint pos checkpoint = {checkpoint & check = checkpoint.check || dist pos checkpoint <= checkpoint.distance}
47
48 checkpointsCleared :: ![Checkpoint] -> Bool
49 checkpointsCleared checks = and [check \\ {check} <- checks]
50
51 distanceFromEdges :== m 5.0
52
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}
56 ) pos
57
58 brain :: !FootballField !(!RefereeInput,!Memory) -> (!RefereeOutput,!Memory)
59
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})
64 where
65 players = [(player.playerID,cornerCheckpoints field distanceFromEdges) \\ player <- team1 ++ team2]
66
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)
70 with
71 (msg`,next) = if (all (checkpointsCleared o snd) checked)
72 ([], ok)
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)
76 where
77 next_memory = { memory & players = checked }
78 checked = [ (playerID, map (checkPoint pos) checkpoints) \\ (playerID,checkpoints) <- players
79 & pos <- positions
80 ]
81 positions = [ (find_player playerID all_players).pos \\ (playerID,_) <- players
82 ]
83 illegal_positions = [ (playerID,pos) \\ (playerID,_) <- players
84 & pos <- positions
85 | isIllegal field pos distanceFromEdges
86 ]
87 all_players = team1 ++ team2
88
89 // Assignment has ended. Stop training session and give final verdict.
90 brain _ (_,memory) = verdict [] memory
91
92 verdict :: ![RefereeAction] !Memory -> (![RefereeAction],!Memory)
93 verdict actions memory=:{stage=End how}
94 = (actions ++ [TellMessage msg,GameOver], memory)
95 where
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)
99
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...")