outline and randomness. Afterfix now tackles if necessary
authorMart Lubbers <mart@martlubbers.net>
Wed, 17 Jun 2015 20:24:11 +0000 (22:24 +0200)
committerMart Lubbers <mart@martlubbers.net>
Wed, 17 Jun 2015 20:24:11 +0000 (22:24 +0200)
18 files changed:
src/Game/Footballer.icl
src/Game/Geometry.icl
src/Game/Referee.icl
src/Game/Team.icl
src/Game/matchControl.icl
src/Gui/Gui2D.icl
src/Gui/guiInterface.dcl
src/Gui/guiInterface.icl
src/SoccerFun.prj
src/SoccerFun_options.txt
src/StdReferee/NoReferee.dcl [new file with mode: 0644]
src/StdReferee/NoReferee.icl [new file with mode: 0644]
src/StdReferee/RefereeCoach_Passing_Assignment.icl
src/StdTeam/Team_Harmless.dcl [new file with mode: 0644]
src/StdTeam/Team_Student_Passing_Assignment.icl
src/StdTeam/Team_Student_Rounds_Assignment.icl
src/StdTeam/Team_Student_Slalom_Assignment.icl
src/Team_MartLubbers.icl

index ef8d800..c08026f 100644 (file)
@@ -410,7 +410,7 @@ getKickPos                                                                  :: !FootballField !Half !RefereeAction -> Maybe Position
 getKickPos field half (GoalKick home)          = Just { zero & px = if (home == West) (penalty_area_depth - half_length) (half_length - penalty_area_depth) }
 where
        half_length                                                             = scale 0.5 field.flength
