Skip to content

Instantly share code, notes, and snippets.

@thejh
Created May 19, 2014 00:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thejh/9b4b7f1a8fd8373d3a62 to your computer and use it in GitHub Desktop.
Save thejh/9b4b7f1a8fd8373d3a62 to your computer and use it in GitHub Desktop.
#define _GNU_SOURCE
#include <jh.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#define RIFLE_SPEED 975
#define PISTOL_SPEED 375
char line[4096];
FILE *in, *out;
void next(void) {
(void)CHK_PTR(fgets(line, sizeof(line), in), "unexpected end of input", 1);
trim_end(line, "\r\n");
printf("INPUT: %s\n", line);
}
double distance(double x, double y) {
return sqrt(x*x+y*y);
}
double deg_atan(double x, double y) {
return atan(y/x)/M_PI*180;
}
double drop(double distance, double speed, double *shot_time) {
double t = distance/speed;
if (shot_time) *shot_time = t;
//printf("shot time to target: %f\n", t);
return 0.5 * 9.81 * (t*t);
}
void sendf(char *fmt, ...) {
va_list ap;
char *buf;
va_start(ap, fmt);
(void)fail_on_neg(vasprintf(&buf, fmt, ap), "vasprintf failed", 1);
va_end(ap);
fputs(buf, out);
printf("OUTPUT: %s", buf);
free(buf);
}
int main(void) {
if (fnetopen(&in, &out, "zombies_8977dda19ee030d0ea35e97ad2439319.2014.shallweplayaga.me", "20689", JH_TCP_HINTS))
xperror("fnetopen failed", 0);
do next(); while (line[0] != '3');
sendf("2\n");
do next(); while (line[0] != '3');
sendf("3\n");
do next(); while (strstr(line, "Tribbletown will only let you in") == NULL);
while (1) {
next();
if (strncmp(line, "-----", 5)) xperror("start marker not found", 0);
next(); // "Level <n>"
next();
if (strcmp(line, "You are still, aiming carefully from your van")) xperror("I want to be still", 0);
next();
double x0, y0, pupx, pupy, time_to_death, vx=0, vy=0, shot_time;
if (sscanf(line, "The zombie is stalking a puppy %lfm from your van and %lfm above your van", &x0, &y0) == 2) {
next();
if (strcmp(line, "The zombie has no legs...it's not moving.")) xperror("IT'S MOVING! SHOOT IT! I CAN'T!", 0);
} else if (sscanf(line, "The zombie is stalking a puppy across a hillside, starting at a distance of %lfm from your van and %lfm above it. The puppy is frozen in terror %lfm from your van and %lfm above your van.", &x0, &y0, &pupx, &pupy) == 4) {
next();
if (sscanf(line, "You have %lf seconds before the zombie eats the puppy!", &time_to_death) != 1) xperror("want deathtime", 0);
printf("x1=%f y1=%f x2=%f y2=%f ttd=%f\n", x0, y0, pupx, pupy, time_to_death);
// assume 1s reaction time
double dx = pupx-x0, dy = pupy-y0;
double scale = 1/time_to_death;
vx = dx * scale;
x0 += vx;
vy = dy * scale;
y0 += vy;
printf("dx=%f dy=%f scale=%f newx=%f newy=%f\n", dx, dy, scale, x0, y0);
} else {
xperror("matching coords failed", 0);
}
next();
if (strcmp(line, "Enter your shot details:")) xperror("i want to enter details", 0);
double shot_angle, view_angle, dist;
if (vx==0 && vy==0) {
dist = distance(x0, y0);
view_angle = deg_atan(x0, y0);
double corrected_y = y0 + drop(dist, RIFLE_SPEED, &shot_time);
printf("corrected y: %f\n", corrected_y);
shot_angle = deg_atan(x0, corrected_y);
} else {
double t=0, dt, x, y;
for (int i=0; i<100; i++) {
x = x0 + t * vx;
y = y0 + t * vy;
dist = distance(x, y);
view_angle = deg_atan(x, y);
y = y + drop(dist, RIFLE_SPEED, &shot_time);
shot_angle = deg_atan(x, y);
// shot takes shot_time to arrive, but should arrive after t
double t_new = (t + shot_time)/2;
dt = t_new-t;
t = t_new;
}
printf("x=%f y=%f\n", x, y);
printf("t=%f dt=%f\n", t, dt);
}
sendf("r, %f, %f, %f\n", shot_angle, dist, view_angle);
next();
if (!strcmp(line, "1 second gone by")) next();
if (strcmp(line, "Bullseye!, you nailed it in the face") &&
strstr(line, "You hit the zombie, but missed his eye by")==NULL) {
printf("not a hit\n");
while (1) next();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment