Remote agent/Simulation/C: Difference between revisions

no edit summary
m (Use {{collection}}, not {{implementation}}.)
imported>Katsumi
No edit summary
 
(5 intermediate revisions by 4 users not shown)
Line 1:
<noinclude>{{collection|Remote agent/Simulation}}</noinclude>
Server/client programs share a lot of code, so they are all lumped together here. To compile, dump all three files in the same dir, and compile server.c and client.c separately. The server binds to port 11111. Both server and client display the current map, though only the server has the whole world, the client only knows cells the agent has been to.
 
;<nowiki>server.c:</nowiki>
<syntaxhighlight lang="c" line>
<lang c>#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
Line 131 ⟶ 132:
 
return 1;
}</langsyntaxhighlight>
 
;<nowiki>client.c:</nowiki>
<syntaxhighlight lang="c" line>
<lang c>#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
Line 145 ⟶ 147:
#include <err.h>
#include "common.c"
 
typedef struct task_node_t {
int x, y;
struct task_node_t *prev, *sibling, *chain;
} task_node_t, *task;
 
task pool = 0, used = 0;
task find_place_to_go(byte **f);
Line 165 ⟶ 167:
return used;
}
 
void remove_tasks()
{
Line 176 ⟶ 178:
}
}
 
int w, h;
int do_client_stuff(int);
 
int main(int c, char *v[])
{
Line 185 ⟶ 187:
struct sockaddr_in peer;
struct hostent *server;
 
if (c < 3) err(1, "Usage: %s host port\n", v[0]);
 
port = atoi(v[2]);
if (port <= 0) err(1, "bad port: %d\n", port);
 
server = gethostbyname(v[1]);
if (!server) err(1, "Unknown server %s", v[1]);
 
if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
err(1, "Can't open socket");
 
memset(&peer, 0, sizeof(peer));
peer.sin_family = AF_INET;
memcpy(server->h_addr, &peer.sin_addr.s_addr, server->h_addr, server->h_length);
peer.sin_port = htons(port);
 
if (connect(sfd, (struct sockaddr *)&peer, sizeof(peer)) < 0)
err(1, "Can't connect to %s port %d", v[1], port);
 
puts("\033[H\033[J");
do_client_stuff(sfd);
close(sfd);
 
return 0;
}
 
byte ** init_map()
{
Line 220 ⟶ 222:
return f;
}
 
byte **f;
int try_forward(int);
void say_and_listen(int, int, int*);
 
int do_client_stuff(int fd)
{
Line 230 ⟶ 232:
int response[MAX_CMD];
task tgt;
 
if (c != 'A') {
fprintf(stderr, "Bad handshake: %c\n", c);
Line 238 ⟶ 240:
f = init_map();
c = 0;
 
while (c != -1) {
x = agent.x, y = agent.y;
show_field(f, w, h);
 
if (agent.ball == -1 && cell_ball(f, x, y) >= 0
&& cell_ball(f, x, y) != cell_color(f, x, y))
Line 252 ⟶ 254:
continue;
}
 
if (agent.ball == cell_color(f, x, y) && cell_ball(f, x, y) == -1) {
say_and_listen(fd, c_drop, response);
Line 261 ⟶ 263:
continue;
}
 
goto_place(fd, f, tgt = find_place_to_go(f));
continue;
Line 267 ⟶ 269:
return 0;
}
 
void expand_map()
{
Line 273 ⟶ 275:
int dx, dy;
byte **nf;
 
switch(d) {
case 0: case 2: w2++; break;
default: h2++; break;
}
 
nf = byte_array(w2, h2);
FOR(i, h2) FOR(j, w2) nf[i][j] = unknown;
 
dx = agent.x == 0;
dy = agent.y == 0;
 
FOR(i, h) FOR(j, w) nf[i + dy][j + dx] = f[i][j];
 
if (!agent.x) agent.x = 1;
if (!agent.y) agent.y = 1;
 
w = w2, h = h2;
printf("expand: %d %d\n", w, h);
Line 295 ⟶ 297:
f = nf;
}
 
int try_forward(int fd)
{
Line 327 ⟶ 329:
return 1;
}
 
void say_and_listen(int fd, int cmd, int *resp)
{
Line 340 ⟶ 342:
}
}
 
int is_interesting(byte **f, task t)
{
Line 346 ⟶ 348:
if ((f[y][x] & unknown))
return y != agent.y || x != agent.x;
 
c = cell_color(f, x, y);
b = cell_ball(f, x, y);
a = agent.ball;
 
if (a >= 0)
return a == c && b == -1;
else if (b >= 0 && b != c)
return 1;
 
return 0;
}
 
task find_place_to_go(byte **f)
{
Line 368 ⟶ 370:
current->x = agent.x, current->y = agent.y;
f[current->y][current->x] |= marked;
 
if (is_interesting(f, current)) return current;
 
while (current) {
while (current) {
Line 390 ⟶ 392:
next = 0;
}
puts("nowhere to go");
abort();
}
 
void goto_place(int fd, byte **f, task t)
{
Line 399 ⟶ 402:
usleep(50000);
t->prev = 0;
 
if (agent.x == t->x && agent.y == t->y) return;
while ( t->x != agent.x + dirs[agent.facing][0] ||
Line 405 ⟶ 408:
turn(c_cw), say(c_cw), hear();
try_forward(fd);
}
}</lang>
</syntaxhighlight>
 
and share source ";<nowiki>common.c":</nowiki>
<syntaxhighlight lang="c" line>
<lang c>struct agent_t{ int x, y, facing, ball; } agent = { 0, 0, 0, -1 };
enum {
c_fwd, c_cw, c_ccw, c_get, c_drop, c_over, c_stop,
Line 419 ⟶ 424:
};
 
const char *cmds = "^><@!+.RGYBrgyb|SAsa";
inline int cmd_to_char(int c) { return cmds[c]; }
inline int char_to_cmd(int c) {
Line 550 ⟶ 555:
}
 
const char *colors[] = { "31", "32", "33", "34" };
const char *ag[] = { "<V>A" };
 
inline int cell_color(byte **f, int x, int y)
Line 611 ⟶ 616:
if (dir == c_cw)
if (++agent.facing > 3) agent.facing = 0;
}
}</lang>
</syntaxhighlight>
Anonymous user