mirror of https://github.com/dirtbags/tanks.git
155 lines
3.3 KiB
C
155 lines
3.3 KiB
C
|
#include <string.h>
|
||
|
#include <stdlib.h>
|
||
|
#include "brad.h"
|
||
|
#include "ctanks.h"
|
||
|
|
||
|
void
|
||
|
tank_init(struct tank *tank, tank_run_func *run, void *udata)
|
||
|
{
|
||
|
memset(tank, 0, sizeof(*tank));
|
||
|
tank->run = run;
|
||
|
tank->udata = udata;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
tank_fire_ready(struct tank *tank)
|
||
|
{
|
||
|
return (! tank->turret.recharge);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
tank_fire(struct tank *tank)
|
||
|
{
|
||
|
tank->turret.firing = tank_fire_ready(tank);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
tank_set_speed(struct tank *tank, bs_t left, bs_t right)
|
||
|
{
|
||
|
tank->speed.desired[0] = left;
|
||
|
tank->speed.desired[1] = right;
|
||
|
}
|
||
|
|
||
|
brad_t
|
||
|
tank_get_turret(struct tank *tank)
|
||
|
{
|
||
|
return tank->turret.current;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
tank_set_turret(struct tank *tank, brad_t angle)
|
||
|
{
|
||
|
tank->turret.desired = angle;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
tank_get_sensor(struct tank *tank, int sensor_num)
|
||
|
{
|
||
|
if ((sensor < 0) || (sensor > MAX_SENSORS)) {
|
||
|
return 0;
|
||
|
}
|
||
|
return tank->sensor[sensor_num].triggered;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
tank_set_led(struct tank *tank, int active)
|
||
|
{
|
||
|
tank->led = active;
|
||
|
}
|
||
|
|
||
|
/** Return distance^2 between tanks a and b.
|
||
|
*
|
||
|
* Comparing this against sensor_range^2 will tell you whether the tanks
|
||
|
* are within sensor range of one another. Similarly, comparing it
|
||
|
* against (2*tank_radius)^2 will tell you if they've collided.
|
||
|
*
|
||
|
*/
|
||
|
bs_t
|
||
|
tank_dist2(struct tanks_game *game, struct tank *a, struct tank *b)
|
||
|
{
|
||
|
bs_t d[2];
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < 2; i += 1) {
|
||
|
d[i] = abs(a.position[i] - b.position[i]);
|
||
|
d[i] = min(game.size[i] - dx[i], dx[i]);
|
||
|
}
|
||
|
return ((d[0] * d[0]) + (d[1] * d[1]));
|
||
|
}
|
||
|
|
||
|
void
|
||
|
do_shit_with(struct tanks_game *game,
|
||
|
struct tank *this,
|
||
|
struct tank *that)
|
||
|
{
|
||
|
bs_t vector[2];
|
||
|
int dist2; /* Integer to avoid overflow! */
|
||
|
bs_t xpos; /* Translated position */
|
||
|
int i;
|
||
|
|
||
|
/* Don't bother if one is dead */
|
||
|
if ((this->killer) || (that->killer)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Establish shortest vector from center of this to center of that,
|
||
|
* taking wrapping into account */
|
||
|
for (i = 0; i < 2; i += 1) {
|
||
|
bs_t halfsize = game->size[i] / 2;
|
||
|
|
||
|
/* XXX: is there a more elegant way to do this? */
|
||
|
vector[i] = that->position[i] - this->position[i];
|
||
|
if (2*vector[i] > game->size[i]) {
|
||
|
vector[i] -= game->size[i];
|
||
|
} else if (2*vector[i] < game->size[i]) {
|
||
|
vector[i] += game->size[i];
|
||
|
}
|
||
|
}
|
||
|
/* Compute distance^2 for range comparisons */
|
||
|
dist2 = ((bs_to_int(vector[0]) * bs_to_int(vector[0])) +
|
||
|
(bs_to_int(vector[1]) * bs_to_int(vector[1])));
|
||
|
|
||
|
/* If they're not within sensor range, there's nothing to do. */
|
||
|
if (dist2 > TANK_SENSOR_ADJ2) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Did they collide? Oh, goody! */
|
||
|
if (dist2 < TANK_COLLISION_ADJ2) {
|
||
|
/* XXX: kill both tanks */
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Has anybody been shot? */
|
||
|
|
||
|
/* Translate other tank's position to make us the origin */
|
||
|
for (i = 0; i < 2; i += 1) {
|
||
|
xpos[i] = that->position[i] - this->position[i];
|
||
|
}
|
||
|
|
||
|
/* Calculate sensors */
|
||
|
for (i = 0; i < this->num_sensors; i += 1) {
|
||
|
brad_t theta;
|
||
|
|
||
|
if (dist2 < this->sensor[i].range_adj2) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* Translate other tank so that we're the origin */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
tanks_run_turn(struct tanks_game *game, struct tank *tanks, int ntanks)
|
||
|
{
|
||
|
int i, j;
|
||
|
|
||
|
for (i = 0; i < ntanks; i += 1) {
|
||
|
for (j = i + 1; j < ntanks, j += 1) {
|
||
|
do_shit_with(game, &(tanks[i]), &(tanks[j]));
|
||
|
}
|
||
|
tanks_print_tank(game, &(tanks[i]));
|
||
|
tanks_move(game, &(tanks[i]));
|
||
|
}
|
||
|
}
|