#! /pkg/gnu/bin/gawk -f
BEGIN {
print "Content-type: text/html\n"
srand()
lmargin = 10
tmargin = 10
height = 300
width = 600
halfemh = 18
halfemw = 12
MAXDEVP = 20
DENSESPACE = 3
SPARSESPACE = 8
# -v for redplayer and greenplayer
TRAILS = 1
DELAY = 0
redrgoal = height/2
redcgoal = 0
greenrgoal = height/2
greencgoal = width
com = ENVIRON["QUERY_STRING"]
if (com ~ "init") {
init()
sub(/init/,"",com)
}
if (com+0 == com) system("sleep "com)
split(com,temp,"&")
for (i in temp) {
split(temp[i],tt,"=")
cgidat[tt[1]] = tt[2]
}
redplayer = cgidat["redplayer"]
greenplayer = cgidat["greenplayer"]
print ""redplayer" vs. "greenplayer""
print ""
print ""
print "
dirs pos init 2minpause stop
"
#graph(tmargin+height/2,lmargin,"[","red")
#graph(tmargin+height/2,lmargin+width,"]","green")
graph(tmargin+height/2-8,lmargin,"|","red")
graph(tmargin+height/2,lmargin,"|","red")
graph(tmargin+height/2+8,lmargin,"|","red")
graph(tmargin+height/2-8,lmargin+width,"|","green")
graph(tmargin+height/2,lmargin+width,"|","green")
graph(tmargin+height/2+8,lmargin+width,"|","green")
while (getline < "pos" > 0) {
# check for corruption
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"
}
}
}
close("pos")
for (i in dat) {
graph(tmargin+rdat[i],lmargin+cdat[i],""symbol(i) printme(i)"",color[i])
}
while (getline < "dirs" > 0) {
if ($1 ~ /^[a-zA-Z0]$/) {
dirdat[$1] = $0
rdev[$1] = $3
cdev[$1] = $4
rrdev[$1] = rdev[$1]
ccdev[$1] = cdev[$1]
rkick[$1] = $6
ckick[$1] = $7
}
}
close("dirs")
rrdev["0"] = rdev["0"] = (abs(rdev["0"])-1)*sgn(rdev["0"])
ccdev["0"] = cdev["0"] = (abs(cdev["0"])-1)*sgn(cdev["0"])
# print "moving"
move()
# print "making"
if (redplayer) system("./"redplayer)
if (greenplayer) system("./"greenplayer)
makedirs()
# print "writing"
for (i in dat) {
print i, color[i], rdat[i], cdat[i], edat[i], notes[i] > "pos"
}
close("pos")
for (i in rrdev) {
print i, color[i], rrdev[i], ccdev[i], kick[i] > "dirs"
}
close("dirs")
if (1) {
print ""
print ""
print ""
print ""
print ""
system("sort pos")
print " | "
print ""
print ""
system("sort dirs")
print " |
"
print ""
}
}
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 printme(x) {
if (x=="0") return ""
return x
}
func symbol(x) {
if (x=="0" && notes["0"] ~ /aloft/) return "^"
if (x=="0") return "@"
return ""
}
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 move( n) {
for (i in dat) {
print edat[i],i > "tmp/soc.tmp"
}
close("tmp/soc.tmp")
com = "sort -nr tmp/soc.tmp"
while (com | getline) {
order[++n] = $2
}
close(com)
for (i=1; i<=n; i++) {
who = order[i]
# to do: occupied indexed by team
# occupied[rdat[who],cdat[who]] = who
occupy(who,rdat[who],cdat[who])
}
for (i=1; i<=n; i++) {
who = order[i]
if (who == "0" && notes["0"] ~ /aloft/) aloftball = 1
else aloftball = 0
if (abs(cdev[who])>1 || abs(rdev[who])>1) go = 1
else go = 0
# to do: make this check on each step
if (edat[who] > 0) {
if (rdev[who]) slope = cdev[who]/rdev[who]
else slope = "inf"
rdev[who] = maxdev(rdev[who])
cdev[who] = maxdev(cdev[who])
if (slope == "inf") {
if (cdev[who] > 0) for (cj=1; go && cj<=cdev[who]; cj++) {
if (!aloftball && !myclear(who,occupied[rdat[who],cok(cdat[who]+1)])) go = 0
else {
cdat[who] = cok(cdat[who]+1)
occupy(who,rdat[who],cdat[who])
}
} else for (cj=cdev[who]; go && cj<0; cj++) {
if (!aloftball && !myclear(who,occupied[rdat[who],cok(cdat[who]-1)])) go = 0
else {
cdat[who] = cok(cdat[who]-1)
occupy(who,rdat[who],cdat[who])
}
}
} else if (slope == 0) {
if (rdev[who] > 0) for (rj=1; go && rj<=rdev[who]; rj++) {
if (!aloftball && !myclear(who,occupied[rok(rdat[who]+1),cdat[who]])) go = 0
else {
rdat[who] = rok(rdat[who]+1)
occupy(who,rdat[who],cdat[who])
}
} else for (rj=rdev[who]; go && rj<0; rj++) {
if (!aloftball && !myclear(who,occupied[rok(rdat[who]-1),cdat[who]])) go = 0
else {
rdat[who] = rok(rdat[who]-1)
occupy(who,rdat[who],cdat[who])
}
}
} else {
if (abs(slope) < 1) {
islope = 1/slope
if (cdev[who] > 0) for (cj=1; go && cj<=cdev[who]; cj++) {
if (!aloftball && !myclear(who,occupied[rok(rdat[who]+islope),cok(cdat[who]+1)])) go = 0
else {
rdat[who] = rok(rdat[who]+islope)
cdat[who] = cok(cdat[who]+1)
occupy(who,rdat[who],cdat[who])
}
} else for (cj=cdev[who]; go && cj<0; cj++) {
if (!aloftball && !myclear(who,occupied[rok(rdat[who]-islope),cok(cdat[who]-1)])) go = 0
else {
rdat[who] = rok(rdat[who]-islope)
cdat[who] = cok(cdat[who]-1)
occupy(who,rdat[who],cdat[who])
}
}
} else {
if (rdev[who] > 0) for (rj=1; go && rj<=rdev[who]; rj++) {
if (!aloftball && !myclear(who,occupied[rok(rdat[who]+1),cok(cdat[who]+slope)])) go = 0
else {
rdat[who] = rok(rdat[who]+1)
cdat[who] = cok(cdat[who]+slope)
occupy(who,rdat[who],cdat[who])
}
} else for (rj=rdev[who]; go && rj<0; rj++) {
if (!aloftball && !myclear(who,occupied[rok(rdat[who]-1),cok(cdat[who]-slope)])) go = 0
else {
rdat[who] = rok(rdat[who]-1)
cdat[who] = cok(cdat[who]-slope)
occupy(who,rdat[who],cdat[who])
}
}
}
}
} else {
# zero the motion when tired?
cdev[who] = rdev[who] = 0
}
# to do: energy curves
# to do: kicking costs energy
edat[who] = eok(edat[who]+15-sqrt(rdev[who]*rdev[who]+cdev[who]*cdev[who]))-5*rand()
rball = rdat["0"]; cball = cdat["0"]
# to do: ball bounce
# to do: check for goal
if (who == "0") {
if (cball==redcgoal && abs(rball-redrgoal)<=1) {
print "GREEN SCORES!"
system("sleep 10")
init()
exit
}
if (cball==greencgoal && abs(rball-greenrgoal)<=1) {
print "RED SCORES!"
system("sleep 10")
init()
exit
}
}
if (who != "0" && dirdat[who] ~ /kick/ && notes["0"] !~ /aloft/) {
if (abs(rdat[who]-rball)<=5 && abs(cdat[who]-cball)<=5) {
# to do: kicking error based on ball speed, player speed
rrdev["0"] = maxkick(rkick[who])
ccdev["0"] = maxkick(ckick[who])
kicked = 1
# to do: do this w/prob
if (dirdat[who] ~ /aloft/) {
notes["0"] = "aloft"
}
}
}
}
if (TRAILS) for (s in occupied) {
split(s,temp,SUBSEP)
graph(temp[1],temp[2],".","EEEEEE",-1)
# graph(temp[1],temp[2],occupied[s],"black")
}
}
func graph(r,c,x,xcolor,zz) {
if (!zz) zz=0
print ""x""
}
func makedirs() {
# ball slows
if (!kicked) {
ccdev["0"] *= .6
rrdev["0"] *= .6
}
# don't let ball wiggle
if (abs(ccdev["0"]) < 1 && abs(rrdev["0"]) < 1) { ccdev["0"] = 0; rrdev["0"] = 0 }
# ball falls
if (!kicked && notes["0"] ~ /aloft/) {
if (rand() < .3) notes["0"] = ""
if (ccdev["0"] < 1 && rrdev["0"] < 1) notes["0"] = ""
}
while (getline < "init") {
rinit[$1] = $3
cinit[$1] = $4
}
close("init")
if (rand() < .9) chaser["f"] = 1
if (rand() < .9) chaser["g"] = 1
if (rand() < .7) chaser["F"] = 1
if (rand() < .7) chaser["G"] = 1
if (rand() < .4) chaser["c"] = 1
if (rand() < .4) chaser["C"] = 1
if (rand() < .4) chaser["b"] = 1
if (rand() < .4) chaser["B"] = 1
# to do: vision based on direction, speed, ball, player
# to do: call each program
for (i in dat) {
if (redplayer && color[i] == "red") continue
if (greenplayer && color[i] == "green") continue
if (i == "0") continue
key = index("aAbBcCdDeEfFgG",i)
if (i != "0" && i !="a" && i != "A") {
if (edat[i] > 20 && chaser[i] || (abs(cdat["0"]-cdat[i]) < 50 && abs(rdat["0"]-rdat[i]) < 20)) {
ccdev[i] = maxdev(cdat["0"]-cdat[i])
rrdev[i] = maxdev(rdat["0"]-rdat[i])
if (rand() < .8 && (rball < 20 || rball > width-20 || rand() < .25)) {
if (color[i] ~ /red/) kick[i] = "kick.aloft "greenrgoal-rdat[i]" "greencgoal-cdat[i]
if (color[i] ~ /green/) kick[i] = "kick.aloft "redrgoal-rdat[i]" "redcgoal-cdat[i]
} else {
if (color[i] ~ /red/) kick[i] = "kick.aloft "300+900*rand()" "greencgoal-cdat[i]
if (color[i] ~ /green/) kick[i] = "kick.aloft "-300-900*rand()" "redcgoal-cdat[i]
}
} else if (edat[i] > 50) {
ccdev[i] = maxdev(cinit[i]-cdat[i])
rrdev[i] = maxdev(rinit[i]-rdat[i])
} else {
ccdev[i] = 0
rrdev[i] = 0
}
}
}
}
func maxkick(x) {
if (x > 2*MAXDEVP) return 2*MAXDEVP
if (x < -2*MAXDEVP) return -2*MAXDEVP
return x
}
func maxdev(x) {
if (x > MAXDEVP) return MAXDEVP
if (x < -1*MAXDEVP) return -1*MAXDEVP
return x
}
func myclear(x,y) {
# you can move into your own space or an unclaimed space
# to do: goalie area restriction
if (y == "") return 1
if (y == "0") return 1
if (x == y) return 1
return 0
}
function occupy(who,rrr,ccc,ri,ci) {
for (ri=-DENSESPACE; ri<=DENSESPACE; ri++)
for (ci=-DENSESPACE; ci<=DENSESPACE; ci++)
if (!occupied[rrr+ri,ccc+ci]) occupied[rrr+ri,ccc+ci] = who
for (ri=-SPARSESPACE; ri<=SPARSESPACE; ri+=4)
if (ri) for (ci=-SPARSESPACE; ci<=SPARSESPACE; ci+=4)
if (ci) if (!occupied[rrr+ri,ccc+ci]) occupied[rrr+ri,ccc+ci] = who
}
func init() {
system("/bin/cp -f init pos")
print "" > "dirs"
close("dirs")
system("chmod a+rw pos dirs")
}