mirror of https://github.com/dirtbags/tanks.git
Add summary page generator
This commit is contained in:
parent
c3a5b3dcd6
commit
7c7acc5ffe
|
@ -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">
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
kills[$4] += 1;
|
} else {
|
||||||
|
reason[id] = $3;
|
||||||
|
killer[id] = $4;
|
||||||
|
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>";
|
||||||
}
|
}
|
21
round.sh
21
round.sh
|
@ -8,28 +8,24 @@ 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... "
|
||||||
cat <<EOF > $fn
|
cat <<EOF >$fn
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<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."
|
||||||
|
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
#! /usr/bin/awk -f
|
||||||
|
|
||||||
|
function esc(s) {
|
||||||
|
gsub(/&/, "&", s);
|
||||||
|
gsub(/</, "<", s);
|
||||||
|
gsub(/>/, ">", 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>";
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
2
tanks.js
2
tanks.js
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue