Add summary page generator

This commit is contained in:
Neale Pickett 2010-07-20 12:06:33 -06:00
parent c3a5b3dcd6
commit 7c7acc5ffe
8 changed files with 200 additions and 49 deletions

View File

@ -2,22 +2,7 @@
<html> <html>
<head> <head>
<title>Tank Designer</title> <title>Tank Designer</title>
<style type="text/css"> <link rel="stylesheet" href="tanks.css" type="text/css">
body {
background-color: #444444;
color: white;
}
#preview {
float: right;
}
#sensors input {
width: 5em;
}
#program textarea {
width: 100%;
min-height: 20em;
}
</style>
<script type="application/javascript" src="tanks.js"></script> <script type="application/javascript" src="tanks.js"></script>
<script type="application/javascript" src="designer.js"></script> <script type="application/javascript" src="designer.js"></script>
<script type="application/javascript"> <script type="application/javascript">

View File

@ -51,8 +51,8 @@ function design() {
frame += 1; frame += 1;
canvas.width = canvas.width; canvas.width = canvas.width;
tank.set_state(100, 100, Math.PI * 1.5, turret, 0, 0); tank.set_state(100, 100, Math.PI * 1.5, turret, 0, 0);
tank.draw_tank();
tank.draw_sensors(); tank.draw_sensors();
tank.draw_tank();
} }
loop_id = setInterval(update, 66); loop_id = setInterval(update, 66);

90
rank.awk Normal file → Executable file
View File

@ -1,3 +1,16 @@
#! /usr/bin/awk -f
##
## C doesn't have good string handling routines, but awk does. Figuring
## out rankings, who shot whom, and deciding on a "winner" is therefore
## handled with this awk script.
##
## Input looks like this:
## 0xbff81f28 players/sittingduckwithteeth shot 0xbff82138 0 None
## 0xbff82030 players/sandlion shot 0xbff82138 0 None
## 0xbff82138 players/chashtank (null) (nil) 0 None
##
BEGIN { BEGIN {
FS = "\t"; FS = "\t";
} }
@ -10,29 +23,72 @@ function esc(s) {
} }
{ {
tanks[i++] = $1; id = $1;
reason[$1] = $3; ntanks += 1;
killer[$1] = $4; tanks[id] = id;
errchar[$1] = $5; if ($4 == "(nil)") {
lasterr[$1] = $6; score[id] += 1;
} else {
reason[id] = $3;
killer[id] = $4;
kills[$4] += 1; kills[$4] += 1;
score[$4] += 1;
}
path[id] = $2;
if ($5) {
lasterr[id] = $6 " around char " $5;
} else {
lasterr[id] = $6;
}
getline < ($2 "/name"); if (1 == getline < (path[id] "/name")) {
name[$1] = $0; name[id] = esc($0);
} else {
name[id] = "<i>Unnamed</i>";
}
getline < (path[id] "/color");
if (/^#[0-9A-Fa-f]+$/) {
color[id] = $0;
} else {
color[id] = "#c0c0c0";
}
} }
END { END {
# Fill in who killed whom
for (id in tanks) {
if (score[id] > topscore) {
winner = id;
topscore = score[id];
}
if (killer[id]) {
reason[id] = reason[id] " (" name[killer[id]] ")";
}
}
# Give the winner a point
print "1" >> (path[winner] "/points");
# Output the table
print "<table id=\"results\">"; print "<table id=\"results\">";
print "<tr><th>Name</th><th>Kills</th><th>Cause of Death</th><th>Killer</th><th>Last Error</th><th>Parse error @</th></tr>"; print "<tr><th>Name</th><th>Score</th><th>Cause of Death</th><th>Last Error</th></tr>";
for (me in name) { for (i = ntanks; i >= 0; i -= 1) {
print "<tr>"; for (me in tanks) {
print "<td>" esc(name[me]) "</td>"; if (score[me] == i) {
print "<td>" kills[me] "</td>"; if (me == winner) {
print "<td>" reason[me] "</td>"; style = "style=\"font-weight: bold; background-color: #666666\"";
print "<td>" esc(name[killer[me]]) "</td>"; } else {
print "<td>" lasterr[me] "</td>"; style = "";
print "<td>" errchar[me] "</td>"; }
print "</tr>"; printf("<tr " style ">");
printf("<td><span class=\"swatch\" style=\"background-color: " color[me] "\">#</span> " name[me] "</td>");
printf("<td>" score[me] "</td>");
printf("<td>" reason[me] "</td>");
printf("<td>" lasterr[me] "</td>");
printf("</tr>\n");
}
}
} }
print "</table>"; print "</table>";
} }

View File

