From 9baf77180794602c72d793d36a8477de270ed2fa Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Thu, 22 Dec 2011 15:28:05 +0100 Subject: [PATCH] Incomp. Proto. Change: Maintain sync by prefixing client commands by tick id --- README | 15 +++++++++++---- agent.cc | 2 +- client/example.pl | 4 ++-- connection.cc | 21 ++++++++++++++------- connection.h | 2 +- 5 files changed, 29 insertions(+), 15 deletions(-) diff --git a/README b/README index 937314b..dac649a 100644 --- a/README +++ b/README @@ -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 ... cmd2 ... @@ -53,6 +53,16 @@ The following inputs (in no particular order) are supported: : pheromone id 0..65535 : floating-point number +Client output follows a slightly different format: + + cmd1 ... + cmd2 ... + ... + +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 @@ -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 diff --git a/agent.cc b/agent.cc index 237a341..d3090b4 100644 --- a/agent.cc +++ b/agent.cc @@ -179,7 +179,7 @@ agent::on_action_takes(void) return; } - conn->actions(this); + conn->actions(tick_id, this); } void diff --git a/client/example.pl b/client/example.pl index 9bbc82f..2ada3ca 100755 --- a/client/example.pl +++ b/client/example.pl @@ -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"; diff --git a/connection.cc b/connection.cc index eaa90f6..20579df 100644 --- a/connection.cc +++ b/connection.cc @@ -6,6 +6,8 @@ #include #include +#include +#include #include #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; } } diff --git a/connection.h b/connection.h index 7c4722f..8389f2e 100644 --- a/connection.h +++ b/connection.h @@ -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);