initial framework added
[fp1415-soccerfun.git] / src / Game / FootballerFunctions.icl
diff --git a/src/Game/FootballerFunctions.icl b/src/Game/FootballerFunctions.icl
new file mode 100644 (file)
index 0000000..2bcd55a
--- /dev/null
@@ -0,0 +1,95 @@
+implementation module FootballerFunctions\r
+\r
+import Footballer\r
+\r
+returnAI`                                      :: !FootballerAction -> FootballerAI`\r
+returnAI` action                       = const action\r
+\r
+move`                                          :: !Speed !Angle -> FootballerAI`\r
+move` speed angle                      = returnAI` (Move speed angle)\r
+\r
+halt`                                          :: FootballerAI`\r
+halt`                                          = move` zero zero\r
+\r
+rotate`                                                :: !Angle -> FootballerAI`\r
+rotate` angle                          = move` zero angle\r
+\r
+ahead`                                         :: !Velocity -> FootballerAI`\r
+ahead` v                                       = \input=:{me} -> move` {direction=me.nose,velocity=v} zero input\r
+\r
+fix`                                           :: !Position !Metre -> FootballerAI`\r
+fix` point eps                         = \input=:{me} ->\r
+  let distance                         = dist            me point\r
+      angle                                    = bearing zero    me point\r
+      rotate                           = bearing me.nose me point\r
+      v                                                = ms (max 6.0 (toReal distance))\r
+  in if (distance <= eps)\r
+        (halt` input)\r
+           (move` {direction=angle,velocity=v} rotate input)\r
+\r
+kick`                                          :: !Position -> FootballerAI`\r
+kick` point                            = \input=:{me} ->\r
+  let ball                                     = getBall input\r
+      angle                                    = bearing zero me point\r
+      v                                                = ms (2.0 * (toReal (dist me point)))\r
+  in if (dist me ball <= maxKickReach me)\r
+               (KickBall {vxy = {direction=angle,velocity=v},vz=ms 1.0})\r
+               (halt` input)\r
+\r
+track_ball`                                    :: !Metre -> FootballerAI`\r
+track_ball` eps                                = \input -> fix` (getBall input).ballPos.pxy eps input\r
+\r
+amnesia                                                :: FootballerAI` -> FootballerAI m\r
+amnesia f                   = \(input,m) -> (f input,m)\r
+\r
+returnAI                                       :: (FootballerAction -> FootballerAI m)\r
+returnAI                                       = amnesia o returnAI`\r
+\r
+move                                           :: (Speed Angle -> FootballerAI m)\r
+move                                           = \speed angle -> amnesia (move` speed angle)\r
+\r
+halt                                           :: (FootballerAI m)\r
+halt                                           = amnesia halt`\r
+\r
+rotate                                         :: (Angle -> FootballerAI m)\r
+rotate                                         = amnesia o rotate`\r
+\r
+ahead                                          :: (Velocity -> FootballerAI m)\r
+ahead                                          = amnesia o ahead`\r
+\r
+fix                                                    :: (Position Metre -> FootballerAI m)\r
+fix                                                    = \point eps -> amnesia (fix` point eps)\r
+\r
+kick                                           :: (Position -> FootballerAI m)\r
+kick                                           = amnesia o kick`\r
+\r
+track_ball                                     :: (Metre -> FootballerAI m)\r
+track_ball                                     = \eps -> amnesia (track_ball` eps)\r
+\r
+centerOfGoal                           :: !Home !FootballField -> Position\r
+centerOfGoal home field                = {zero & px = if (home==West) (~half_length) half_length}\r
+where\r
+       half_length                             = scale 0.5 field.flength\r
+\r
+(team) infix 9                         :: !Footballer ![Footballer] -> [Footballer]\r
+(team) player players          = filter (sameClub player) players\r
+\r
+(opponents) infix 9                    :: !Footballer ![Footballer] -> [Footballer]\r
+(opponents) player players     = filter (not o (sameClub player)) players\r
+\r
+getBall                                                :: !BrainInput -> Football\r
+getBall {football,me,others}= getFootball football [me : others]\r
+\r
+:: HomeM m                                     = { home :: !Home, mem :: !m }\r
+\r
+educate`                                       :: (Home -> FootballerAI`) -> FootballerAI (HomeM m)\r
+educate` home_ai                       = \(input=:{referee},memory) ->\r
+  let new_home                         = if (any isEndHalf referee) other id memory.home\r
+      action                           = home_ai new_home input\r
+  in  (action, {memory & home = new_home})\r
+\r
+educate                                                :: (Home -> FootballerAI m) -> FootballerAI (HomeM m)\r
+educate home_ai                                = \(input=:{referee},memory) ->\r
+  let new_home                         = if (any isEndHalf referee) other id memory.home\r
+      (action,new_memory)      = home_ai new_home (input,memory.mem)\r
+  in  (action, {memory & home = new_home, mem = new_memory})\r