1 implementation module Team_MartLubbers
4 import FootballerFunctions
24 Team_MartLubbers :: !Home !FootballField -> Team
25 Team_MartLubbers home field
26 | home==West = westTeam
27 | otherwise = eastTeam
29 eastTeam = mirror field westTeam
30 westTeam = [keeper : fielders]
31 clubname = base_TeamName_MartLubbers +++ if (home == West) "_W" "_E"
32 keeper = Aesir clubname home field {zero & px=scale -0.5 field.flength} 1 "Thor"
33 fielders = [Aesir clubname home field {px=scale (-0.5*dx) field.flength,py=scale (0.5*dy) field.fwidth} nr name
34 \\ (dx,dy) <- west_positions_fielders
38 west_positions_fielders = [(0.20, 0.40)
50 :: Role = Attack | Mid | Defense | Keeper
52 isAttack :: Role -> Bool
53 isAttack Attack = True
60 isDefense :: Role -> Bool
61 isDefense Defense = True
64 isKeep :: Role -> Bool
68 fromNumber :: Int -> Role
75 :: Mem = {home :: !Home, origpos :: Position, seed :: !RandomSeed, role :: Role}
77 mirrorMem :: !Mem !FootballField -> Mem
78 mirrorMem mm field = {mm & home=other mm.home, origpos=mirror field mm.origpos}
80 Aesir :: !ClubName !Home !FootballField !Position !PlayersNumber !String -> Footballer
81 Aesir club home field position nr name
82 = { playerID = {clubName=club,playerNr=nr}
83 , name = name +++ "_" <+++ nr
88 , skills = (Running, Kicking, Rotating)
90 , stamina = max_stamina
92 , brain = {memory=if (home == West) mm (mirrorMem mm field), ai = mind field}
95 mm = {home=West, origpos=position, seed=nullRandomSeed, role=fromNumber nr}
97 nextRandomNumber :: !Mem -> (Int, !Mem)
98 nextRandomNumber mm=:{seed} = let (i, newseed) = random seed in (i rem 100, {mm & seed=newseed})
100 mind :: !FootballField !(!BrainInput, !Mem) -> (!BrainOutput, !Mem)
101 mind field (x=:{referee,football,others,me}, mm=:{home,origpos,role})
102 # (i, mm) = nextRandomNumber mm
103 // In case of the end of the half, mirror memory
104 | any (isEndHalf) referee = mind field ({x & referee=filter (\x.not (isEndHalf x)) referee}, mirrorMem mm field)
105 // In case of a pause or end, just halt
106 | any (isPauseGame) referee || any (isGameOver) referee = halt (x, mm)
108 | i_have_the_ball = kick kicktarget_keeper (x, mm)
109 | (dist me.pos ballPos) < (maxCatchReach me) = (CatchBall, mm)
110 | closerToHome home zero ballPos.pxy.px = halt (x, mm)
112 | ballIsFree football
113 | isClosest others me ballPos.pxy = halt (x, mm)
114 | otherwise = stayInGoal (x, mm)
115 | we_have_ball = stayInGoal (x, mm)
117 | length (filter player_within_16 them) == 1
118 | (dist me.pos ballPos.pxy) < (maxCatchReach me)= (CatchBall, mm)
119 | otherwise = fix ballPos.pxy (maxCatchReach me) (x, mm)
120 | otherwise = stayInGoal (x, mm)
122 | we_have_ball = halt (x, mm)
123 | otherwise = stayInGoal (x, mm)
124 // If I'm a field player
125 | otherwise = halt (x, mm)
126 /* // TODO:: The ball is free
127 | ballIsFree football
128 // I'm closest to the ball
129 | isClosest us me ballPos.pxy = afterfix (\(_,_).(GainBall, mm)) ballPos.pxy prec (x, mm)
130 // TODO: Some other player is the closest to the ball
131 | otherwise = halt (x, mm)
132 // TODO: We have the ball
133 | we_have_ball = halt (x, mm)
134 // TODO: I have the ball
135 | ballIsGainedBy me.playerID football = halt (x, mm)
136 // TODO: Someone else has the ball
137 | otherwise = halt (x, mm)
138 // TODO: The ball is with the others
139 | otherwise = halt (x, mm)*/
141 stayInGoal = fix (attract goal_area_depth our_goal ballPos.pxy) prec
142 our_goal = (centerOfGoal home field)
143 their_goal = (centerOfGoal (other home) field)
144 kicktarget_keeper = their_goal //TODO
145 i_have_the_ball = ballIsGainedBy me.playerID football
146 player_within_16 p = inPenaltyArea field home p.pos
147 ball_within_16 = inPenaltyArea field home ballPos.pxy
148 we_have_ball = any (\x.ballIsGainedBy x.playerID football) us
149 they_have_ball = any (\x.ballIsGainedBy x.playerID football) them
150 ballPos = (getBall x).ballPos
151 them = me opponents others
153 prec = scale 0.5 (maxKickReach me)
155 closest :: [Footballer] Position -> Footballer
156 closest xs p = minListBy (\x y.(dist x.pos p) < (dist y.pos p)) xs
158 isClosest :: [Footballer] Footballer Position -> Bool
159 isClosest xs x p = closest [x:xs] p == x
161 closerToHome :: !Home -> a a -> Bool | Ord a
162 closerToHome East = (>)
163 closerToHome West = (<)
165 closerToGoal :: !Home -> a a -> Bool | Ord a
166 closerToGoal h = closerToHome (other h)
168 distToLine :: Position Position Position -> Metre
169 distToLine a b c = (abs (((b.px-a.px)*(a.py-c.py))-((a.px-c.px)*(b.py-a.py))))/d
171 (*) m1 m2 = (m (toReal m1)/(toReal m2))
172 (/) m1 m2 = (m (toReal m1)/(toReal m2))
173 d = sqrt(((b.px-a.px)*(b.px-a.px))+((b.py-a.py)*(b.py-a.py)))
175 afterfix :: (FootballerAI Mem) !Position !Metre !(!BrainInput, !Mem) -> (BrainOutput, !Mem)
176 afterfix after point diff (input=:{me,others}, mm)
177 | d < diff = after (input, mm)
178 // There is no enemy standing in the way
179 | otherwise = (move, mm)
182 a = bearing zero me point
183 r = bearing me.nose me point
184 v = ms (max 6.0 (toReal d))
185 move = Move {direction=a, velocity=v} r
187 base_TeamName_MartLubbers :: String
188 base_TeamName_MartLubbers = "Æsir"