Incomp. Proto. Change: Maintain sync by prefixing client commands by tick id

This commit is contained in:
Petr Baudis 2011-12-22 15:28:05 +01:00
parent 091708f577
commit 9baf771807
5 changed files with 29 additions and 15 deletions

15
README
View file

@ -6,7 +6,7 @@ In each tick, the server sends sensor input to the agent.
Until the next tick, the client may supply actions to take
to the server.
Both server input and client output follow the same format:
Server input follows the format:
cmd1 <par1> <par2>...
cmd2 <par1> <par2>...
@ -53,6 +53,16 @@ The following inputs (in no particular order) are supported:
<id>: pheromone id 0..65535
<intensity>: floating-point number
Client output follows a slightly different format:
<tickid> cmd1 <par1> <par2>...
<tickid> cmd2 <par1> <par2>...
...
Only commands with a matching tickid are processed; in case a command
is delayed, causing late relaying to the server and processing in the
future, it is silently dropped and ignored.
The following outputs are supported:
move_dir <x> <y>
@ -106,6 +116,3 @@ If the id corresponds to a disconnected agent, the connection
is immediately attached to that agent. Combining this with other
negotiation commands is undefined, except for newborns - in that case,
negotiation commands must follow after agent_id.
TODO proto. change:
tickid for input

View file

@ -179,7 +179,7 @@ agent::on_action_takes(void)
return;
}
conn->actions(this);
conn->actions(tick_id, this);
}
void

View file

@ -116,9 +116,9 @@ sub take_action($$) {
print "moves ".join(", ", @move)." => (".dirindex($max).":$max->[0],$max->[1])\n";
if ($attack[dirindex($max)]) {
print $socket "attack_dir $max->[0] $max->[1] 100\r\n";
print $socket $state->{tick}." attack_dir $max->[0] $max->[1] 100\r\n";
} else {
print $socket "move_dir $max->[0] $max->[1]\r\n";
print $socket $state->{tick}." move_dir $max->[0] $max->[1]\r\n";
}
print $socket "secrete 65536 1\r\n";
print $socket "\r\n";

View file

@ -6,6 +6,8 @@
#include <sys/select.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "agent.h"
@ -97,22 +99,31 @@ connection::bump(void)
}
void
connection::actions(class agent *agent)
connection::actions(int tick_id, class agent *agent)
{
pthread_mutex_lock(&buf_lock);
if (buf_incomplete(in_buf)) {
if (in_buf.find("\r\n") == std::string::npos) {
/* Not enough data, needs to wait until next turn, sorry. */
pthread_mutex_unlock(&buf_lock);
return;
}
int mask = 0;
while (in_buf.c_str()[0] != '\r') {
while (in_buf.find("\r\n") != std::string::npos) {
int nlofs = in_buf.find("\r\n");
std::string line = in_buf.substr(0, nlofs);
in_buf.erase(0, nlofs + 2);
int spofs = line.find(' ');
std::string cmd_tick_id = line.substr(0, spofs);
line.erase(0, spofs + 1);
if (atol(cmd_tick_id.c_str()) != tick_id - 1) {
/* Out of sync command, ignore and continue. */
continue;
}
spofs = line.find(' ');
std::string cmd = line.substr(0, spofs);
line.erase(0, spofs + 1);
@ -282,13 +293,9 @@ connection::thread_loop(void)
break;
} else {
bool want_moar = false;
pthread_mutex_lock(&buf_lock);
in_buf += std::string(cbuf, len);
want_moar = buf_incomplete(in_buf);
pthread_mutex_unlock(&buf_lock);
if (!want_moar)
break;
}
}

View file

@ -29,7 +29,7 @@ public:
void senses(int tick_id, class agent &);
void bred(int agent_id, std::string &info);
void actions(class agent *);
void actions(int tick_id, class agent *);
void cancel(void);