Remote agent/Simulation/C: Difference between revisions

no edit summary
(Created page with "{{implementation|Remote agent/Simulation}} 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, an...")
 
imported>Katsumi
No edit summary
 
(7 intermediate revisions by 5 users not shown)
Line 1:
<noinclude>{{implementationcollection|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 16 ⟶ 17:
#define W 30
#define H 30
char response[] = "A";
 
int do_server_stuff(int);
Line 132:
 
return 1;
}</langsyntaxhighlight>
 
;<nowiki>client.c:</nowiki>
<syntaxhighlight lang="c" line>
<lang c>#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
Line 146 ⟶ 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 166 ⟶ 167:
return used;
}
 
void remove_tasks()
{
Line 177 ⟶ 178:
}
}
 
int w, h;
int do_client_stuff(int);
 
int main(int c, char *v[])
{
Line 186 ⟶ 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 221 ⟶ 222:
return f;
}
 
byte **f;
int try_forward(int);
void say_and_listen(int, int, int*);
 
int do_client_stuff(int fd)
{
Line 231 ⟶ 232:
int response[MAX_CMD];
task tgt;
 
if (c != 'A') {
fprintf(stderr, "Bad handshake: %c\n", c);
Line 239 ⟶ 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 253 ⟶ 254:
continue;
}
 
if (agent.ball == cell_color(f, x, y) && cell_ball(f, x, y) == -1) {
say_and_listen(fd, c_drop, response);
Line 262 ⟶ 263:
continue;
}
 
goto_place(fd, f, tgt = find_place_to_go(f));
continue;
Line 268 ⟶ 269:
return 0;
}
 
void expand_map()
{
Line 274 ⟶ 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 296 ⟶ 297:
f = nf;
}
 
int try_forward(int fd)
{
Line 328 ⟶ 329:
return 1;
}
 
void say_and_listen(int fd, int cmd, int *resp)
{
Line 341 ⟶ 342:
}
}
 
int is_interesting(byte **f, task t)
{
Line 347 ⟶ 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 369 ⟶ 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 391 ⟶ 392:
next = 0;
}
puts("nowhere to go");
abort();
}
 
void goto_place(int fd, byte **f, task t)
{
Line 400 ⟶ 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 406 ⟶ 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 420 ⟶ 424:
};
 
const char *cmds = "^><@!+.RGYBrgyb|SAsa";
inline int cmd_to_char(int c) { return cmds[c]; }
inline int char_to_cmd(int c) {
Line 551 ⟶ 555:
}
 
const char *colors[] = { "31", "32", "33", "34" };
const char *ag[] = { "<V>A" };
 
inline int cell_color(byte **f, int x, int y)
Line 612 ⟶ 616:
if (dir == c_cw)
if (++agent.facing > 3) agent.facing = 0;
}
}</lang>
</syntaxhighlight>
Anonymous user