diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7050d8f --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*~ +*# +*.o diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..ab6c4d9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "forf"] + path = forf + url = woozle.org:projects/forf diff --git a/Makefile b/Makefile index c60606d..a727c14 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,23 @@ CFLAGS = -Wall -LDFLAGS = -lm -all: run-tanks +all: html run-tanks designer.cgi +html: forf.html -test: test-tanks - ./test-tanks | m4 round.html.m4 - > round.html +run-tanks: run-tanks.o ctanks.o forf.o +run-tanks: LDFLAGS = -lm -test-tanks: test-tanks.o ctanks.o +run-tanks.o: forf.h ctanks.h +forf.o: forf.c forf.h +ctanks.o: ctanks.h -run-tanks: run-tanks.o ctanks.o cforf.o +forf.html: forf.html.sh forf/forf.txt + ./forf.html.sh > $@ + +forf.%: forf/forf.% + cp forf/$@ $@ +forf/%: + git submodule update --init clean: - rm -f test-tanks run-tanks *.o \ No newline at end of file + rm -f run-tanks designer.cgi *.o forf.c forf.h + rm -f next-round round-*.html summary.html forf.html diff --git a/cforf.c b/cforf.c deleted file mode 100644 index 76196a2..0000000 --- a/cforf.c +++ /dev/null @@ -1,752 +0,0 @@ -/* forf: a crappy Forth implementation - * Copyright (C) 2010 Adam Glasgall - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* Notes - * ------------------------------------------------------- - * - * This is intended to be implemented as a library. As such, it doesn't - * use the libc memory allocation functions. This may be a different - * programming style than you're used to. - * - * There are two data types: numbers and stacks. Because we can't - * allocate memory, stacks are implemented with begin and end markers - * and not new stack types. - */ - -#include -#include -#include - -#include "cforf.h" -#include "dump.h" - -#ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -char *forf_error_str[] = { - "None", - "Runtime", - "Parse", - "Underflow", - "Overflow", - "Type", - "No such procedure", - "Divide by zero", -}; - -/* - * - * Memory manipulation - * - */ -void -forf_memory_init(struct forf_memory *m, - long *values, - size_t size) -{ - m->mem = values; - m->size = size; -} - - -/* - * - * Stack manipulation - * - */ - -void -forf_stack_init(struct forf_stack *s, - struct forf_value *values, - size_t size) -{ - s->stack = values; - s->size = size; - s->top = 0; -} - -void -forf_stack_reset(struct forf_stack *s) -{ - s->top = 0; -} - -size_t -forf_stack_len(struct forf_stack *s) -{ - return s->top; -} - -int -forf_stack_push(struct forf_stack *s, struct forf_value *v) -{ - if (s->top == s->size) { - return 0; - } - s->stack[(s->top)++] = *v; - return 1; -} - -int -forf_stack_pop(struct forf_stack *s, struct forf_value *v) -{ - if (0 == s->top) { - return 0; - } - *v = s->stack[--(s->top)]; - return 1; -} - -void -forf_stack_copy(struct forf_stack *dst, struct forf_stack *src) -{ - int top = min(dst->size, src->top); - - dst->top = top; - memcpy(dst->stack, src->stack, sizeof(*dst->stack) * top); -} - - -void -forf_stack_reverse(struct forf_stack *s) -{ - struct forf_value val; - size_t pos; - - for (pos = 0; pos < (s->top)/2; pos += 1) { - size_t qos = s->top - pos - 1; - - val = s->stack[pos]; - s->stack[pos] = s->stack[qos]; - s->stack[qos] = val; - } -} - -long -forf_pop_num(struct forf_env *env) -{ - struct forf_value val; - - if (! forf_stack_pop(env->data, &val)) { - env->error = forf_error_underflow; - return 0; - } - if (forf_type_number != val.type) { - forf_stack_push(env->data, &val); - env->error = forf_error_type; - return 0; - } - return val.v.i; -} - -void -forf_push_num(struct forf_env *env, long i) -{ - struct forf_value val; - - val.type = forf_type_number; - val.v.i = i; - if (! forf_stack_push(env->data, &val)) { - env->error = forf_error_overflow; - } -} - - -/* Pop an entire stack - * - * DANGER WILL ROBINSON - * - * This returned stack points to values on the data stack. You must be - * finished with this stack before you push anything onto the data - * stack, otherwise your returned stack will be corrupted. - */ -struct forf_stack -forf_pop_stack(struct forf_env *env) -{ - struct forf_stack s = { 0, 0, NULL }; - struct forf_value val; - size_t depth = 1; - - if (! forf_stack_pop(env->data, &val)) { - env->error = forf_error_underflow; - return s; - } - if (forf_type_stack_end != val.type) { - forf_stack_push(env->data, &val); - env->error = forf_error_type; - return s; - } - /* Duplicate just the stack onto s. Begin with -1 to account for the - end of list marker. */ - s.size = -1; - while (depth) { - s.size += 1; - if (! forf_stack_pop(env->data, &val)) { - /* You should never underflow here, there should at least be a - stack begin marker. */ - env->error = forf_error_runtime; - s.size = 0; - return s; - } - switch (val.type) { - case forf_type_stack_end: - depth += 1; - break; - case forf_type_stack_begin: - depth -= 1; - break; - default: - break; - } - } - s.top = s.size; - s.stack = (env->data->stack) + (env->data->top + 1); - return s; -} - -/* Push an entire stack onto another stack. - */ -int -forf_push_stack(struct forf_stack *dst, struct forf_stack *src) -{ - struct forf_value val; - - while (forf_stack_pop(src, &val)) { - if (! forf_stack_push(dst, &val)) { - return 0; - } - } - return 1; -} - -/* Push an entire stack onto the command stack. - * - * This is meant to work with the return value from forf_pop_stack. - */ -int -forf_push_to_command_stack(struct forf_env *env, struct forf_stack *src) -{ - if (! forf_push_stack(env->command, src)) { - env->error = forf_error_overflow; - return 0; - } - return 1; -} - -/* Move one value from src to dst. Note that one value could mean a - * whole substack, in which case dst gets the stack in reverse! dst can - * also be NULL, in which case a value is just discarded. - * - * Because of the reversing thing, it's important to make sure that the - * data stack is either src or dst. This way, the data stack will - * always have "reversed" substacks, and everything else will have them - * in the right order. - */ -int -forf_stack_move_value(struct forf_env *env, - struct forf_stack *dst, - struct forf_stack *src) -{ - struct forf_value val; - size_t depth = 0; - - do { - /* Pop from src */ - if (! forf_stack_pop(env->command, &val)) { - env->error = forf_error_underflow; - return 0; - } - - /* Push to dst (or discard if dst is NULL) */ - if (dst) { - if (! forf_stack_push(env->data, &val)) { - env->error = forf_error_overflow; - return 0; - } - } - - /* Deal with it being a substack marker */ - switch (val.type) { - case forf_type_stack_begin: - depth += 1; - break; - case forf_type_stack_end: - depth -= 1; - break; - default: - break; - } - } while (depth > 0); - - return 1; - -} - - -/* - * - * Procedures - * - */ - -#define unproc(name, op) \ - static void \ - forf_proc_ ## name(struct forf_env *env) \ - { \ - long a = forf_pop_num(env); \ - \ - forf_push_num(env, op a); \ - } - -unproc(inv, ~) -unproc(not, !) - -#define binproc(name, op) \ - static void \ - forf_proc_ ## name(struct forf_env *env) \ - { \ - long a = forf_pop_num(env); \ - long b = forf_pop_num(env); \ - \ - forf_push_num(env, b op a); \ - } - -binproc(add, +) -binproc(sub, -) -binproc(mul, *) -binproc(and, &) -binproc(or, |) -binproc(xor, ^) -binproc(lshift, <<) -binproc(rshift, >>) -binproc(gt, >) -binproc(ge, >=) -binproc(lt, <) -binproc(le, <=) -binproc(eq, ==) -binproc(ne, !=) - -static void -forf_proc_div(struct forf_env *env) -{ - long a = forf_pop_num(env); - long b = forf_pop_num(env); - - if (0 == a) { - env->error = forf_error_divzero; - return; - } - forf_push_num(env, b / a); -} - -static void -forf_proc_mod(struct forf_env *env) -{ - long a = forf_pop_num(env); - long b = forf_pop_num(env); - - if (0 == a) { - env->error = forf_error_divzero; - return; - } - forf_push_num(env, b % a); -} - -static void -forf_proc_abs(struct forf_env *env) -{ - forf_push_num(env, abs(forf_pop_num(env))); -} - -static void -forf_proc_dup(struct forf_env *env) -{ - long a = forf_pop_num(env); - - forf_push_num(env, a); - forf_push_num(env, a); -} - -static void -forf_proc_pop(struct forf_env *env) -{ - forf_pop_num(env); -} - -static void -forf_proc_exch(struct forf_env *env) -{ - long a = forf_pop_num(env); - long b = forf_pop_num(env); - - forf_push_num(env, a); - forf_push_num(env, b); -} - -static void -forf_proc_if(struct forf_env *env) -{ - struct forf_stack ifclause = forf_pop_stack(env); - long cond = forf_pop_num(env); - - if (cond) { - forf_push_to_command_stack(env, &ifclause); - } -} - -static void -forf_proc_ifelse(struct forf_env *env) -{ - struct forf_stack elseclause = forf_pop_stack(env); - struct forf_stack ifclause = forf_pop_stack(env); - long cond = forf_pop_num(env); - - if (cond) { - forf_push_to_command_stack(env, &ifclause); - } else { - forf_push_to_command_stack(env, &elseclause); - } -} - -static void -forf_proc_memset(struct forf_env *env) -{ - long pos = forf_pop_num(env); - long a = forf_pop_num(env); - - if (pos >= env->memory->size) { - env->error = forf_error_overflow; - return; - } - - env->memory->mem[pos] = a; -} - -static void -forf_proc_memget(struct forf_env *env) -{ - long pos = forf_pop_num(env); - - if (pos >= env->memory->size) { - env->error = forf_error_overflow; - return; - } - - forf_push_num(env, env->memory->mem[pos]); -} - -/* - * - * Lexical environment - * - */ -struct forf_lexical_env forf_base_lexical_env[] = { - {"~", forf_proc_inv}, - {"!", forf_proc_not}, - {"+", forf_proc_add}, - {"-", forf_proc_sub}, - {"*", forf_proc_mul}, - {"/", forf_proc_div}, - {"%", forf_proc_mod}, - {"&", forf_proc_and}, - {"|", forf_proc_or}, - {"^", forf_proc_xor}, - {"<<", forf_proc_lshift}, - {">>", forf_proc_rshift}, - {">", forf_proc_gt}, - {">=", forf_proc_ge}, - {"<", forf_proc_lt}, - {"<=", forf_proc_le}, - {"=", forf_proc_eq}, - {"<>", forf_proc_ne}, - {"abs", forf_proc_abs}, - {"dup", forf_proc_dup}, - {"pop", forf_proc_pop}, - {"exch", forf_proc_exch}, - {"if", forf_proc_if}, - {"ifelse", forf_proc_ifelse}, - {"mset", forf_proc_memset}, - {"mget", forf_proc_memget}, - {NULL, NULL} -}; - -/** Extend a lexical environment */ -int -forf_extend_lexical_env(struct forf_lexical_env *dest, - struct forf_lexical_env *src, - size_t size) -{ - int base, i; - - for (base = 0; dest[base].name; base += 1); - for (i = 0; (base+i < size) && (src[i].name); i += 1) { - dest[base+i] = src[i]; - } - if (base + i == size) { - /* Not enough room */ - return 0; - } - dest[base+i].name = NULL; - dest[base+i].proc = NULL; - return 1; -} - - -/* - * - * Parsing - * - */ -static int -forf_push_token(struct forf_env *env, char *token, size_t tokenlen) -{ - long i; - char s[MAX_TOKEN_LEN + 1]; - char *endptr; - struct forf_value val; - - /* Zero-length token yields int:0 from strtol */ - - /* NUL-terminate it */ - memcpy(s, token, tokenlen); - s[tokenlen] = '\0'; - - /* Try to make in an integer */ - i = strtol(s, &endptr, 0); - if ('\0' == *endptr) { - /* Was an int */ - val.type = forf_type_number; - val.v.i = i; - } else { - /* If not an int, a procedure name */ - val.type = forf_type_proc; - for (i = 0; NULL != env->lenv[i].name; i += 1) { - if (0 == strcmp(s, env->lenv[i].name)) { - val.v.p = env->lenv[i].proc; - break; - } - } - if (NULL == env->lenv[i].name) { - env->error = forf_error_noproc; - return 0; - } - } - - if (! forf_stack_push(env->command, &val)) { - env->error = forf_error_overflow; - return 0; - } - - return 1; -} - -/* Parse an input stream onto the command stack */ -int -forf_parse_stream(struct forf_env *env, - forf_getch_func *getch, - void *datum) -{ - int running = 1; - long pos = 0; - char token[MAX_TOKEN_LEN]; - size_t tokenlen = 0; - struct forf_value val; - size_t stack_depth = 0; - int comment = 0; - -#define _tokenize() \ - do { \ - if (tokenlen) { \ - if (! forf_push_token(env, token, tokenlen)) return pos; \ - tokenlen = 0; \ - } \ - } while (0) - - while (running) { - int c; - - c = getch(datum); - pos += 1; - - /* Handle comments */ - if (comment) { - if (')' == c) { - comment = 0; - } - continue; - } - - switch (c) { - case EOF: - running = 0; - break; - case '(': - comment = 1; - break; - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - case '\v': - _tokenize(); - break; - case '{': - _tokenize(); - val.type = forf_type_stack_begin; - if (! forf_stack_push(env->command, &val)) { - env->error = forf_error_overflow; - return pos; - } - stack_depth += 1; - break; - case '}': - _tokenize(); - val.type = forf_type_stack_end; - if (! forf_stack_push(env->command, &val)) { - env->error = forf_error_overflow; - return pos; - } - stack_depth -= 1; - break; - default: - if (tokenlen < sizeof(token)) { - token[tokenlen++] = c; - } - break; - } - } - _tokenize(); - - if (0 != stack_depth) { - env->error = forf_error_parse; - return pos; - } - - // The first thing we read should be the first thing we do - forf_stack_reverse(env->command); - - return 0; -} - -struct forf_char_stream { - char *buf; - size_t len; - size_t pos; -}; - -static int -forf_string_getch(struct forf_char_stream *stream) -{ - if (stream->pos >= stream->len) { - return EOF; - } - return stream->buf[stream->pos++]; -} - -int -forf_parse_buffer(struct forf_env *env, - char *buf, - size_t len) -{ - struct forf_char_stream stream; - - stream.buf = buf; - stream.len = len; - stream.pos = 0; - - return forf_parse_stream(env, (forf_getch_func *)forf_string_getch, &stream); -} - -int -forf_parse_string(struct forf_env *env, - char *str) -{ - return forf_parse_buffer(env, str, strlen(str)); -} - -int -forf_parse_file(struct forf_env *env, - FILE *f) -{ - return forf_parse_stream(env, (forf_getch_func *)fgetc, f); -} - - -/* - * - * Forf environment - * - */ - -void -forf_env_init(struct forf_env *env, - struct forf_lexical_env *lenv, - struct forf_stack *data, - struct forf_stack *cmd, - struct forf_memory *mem, - void *udata) -{ - env->lenv = lenv; - env->data = data; - env->command = cmd; - env->memory = mem; - env->udata = udata; -} - - -int -forf_eval_once(struct forf_env *env) -{ - struct forf_value val; - - if (! forf_stack_pop(env->command, &val)) { - env->error = forf_error_underflow; - return 0; - } - switch (val.type) { - case forf_type_number: - case forf_type_stack_begin: - // Push back on command stack, then move it - forf_stack_push(env->command, &val); - if (! forf_stack_move_value(env, env->data, env->command)) return 0; - break; - case forf_type_proc: - (val.v.p)(env); - break; - default: - env->error = forf_error_runtime; - return 0; - } - return 1; -} - -int -forf_eval(struct forf_env *env) -{ - int ret; - - while (env->command->top) { - ret = forf_eval_once(env); - if ((! ret) || (env->error)) { - return 0; - } - } - return 1; -} diff --git a/cforf.h b/cforf.h deleted file mode 100644 index ca8e384..0000000 --- a/cforf.h +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef __CFORF_H__ -#define __CFORF_H__ - -#include -#include - -#define MAX_TOKEN_LEN 20 -#define MAX_CMDSTACK 200 - -struct forf_env; - -enum forf_value_type { - forf_type_number, - forf_type_proc, - forf_type_stack_begin, - forf_type_stack_end, -}; - -enum forf_error_type { - forf_error_none, - forf_error_runtime, - forf_error_parse, - forf_error_underflow, - forf_error_overflow, - forf_error_type, - forf_error_noproc, - forf_error_divzero, -}; - -extern char *forf_error_str[]; - -typedef void (forf_proc)(struct forf_env *); - -struct forf_value { - enum forf_value_type type; - union { - forf_proc *p; - long i; - } v; -}; - -struct forf_stack { - size_t size; - size_t top; - struct forf_value *stack; -}; - -struct forf_memory { - size_t size; - long *mem; -}; - -struct forf_lexical_env { - char *name; - forf_proc *proc; -}; - -struct forf_env { - enum forf_error_type error; - struct forf_lexical_env *lenv; - struct forf_stack *data; - struct forf_stack *command; - struct forf_memory *memory; - void *udata; -}; - - -/* - * - * Main entry points - * - */ - -/** Initialize a memory structure, given an array of longs */ -void forf_memory_init(struct forf_memory *m, - long *values, - size_t size); - -/** Initialize a stack, given an array of values */ -void forf_stack_init(struct forf_stack *s, - struct forf_value *values, - size_t size); - -void forf_stack_reset(struct forf_stack *s); -void forf_stack_copy(struct forf_stack *dst, struct forf_stack *src); -int forf_stack_push(struct forf_stack *s, struct forf_value *v); -int forf_stack_pop(struct forf_stack *s, struct forf_value *v); - -/** Pop a number off the data stack */ -long forf_pop_num(struct forf_env *env); - -/** Push a number onto the data stack */ -void forf_push_num(struct forf_env *env, long i); - -/** Pop a whole stack */ -struct forf_stack forf_pop_stack(struct forf_env *env); - - -/** The base lexical environment */ -extern struct forf_lexical_env forf_base_lexical_env[]; - -/** Extend a lexical environment */ -int -forf_extend_lexical_env(struct forf_lexical_env *dest, - struct forf_lexical_env *src, - size_t size); - -/** Initialize a forf runtime environment. - * - * data, cmd, and mem should have already been initialized - */ -void forf_env_init(struct forf_env *env, - struct forf_lexical_env *lenv, - struct forf_stack *data, - struct forf_stack *cmd, - struct forf_memory *mem, - void *udata); - -/** The type of a getch function (used for parsing) */ -typedef int (forf_getch_func)(void *); - -/** 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); - -/** Parse a buffer */ -int forf_parse_buffer(struct forf_env *env, - char *buf, - size_t len); - -/** Parse a string */ -int forf_parse_string(struct forf_env *env, - char *str); - -/** Parse a FILE * */ -int forf_parse_file(struct forf_env *env, - FILE *f); - -/** Evaluate the topmost value on the command stack */ -int forf_eval_once(struct forf_env *env); - -/** Evaluate the entire command stack */ -int forf_eval(struct forf_env *env); - -#endif diff --git a/designer.html b/designer.html index 81f0e71..9fd2c34 100644 --- a/designer.html +++ b/designer.html @@ -2,7 +2,22 @@ Tank Designer - + + +

