Created
May 19, 2014 00:36
-
-
Save thejh/9b4b7f1a8fd8373d3a62 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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