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 Until the next tick, the client may supply actions to take
to the server. to the server.
Both server input and client output follow the same format: Server input follows the format:
cmd1 <par1> <par2>... cmd1 <par1> <par2>...
cmd2 <par1> <par2>... cmd2 <par1> <par2>...
@ -53,6 +53,16 @@ The following inputs (in no particular order) are supported:
<id>: pheromone id 0..65535 <id>: pheromone id 0..65535
<intensity>: floating-point number <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: The following outputs are supported:
move_dir <x> <y> 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 is immediately attached to that agent. Combining this with other
negotiation commands is undefined, except for newborns - in that case, negotiation commands is undefined, except for newborns - in that case,
negotiation commands must follow after agent_id. 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; return;
} }
conn->actions(this); conn->actions(tick_id, this);
} }
void void

View file

@ -116,9 +116,9 @@ sub take_action($$) {
print "moves ".join(", ", @move)." => (".dirindex($max).":$max->[0],$max->[1])\n"; print "moves ".join(", ", @move)." => (".dirindex($max).":$max->[0],$max->[1])\n";
if ($attack[dirindex($max)]) { 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 { } 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 "secrete 65536 1\r\n";
print $socket "\r\n"; print $socket "\r\n";

View file

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

View file

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