Tank Designer

diff --git a/dirtbags.css b/dirtbags.css new file mode 100644 index 0000000..db5aa91 --- /dev/null +++ b/dirtbags.css @@ -0,0 +1,201 @@ +/**** document ****/ + +html { + background: #222 url(grunge.png) repeat-x; +} + +body { + font-family: sans-serif; + color: #fff; + margin: 50px 0 0 110px; + padding: 10px; + max-width: 700px; +} + +/**** heading ****/ + +h1:first-child { + text-transform: lowercase; + font-size: 1.6em; +/* background-color: #222; */ +/* opacity: 0.9; */ + padding: 3px; + color: #2a2; + margin: 0 0 1em 70px; +} + +h1:first-child:before { + color: #fff; + letter-spacing: -0.1em; + content: "Dirtbags: "; +} + +/*** left side bar ***/ + +#navigation { + position: absolute; + background: #222; + opacity: 0.9; + top: 80px; + left: 0px; + padding: 0; +} + +#navigation h3 { + font-size: 100%; + border-bottom: 2px solid #444; +} + +#navigation ul { + list-style: none; + padding: 0; + margin: 0; +} + +#navigation li a { + display: block; + height: 25px; + width: 90px; + padding: 5px; + margin: 5px; + background: inherit; + border-right: 4px solid #444; + color: #999; + text-transform: lowercase; + font-size: 0.9em; +} + +#navigation li a:hover { + color: #f4f4f4; + background: #333; + border-right: 4px solid #2a2; +} + +#navigation li .active { + color: #999; + background: #333; + border-right: 4px solid #444; +} + + +/**** body ****/ + +a img { + border: 0px; +} + +a { + text-decoration: none; + color: #2a2; + font-weight: bold; +} + +a:hover { + color: #fff; + background: #2a2; + font-weight: bold; +} + + +h1, h2, h3 { + color: #999; + letter-spacing: -0.05em; + clear: both; +} + +.readme { + color: #fff; + background-color: #555; + margin: 1em; +} + +pre { + color: #fff; + background-color: #222; + border: solid #ccc 2px; + padding: 0.25em; +} + + +th { + vertical-align: top; + text-align: center; +} +td { + vertical-align: top; + text-align: right; +} + +p { + line-height: 1.4em; + margin-bottom: 20px; + color: #f4f4f4; +} + +hr { + border: 1px solid #444; +} + +dt { + white-space: pre; + background-color: #333; + padding: 5px; + border: 2px solid green; + border-bottom: none; + font-weight: bold; +} + +dd { + border: 2px solid green; + margin: 0px; + padding: 5px; + background-color: #282828; +} + + +/**** special cases ****/ + +.wide { + max-width: inherit; +} + +.figure { + margin: 0.5em 1em; + float: right; + font-size: small; + text-align: center; + caption-side: bottom; +} + +.left { + float: left; +} + +.scoreboard { + background: #222; +} + +.scoreboard td { + height: 400px; +} + +#battlefield { + border: 2px solid green; +} + +.solved { + text-decoration: line-through; +} + +table.pollster { + margin-left: 5em; +} + +table.pollster td { + padding: 2px 1em 2px 5px; +} + +table.pollster thead { + font-weight: bold; +} + diff --git a/figures.js b/figures.js new file mode 100644 index 0000000..27b40be --- /dev/null +++ b/figures.js @@ -0,0 +1,5 @@ +default_ = [[300, 150, 50],[["#a08080",[[50, 0.00, 0.14, 1],[30, 0.00, 0.87, 0],[50, 0.00, 0.17, 0],[100, 5.50, 1.75, 1],[100, 0.79, 1.75, 1],[60, 3.14, 3.14, 0],]], ["#808080",[[50, 0.00, 0.12, 1],[30, 0.00, 1.57, 0],]],],[[[75,75,3.86,0.96,2,0], [225,75,4.26,0.49,0,0],], [[73,73,3.86,0.65,2,0], [223,72,4.26,0.68,0,0],], [[69,70,3.86,0.33,2,0], [222,70,4.24,0.87,0,0],], [[65,66,3.86,0.02,2,0], [221,67,4.23,1.06,0,0],], [[61,62,3.86,-0.00,2,0], [220,65,4.22,1.27,0,0],], [[56,59,3.86,0.00,2,0], [218,63,4.20,1.48,0,0],], [[52,55,3.86,-0.00,2,0], [217,60,4.19,1.68,0,0],], [[48,51,3.86,-0.00,2,0], [215,58,4.18,1.88,0,0],], [[44,48,3.86,0.00,2,0], [214,55,4.16,2.09,0,0],], [[39,44,3.86,-0.00,2,0], [213,53,4.15,2.30,0,0],], [[35,41,3.77,0.00,2,0], [211,51,4.13,2.51,0,0],], [[31,38,3.68,-0.00,2,0], [209,48,4.12,2.72,0,0],], [[26,36,3.60,-0.00,2,0], [208,46,4.11,2.93,0,0],], [[21,34,3.51,0.00,2,0], [206,44,4.09,3.14,0,0],], [[16,33,3.43,-0.00,2,0], [205,42,4.08,3.35,0,0],], [[11,32,3.34,-0.00,2,0], [203,39,4.06,3.56,0,0],], [[6,31,3.25,0.00,2,8], [201,37,4.05,3.77,0,0],], [[2,31,3.11,-0.31,2,16], [200,35,4.04,3.98,0,0],], [[299,31,3.25,0.00,2,24], [198,33,4.02,4.19,0,0],], [[293,29,3.39,-0.00,2,8], [196,31,4.01,4.40,0,0],], [[289,28,3.39,-0.31,2,24], [194,29,4.00,4.59,0,0],], [[283,27,3.39,-0.31,2,24], [192,27,3.98,4.80,0,0],], [[276,25,3.39,-0.31,2,24], [190,25,3.97,4.99,0,0],], [[269,23,3.39,-0.30,2,24], [189,23,3.95,5.18,0,0],], [[262,21,3.39,-0.28,2,24], [187,21,3.94,5.39,0,0],], [[255,20,3.39,-0.26,2,24], [185,19,3.93,5.59,0,0],], [[249,18,3.39,-0.24,2,24], [183,17,3.91,5.78,0,0],], [[242,16,3.39,-0.23,2,24], [181,15,3.90,5.99,0,0],], [[235,14,3.39,-0.21,3,25], 0,],]]; + +antlion = [[300, 150, 50],[["#808080",[[50, 0.00, 0.00, 1],[70, 0.00, 0.87, 0],]], ["#ff8844",[[50, 0.00, 0.09, 1],[100, 4.68, 3.09, 1],[100, 1.61, 3.11, 1],[60, 0.00, 2.09, 0],[60, 2.09, 2.09, 0],[60, 4.19, 2.09, 0],[100, 0.00, 0.09, 1],]],],[[[75,75,5.78,2.71,0,0], [225,75,3.28,1.95,0,0],], [[77,73,5.78,3.02,0,0], [225,75,3.28,2.06,0,0],], [[81,71,5.78,3.14,0,0], [225,75,3.28,2.16,0,0],], [[87,68,5.78,3.14,0,0], [225,75,3.28,2.25,0,0],], [[93,64,5.78,3.14,0,0], [225,75,3.28,2.34,0,0],], [[99,61,5.78,3.14,0,0], [225,75,3.28,2.44,0,0],], [[105,57,5.78,3.14,0,0], [225,75,3.28,2.53,0,0],], [[112,54,5.78,3.14,0,0], [225,75,3.28,2.62,0,0],], [[118,51,5.78,3.14,0,0], [225,75,3.28,2.71,0,0],], [[124,47,5.78,3.14,0,0], [225,75,3.28,2.79,0,2],], [[130,44,5.78,3.14,0,0], [225,75,3.28,2.48,0,2],], [[136,40,5.78,3.14,0,0], [225,75,3.28,2.16,0,2],], [[142,37,5.78,3.14,0,0], [225,75,3.28,1.85,0,2],], [[148,34,5.78,3.14,0,0], [225,75,3.28,1.54,0,2],], [[154,30,5.78,3.14,0,0], [225,75,3.28,1.22,0,2],], [[160,28,5.90,3.14,0,0], [225,75,3.28,0.91,0,2],], [[167,25,5.90,3.14,0,0], [225,75,3.28,0.59,0,70],], [[173,23,5.90,3.14,0,0], [225,75,3.28,0.28,0,4],], [[180,20,5.90,3.14,0,0], [225,75,3.28,0.59,0,68],], [[186,17,5.90,3.14,0,0], [225,75,3.28,0.28,0,4],], [[193,15,5.90,3.14,0,0], [225,75,3.28,0.59,0,4],], [[199,12,5.90,3.14,0,0], [225,75,3.28,0.91,0,92],], [[206,10,5.90,3.14,0,0], [222,74,3.24,0.59,0,20],], [[212,7,5.90,3.14,0,0], [218,74,3.15,0.91,0,20],], [[218,4,5.78,3.14,0,0], [212,75,2.96,1.22,0,4],], [[224,1,5.78,3.14,0,0], [208,77,2.77,1.54,0,2],], [[230,147,5.78,3.14,0,0], [207,78,2.65,1.22,0,2],], [[236,144,5.78,3.14,0,0], [207,78,2.65,0.91,0,2],], [[242,140,5.78,3.14,0,0], [207,78,2.65,0.59,0,2],], [[248,137,5.78,3.14,0,0], [207,78,2.65,0.28,0,2],], [[254,134,5.78,3.14,0,0], [207,78,2.65,-0.03,0,2],], [[260,130,5.78,3.14,0,0], [207,78,2.65,-0.35,0,2],], [[267,127,5.78,3.14,0,0], [207,78,2.65,-0.66,0,2],], [[273,123,5.78,3.14,0,0], [207,78,2.65,-0.98,0,2],], [[279,120,5.78,3.14,0,0], [207,78,2.65,-1.29,0,2],], [[285,117,5.78,3.14,0,0], [207,78,2.65,-1.61,0,2],], [[291,113,5.78,3.14,0,0], [207,78,2.65,-1.92,0,2],], [[297,110,5.78,3.14,0,0], [207,78,2.65,-2.23,0,66],], [[3,106,5.78,3.14,0,0], [207,78,2.65,-1.92,0,2],], [[9,103,5.78,3.14,0,0], [207,78,2.65,-2.23,0,2],], [[16,100,5.78,3.14,0,0], [207,78,2.65,-2.55,0,0],], [[22,96,5.78,3.14,0,0], [207,78,2.65,-2.44,0,0],], [[28,93,5.78,3.14,0,0], [207,78,2.65,-2.32,0,0],], [[34,90,5.78,3.14,0,0], [207,78,2.65,-2.20,0,0],], [[40,86,5.78,3.14,0,0], [207,78,2.65,-2.08,0,0],], [[46,84,5.90,3.14,0,0], [207,78,2.65,-1.95,0,0],], [[52,81,5.90,3.14,0,0], [207,78,2.65,-1.85,0,0],], [[59,79,5.90,3.14,0,0], [207,78,2.65,-1.75,0,0],], [[65,76,5.90,3.14,0,0], [207,78,2.65,-1.64,0,0],], [[72,73,5.90,3.14,0,0], [207,78,2.65,-1.54,0,0],], [[78,71,5.90,3.14,0,0], [207,78,2.65,-1.43,0,0],], [[85,68,5.90,3.14,0,0], [207,78,2.65,-1.33,0,0],], [[91,66,5.90,3.14,0,0], [207,78,2.65,-1.20,0,0],], [[98,63,5.90,3.14,0,0], [207,78,2.65,-1.08,0,0],], [[104,60,5.90,3.14,0,0], [207,78,2.65,-0.96,0,4],], [[111,58,5.90,3.14,0,0], [207,78,2.65,-0.65,0,4],], [[117,56,6.03,3.14,0,0], [207,78,2.65,-0.33,0,4],], [[124,54,6.03,3.14,0,0], [207,78,2.65,-0.02,0,4],], [[130,53,6.03,3.14,0,0], [207,78,2.65,0.30,0,4],], [[137,51,6.03,3.14,0,0], [207,78,2.65,0.61,0,4],], [[144,49,6.03,3.14,0,0], [207,78,2.65,0.93,0,70],], [[151,47,6.03,3.14,0,0], [207,78,2.65,0.61,0,28],], [[157,45,6.03,3.14,0,0], [205,79,2.65,0.93,0,28],], [0, [201,81,2.56,1.24,1,85],],]]; + +shortround = [[300, 300, 50],[["#80f0c0",[[50, 0.00, 0.17, 1],[35, 0.00, 1.57, 0],[100, 0.52, 1.03, 0],[100, 5.76, 1.03, 0],[70, 3.14, 3.14, 0],[100, 1.57, 1.03, 0],[100, 4.71, 1.03, 0],[100, 0.00, 0.09, 1],[55, 0.87, 1.55, 0],[55, 5.41, 1.55, 0],]], ["#ff8844",[[50, 0.00, 0.09, 1],[100, 4.68, 3.09, 1],[100, 1.61, 3.11, 1],[60, 0.00, 2.09, 0],[60, 2.09, 2.09, 0],[60, 4.19, 2.09, 0],[100, 0.00, 0.09, 1],]], ["#ff0033",[[50, 0.00, 0.17, 1],[100, 1.57, 2.62, 1],[100, 4.71, 2.62, 1],]], ["#a08080",[[50, 0.00, 0.14, 1],[30, 0.00, 0.87, 0],[50, 0.00, 0.17, 0],[100, 5.50, 1.75, 1],[100, 0.79, 1.75, 1],[60, 3.14, 3.14, 0],]],],[[[75,75,0.87,0.02,2,0], [225,75,0.24,1.41,0,0], [75,225,5.64,2.15,0,0], [225,225,0.35,-0.00,2,0],], [[76,76,0.87,-0.00,2,0], [225,75,0.24,1.50,0,0], [75,225,5.64,1.83,0,0], [227,225,0.35,0.00,2,0],], [[79,80,0.87,0.00,2,0], [225,75,0.24,1.61,0,0], [75,225,5.64,1.52,0,0], [231,227,0.35,-0.00,2,0],], [[83,85,0.87,-0.00,2,0], [225,75,0.24,1.71,0,0], [75,225,5.64,1.20,0,0], [237,229,0.35,-0.00,2,0],], [[87,90,0.87,-0.00,2,0], [225,75,0.24,1.82,0,0], [75,225,5.64,0.89,0,0], [242,231,0.35,0.00,2,0],], [[91,95,0.87,0.00,2,0], [225,75,0.24,1.92,0,0], [75,225,5.64,0.58,0,0], [247,233,0.35,-0.00,2,0],], [[95,100,0.96,-0.00,2,0], [225,75,0.24,2.02,0,0], [75,225,5.64,0.26,0,0], [252,235,0.35,0.00,2,0],], [[98,105,1.05,-0.00,2,0], [225,75,0.24,2.11,0,0], [75,225,5.64,0.00,0,0], [258,237,0.35,-0.00,2,0],], [[101,111,1.13,0.00,2,0], [225,75,0.24,2.20,0,0], [75,225,5.64,-0.00,0,0], [263,239,0.35,-0.00,2,0],], [[103,116,1.13,-0.00,2,0], [225,75,0.24,2.29,0,0], [75,225,5.64,0.00,0,4], [268,240,0.35,0.00,2,8],], [[105,122,1.22,0.00,2,4], [225,75,0.24,2.37,0,0], [75,225,5.64,-0.31,0,4], [272,242,0.28,-0.31,2,24],], [[106,127,1.38,-0.00,2,4], [225,75,0.24,2.46,0,0], [75,225,5.64,-0.63,0,4], [278,243,0.22,-0.30,2,24],], [[106,131,1.63,-0.00,2,4], [225,75,0.24,2.55,0,0], [75,225,5.64,-0.94,0,6], [285,244,0.22,-0.28,2,24],], [[105,134,1.93,0.00,2,140], [225,75,0.24,2.65,0,0], [75,225,5.64,-1.26,0,6], [292,246,0.22,-0.26,2,8],], [[102,138,2.22,-0.00,2,8], [225,75,0.24,2.74,0,0], [75,225,5.64,-1.57,0,6], [296,247,0.22,-0.58,2,24],], [[99,141,2.32,-0.00,2,8], [225,75,0.24,2.83,0,0], [75,225,5.64,-1.88,0,6], [3,248,0.22,-0.58,2,24],], [[97,144,2.15,0.00,2,8], [225,75,0.24,2.91,0,0], [75,225,5.64,-2.20,0,6], [10,250,0.22,-0.56,2,24],], [[96,148,1.88,-0.00,2,140], [225,75,0.24,3.00,0,0], [75,225,5.64,-2.51,0,6], [17,251,0.22,-0.54,2,24],], [[95,153,1.64,-0.00,2,4], [225,75,0.24,3.09,0,0], [75,225,5.64,-2.83,0,6], [24,253,0.22,-0.54,2,24],], [[95,158,1.64,0.00,2,4], [225,75,0.24,3.18,0,0], [75,225,5.64,-3.14,1,3], 0,], [[94,162,1.82,-0.00,2,140], [225,75,0.24,3.26,0,0], [75,225,5.64,-2.83,0,2], 0,], [[92,168,1.97,0.00,2,652], [225,75,0.24,3.37,0,0], [75,225,5.64,-2.51,0,2], 0,], [[89,175,1.97,-0.00,3,653], [225,75,0.24,3.46,0,0], 0, 0,], [[86,181,1.97,-0.00,0,0], [225,75,0.24,3.54,0,0], 0, 0,], [[84,187,1.97,0.00,0,0], [225,75,0.24,3.63,0,0], 0, 0,], [[81,193,1.97,-0.00,0,0], [225,75,0.24,3.72,0,0], 0, 0,], [[78,198,2.05,-0.00,0,0], [225,75,0.24,3.80,0,0], 0, 0,], [[76,204,2.05,0.00,0,0], [225,75,0.24,3.89,0,0], 0, 0,], [[73,209,2.05,-0.00,0,0], [225,75,0.24,3.98,0,0], 0, 0,], [[70,215,2.05,0.00,0,0], [225,75,0.24,4.08,0,0], 0, 0,], [[67,220,2.05,-0.00,0,0], [225,75,0.24,4.19,0,0], 0, 0,], [[64,226,2.05,-0.00,0,0], [225,75,0.24,4.29,0,0], 0, 0,], [[61,231,2.14,0.00,0,0], [225,75,0.24,4.40,0,0], 0, 0,], [[57,237,2.14,-0.00,0,0], [225,75,0.24,4.49,0,0], 0, 0,], [[54,242,2.14,-0.00,0,0], [225,75,0.24,4.57,0,0], 0, 0,], [[50,247,2.14,0.00,0,0], [225,75,0.24,4.66,0,0], 0, 0,], [[47,252,2.14,-0.00,0,0], [225,75,0.24,4.75,0,0], 0, 0,], [[44,258,2.14,-0.00,0,0], [225,75,0.24,4.83,0,0], 0, 0,], [[40,263,2.14,0.00,0,0], [225,75,0.24,4.92,0,0], 0, 0,], [[37,268,2.14,-0.00,0,0], [225,75,0.24,5.01,0,0], 0, 0,], [[33,274,2.14,0.00,0,0], [225,75,0.24,5.10,0,0], 0, 0,], [[30,279,2.23,-0.00,0,0], [225,75,0.24,5.20,0,0], 0, 0,], [[26,284,2.23,-0.00,2,0], [225,75,0.24,5.31,0,0], 0, 0,], [[22,289,2.23,0.00,2,0], [225,75,0.24,5.39,0,0], 0, 0,], [[18,294,2.23,-0.00,2,0], [225,75,0.24,5.48,0,0], 0, 0,], [[14,299,2.23,-0.00,2,0], [225,75,0.24,5.57,0,0], 0, 0,], [[10,3,2.31,0.00,2,0], [225,75,0.24,5.65,0,0], 0, 0,], [[6,8,2.31,-0.00,2,4], [225,75,0.24,5.74,0,2], 0, 0,], [[2,11,2.42,-0.00,2,140], [225,75,0.24,5.43,0,66], 0, 0,], [[297,15,2.46,0.00,2,140], [225,75,0.24,5.74,0,2], 0, 0,], [[291,20,2.46,-0.00,2,140], [225,75,0.24,5.43,0,66], 0, 0,], [[286,24,2.46,0.00,2,140], [225,75,0.24,5.74,0,2], 0, 0,], [[280,29,2.46,-0.00,2,140], [225,75,0.24,5.43,0,66], 0, 0,], [[275,33,2.46,-0.00,2,140], [225,75,0.24,5.74,0,10], 0, 0,], [[270,37,2.46,0.00,2,908], [222,74,0.24,5.43,0,78], 0, 0,], [[264,42,2.46,-0.00,3,397], 0, 0, 0,],]]; \ No newline at end of file diff --git a/forf b/forf new file mode 160000 index 0000000..fb482e2 --- /dev/null +++ b/forf @@ -0,0 +1 @@ +Subproject commit fb482e222f4357553d717a0cb9daac1721973d23 diff --git a/forf.html.sh b/forf.html.sh new file mode 100755 index 0000000..3aeceaa --- /dev/null +++ b/forf.html.sh @@ -0,0 +1,16 @@ +#! /bin/sh + +cat < + + Forf Manual + + + + +EOF +markdown forf/forf.txt +cat < + +EOF diff --git a/grunge.png b/grunge.png new file mode 100644 index 0000000..9a8c41a Binary files /dev/null and b/grunge.png differ diff --git a/intro.html b/intro.html new file mode 100644 index 0000000..7789761 --- /dev/null +++ b/intro.html @@ -0,0 +1,146 @@ + + + + Tanks Introduction + + + + + + +

Tanks Introduction

+ + + + + + +
"ChashTank" dominates this short round.
+ + +
+ +

+ Tanks is a game in which you pit your coding abilities against + other hackers. You write a program for your tank, set it out on + the battlefield, and watch how it fares against other tanks while + running your program. +

+ +

+ Each tank has a turret-mounted laser, two treads, up to ten + sensors, and a diagnostic LED. Sensors are used to detect when + other tanks are inside a given arc. In the examples on this page, + "triggered" sensors turn black. Most tanks will take some action + if a sensor is triggered, such as changing speed of the treads, + turning the turret, or firing. +

+ +

+ Tanks are programmed in Forf, a stack-based language similar to + PostScript. Please read the Forf manual + to learn more about forf, and the Tanks + procedure reference for a description of Tanks extensions. +

+ +

Quick Start for the Impatient

+ + + + + + +
"Crashmaster" pwns the lame default tank provided in this + section.
+ + +
+ +

+ To get started, head over to the Tank + Designer and enter the following example tank. This tank will + move around, turn the turret, and fire if there's something in + front of it. +

+ +
+Sensor 0: 50 0 7 ☑
+Sensor 1: 30 0 90 ☐
+
+get-turret 12 + set-turret!         ( Rotate turret )
+37 40 set-speed!                    ( Go in circles )
+0 sensor? { fire! } if              ( Fire if turret sensor triggered )
+1 sensor? { -50 50 set-speed! } if  ( Turn if collision sensor triggered )
+    
+ +

+ Obviously, this tank could be improved. Studying the examples on + this page should give you ideas about how to make a better tank. + Don't forget the Forf manual and the + Tank procedure reference. +

+ +

Tank Specifications

+ + + + + + +
"Ant Lion" nails "Rabbit With Gun".
+ + +
+ +

+ Your PF-255 autonomous tank is built to the exacting + specifications sent to our factory in New Khavistan. All + distances are in meters, angles in degrees. +

+ +
+
Tank size
+
+ The targettable area of the tank—the part which can be hit by a + cannon—is a circle about 7½ meters in radius. +
+ +
Speed
+
+ Each tread can have a speed between -100 and 100. This is in + percentage of total speed for that tread, where total speed is + roughly 7 meters per turn. +
+ +
Sensors
+
+ Each sensor has a maximum range of 100 meters. Of course, you + don't have to use the full range. Sensors may be attached to + the turret (they turn along with the turret), or left fixed to + the tank. +
+ +
Turret
+
+ Turret angle can be set between -359° and 359°, with 0° directly + in front of the tank. Be aware that it takes time for the + turret to swing around: the turret can swing about 60° per turn. +
+ +
Cannon range and recharging
+
+ When the cannon is fired, it obliterates everything for 50 + meters in front of it. It takes around 20 turns for your cannon + to recharge after it's been fired, so only shoot when you feel + like you're going to hit something. +
+
+ + Good luck blowing everybody up! + diff --git a/procs.html b/procs.html new file mode 100644 index 0000000..c902b18 --- /dev/null +++ b/procs.html @@ -0,0 +1,72 @@ + + + + Tanks Procedure Reference + + + + +

Tanks Procedure Reference

+ +

+ Each tank's program is run once per turn. The data and command + stacks are reset at the beginning of each turn, but memory is not, + so you can carry data over in memory registers if you want. See + the Forf manual for more information about + the base language. +

+ +

+ For tank specifications (sensor range, maximum speeds, etc.), see + the introduction. +

+ + +

Limits

+ +

+ Forf Tanks has a data stack size of 200, and a command stack size + of 500. This means your program cannot have more than 200 data + items, or 500 instructions, including 2 instructions for each + substack. +

+ +

+ Forf Tanks provides 10 memory registers (0-9) which persist across + invocations of your tank's program. +

+ + +

Additional Procedures

+ +
+
fire-ready?
+
Returns 1 if the tank can fire, 0 if not.
+ +
fire!
+
Fires the cannon.
+ +
l r set-speed!
+
Sets the speed of the left and right treads (range: -100 to + 100).
+ +
get-turret
+
Returns the current angle of the turret.
+ +
a set-turret!
+
Set the turret to a degrees.
+ +
n sensor?
+
Returns 1 if sensor n is triggered, 0 if not.
+ +
s set-led!
+
Turns off the LED if s is 0, on for any other value.
+ +
n random
+
Returns a random number in the range [0, n). That is, between + 0 and n-1, inclusive.
+
+ + + + diff --git a/round.sh b/round.sh index 1efe934..610fb78 100755 --- a/round.sh +++ b/round.sh @@ -21,7 +21,7 @@ cat <$fn