#! /pkg/gnu/bin/gawk -f BEGIN { srand() lmargin = 10 tmargin = 10 height = 300 width = 600 halfemh = 18 halfemw = 12 restricted = 25 MAXDEVP = 20 TRAILS = 1 redrgoal = height/2 redcgoal = 0 greenrgoal = height/2 greencgoal = width getline whoami # print "i am "whoami if (whoami == "red") { mygoalr = redrgoal; mygoalc = redcgoal hergoalr = greenrgoal; hergoalc = greencgoal } else { mygoalr = greenrgoal; mygoalc = greencgoal hergoalr = redrgoal; hergoalc = redcgoal } while (getline < "init" > 0) { initr[$1] = $3 initr2[$1] = height/2 + 2.5*($3 - height/2) # split it out twice as wide initc[$1] = $4 } while (getline < "pos" > 0) { if ($1 ~ /^[a-zA-Z0]$/) { dat[$1] = $0 color[$1] = $2 rdat[$1] = $3 cdat[$1] = $4 edat[$1] = $5 if ($1 == "0") { rball = rdat["0"] cball = cdat["0"] if ($0 ~ /aloft/) notes["0"] = "aloft" if (match($0,/static[0-9]*/)) static["0"] = substr($0,RSTART+6,RLENGTH) } } } close("pos") while (getline < "dirs" > 0) { if ($1 ~ /^[a-zA-Z0]$/) { dirdat[$1] = $0 rdev[$1] = $3 cdev[$1] = $4 if ($1 == "0") { rrdev[$1] = rdev[$1] ccdev[$1] = cdev[$1] } else { rrdev[$1] = maxdev(rdev[$1]) ccdev[$1] = maxdev(cdev[$1]) } rkick[$1] = maxkick($6) ckick[$1] = maxkick($7) kick[$1] = $5" "$6" "$7 } } close("dirs") for (i in dirdat) { if (color[i] == whoami) { rkick[i] = "" ckick[i] = "" kick[i] = "" } } initrules() # print nr" rules" makedirs() for (i in rrdev) { if (color[i] == whoami) print i, color[i], rdev[i], cdev[i], kick[i], notes[i] } } func sq(x) { return x*x } func maxkick(x,y, z,zscale) { z = sqrt(x*x + y*y) if (z > 2*MAXDEVP) zscale = sqrt(z/(2*MAXDEVP)) else zscale = 1 return x/zscale } func maxdev(x,y, z,zscale) { z = sqrt(x*x + y*y) if (z > MAXDEVP) zscale = sqrt(z/MAXDEVP) else zscale = 1 return x/zscale } func rok(x) { x = int(.5+x) if (x < 0) return 0 if (x > height) return height return x } func cok(x) { x = int(.5+x) if (x < 0) return 0 if (x > width) return width return x } func eok(x) { x = int(.5+x) if (x < 0) return 0 if (x > 100) return 100 return x } func sgn(x) { if (x < 0) return -1 if (x > 0) return 1 return 0 } func abs(x) { if (x < 0) return -x return x } func makedirs( i,r) { calcnearest() for (i in dirdat) { if (color[i] != whoami) continue for (r=1; r in pre; r++) { # for now, only do first rule that applies! if (app(r,i)) { process(post[r],i) # special check for goalie area if (restrictedarea(i,rdat[i]+rdev[i],cdat[i]+cdev[i])) { rdev[i] += rdev[i]*rand()/10 - rdev[i]*rand()/10 cdev[i] += cdev[i]*rand()/10 - cdev[i]*rand()/10 } if (restrictedarea(i,rdat[i]+rdev[i]/2,cdat[i]+cdev[i]/2)) { rdev[i] += rdev[i]*rand()/10 - rdev[i]*rand()/10 cdev[i] += cdev[i]*rand()/10 - cdev[i]*rand()/10 } notes[i] = " : : : " pre[r] " ---> " post[r] break } } } } func restrictedarea(who,rr,cc) { if (who == "A" && cc > width-restricted) return 0 if (who == "a" && cc < restricted) return 0 if (cc < restricted && abs(rr-mygoalr) < restricted) return 1 if (cc > width-restricted && abs(rr-mygoalr) < restricted) return 1 return 0 } func initrules() { #pre[++nr] = "iamnearestplayer iamdefended" #post[nr] = "passtonearestopenteammate" pre[++nr] = "staticball nearestnongoalieonteam" post[nr] = "moveandkick" pre[++nr] = "offense iamnearestplayer not-defended spry not-quitenear" post[nr] = "movetoball" pre[++nr] = "offense iamnearestplayer not-defended spry quitenear not-ballnearhergoal" post[nr] = "movetoball dribbleforward" pre[++nr] = "offense iamnearestplayer not-tired not-quitenear" post[nr] = "movetoball" pre[++nr] = "iamgoalie ballinmygoal" post[nr] = "moveandkick" pre[++nr] = "iamgoalie not-ballnearmygoal" post[nr] = "reset" pre[++nr] = "defense iamnearestplayer not-tired" post[nr] = "moveandkick" pre[++nr] = "iamgoalie ballnearmygoal iamnearestplayer" post[nr] = "moveandkick" pre[++nr] = "iamgoalie ballverynearmygoal" post[nr] = "block" pre[++nr] = "iamgoalie ballnearmygoal ballbelowgoal" post[nr] = "movedowningoal" pre[++nr] = "iamgoalie ballnearmygoal ballabovegoal" post[nr] = "moveupingoal" pre[++nr] = "attacker defense quitenear" post[nr] = "moveandkick" pre[++nr] = "attacker defense not-near" post[nr] = "reset2" pre[++nr] = "attacker nearestonteam" post[nr] = "moveandkick" pre[++nr] = "attacker not-nearestonteam not-iamcenter" post[nr] = "movectogoal" pre[++nr] = "defender openfield" post[nr] = "supportinrow" pre[++nr] = "attacker openfield" post[nr] = "attackinrow" pre[++nr] = "offense nearestonteam not-tired" post[nr] = "moveandkick" pre[++nr] = "defense nearestonteam not-tired" post[nr] = "moveandkick" pre[++nr] = "defense defender near not-tired" post[nr] = "block" pre[++nr] = "defense not-nearestonteam not-attacker not-iamgoalie not-tired" post[nr] = "retreatinrow" pre[++nr] = "not-iamgoalie quitenear nearestonteam not-tired" post[nr] = "moveandkick" pre[++nr] = "iamgoalie defense" post[nr] = "retreatinrow" pre[++nr] = "iamgoalie offense" post[nr] = "retreatinrow" pre[++nr] = "true" post[nr] = "halt" } func app(r,who, j,predlist) { split(pre[r],predlist," ") for (j in predlist) { if (!applies(predlist[j],who)) return 0 } return 1 } function applies(predicate,who, i,mydist,herdist,suffix) { if (predicate ~ /^not-/) { suffix = substr(predicate,5) if (applies(suffix,who)) return 0 return 1 } if (predicate == "true") return 1 else if (predicate == "iamgoalie") { if (whoami == "red" && who == "a") return 1 if (whoami == "green" && who == "A") return 1 return 0 } else if (predicate == "ballabovegoal") { if (rball > mygoalr-10) return 1 return 0 } else if (predicate == "ballbelowgoal") { if (rball > mygoalr+10) return 1 return 0 } else if (predicate == "ballverynearmygoal") { if (sqrt(sq(cball - mygoalc)+sq(rball - mygoalr)) < 60) return 1 return 0 } else if (predicate == "ballnearmygoal") { if (sqrt(sq(cball - mygoalc)+sq(rball - mygoalr)) < 100) return 1 return 0 } else if (predicate == "ballnearhergoal") { if (sqrt(sq(cball - hergoalc)+sq(rball - hergoalr)) < 120) return 1 return 0 } else if (predicate == "cballnearhergoal") { if (sqrt(sq(cball - hergoalc)+sq(rball - hergoalr)) < 150) return 1 if (abs(hergoalc - cball) < 20) return 1 return 0 } else if (predicate == "ballinmygoal") { if (abs(rball - mygoalr) < restricted && abs(cball - mygoalc) < restricted) return 1 return 0 } else if (predicate == "iamcenter") { if (who == "C" || who =="c") return 1 return 0 } else if (predicate == "quitenear") { if (sqrt(sq(cball - cdat[who])+sq(rball - rdat[who])) < 50) return 1 return 0 } else if (predicate == "near") { if (sqrt(sq(cball - cdat[who])+sq(rball - rdat[who])) < 150) return 1 return 0 } else if (predicate == "iamnearestplayer") { if (nearestplayerid == who) return 1 return 0 } else if (predicate == "nearestonteam") { if (cnearestplayerid[color[who]] == who) return 1 return 0 } else if (predicate == "nearestnongoalieonteam") { if (whonongoalienearest && (whonongoalienearest == who)) return 1 if (whonongoalienearest && (whonongoalienearest != who)) return 0 mydist = sqrt(sq(cball - cdat[who])+sq(rball - rdat[who])) for (i in dat) { if (color[i]==whoami && i!=who && i!="a" && i!="A") { herdist = sqrt(sq(cball - cdat[i])+sq(rball - rdat[i])) if (herdist < mydist) { whonongoalienearest=i; return 0 } } } return 1 } else if (predicate == "staticball") { if (static["0"] >= 5 ) return 1 return 0 } else if (predicate == "tired") { if (edat[who] < 25) return 1 return 0 } else if (predicate == "spry") { if (edat[who] > 50) return 1 return 0 } else if (predicate == "defended") { for (i in dat) if (color[i]!=whoami && i!="0") if (sqrt(sq(cdat[who]-cdat[i])+sq(rdat[who]-rdat[i])) < 50) return 1 return 0 } else if (predicate == "defender") { if (who == "B" || who == "D" || who == "E") return 1 if (who == "b" || who == "d" || who == "e") return 1 return 0 } else if (predicate == "attacker") { if (who == "F" || who == "C" || who == "G") return 1 if (who == "f" || who == "c" || who == "g") return 1 return 0 } else if (predicate == "openfield") { # the other team is regrouping on a deep ball if (nearestteamid == whoami) return 0 if (whoami == "red" && cball > 2*width/3) return 1 if (whoami == "green" && cball < width/3) return 1 return 0 } else if (predicate == "offense") { if (nearestteamid != whoami) return 0 if (whoami == "red" && cball > .3*width) return 1 if (whoami == "green" && cball < .7*width) return 1 return 0 } else if (predicate == "defense") { if (nearestteamid == whoami) return 0 if (whoami == "red" && cball < .8*width) return 1 if (whoami == "green" && cball > .2*width) return 1 return 0 } } func calcnearest( i,dist,bestdist) { for (i in dat) { if (i == "0") continue dist = sqrt(sq(cball - cdat[i])+sq(rball - rdat[i])) if (dist < bestdist || bestdist=="") { bestdist = dist nearestteamid = color[i] nearestplayerid = i nearestdist = dist } if (dist < cbestdist[color[i]] || cbestdist[color[i]]=="") { cbestdist[color[i]] = dist cnearestplayerid[color[i]] = i cnearestdist[color[i]] = dist } } } func process(r,who, j,predlist,action,cc,dd) { split(r,predlist," ") for (j in predlist) { action = predlist[j] if (action == "kickatgoal") { cc = hergoalc - cdat[who] dd = hergoalr - rdat[who] kick[who] = "kick.aloft "dd" "cc } else if (action == "kickaway") { cc = hergoalc - cdat[who] dd = rand()*2*cc-rand()*2*cc kick[who] = "kick.aloft "dd" "cc } else if (action == "dribbleforward") { cc = hergoalc - cdat[who] if (abs(cc) > 10) cc = 10*cc/abs(cc) dd = rand()*2*cc - rand()*2*cc kick[who] = "kick "dd" "cc } else if (action == "block") { targetr = (rball+mygoalr)/2 targetc = (cball+mygoalc)/2 cdev[who] = targetc - cdat[who] rdev[who] = targetr - rdat[who] } else if (action == "reset") { cdev[who] = initc[who] - cdat[who] rdev[who] = initr[who] - rdat[who] } else if (action == "reset2") { cdev[who] = initc[who] - cdat[who] rdev[who] = initr2[who] - rdat[who] } else if (action == "retreat") { cdev[who] = mygoalc - cdat[who] rdev[who] = mygoalr - rdat[who] } else if (action == "retreatinrow") { cdev[who] = mygoalc - cdat[who] if (abs(cdat[who] - mygoalc) < 50) cdev[who] = 0 rdev[who] = initr[who] - rdat[who] } else if (action == "attackinrow") { cdev[who] = (cball+hergoalc)/2 - cdat[who] if (abs(cdat[who] - hergoalc) < 50) cdev[who] = 0 rdev[who] = initr[who] - rdat[who] } else if (action == "supportinrow") { if (abs(cdat[who]-mygoalc) < width/2) cdev[who] = (cball+hergoalc)/2 - cdat[who] else cdev[who] = 0 rdev[who] = initr[who] - rdat[who] } else if (action == "movetogoal") { cdev[who] = hergoalc - cdat[who] rdev[who] = hergoalr - rdat[who] if (abs(cdat[who]-hergoalc)