-getKickPos field half (Corner home edge)       = Just { px = if (home == West && half == SecondHalf || home == East && half == FirstHalf)
+getKickPos field half (Corner home edge)       = Just { px = if (home == East)
                                                                                                         (half_radius_corner_kick_area - half_length)
                                                                                                         (half_length - half_radius_corner_kick_area)
                                                                                               , py = if (edge == North)
@@ -421,7 +421,7 @@ where
        half_width                                                              = scale 0.5 field.fwidth
        half_length                                                             = scale 0.5 field.flength
        half_radius_corner_kick_area                    = scale 0.5 radius_corner_kick_area
-getKickPos field half (Penalty home)           = Just { zero & px = if (home == West && half == SecondHalf || home == East && half == FirstHalf)
+getKickPos field half (Penalty home)           = Just { zero & px = if (home == East)
                                                                                                                (penalty_spot_depth - half_length)
                                                                                                                (half_length - penalty_spot_depth)
                                                                                               }
index e9b29da..fe22693 100644 (file)
@@ -65,12 +65,14 @@ degree                                      :: !Int -> Angle
 degree x                               = rad (toReal x * pi / 180.0)
 
 normalize_radian               :: !Real -> Real
-normalize_radian r
-| r < (~cycle)                 = normalize_radian (r + cycle)
-| r >   cycle                  = normalize_radian (r - cycle)
-| otherwise                            = r
-where
-       cycle                           = 2.0 * pi
+normalize_radian r             = normalize r 100
+where 
+    normalize r 0              = abort "Loop in normalize_radian. Mail p.achten@cs.ru.nl"
+       normalize r n
+       | r < ~pi                       = normalize (r + 2.0*pi) (n-1)
+       | r >  pi                       = normalize (r - 2.0*pi) (n-1)
+       | otherwise                     = r
+  
 
 instance zero           Angle                  where zero                          = Radian zero
 instance +              Angle                  where + (Radian r1)  (Radian r2)    = Radian (normalize_radian (r1 + r2))
@@ -208,6 +210,7 @@ orthogonal a                                        = (a + rad (0.25*pi), a - rad (0.25*pi))
 
 px_bearing                                             :: !base !target -> Angle | toPosition base & toPosition target
 px_bearing base target
+| abs ratio > 1.0                              = Radian zero                           // Corner-cases: d==0 and "large values of 1.0"
 | v.dx >= zero && v.dy >= zero = Radian base_angle                     // 1st quadrant
 | v.dx <= zero && v.dy >= zero = Radian (pi-base_angle)        // 2nd quadrant
 | v.dx <= zero && v.dy <= zero = Radian (base_angle-pi)        // 3rd quadrant
@@ -217,7 +220,8 @@ where
        ptarget                                         = toPosition target
        v                                                       = {dx = ptarget.px - pbase.px, dy = ptarget.py - pbase.py}
        d                                                       = toReal (dist pbase ptarget)
-       base_angle                                      = acos ((toReal (abs v.dx)) / d)
+    ratio                                              = toReal (abs v.dx) / d
+       base_angle                                      = acos ratio
 
 bearing                                                        :: !Angle !base !target -> Angle | toPosition base & toPosition target
 bearing angle base target              = px_bearing base target - angle
index 2f88d83..8f8c206 100644 (file)
@@ -3,6 +3,7 @@ implementation module Referee
 import StdEnvExt
 import matchGame
 import Umpire
+import NoReferee
 //     When coding for all referees, include following modules:
 import RefereeCoach_Rounds_Assignment
 import RefereeCoach_Slalom_Assignment
@@ -11,7 +12,7 @@ import RefereeCoach_DeepPass_Assignment
 import RefereeCoach_Keeper_Assignment
 
 allAvailableReferees   :: [FootballField -> Referee]
-allAvailableReferees   = [ umpire ]
+allAvailableReferees   = [ umpire, NoReferee ]
 //     When coding for all referees, use following list:
                                                        ++
                                                  [ RefereeCoach_Rounds
index d41af0b..f7817b9 100644 (file)
@@ -14,10 +14,12 @@ import Team_Student_Passing_Assignment
 import Team_Student_DeepPass_Assignment
 import Team_Student_Keeper_Assignment
 import Team_MartLubbers
+import Team_Harmless
 
 allAvailableTeams                                      :: [Home FootballField -> Team]
 allAvailableTeams                                      = [ Team_MartLubbers
                                                                          , Team_MiniEffies
+                                                                         , Harmless
                                                                          , Team_Student_Rounds
                                                                          , Team_Student_Slalom
                                                                          , Team_Student_Passing
index e0505c0..f52e843 100644 (file)
@@ -22,6 +22,16 @@ instance toString  Seconds where toString  (Seconds s)                               = s +++> " sec."
 doSoccerFun :: !*World -> *World\r
 doSoccerFun world                                                      = SoccerFunGUI2D world\r
 \r
+simulationGranularity :: Seconds\r
+simulationGranularity = s 0.05\r
+\r
+// the original simulation expected to run at 0.1s; this function is used to adjust it to different rates\r
+rateAdjust :: (Real -> Real)\r
+rateAdjust = case simulationGranularity of\r
+                                       Seconds 0.1  -> id\r
+                                       Seconds 0.05 -> sqrt\r
+                                       Seconds x        -> \y -> y^(10.0*x)\r
+\r
 setMatchStart :: !Team !Team !FootballField !Referee !PlayingTime !RandomSeed -> Match\r
 setMatchStart fstTeam sndTeam field referee time rs\r
        = { team1                                                               = validateTeam fstTeam\r
@@ -31,7 +41,7 @@ setMatchStart fstTeam sndTeam field referee time rs
          , theReferee                                                  = referee\r
          , playingHalf                                                 = FirstHalf\r
          , playingTime                                                 = time\r
-         , unittime                                                    = s 0.05\r
+         , unittime                                                    = simulationGranularity\r
          , score                                                               = (0,0)\r
          , nextRandomP                                                 = nextRandomP\r
          , seed                                                                = rs\r
@@ -266,7 +276,7 @@ where
                                angleDifficulty                         = angleHowFarFromPi   (speed.direction-new_nose)\r
                                angleDifference                         = angleHowFarFromAngle speed.direction new_nose\r
                                new_stamina                                     = alter_stamina ball fb angleDifficulty angleDifference\r
-                               new_vel                                         = scale (1.4 * fb.health * new_stamina) (setbetween speed.velocity zero (maxVelocity (skillsAsList fb) angleDifficulty angleDifference))\r
+                               new_vel                                         = scale (fb.health * new_stamina) (setbetween speed.velocity zero (maxVelocity (skillsAsList fb) angleDifficulty angleDifference))\r
                                new_speed                                       = {speed & velocity=new_vel}\r
                                new_position`                           = move_point (scale (dt * (toReal new_vel)) (toRVector new_speed.direction)) fb.pos\r
                                new_position                            = point_to_rectangle ({px=scale -0.5 flength, py=scale -0.5 fwidth},{px=scale 0.5 flength,py=scale 0.5 fwidth}) new_position` \r
@@ -404,7 +414,7 @@ where
        where\r
                old_height                                                      = ballPos.pz\r
                in_the_air                                                      = old_height > zero\r
-               resistance                                                      = if in_the_air air_resistance surface_resistance\r
+               resistance                                                      = rateAdjust if in_the_air air_resistance surface_resistance\r
                dt                                                                      = toReal unittime\r
                surface_movement                                        = scale (dt * (toReal v)) (toRVector d)\r
                new_speed2D                                                     = let new_v = scale resistance v in {direction = d, velocity = if (new_v <= ms 0.05) zero new_v}\r
@@ -470,18 +480,18 @@ alter_stamina :: !FootballState !Footballer !Angle !Angle -> Stamina
 alter_stamina ballState fb angleDifficulty angleDifference\r
 | velocity <= rfv                                                                                      // increase stamina\r
        | stamina < MinimumFatigue                              = MinimumFatigue\r
-       | otherwise                                                             = stamina^0.8   \r
-| otherwise                                                                    = fatigue * factor\r
+       | otherwise                                                             = stamina^(rateAdjust 0.8)\r
+| otherwise                                                                    = fatigue * (rateAdjust factor)\r
 where\r
        velocity                                                                = fb.speed.velocity\r
        length                                                                  = fb.length\r
        stamina                                                                 = fb.stamina\r
        rfv                                                                             = restore_stamina_velocity (ballIsGainedBy fb.playerID ballState) (skillsAsList fb) angleDifficulty angleDifference\r
        diff                                                                    = velocity - rfv\r
-       fv                                                                              = if (diff >= ms 6.0) (stamina^(stamina^(1.6 + 0.02 * toReal length)))\r
-                                                                                        (if (diff >= ms 4.0) (stamina^(         1.5 + 0.01 * toReal length))\r
-                                                                                        (if (diff >= ms 2.0) (stamina^(         1.4 - 0.01 * toReal length))\r
-                                                                                                                         (stamina^(         1.3 - 0.02 * toReal length))))\r
+       fv                                                                              = if (diff >= ms 6.0) (stamina^rateAdjust (stamina^(1.6 + 0.02 * toReal length)))  // problematic\r
+                                                                                        (if (diff >= ms 4.0) (stamina^rateAdjust (         1.5 + 0.01 * toReal length))\r
+                                                                                        (if (diff >= ms 2.0) (stamina^rateAdjust (         1.4 - 0.01 * toReal length))\r
+                                                                                                             (stamina^rateAdjust (         1.3 - 0.02 * toReal length))))\r
        factor                                                                  = one - (toReal angleDifficulty)/(4.0*pi)\r
        fatigue                                                                 = if (stamina > MaximumFatigue) MaximumFatigue fv\r
 \r
index 53902a3..2b59d60 100644 (file)
@@ -108,9 +108,10 @@ where
                                                                                                                            , ("&Predictable",Nothing,Nothing,noLS predictablef)\r
                                                                                                                            ] 0 []\r
                                                                                                                ) []\r
-                                                                               :+: SubMenu "Sp&eed"            ( RadioMenu [ ("&Slowest",Nothing, Just '1', noLS (changeSpeedf timerId Slowest))\r
-                                                                                                                               , ("S&lower", Nothing, Just '2', noLS (changeSpeedf timerId Slower))\r
-                                                                                                                               , ("N&ormal", Nothing, Just '3', noLS (changeSpeedf timerId Normal))\r
+                                                                               :+: SubMenu "Sp&eed"            ( RadioMenu [ ("&Slowest",Nothing, Just '`', noLS (changeSpeedf timerId Slowest))\r
+                                                                                                                               , ("S&lower", Nothing, Just '1', noLS (changeSpeedf timerId Slower))\r
+                                                                                                                               , ("N&ormal", Nothing, Just '2', noLS (changeSpeedf timerId Normal))\r
+                                                                                                                               , ("F&ast",   Nothing, Just '3', noLS (changeSpeedf timerId Fast))\r
                                                                                                                                , ("&Faster", Nothing, Just '4', noLS (changeSpeedf timerId Faster))\r
                                                                                                                                , ("Fas&test",Nothing, Just '5', noLS (changeSpeedf timerId Fastest))\r
                                                                                                                                ] ([Slowest,Slower,Normal,Faster,Fastest]??options.displaySpeed+1) []\r
index e7e5db4..42c184e 100644 (file)
@@ -13,7 +13,7 @@ getActionPicsForGui           :: !Match !*env -> (!ActionPics,!*env) | FileSystem env
 */\r
 stepMatchForGui                        :: !FootballGame !*env -> (![RefereeAction], !FootballGame, !*env) | FileSystem env\r
 \r
-:: DisplaySpeed                        = Slowest | Slower | Normal | Faster | Fastest\r
+:: DisplaySpeed                        = Slowest | Slower | Normal | Fast | Faster | Fastest\r
 instance toString              DisplaySpeed\r
 instance fromString            DisplaySpeed\r
 instance ==                            DisplaySpeed\r
index e6a7dff..1f715ec 100644 (file)
@@ -50,6 +50,7 @@ instance ==         DisplaySpeed where        == Slowest Slowest              = True
 intervalFactor :: !DisplaySpeed -> Real\r
 intervalFactor Slowest         = 1.0 / 0.2     // five times slower\r
 intervalFactor Slower          = 1.0 / 0.5     // two  times slower\r
-intervalFactor Normal          = 1.0           // two  times faster\r
+intervalFactor Normal          = 1.0           // normal speed\r
+intervalFactor Fast                    = 1.0 / 2.0     // two times faster\r
 intervalFactor Faster          = 1.0 / 5.0 // five times faster\r
 intervalFactor Fastest         = zero          // no timer delay\r
index bfb80ed..28de46c 100644 (file)
@@ -401,6 +401,20 @@ OtherModules
                        ReadableABC:    False\r
                        ReuseUniqueNodes:       True\r
                        Fusion: False\r
+       Module\r
+               Name:   NoReferee\r
+               Dir:    {Project}\StdReferee\r
+               Compiler\r
+                       NeverMemoryProfile:     False\r
+                       NeverTimeProfile:       False\r
+                       StrictnessAnalysis:     True\r
+                       ListTypes:      StrictExportTypes\r
+                       ListAttributes: True\r
+                       Warnings:       True\r
+                       Verbose:        True\r
+                       ReadableABC:    False\r
+                       ReuseUniqueNodes:       True\r
+                       Fusion: False\r
        Module\r
                Name:   RefereeCoach_DeepPass_Assignment\r
                Dir:    {Project}\StdReferee\r
@@ -541,6 +555,20 @@ OtherModules
                        ReadableABC:    False\r
                        ReuseUniqueNodes:       True\r
                        Fusion: False\r
+       Module\r
+               Name:   Team_Harmless\r
+               Dir:    {Project}\StdTeam\r
+               Compiler\r
+                       NeverMemoryProfile:     False\r
+                       NeverTimeProfile:       False\r
+                       StrictnessAnalysis:     True\r
+                       ListTypes:      StrictExportTypes\r
+                       ListAttributes: True\r
+                       Warnings:       True\r
+                       Verbose:        True\r
+                       ReadableABC:    False\r
+                       ReuseUniqueNodes:       True\r
+                       Fusion: False\r
        Module\r
                Name:   Team_Opponent_DeepPass_Assignment\r
                Dir:    {Project}\StdTeam\r
index deea162..787224a 100644 (file)
@@ -1 +1 @@
-{closeReferee=True,showSplash=False,displaySpeed=Faster,showReferee=True,playingTime=4:00 min,renderStyle=Fixed camera}
\ No newline at end of file
+{closeReferee=True,showSplash=False,displaySpeed=Normal,showReferee=True,playingTime=4:00 min,renderStyle=Fixed camera}
\ No newline at end of file
diff --git a/src/StdReferee/NoReferee.dcl b/src/StdReferee/NoReferee.dcl
new file mode 100644 (file)
index 0000000..202c5dd
--- /dev/null
@@ -0,0 +1,7 @@
+definition module NoReferee
+
+/** This module implements a null referee which doesn't do anything */
+
+import Referee
+
+NoReferee :: !FootballField -> Referee
diff --git a/src/StdReferee/NoReferee.icl b/src/StdReferee/NoReferee.icl
new file mode 100644 (file)
index 0000000..88ef8d9
--- /dev/null
@@ -0,0 +1,21 @@
+implementation module NoReferee
+
+import StdEnvExt
+import Referee
+
+NoReferee :: !FootballField -> Referee
+NoReferee field        = { name  = "NoReferee"
+                                                         , brain = { memory = initMem
+                                                                   , ai     = randomlessRefereeAI (brain field)
+                                                                   }
+                                                         , refActionPics    = []
+                                                         }
+
+::     Memory = Memory
+
+initMem :: Memory
+initMem = Memory
+
+brain :: !FootballField !(!RefereeInput,!Memory) -> (!RefereeOutput,!Memory)
+brain field ({RefereeInput | theBall=ballState,team1,team2},memory)
+       = ([], memory)
index d5fdc6a..6ab6e2f 100644 (file)
@@ -95,8 +95,7 @@ brain field ({RefereeInput | theBall=ballState, team1, team2}, memory)
 where\r
        theBall                                                                         = getFootball ballState (team1 ++ team2)\r
        (compTeam,(studentTeam,studentHome))            = if (stringStarts (nameOf team1) base_TeamName_Opponent_Passing) (team1,(team2,East)) (team2,(team1,West))\r
-       ballKickoff                                                                     = {zero & px = if (studentHome == West) (scale -0.5 field.flength + scale 2.0 penalty_area_depth) (scale 0.5 field.flength - scale 2.0 penalty_area_depth)}\r
-//     ballKickoff                                                                     = {zero & px = if (studentHome == West) (scale -0.5 field.flength + penalty_area_depth) (scale 0.5 field.flength - penalty_area_depth)}\r
+       ballKickoff                                                                     = {zero & px = if (studentHome == West) (scale -0.5 field.flength + penalty_area_depth) (scale 0.5 field.flength - penalty_area_depth)}\r
        getMessagesForTooFarPlayers                                     = map (\fb -> TellMessage ("Your player with number " <+++ fb.playerID.playerNr <+++ " moved further than 10 meters"))\r
        (north_pole,south_pole)                                         = goal_poles field\r
        \r
diff --git a/src/StdTeam/Team_Harmless.dcl b/src/StdTeam/Team_Harmless.dcl
new file mode 100644 (file)
index 0000000..d4f9554
--- /dev/null
@@ -0,0 +1,11 @@
+system module Team_Harmless
+
+import Team
+
+:: NumPlayers :== Int
+:: Difficulty = Auto | Level Int
+
+// import this module and add the team 'Harmless (n, level)' in Game\Team.icl
+MostlyHarmless :: (!NumPlayers,!Difficulty) Home FootballField -> Team
+
+Harmless :== MostlyHarmless (11,Auto)
index 075236d..ce8f846 100644 (file)
@@ -9,13 +9,11 @@ implementation module Team_Student_Passing_Assignment
 */\r
 \r
 import Footballer\r
-import FootballerFunctions\r
-import StdMaybe\r
 \r
 Team_Student_Passing :: !Home FootballField -> Team\r
 Team_Student_Passing home field        = if (home == West) team (mirror field team)\r
 where\r
-       team                                            = [  {footballer {clubName=club,playerNr=nr} nr & pos = toPosition (scale (0.5*x) field.flength,scale (0.5*y) field.fwidth),nose = rad (dir*pi)}\r
+       team                                            = [  {footballer {clubName=club,playerNr=nr} & pos = toPosition (scale (0.5*x) field.flength,scale (0.5*y) field.fwidth),nose = rad (dir*pi)}\r
                                                                  \\ (x,y) <- positions\r
                                                                   & nr    <- [2..]\r
                                                                   & dir   <- noses\r
@@ -29,49 +27,7 @@ where
                                                                  ,( 0.43,-0.05)\r
                                                                  ]\r
        noses                                           = [1.8,0.0,1.5,0.5,1.2,0.2]\r
-       footballer playerID     nr              = {defaultFootballer playerID & name = "Peter88_" +++ toString nr, brain = {memory=False, ai=mind (getOps field home)}}\r
-       \r
+       footballer playerID                     = defaultFootballer playerID            // implement your footballer here\r
+\r
 base_TeamName_Student_Passing :: String\r
 base_TeamName_Student_Passing = "Student Passing"\r
-\r
-\r
-:: Ops = {\r
-       c :: Metre Metre -> Bool, \r
-       a :: Metre Metre -> Metre, \r
-       s :: Metre Metre -> Metre,\r
-       g :: Position}\r
-\r
-getOps :: !FootballField !Home -> Ops\r
-getOps field West = {c=(<), a=(+), s=(-), g={px=scale 0.5 field.flength, py=(m 0.0)}}\r
-getOps field East = {c=(>), a=(-), s=(+), g={px= ~(scale 0.5 field.flength), py=(m 0.0)}}\r
-\r
-mind :: !Ops !(!BrainInput, !Bool) -> (!BrainOutput, !Bool)\r
-mind op (x=:{me,others}, mm)\r
-| mm || not (best (me team others) me bp) = halt (x, mm)\r
-| otherwise = (afterfix (((\f.(\(i, _).(f i, True))) o kick`) kickpos) bp (maxKickReach me)) (x, mm)\r
-       where\r
-               bp = (getBall x).ballPos.pxy\r
-               \r
-               kickpos = let f = nextPlayer others me in if (isNothing f) op.g (fromJust f).pos\r
-               \r
-               nextPlayer :: [Footballer] Footballer -> Maybe Footballer\r
-               nextPlayer [] me = Nothing\r
-               nextPlayer [x:xs] me\r
-               | op.c x.pos.px me.pos.px = nextPlayer xs me\r
-               | otherwise = Just x\r
-               \r
-               best :: [Footballer] Footballer Position -> Bool\r
-               best [] _ _ = True\r
-               best [x:xs] me bp\r
-               | dist x.pos bp < dist me.pos bp = False\r
-               | otherwise = best xs me bp\r
-               \r
-               afterfix after point diff (input=:{me}, m)\r
-               | d < diff = after (input, m)\r
-               | otherwise = (move, m)\r
-               where\r
-                       d = dist me point\r
-                       a = bearing zero me point\r
-                       r = bearing me.nose me point\r
-                       v = ms (max 6.0 (toReal d))\r
-                       move = Move {direction=a, velocity=v} r
\ No newline at end of file
index a68889c..8c0e333 100644 (file)
@@ -8,7 +8,6 @@ implementation module Team_Student_Rounds_Assignment
        Do not change the implementation of base_TeamName_Student_Rounds.\r
 */\r
 import Footballer\r
-import FootballerFunctions\r
 \r
 Team_Student_Rounds :: !Home !FootballField -> Team\r
 Team_Student_Rounds home field         = if (home == West) team (mirror field team)\r
@@ -19,18 +18,7 @@ where
                                                                          ]\r
        club                                                    = base_TeamName_Student_Rounds +++ if (home==West) "_W" "_E"\r
        positions                                               = [(-0.49,0.00)]\r
-       footballer playerID                             = {defaultFootballer playerID & name = "Peter88", brain = {memory = Void, ai = mind field}}\r
+       footballer playerID                             = defaultFootballer playerID            // implement your footballer here\r
 \r
 base_TeamName_Student_Rounds :: String\r
 base_TeamName_Student_Rounds = "Student Rounds"\r
-\r
-mind :: !FootballField !(!BrainInput, !Void) -> (!BrainOutput, !Void)\r
-mind field (i=:{me}, mm)\r
-| y >= (t -o) && x > (~r+o) = (fix {px= ~r,py= t}  c) (i, mm)\r
-| x <= (~r+o) && y > (~t+o) = (fix {px= ~r,py= ~t} c) (i, mm)\r
-| y <= (~t+o) && x < (r -o) = (fix {px= r, py= ~t} c) (i, mm)\r
-| x >= (r -o) && y < (t -o) = (fix {px= r, py= t}  c) (i, mm)\r
-       where\r
-               (x, y, o, c) = (me.pos.px, me.pos.py, m 4.0, m 1.5)\r
-               t = scale 0.5 field.fwidth\r
-               r = scale 0.5 field.flength
\ No newline at end of file
index a62f4a5..a77671d 100644 (file)
@@ -1,4 +1,3 @@
-\r
 implementation module Team_Student_Slalom_Assignment\r
 \r
 /**    Implement a solution to the slalom assignment.\r
@@ -18,26 +17,7 @@ where
        team                                            = [{footballer {clubName=club,playerNr=2} & pos = if (home == West) position (mirror field position)}]\r
        club                                            = base_TeamName_Student_Slalom +++ if (home == West) "_W" "_E"\r
        position                                        = {zero & px = scale -0.5 field.flength + penalty_area_depth}\r
-       footballer player_id            = {defaultFootballer player_id & name = "Peter88", brain = {memory = Void, ai =  mind field home}}\r
+       footballer player_id            = defaultFootballer player_id   // implement your footballer here\r
 \r
 base_TeamName_Student_Slalom :: String\r
 base_TeamName_Student_Slalom   = "Student Slalom"\r
-\r
-mind :: !FootballField !Home !(!BrainInput, !Void) -> (!BrainOutput, !Void)\r
-mind field home (x=:{me,others}, mm)\r
-| dist (getBall x).ballPos me.pos < (maxKickReach me) = (kick {px=sig (scale 0.5 field.flength), py=m 0.0}) (x, mm)\r
-| otherwise = (fix  {px=pp2 cp.px (m 2.5), py=up cp.py (m 3.5)} (maxKickReach me)) (x, mm)\r
-       where\r
-               (comparator, pp1, pp2, sig) = if (home == West) ((<), (-), (+), (\w.w)) ((>), (+), (-), (~))\r
-               sf2 = sortBy (\x y.comparator x.pos.px y.pos.px) others\r
-               sf = sf2 % (0, (length sf2) - 2)\r
-               (cp, up) = closestPos (zip2 [1..] sf) (pp1 me.pos.px xWidthFootballer) (getBall x).ballPos.pxy comparator\r
-               \r
-closestPos :: [(Int, Footballer)] Metre Position (Metre Metre -> Bool) -> (Position, (Metre Metre -> Metre))\r
-closestPos [] _ d _ = (d, (\x y.x))\r
-closestPos [(i, x):xs] p d c\r
-| c p x.pos.px = (x.pos, if (i rem 2 == 0) (+) (-))\r
-| otherwise = closestPos xs p d c\r
-\r
-\r
-\r
index ee0de18..ef3ff01 100644 (file)
@@ -47,7 +47,10 @@ where
                                                          ,(0.90,-0.05)\r
                                                          ]                                                       \r
 \r
-:: Mem = {home :: !Home, origpos :: Position}\r
+:: Mem = {home :: !Home, origpos :: Position, seed :: !RandomSeed}\r
+\r
+mirrorMem :: !Mem !FootballField -> Mem\r
+mirrorMem mm field = {mm & home=other mm.home, origpos=mirror field mm.origpos}\r
 \r
 Aesir :: !ClubName !Home !FootballField !Position !PlayersNumber !String -> Footballer\r
 Aesir club home field position nr name\r
@@ -61,55 +64,67 @@ Aesir club home field position nr name
          , effect                              = Nothing\r
          , stamina                             = max_stamina\r
          , health                              = max_health\r
-         , brain                               = {memory = {home=home, origpos=position}, ai = mind field }\r
+         , brain                               = {memory=if (home == West) mm (mirrorMem mm field), ai = mind field}\r
          }\r
-         \r
-closerToGoal :: !Home -> Metre Metre -> Bool\r
-closerToGoal East = (<)\r
-closerToGoal West = (>)\r
-\r
-getMin :: !Home -> Metre Metre -> Metre\r
-getMin h = getMax (other h)\r
-\r
-getMax :: !Home -> Metre Metre -> Metre\r
-getMax East = (max)\r
-getMax West = (min)\r
+       where\r
+               mm = {home=West, origpos=position, seed=nullRandomSeed}\r
+               \r
+nextRandomNumber :: !Mem -> (Int, !Mem)\r
+nextRandomNumber mm=:{seed} = let (i, newseed) = random seed in (i rem 100, {mm & seed=newseed})\r
 \r
 mind :: !FootballField !(!BrainInput, !Mem) -> (!BrainOutput, !Mem)\r
 mind field (x=:{referee,football,others,me}, mm=:{home,origpos})\r
-# mm=:{home,origpos} = if (any isEndHalf referee) {home=other home, origpos=mirror field origpos} mm\r
-| ballIsGainedBy me.playerID football\r
-       | dist nextPos me.pos < (m 10.0) = kick nextPos (x, mm)\r
-       | otherwise = fix nextPos (m 1.0) (x, mm)\r
-| isClosest others me ballPos.pxy = afterfix (\(_, m).(GainBall, m)) ballPos.pxy (scale 0.5 (maxKickReach me)) (x, mm)\r
-| otherwise\r
-       | we_have_ball = fix {px=getMin home ballPos.pxy.px (field.flength-me.pos.px), py=me.pos.py} (m 1.0) (x, mm)\r
-       | otherwise\r
-               | me.stamina > 0.5 = fix origpos (m 1.0) (x, mm)\r
-               | otherwise = halt (x, mm)\r
+// In case of the end of the half, mirror memory\r
+| any (isEndHalf) referee = mind field ({x & referee=filter (\x.not (isEndHalf x)) referee}, mirrorMem mm field)\r
+// In case of a pause or end, just halt\r
+| any (isPauseGame) referee || any (isGameOver) referee = halt (x, mm)\r
+// TODO:: The ball is free\r
+| ballIsFree football\r
+       // I'm closest to the ball\r
+       | isClosest us me ballPos.pxy = afterfix (\(_,_).(GainBall, mm)) ballPos.pxy prec (x, mm)\r
+       // TODO: Some other player is the closest to the ball\r
+       | otherwise = halt (x, mm)\r
+// TODO: We have the ball\r
+| any (\x.ballIsGainedBy x.playerID football) us = halt (x, mm)\r
+       // TODO: I have the ball\r
+       | ballIsGainedBy me.playerID football\r
+       // TODO: Someone else has the ball\r
+       | otherwise = halt (x, mm)\r
+// TODO: The ball is with the others\r
+| otherwise = halt (x, mm)\r
        where\r
-               us = me team others\r
                ballPos = (getBall x).ballPos\r
-               nextPos = nextPlayer home field us me.pos\r
-               we_have_ball = or (map (\x.ballIsGainedBy x.playerID football) us)\r
-\r
-nextPlayer :: !Home !FootballField [Footballer] Position -> Position\r
-nextPlayer home field xs pos\r
-# xs = filter (\x.closerToGoal home x.pos.px pos.px) xs\r
-| xs == [] = centerOfGoal (other home) field\r
-| otherwise = (minListBy (\x y.(dist x.pos pos) < (dist y.pos pos)) xs).pos\r
-\r
+               them = me opponents others\r
+               us = me team others\r
+               prec = scale 0.5 (maxKickReach me)\r
+               \r
 closest :: [Footballer] Position -> Footballer\r
 closest xs p = minListBy (\x y.(dist x.pos p) < (dist y.pos p)) xs\r
 \r
 isClosest :: [Footballer] Footballer Position -> Bool\r
 isClosest xs x p = closest [x:xs] p == x\r
 \r
-afterfix :: (FootballerAI m) !Position !Metre !(!BrainInput, m) -> (BrainOutput, m)\r
-afterfix after point diff (input=:{me}, m)\r
-| d < diff = after (input, m)\r
-| otherwise = (move, m)\r
+closerToGoal :: !Home -> Metre Metre -> Bool\r
+closerToGoal East = (<)\r
+closerToGoal West = (>)\r
+\r
+distToLine :: Position Position Position -> Metre\r
+distToLine a b c = (abs (((b.px-a.px)*(a.py-c.py))-((a.px-c.px)*(b.py-a.py))))/d\r
+       where\r
+               (*) m1 m2 = (m (toReal m1)/(toReal m2))\r
+               (/) m1 m2 = (m (toReal m1)/(toReal m2))\r
+               d = sqrt(((b.px-a.px)*(b.px-a.px))+((b.py-a.py)*(b.py-a.py)))\r
+\r
+//afterfix :: (FootballerAI m) !Position !Metre !(!BrainInput, !Mem) -> (BrainOutput, !Mem)\r
+afterfix after point diff (input=:{me,others}, mm)\r
+# (i, mm) = nextRandomNumber mm\r
+| d < diff = after (input, mm)\r
+// There is a enemy standing in the way and I feel like it\r
+| (dist closestOpp me.pos) < (maxTackleReach me) && i < 15 = (Tackle closestOpp.playerID (ms 6.0), mm)\r
+// There is no enemy standing in the way\r
+| otherwise = (move, mm)\r
        where\r
+               closestOpp = closest (me opponents others) me.pos\r
                d = dist me point\r
                a = bearing zero me point\r
                r = bearing me.nose me point\r