Remote agent/Simulation/C: Difference between revisions
Content added Content deleted
m (formatting) |
(bug fix) |
||
Line 145: | Line 145: | ||
#include <err.h> |
#include <err.h> |
||
#include "common.c" |
#include "common.c" |
||
typedef struct task_node_t { |
typedef struct task_node_t { |
||
int x, y; |
int x, y; |
||
struct task_node_t *prev, *sibling, *chain; |
struct task_node_t *prev, *sibling, *chain; |
||
} task_node_t, *task; |
} task_node_t, *task; |
||
task pool = 0, used = 0; |
task pool = 0, used = 0; |
||
task find_place_to_go(byte **f); |
task find_place_to_go(byte **f); |
||
Line 165: | Line 165: | ||
return used; |
return used; |
||
} |
} |
||
void remove_tasks() |
void remove_tasks() |
||
{ |
{ |
||
Line 176: | Line 176: | ||
} |
} |
||
} |
} |
||
int w, h; |
int w, h; |
||
int do_client_stuff(int); |
int do_client_stuff(int); |
||
int main(int c, char *v[]) |
int main(int c, char *v[]) |
||
{ |
{ |
||
Line 185: | Line 185: | ||
struct sockaddr_in peer; |
struct sockaddr_in peer; |
||
struct hostent *server; |
struct hostent *server; |
||
if (c < 3) err(1, "Usage: %s host port\n", v[0]); |
if (c < 3) err(1, "Usage: %s host port\n", v[0]); |
||
port = atoi(v[2]); |
port = atoi(v[2]); |
||
if (port <= 0) err(1, "bad port: %d\n", port); |
if (port <= 0) err(1, "bad port: %d\n", port); |
||
server = gethostbyname(v[1]); |
server = gethostbyname(v[1]); |
||
if (!server) err(1, "Unknown server %s", v[1]); |
if (!server) err(1, "Unknown server %s", v[1]); |
||
if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) |
if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) |
||
err(1, "Can't open socket"); |
err(1, "Can't open socket"); |
||
memset(&peer, 0, sizeof(peer)); |
memset(&peer, 0, sizeof(peer)); |
||
peer.sin_family = AF_INET; |
peer.sin_family = AF_INET; |
||
memcpy( |
memcpy(&peer.sin_addr.s_addr, server->h_addr, server->h_length); |
||
peer.sin_port = htons(port); |
peer.sin_port = htons(port); |
||
if (connect(sfd, (struct sockaddr *)&peer, sizeof(peer)) < 0) |
if (connect(sfd, (struct sockaddr *)&peer, sizeof(peer)) < 0) |
||
err(1, "Can't connect to %s port %d", v[1], port); |
err(1, "Can't connect to %s port %d", v[1], port); |
||
puts("\033[H\033[J"); |
puts("\033[H\033[J"); |
||
do_client_stuff(sfd); |
do_client_stuff(sfd); |
||
close(sfd); |
close(sfd); |
||
return 0; |
return 0; |
||
} |
} |
||
byte ** init_map() |
byte ** init_map() |
||
{ |
{ |
||
Line 220: | Line 220: | ||
return f; |
return f; |
||
} |
} |
||
byte **f; |
byte **f; |
||
int try_forward(int); |
int try_forward(int); |
||
void say_and_listen(int, int, int*); |
void say_and_listen(int, int, int*); |
||
int do_client_stuff(int fd) |
int do_client_stuff(int fd) |
||
{ |
{ |
||
Line 230: | Line 230: | ||
int response[MAX_CMD]; |
int response[MAX_CMD]; |
||
task tgt; |
task tgt; |
||
if (c != 'A') { |
if (c != 'A') { |
||
fprintf(stderr, "Bad handshake: %c\n", c); |
fprintf(stderr, "Bad handshake: %c\n", c); |
||
Line 238: | Line 238: | ||
f = init_map(); |
f = init_map(); |
||
c = 0; |
c = 0; |
||
while (c != -1) { |
while (c != -1) { |
||
x = agent.x, y = agent.y; |
x = agent.x, y = agent.y; |
||
show_field(f, w, h); |
show_field(f, w, h); |
||
if (agent.ball == -1 && cell_ball(f, x, y) >= 0 |
if (agent.ball == -1 && cell_ball(f, x, y) >= 0 |
||
&& cell_ball(f, x, y) != cell_color(f, x, y)) |
&& cell_ball(f, x, y) != cell_color(f, x, y)) |
||
Line 252: | Line 252: | ||
continue; |
continue; |
||
} |
} |
||
if (agent.ball == cell_color(f, x, y) && cell_ball(f, x, y) == -1) { |
if (agent.ball == cell_color(f, x, y) && cell_ball(f, x, y) == -1) { |
||
say_and_listen(fd, c_drop, response); |
say_and_listen(fd, c_drop, response); |
||
Line 261: | Line 261: | ||
continue; |
continue; |
||
} |
} |
||
goto_place(fd, f, tgt = find_place_to_go(f)); |
goto_place(fd, f, tgt = find_place_to_go(f)); |
||
continue; |
continue; |
||
Line 267: | Line 267: | ||
return 0; |
return 0; |
||
} |
} |
||
void expand_map() |
void expand_map() |
||
{ |
{ |
||
Line 273: | Line 273: | ||
int dx, dy; |
int dx, dy; |
||
byte **nf; |
byte **nf; |
||
switch(d) { |
switch(d) { |
||
case 0: case 2: w2++; break; |
case 0: case 2: w2++; break; |
||
default: h2++; break; |
default: h2++; break; |
||
} |
} |
||
nf = byte_array(w2, h2); |
nf = byte_array(w2, h2); |
||
FOR(i, h2) FOR(j, w2) nf[i][j] = unknown; |
FOR(i, h2) FOR(j, w2) nf[i][j] = unknown; |
||
dx = agent.x == 0; |
dx = agent.x == 0; |
||
dy = agent.y == 0; |
dy = agent.y == 0; |
||
FOR(i, h) FOR(j, w) nf[i + dy][j + dx] = f[i][j]; |
FOR(i, h) FOR(j, w) nf[i + dy][j + dx] = f[i][j]; |
||
if (!agent.x) agent.x = 1; |
if (!agent.x) agent.x = 1; |
||
if (!agent.y) agent.y = 1; |
if (!agent.y) agent.y = 1; |
||
w = w2, h = h2; |
w = w2, h = h2; |
||
printf("expand: %d %d\n", w, h); |
printf("expand: %d %d\n", w, h); |
||
Line 295: | Line 295: | ||
f = nf; |
f = nf; |
||
} |
} |
||
int try_forward(int fd) |
int try_forward(int fd) |
||
{ |
{ |
||
Line 327: | Line 327: | ||
return 1; |
return 1; |
||
} |
} |
||
void say_and_listen(int fd, int cmd, int *resp) |
void say_and_listen(int fd, int cmd, int *resp) |
||
{ |
{ |
||
Line 340: | Line 340: | ||
} |
} |
||
} |
} |
||
int is_interesting(byte **f, task t) |
int is_interesting(byte **f, task t) |
||
{ |
{ |
||
Line 346: | Line 346: | ||
if ((f[y][x] & unknown)) |
if ((f[y][x] & unknown)) |
||
return y != agent.y || x != agent.x; |
return y != agent.y || x != agent.x; |
||
c = cell_color(f, x, y); |
c = cell_color(f, x, y); |
||
b = cell_ball(f, x, y); |
b = cell_ball(f, x, y); |
||
a = agent.ball; |
a = agent.ball; |
||
if (a >= 0) |
if (a >= 0) |
||
return a == c && b == -1; |
return a == c && b == -1; |
||
else if (b >= 0 && b != c) |
else if (b >= 0 && b != c) |
||
return 1; |
return 1; |
||
return 0; |
return 0; |
||
} |
} |
||
task find_place_to_go(byte **f) |
task find_place_to_go(byte **f) |
||
{ |
{ |
||
Line 368: | Line 368: | ||
current->x = agent.x, current->y = agent.y; |
current->x = agent.x, current->y = agent.y; |
||
f[current->y][current->x] |= marked; |
f[current->y][current->x] |= marked; |
||
if (is_interesting(f, current)) return current; |
if (is_interesting(f, current)) return current; |
||
while (current) { |
while (current) { |
||
while (current) { |
while (current) { |
||
Line 390: | Line 390: | ||
next = 0; |
next = 0; |
||
} |
} |
||
puts("nowhere to go"); |
|||
abort(); |
abort(); |
||
} |
} |
||
void goto_place(int fd, byte **f, task t) |
void goto_place(int fd, byte **f, task t) |
||
{ |
{ |
||
Line 399: | Line 400: | ||
usleep(50000); |
usleep(50000); |
||
t->prev = 0; |
t->prev = 0; |
||
if (agent.x == t->x && agent.y == t->y) return; |
if (agent.x == t->x && agent.y == t->y) return; |
||
while ( t->x != agent.x + dirs[agent.facing][0] || |
while ( t->x != agent.x + dirs[agent.facing][0] || |