@ -8,6 +8,7 @@ fi
expr $next + 1 > next-round expr $next + 1 > next-round
fn=$(printf "round-%04d.html" $next) fn=$(printf "round-%04d.html" $next)
rfn=results$$.txt
echo -n "Running round $next... " echo -n "Running round $next... "
@ -17,18 +18,13 @@ cat <<EOF > $fn
<head> <head>
<title>Tanks Round $next</title> <title>Tanks Round $next</title>
<script type="application/javascript" src="tanks.js"></script> <script type="application/javascript" src="tanks.js"></script>
<style type="text/css"> <link rel="stylesheet" href="tanks.css" type="text/css">
body {
background-color: #444444;
color: white;
}
</style>
<script type="application/javascript"> <script type="application/javascript">
function go() { function go() {
start( start(
// Start JSON data // Start JSON data
EOF EOF
./run-tanks players/* >> $fn ./run-tanks players/* >>$fn 3>$rfn
cat <<EOF >>$fn cat <<EOF >>$fn
// end JSON data // end JSON data
); );
@ -39,8 +35,15 @@ window.onload = go;
<body> <body>
<div id="game_box"><canvas id="battlefield"></canvas></div> <div id="game_box"><canvas id="battlefield"></canvas></div>
<p><span id="fps">0</span> fps</p> <p><span id="fps">0</span> fps</p>
EOF
./rank.awk $rfn >>$fn
rm -f $rfn
cat <<EOF >>$fn
</body> </body>
</html> </html>
EOF EOF
./summary.awk > summary.html
echo "done." echo "done."

View File

@ -21,7 +21,7 @@
struct forftank { struct forftank {
struct forf_env env; struct forf_env env;
int error_pos; int error_pos;
char color[7]; /* "ff0088" */ char color[8]; /* "#ff0088" */
char name[50]; char name[50];
char *path; char *path;
@ -338,7 +338,7 @@ ft_read_tank(struct forftank *ftank,
/* What is your favorite color? */ /* What is your favorite color? */
ret = ft_read_file(ftank->color, sizeof(ftank->color), path, "color"); ret = ft_read_file(ftank->color, sizeof(ftank->color), path, "color");
if (! ret) { if (! ret) {
strncpy(ftank->color, "808080", sizeof(ftank->color)); strncpy(ftank->color, "#808080", sizeof(ftank->color));
} }
return 1; return 1;
@ -356,7 +356,7 @@ print_header(FILE *f,
fprintf(f, "[[%d, %d, %d],[\n", fprintf(f, "[[%d, %d, %d],[\n",
(int)game->size[0], (int)game->size[1], TANK_CANNON_RANGE); (int)game->size[0], (int)game->size[1], TANK_CANNON_RANGE);
for (i = 0; i < ntanks; i += 1) { for (i = 0; i < ntanks; i += 1) {
fprintf(f, " [\"#%s\",[", forftanks[i].color); fprintf(f, " [\"%s\",[", forftanks[i].color);
for (j = 0; j < TANK_MAX_SENSORS; j += 1) { for (j = 0; j < TANK_MAX_SENSORS; j += 1) {
struct sensor *s = &(tanks[i].sensors[j]); struct sensor *s = &(tanks[i].sensors[j]);

81
summary.awk Executable file
View File

@ -0,0 +1,81 @@
#! /usr/bin/awk -f
function esc(s) {
gsub(/&/, "&amp;", s);
gsub(/</, "&lt;", s);
gsub(/>/, "&gt;", s);
return s;
}
BEGIN {
print "<!DOCTYPE html>";
print "<html>";
print " <head>";
print " <title>Dirtbags Tanks</title>";
print " <link rel=\"stylesheet\" href=\"tanks.css\" type=\"text/css\">";
print " </head>";
print " <body>";
print " <h1>Dirtbags Tanks</h1>";
print " <h2>Resources</h2>";
print " <ul>";
print " <li><a href=\"forf.html\">Forf manual</a></li>";
print " <li><a href=\"tanksprocs.html\">Tanks procedures</a></li>";
print " <li><a href=\"designer.html\">Tanks designer</a></li>";
print " </ul>";
print " <h2>Rankings</h2>";
print " <ol>";
while ("ls -d players/*" | getline id) {
if (1 == getline < (id "/name")) {
names[id] = esc($0);
} else {
names[id] = "<i>Unnamed</i>";
}
getline < (id "/color");
if (/^#[0-9A-Fa-f]+$/) {
color[id] = $0;
} else {
color[id] = "#c0c0c0";
}
p = 0;
while (1 == getline < (id "/points")) {
p += $0;
}
scores[p] = p;
points[id] = p;
nscores
}
while (1) {
# Find highest score
maxscore = -1;
for (p in scores) {
if (p > maxscore) {
maxscore = p;
}
}
if (maxscore == -1) {
break;
}
delete scores[maxscore];
for (id in points) {
if (points[id] == maxscore) {
printf("<li><span class=\"swatch\" style=\"background-color: %s;\">#</span> %s (%d wins)</li>\n", color[id], names[id], points[id]);
}
}
}
print " </ol>";
print " <h2>Rounds</h2>";
print " <ul>";
getline rounds < "next-round";
for (i = rounds - 1; i >= 0; i -= 1) {
printf("<li><a href=\"round-%04d.html\">%04d</a></li>\n", i, i);
}
print " </ul>";
print " </body>";
print "</html>";
}

26
tanks.css Normal file
View File

@ -0,0 +1,26 @@
body {
background-color: #444444;
color: #c0c0c0;
}
table {
border-collapse: collapse;
}
td {
border: solid 1px #c0c0c0;
}
.swatch {
color: #000000;
}
#preview {
float: right;
}
#sensors input {
width: 5em;
}
#program textarea {
width: 100%;
min-height: 20em;
}
a {
color: #00c080;
}

View File

@ -114,7 +114,7 @@ function Tank(ctx, width, height, color, sensors) {
ctx.fillRect(-7, 4, 15, 5); ctx.fillRect(-7, 4, 15, 5);
ctx.rotate(this.turret); ctx.rotate(this.turret);
if (this.fire) { if (this.fire) {
ctx.fillStyle = ("rgba(128,128,255," + this.fire/5 + ")"); ctx.fillStyle = ("rgba(255,255,64," + this.fire/5 + ")");
ctx.fillRect(0, -1, 45, 2); ctx.fillRect(0, -1, 45, 2);
this.fire -= 1; this.fire -= 1;
} else { } else {