mirror of https://github.com/dirtbags/tanks.git
Fix up designer cgi
This commit is contained in:
parent
39169bf352
commit
ea84c67517
5
Makefile
5
Makefile
|
@ -1,6 +1,7 @@
|
|||
CFLAGS = -Wall
|
||||
LDFLAGS = -lm
|
||||
|
||||
all: test
|
||||
all: run-tanks
|
||||
|
||||
test: test-tanks
|
||||
./test-tanks | m4 round.html.m4 - > round.html
|
||||
|
@ -10,4 +11,4 @@ test-tanks: test-tanks.o ctanks.o
|
|||
run-tanks: run-tanks.o ctanks.o cforf.o
|
||||
|
||||
clean:
|
||||
rm -f test-tanks *.o
|
||||
rm -f test-tanks run-tanks *.o
|
4
cforf.c
4
cforf.c
|
@ -211,6 +211,8 @@ forf_pop_stack(struct forf_env *env)
|
|||
case forf_type_stack_begin:
|
||||
depth -= 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
s.top = s.size;
|
||||
|
@ -287,6 +289,8 @@ forf_stack_move_value(struct forf_env *env,
|
|||
case forf_type_stack_end:
|
||||
depth -= 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while (depth > 0);
|
||||
|
||||
|
|
6
cforf.h
6
cforf.h
|
@ -119,7 +119,11 @@ void forf_env_init(struct forf_env *env,
|
|||
/** The type of a getch function (used for parsing) */
|
||||
typedef int (forf_getch_func)(void *);
|
||||
|
||||
/** Parse something by calling getch(datum) */
|
||||
/** Parse something by calling getch(datum)
|
||||
*
|
||||
* Returns the character at which an error was encountered, or
|
||||
* 0 for successful parse.
|
||||
*/
|
||||
int forf_parse_stream(struct forf_env *env,
|
||||
forf_getch_func *getch,
|
||||
void *datum);
|
||||
|
|
5
ctanks.h
5
ctanks.h
|
@ -10,7 +10,7 @@
|
|||
#define TANK_CANNON_RECHARGE 20 /* Turns to recharge cannon */
|
||||
#define TANK_CANNON_RANGE (TANK_SENSOR_RANGE / 2)
|
||||
#define TANK_MAX_ACCEL 35
|
||||
#define TANK_MAX_TURRET_ROT (PI/3)
|
||||
#define TANK_MAX_TURRET_ROT (PI/10)
|
||||
#define TANK_TOP_SPEED 7
|
||||
|
||||
/* (tank radius + tank radius)^2 */
|
||||
|
@ -75,6 +75,8 @@ struct tank {
|
|||
};
|
||||
|
||||
void tank_init(struct tank *tank, tank_run_func *run, void *udata);
|
||||
void tanks_run_turn(struct tanks_game *game, struct tank *tanks, int ntanks);
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -103,4 +105,5 @@ int tank_get_sensor(struct tank *tank, int sensor_num);
|
|||
/** Set the LED state */
|
||||
void tank_set_led(struct tank *tank, int active);
|
||||
|
||||
|
||||
#endif /* __CTANKS_H__ */
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define BASE_PATH "/tmp/"
|
||||
|
||||
struct string {
|
||||
char *s;
|
||||
size_t size;
|
||||
|
@ -71,6 +74,8 @@ read_item(FILE *f, struct string *str)
|
|||
{
|
||||
int c;
|
||||
|
||||
str->len = 0;
|
||||
|
||||
while (1) {
|
||||
c = fgetc(f);
|
||||
switch (c) {
|
||||
|
@ -100,6 +105,7 @@ read_pair(FILE *f, struct string *key, struct string *val)
|
|||
return read_item(f, val);
|
||||
}
|
||||
|
||||
/* This is ugly and I dislike it. */
|
||||
#define new_string(name, size) \
|
||||
char _##name[size]; \
|
||||
struct string name = {_##name, size, 0 }
|
||||
|
@ -111,13 +117,58 @@ main(int argc, char *argv[])
|
|||
|
||||
new_string(key, 20);
|
||||
new_string(val, 8192);
|
||||
new_string(token, 40);
|
||||
new_string(name, 20);
|
||||
new_string(author, 20);
|
||||
new_string(author, 60);
|
||||
new_string(color, 10);
|
||||
new_string(program, 8192);
|
||||
|
||||
printf("Content-type: text/plain\n\n");
|
||||
|
||||
while (! feof(stdin)) {
|
||||
read_pair(stdin, &key, &val);
|
||||
if (0 == string_cmp(&key, "token", 5)) {
|
||||
string_cpy(&token, &key);
|
||||
} else if (0 == string_cmp(&key, "name", 4)) {
|
||||
string_cpy(&name, &key);
|
||||
} else if (0 == string_cmp(&key, "author", 6)) {
|
||||
string_cpy(&author, &key);
|
||||
} else if (0 == string_cmp(&key, "color", 5)) {
|
||||
string_cpy(&color, &key);
|
||||
} else if (0 == string_cmp(&key, "program", 7)) {
|
||||
string_cpy(&program, &key);
|
||||
} else if ((3 == key.len) && ('s' == key.s[0])) {
|
||||
/* sensor dealie, key = "s[0-9][rawt]" */
|
||||
int n = key.s[1] - '0';
|
||||
int i;
|
||||
int p;
|
||||
|
||||
if (! (n >= 0) && (n <= 9)) {
|
||||
break;
|
||||
}
|
||||
if (val.len > 3) {
|
||||
break;
|
||||
}
|
||||
val.s[val.len] = '\0';
|
||||
i = atoi(val.s);
|
||||
|
||||
switch (key.s[2]) {
|
||||
case 'r':
|
||||
p = 0;
|
||||
break;
|
||||
case 'a':
|
||||
p = 1;
|
||||
break;
|
||||
case 'w':
|
||||
p = 2;
|
||||
break;
|
||||
default:
|
||||
p = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
sensor[n][p] = i;
|
||||
}
|
||||
write(1, key.s, key.len);
|
||||
write(1, "=", 1);
|
||||
write(1, val.s, val.len);
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
BEGIN {
|
||||
FS = "\t";
|
||||
}
|
||||
|
||||
function esc(s) {
|
||||
gsub(/&/, "&", s);
|
||||
gsub(/</, "<", s);
|
||||
gsub(/>/, ">", s);
|
||||
return s;
|
||||
}
|
||||
|
||||
{
|
||||
tanks[i++] = $1;
|
||||
reason[$1] = $3;
|
||||
killer[$1] = $4;
|
||||
errchar[$1] = $5;
|
||||
lasterr[$1] = $6;
|
||||
kills[$4] += 1;
|
||||
|
||||
getline < ($2 "/name");
|
||||
name[$1] = $0;
|
||||
}
|
||||
|
||||
END {
|
||||
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>";
|
||||
for (me in name) {
|
||||
print "<tr>";
|
||||
print "<td>" esc(name[me]) "</td>";
|
||||
print "<td>" kills[me] "</td>";
|
||||
print "<td>" reason[me] "</td>";
|
||||
print "<td>" esc(name[killer[me]]) "</td>";
|
||||
print "<td>" lasterr[me] "</td>";
|
||||
print "<td>" errchar[me] "</td>";
|
||||
print "</tr>";
|
||||
}
|
||||
print "</table>";
|
||||
}
|
66
run-tanks.c
66
run-tanks.c
|
@ -20,8 +20,10 @@
|
|||
|
||||
struct forftank {
|
||||
struct forf_env env;
|
||||
int error_pos;
|
||||
char color[7]; /* "ff0088" */
|
||||
char name[50];
|
||||
char *path;
|
||||
|
||||
struct forf_stack _prog;
|
||||
struct forf_value _progvals[CSTACK_SIZE];
|
||||
|
@ -40,7 +42,7 @@ forf_print_val(struct forf_value *val)
|
|||
{
|
||||
switch (val->type) {
|
||||
case forf_type_number:
|
||||
printf("%d", val->v.i);
|
||||
printf("%ld", val->v.i);
|
||||
break;
|
||||
case forf_type_proc:
|
||||
printf("[proc %p]", val->v.p);
|
||||
|
@ -232,7 +234,6 @@ ft_read_program(struct forftank *ftank,
|
|||
struct forf_lexical_env *lenv,
|
||||
char *path)
|
||||
{
|
||||
int ret;
|
||||
char progpath[256];
|
||||
FILE *f;
|
||||
|
||||
|
@ -242,13 +243,9 @@ ft_read_program(struct forftank *ftank,
|
|||
if (! f) return 0;
|
||||
|
||||
/* Parse program */
|
||||
ret = forf_parse_file(&ftank->env, f);
|
||||
ftank->error_pos = forf_parse_file(&ftank->env, f);
|
||||
fclose(f);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Parse error in %s, character %d: %s\n",
|
||||
progpath,
|
||||
ret,
|
||||
forf_error_str[ftank->env.error]);
|
||||
if (ftank->error_pos) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -320,6 +317,8 @@ ft_read_tank(struct forftank *ftank,
|
|||
{
|
||||
int ret;
|
||||
|
||||
ftank->path = path;
|
||||
|
||||
/* What is your name? */
|
||||
ret = ft_read_file(ftank->name, sizeof(ftank->name), path, "name");
|
||||
if (! ret) {
|
||||
|
@ -384,7 +383,6 @@ print_footer(FILE *f)
|
|||
void
|
||||
print_rounds(FILE *f,
|
||||
struct tanks_game *game,
|
||||
struct forftank *forftanks,
|
||||
struct tank *tanks,
|
||||
int ntanks)
|
||||
{
|
||||
|
@ -396,15 +394,15 @@ print_rounds(FILE *f,
|
|||
for (i = 0; (alive > 1) && (i < ROUNDS); i += 1) {
|
||||
int j;
|
||||
|
||||
tanks_run_turn(&game, mytanks, ntanks);
|
||||
fprintf(stdout, "[\n");
|
||||
tanks_run_turn(game, tanks, ntanks);
|
||||
fprintf(f, "[\n");
|
||||
alive = ntanks;
|
||||
for (j = 0; j < ntanks; j += 1) {
|
||||
struct tank *t = &(mytanks[j]);
|
||||
struct tank *t = &(tanks[j]);
|
||||
|
||||
if (t->killer) {
|
||||
alive -= 1;
|
||||
fprintf(stdout, " 0,\n");
|
||||
fprintf(f, " 0,\n");
|
||||
} else {
|
||||
int k;
|
||||
int flags = 0;
|
||||
|
@ -421,7 +419,7 @@ print_rounds(FILE *f,
|
|||
if (t->led) {
|
||||
flags |= 2;
|
||||
}
|
||||
fprintf(stdout, " [%d,%d,%.2f,%.2f,%d,%d],\n",
|
||||
fprintf(f, " [%d,%d,%.2f,%.2f,%d,%d],\n",
|
||||
(int)(t->position[0]),
|
||||
(int)(t->position[1]),
|
||||
t->angle,
|
||||
|
@ -430,7 +428,27 @@ print_rounds(FILE *f,
|
|||
sensors);
|
||||
}
|
||||
}
|
||||
fprintf(stdout, "],\n");
|
||||
fprintf(f, "],\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
print_standings(FILE *f,
|
||||
struct forftank *ftanks,
|
||||
struct tank *tanks,
|
||||
int ntanks)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ntanks; i += 1) {
|
||||
/* &tank path cause &killer parse_error_pos lasterr */
|
||||
fprintf(f, "%p\t%s\t%s\t%p\t%d\t%s\n",
|
||||
&(tanks[i]),
|
||||
ftanks[i].path,
|
||||
tanks[i].cause_death,
|
||||
tanks[i].killer,
|
||||
ftanks[i].error_pos,
|
||||
forf_error_str[ftanks[i].env.error]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -527,9 +545,23 @@ main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
print_header(stdout, &game, myftanks, mytanks, ntanks);
|
||||
print_rounds(stdout, &game, myftanks, mytanks, ntanks);
|
||||
|
||||
print_rounds(stdout, &game, mytanks, ntanks);
|
||||
print_footer(stdout);
|
||||
|
||||
/* Output standings to fd3.
|
||||
*
|
||||
* fd 3 is normally closed, so this won't normally do anything.
|
||||
* To output to fd3 from the shell, you'll need to do something like this:
|
||||
*
|
||||
* ./run-tanks 3>standing
|
||||
**/
|
||||
{
|
||||
FILE *standings = fdopen(3, "w");
|
||||
|
||||
if (standings) {
|
||||
print_standings(standings, myftanks, mytanks, ntanks);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue