Remote agent/Simulation: Difference between revisions

m
(Go solution)
m (→‎{{header|Wren}}: Minor tidy)
 
(7 intermediate revisions by 7 users not shown)
Line 5:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package world
 
import (
Line 253:
}
return true
}</langsyntaxhighlight>
{{out}}
<pre>
Line 297:
WWWWWWWWWWWWWWWW
</pre>
 
=={{header|Julia}}==
See [[Remote agent/Simulation/Julia]]
 
=={{header|Perl}}==
This is the server. It runs in one of three modes. If it is started with a port number as the argument, it
becomes a TCP server listening on that port, and the agent can talk to it over tcp.
If it is started on a terminal (perl's -t is true) it sets the terminal to cbreak mode and can be talked to directly.
Otherwise it can be run under xinetd.
<syntaxhighlight lang="perl">#!/usr/bin/perl
 
use strict; # https://rosettacode.org/wiki/Remote_agent
use warnings;
use List::Util qw( shuffle );
use Term::ReadKey;
 
# server
 
my $port = shift;
 
my ($wide, $high) = ( 30 ) x 2;
my $world = '-' x ($wide + 2) . "\n" .
('-' . ' ' x $wide . "-\n") x $high .
'-' x ($wide + 2) . "\n";
my $balls = $world;
for my $try (1 .. 1e3) # try again if no mismatch
{
s/\w/ /g for $world, $balls;
$world =~ s/ / qw(R G Y B)[rand 4] /ge; # fill in color sectors
my @balls = shuffle map lc, $world =~ /\w/g;
@balls[ @balls >> 1 .. $#balls] = (0) x @balls;
@balls = shuffle @balls;
$balls =~ s/ / shift @balls || 0 /ge; # add balls
findmismatch() and last;
}
 
#sub show
# {
# my @two = split /\n/, $balls;
# warn "$_ ", shift @two, "\n" for $world =~ /.+/g;
# }
#show();
 
my $gap = $wide + 3;
my @cells;
push @cells, $-[0] while $world =~ /\w/g;
my $agent = $cells[rand @cells]; # pick random starting cell
my $dirs = 'NESW' x 2;
my ($holds, $dir) = ( 0, substr $dirs, rand 4, 1 ); # random direction
my ($color, $ball) = map {substr $_, $agent, 1 } $world, $balls;
my %gap = ( N => -$gap, E => 1, S => $gap, W => -1 );
my %commands = (
'^' => \&forward,
'>' => sub { $dirs =~ /$dir(.)/ and $dir = $1 }, # turn right
'<' => sub { $dirs =~ /(.)$dir/ and $dir = $1 }, # turn left
'@' => \&get,
'!' => \&drop,
"\e" => sub {die "\nEnded by ESC\n" },
);
 
sub drop
{
print 'a' x !$holds, 'S' x !!$ball; # errors
if( $holds && !$ball )
{
substr $balls, $agent, 1, $holds;
($ball, $holds) = ($holds, 0);
findmismatch() or print '+';
}
}
 
sub get
{
$ball =~ /[rgby]/ or print 's';
$holds and print 'A';
if( $ball and not $holds )
{
$holds = $ball;
substr $balls, $agent, 1, 0;
}
}
 
sub forward
{
my $new = $agent + $gap{$dir};
if( substr($world, $new, 1) =~ /\w/ ) # not wall
{
$agent = $new;
($color, $ball) = map {substr $_, $agent, 1 } $world, $balls;
print $color, $ball || ''; # 0 means no ball
}
else { print '|'; }
}
 
sub findmismatch
{
my $mask = $balls =~ tr/rgby/\0/cr =~ tr/rgby/\xff/r;
lc($world & $mask) ne ($balls & $mask);
}
 
my $terminal = 0;
 
if( $port ) # then we are tcp server
{
use IO::Socket;
my $listen = IO::Socket::INET->new( LocalPort => $port,
Listen => 10, Reuse => 1 ) or die $@;
# warn "waiting for connect\n";
my $socket = $listen->accept;
close STDIN; # redir STDIN and STDOUT to socket
open STDIN, '<&', $socket or die "$! on input dup";
close STDOUT;
open STDOUT, '>&', $socket or die "$! on output dup";
}
elsif( -t ) # running on a tty
{
$terminal = 1;
# warn "running on terminal\n";
}
else # suitable for xinetd
{
# warn "running as subprocess\n";
}
 
eval # here so die when on tty can reset tty back to normal
{
local $/ = \1; # all commands are one byte
local $| = 1; # autoflush
$terminal and ReadMode 'cbreak';
print 'A'; # handshake
<> eq 'A' or die "handshake failed";
# warn "got handshake reply\n";
while( <> ) # command read loop
{
( $commands{$_} // sub {die "invalid command <$_>"} )->();
print '.'; # eol
}
1 } or warn $@;
$terminal and ReadMode 'restore';
#warn "final\n";
#show;
</syntaxhighlight>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\Remote_Agent_Simulator.exw
-- =======================================
--</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">Remote_Agent_Interface</span><span style="color: #0000FF;">.</span><span style="color: #000000;">exw</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- eg {"+-+-+","|R G|","+-+-+"}, up to 8(h)x11(w)</span>
<span style="color: #000000;">balls</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- eg {".....",".g...","....."}, same size as board </span>
<span style="color: #000000;">drop</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> <span style="color: #000080;font-style:italic;">-- the allowed set of balls (sum(g)&lt;=sum(G) etc)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">w</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">h</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ball</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">North</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">amaze</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"RGYB"</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)]</span>
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span> <span style="color: #000080;font-style:italic;">-- give cell a colour / mark visited</span>
<span style="color: #000000;">drop</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">lower</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">shuffle</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}})</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">nx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ny</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">nx</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">nx</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">w</span>
<span style="color: #008080;">and</span> <span style="color: #000000;">ny</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">ny</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">h</span>
<span style="color: #008080;">and</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ny</span><span style="color: #0000FF;">][</span><span style="color: #000000;">nx</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'?'</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">mx</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">nx</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span>
<span style="color: #000000;">board</span><span style="color: #0000FF;">[(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">ny</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">][</span><span style="color: #000000;">mx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">' '</span> <span style="color: #000080;font-style:italic;">-- knock down wall</span>
<span style="color: #000000;">amaze</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ny</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">drop</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">shuffle</span><span style="color: #0000FF;">(</span><span style="color: #000000;">drop</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">balls</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ny</span><span style="color: #0000FF;">][</span><span style="color: #000000;">nx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">drop</span><span style="color: #0000FF;">[$]</span> <span style="color: #000080;font-style:italic;">-- (all bar start cell)</span>
<span style="color: #000000;">drop</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">drop</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">create_world</span><span style="color: #0000FF;">()</span>
<span style="color: #000080;font-style:italic;">-- (The distro version has several other tests/examples)</span>
<span style="color: #000000;">w</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">11</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">h</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)+(</span><span style="color: #000000;">w</span><span style="color: #0000FF;">==</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (prohibit 1x1 formations, simply because
-- the gameover check won't trigger right.)</span>
<span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">w</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">2</span>
<span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">h</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">2</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">wall</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"+"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">w</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"-"</span><span style="color: #0000FF;">)&</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">cell</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"|"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">w</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"?"</span><span style="color: #0000FF;">)&</span><span style="color: #008000;">"\n"</span>
<span style="color: #000000;">board</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">wall</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span><span style="color: #000000;">cell</span><span style="color: #0000FF;">),</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">balls</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">w</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span><span style="color: #000000;">h</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">amaze</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">gameover</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">balls</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">by</span> <span style="color: #000000;">2</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">balls</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">by</span> <span style="color: #000000;">2</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">byx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">balls</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">byx</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">byx</span><span style="color: #0000FF;">!=</span><span style="color: #7060A8;">lower</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">event_queue</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"A"</span> <span style="color: #000080;font-style:italic;">-- (the initial handshake) [this is a private field]</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">accept_command</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">command</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">switch</span> <span style="color: #000000;">command</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'^'</span><span style="color: #0000FF;">:</span> <span style="color: #000080;font-style:italic;">-- forward</span>
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dy</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dxy</span><span style="color: #0000FF;">[</span><span style="color: #000000;">d</span><span style="color: #0000FF;">],</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">nx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ny</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dy</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ny</span><span style="color: #0000FF;">][</span><span style="color: #000000;">nx</span><span style="color: #0000FF;">]!=</span><span style="color: #008000;">' '</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">event_queue</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'!'</span> <span style="color: #000080;font-style:italic;">-- bump</span>
<span style="color: #008080;">else</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">nx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ny</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dy</span><span style="color: #0000FF;">}</span>
<span style="color: #000000;">event_queue</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #000080;font-style:italic;">-- colour</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">bxy</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">balls</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">bxy</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">event_queue</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">bxy</span> <span style="color: #000080;font-style:italic;">-- ball</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'&lt;'</span><span style="color: #0000FF;">:</span> <span style="color: #000080;font-style:italic;">-- turn left -- NESW(ie 1..4) ==&gt; first four for '&lt;', </span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'&gt;'</span><span style="color: #0000FF;">:</span> <span style="color: #000080;font-style:italic;">-- turn right last four for '&gt;':</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}[</span><span style="color: #000000;">d</span><span style="color: #0000FF;">+</span><span style="color: #000000;">command</span><span style="color: #0000FF;">-</span><span style="color: #008000;">'&lt;'</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'@'</span><span style="color: #0000FF;">:</span> <span style="color: #000080;font-style:italic;">-- get</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">bxy</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">balls</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">bxy</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">event_queue</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'s'</span> <span style="color: #000080;font-style:italic;">-- no ball</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">ball</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">event_queue</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'A'</span> <span style="color: #000080;font-style:italic;">-- agent full</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">balls</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'.'</span>
<span style="color: #000000;">ball</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bxy</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'!'</span><span style="color: #0000FF;">:</span> <span style="color: #000080;font-style:italic;">-- drop</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">bxy</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">balls</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ball</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">event_queue</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'a'</span> <span style="color: #000080;font-style:italic;">-- no ball in agent</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">bxy</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">event_queue</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'S'</span> <span style="color: #000080;font-style:italic;">-- sector full</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">balls</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ball</span>
<span style="color: #000000;">ball</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'.'</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">gameover</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">event_queue</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'+'</span> <span style="color: #000080;font-style:italic;">-- game over</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">default</span><span style="color: #0000FF;">:</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"uh?"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- unknown command</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #000000;">event_queue</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'.'</span> <span style="color: #000080;font-style:italic;">-- stop</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">get_event</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">event_queue</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">integer</span> <span style="color: #000000;">event</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">event_queue</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">event_queue</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">event_queue</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$]}</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">event</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">get_world</span><span style="color: #0000FF;">()</span>
<span style="color: #000080;font-style:italic;">-- (for display only)</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,</span><span style="color: #000000;">balls</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ball</span><span style="color: #0000FF;">}}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #000000;">create_world</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">register_world</span><span style="color: #0000FF;">(</span><span style="color: #000000;">accept_command</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">get_event</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">get_world</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
Of course this is half on one screen and half on another for non-direct (ie the ipc) version.<br>
Note the code that actually displays this is in the [[Remote_agent/Agent_interface#Phix|Agent Interface]], rather than in the above.
<pre>
world -- x: 2, y: 6, ball:., d:3 server handshake recieved
+-+-+-+-+-+-+-+-+ ................. agent handshake recieved
|Y B|Y B|G R|B B| .y.b.y.b.g.r.b.b.
+ + + + + + + +-+ .................
|B|R|B|Y Y|G|B|G| .b.r.b.y.y.g.b.g. game over
+ + + +-+-+ + + + .................
|B|Y R G B|G G Y| .b.y.r...b.g.g.y.
+-+-+-+-+-+-+-+-+ .v...............
 
(after . accepted by agent)
 
agent -- x: 2, y: 6, ball:., d:3
+-+-+-+-+-+-+-+-+ .................
|Y B|Y B|G R|B B| .y.b.y.b.g.r.b.b.
+ + + + + + + +-+ .................
|B|R|B|Y Y|G|B|G| .b.r.b.y.y.g.b.g.
+ + + +-+-+ + + + .................
|B|Y R G B|G G Y| .b.y.r...b.g.g.y.
+-+-+-+-+-+-+-+-+ .v...............
</pre>
<small>(The little v indicates it was heading down, as does d=3, in lower left corner, as do x and y)</small>
 
=={{header|PicoLisp}}==
This is the server. For the client, see [[Remote agent/Agent logic#PicoLisp]].
After starting (gameServer), you might for testing purposes also connect with 'telnet', type the commands, and see the responses.
<langsyntaxhighlight PicoLisplang="picolisp"># Global variables:
# '*Port' is the port where the server is listening
# '*Sock' is the TCP socket after a client connected
Line 430 ⟶ 726:
(if (== *Agent This) "*" " ")
(: field)
(if (: ball) (lowc @) " ") ) ) ) )</langsyntaxhighlight>
An online demo version of this server runs on port 54545 of "picolisp.com". It can be used for testing.
 
For local tests, you can start also it interactively:
Line 454 ⟶ 749:
a b c d e f g h</pre>
This displays the field colors in upper case letters, the balls in lower case letters, and the position of the agent with an asterisk.
 
=={{header|Run BASIC}}==
{{incorrect|Run BASIC|It does not seem to connect to the network, and it looks to be missing other basic elements from the task.}}
<lang runbasic>dim stats(10)
[loop]
cls
html "Please click a number or "
button #ex,"Exit",[exit]
print
for i = 1 to 10
val.i$ = "#val";i
link #val.i$ ,str$(i),[click]
html " Clicked:";stats(i);" times<br>"
next i
wait
 
[click]
num = val(mid$(EventKey$,5))
stats(num) = stats(num) + 1
goto [loop]
 
[exit]
Print "Thanks for playing... BYE!"</lang>
Client side sees stats of number of times each number is clicked
<pre>Please click a number or [Exit]
1 Clicked:1 times
2 Clicked:2 times
3 Clicked:3 times
4 Clicked:4 times
5 Clicked:0 times
6 Clicked:0 times
7 Clicked:0 times
8 Clicked:0 times
9 Clicked:1 times
10 Clicked:2 times
Thanks for playing... BYE!</pre>
 
=={{header|Tcl}}==
{{libheader|TclOO}}
<langsyntaxhighlight lang="tcl">package require TclOO
 
# Utility: pick random item of list
Line 725 ⟶ 984:
# Make the server and run the event loop
BallMaze server $port $width $height {*}$argv
vwait forever</langsyntaxhighlight>
Example call (with the server restricted to only serving on 127.0.0.1):
<pre>tclsh8.5 agent.world.tcl 54545 8 8 -myaddr localhost</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-str}}
{{libheader|Wren-fmt}}
{{libheader|Wren-seq}}
<syntaxhighlight lang="wren">/* world.wren */
 
import "./ifc" for Ifc, Log
import "./str" for Char
import "./fmt" for Fmt
import "./seq" for Lst
 
// Maze sectors are 3x3 characters, with these quirks:
// String starts with a newline.
// Space at end of each line except the last.
// No space, newline, or blank lines following last W.
//
// In each sector, W or sector Color is mandatory. If sector has ball,
// it is in the character to the right. If agent is in a sector, it is in
// the character below and shown by its direction symbol. If agent has a ball,
// it is in the character to the right.
//
// The variable maze is not just input, but is the primary representation
// of the world. Over the course of execution, walls and sector colors
// are constant; agent and balls can move.
var maze = """
 
WWWWWWWWWWWWWWWW
W W W
W W W
W Rb W Rg B W
W W
W W
W G G B G W
W W
W W
W Br G W R W
W W ^ W
W W W
WWWWWWWWWWWWWWWW
""".toList
 
var stream = null
var rowLen = 0
var agentPos = -1
 
var dirString = "^>v<"
var directions = dirString.toList
 
var rightOf = Fn.new { |dir| directions[(dirString.indexOf(dir) + 1) % 4] }
var leftOf = Fn.new { |dir| directions[(dirString.indexOf(dir) + 3) % 4] }
 
var right = Fn.new { maze[agentPos] = rightOf.call(maze[agentPos]) }
var left = Fn.new { maze[agentPos] = leftOf.call(maze[agentPos]) }
 
var get = Fn.new {
var agentBall = agentPos + 1
var sectorBall = agentBall - rowLen
var can = true
if (maze[sectorBall] == " ") {
stream.send(Ifc.evNoBallInSector)
can = false
Fiber.yield()
}
if (maze[agentBall] != " ") {
stream.send(Ifc.evAgentFull)
can = false
Fiber.yield()
}
if (can) {
maze[agentBall] = maze[sectorBall]
maze[sectorBall] = " "
}
}
 
// Win tests for a win state indicating game over.
var win = Fn.new {
var ballPos = 2
while (ballPos < maze.count) {
var ballColor = maze[ballPos]
if ([Ifc.evBallRed, Ifc.evBallGreen, Ifc.evBallYellow, Ifc.evBallBlue].contains(ballColor)) {
if (ballColor != Char.lower(maze[ballPos-1])) return false
}
ballPos = ballPos + 3
if (ballPos % rowLen == 1) ballPos = ballPos + 2 * rowLen
}
return true
}
 
var drop = Fn.new {
var agentBall = agentPos + 1
var sectorBall = agentBall - rowLen
var can = true
if (maze[agentBall] == " ") {
stream.send(Ifc.evNoBallInAgent)
can = false
Fiber.yield()
}
if (maze[sectorBall] != " ") {
stream.send(Ifc.evSectorFull)
can = false
Fiber.yield()
}
if (can) {
maze[sectorBall] = maze[agentBall]
maze[agentBall] = " "
}
if (win.call()) {
stream.send(Ifc.evGameOver)
Fiber.yield()
return true
}
return false
}
 
var logTime = Fn.new { |t| Log.prefix = t }
 
var forward = Fn.new {
var sectorOrigin = agentPos - rowLen
var ch = maze[agentPos]
sectorOrigin = (ch == "^") ? sectorOrigin - 3 * rowLen :
(ch == "v") ? sectorOrigin + 3 * rowLen :
(ch == "<") ? sectorOrigin - 3 :
(ch == ">") ? sectorOrigin + 3 : sectorOrigin
if (maze[sectorOrigin] == "W") {
stream.send(Ifc.evBump)
Fiber.yield()
// bump event consumes no time
return 0
}
 
// move agent, plus any ball it has.
var newPos = sectorOrigin + rowLen
maze[newPos] = maze[agentPos]
maze[newPos+1] = maze[agentPos+1]
maze[agentPos] = " "
maze[agentPos+1] = " "
agentPos = newPos
 
// send color event for new sector
stream.send(maze[sectorOrigin])
Fiber.yield()
var ball = maze[sectorOrigin+1]
if (ball != " ") {
// send ball event
stream.send(maze[sectorOrigin+1])
Fiber.yield()
}
// for all events except bump, time consumed is 1.
return 1
}
 
// Process a single command.
var process = Fn.new { |cmd|
// timeConsumed is 1, unless the forward function says otherwise.
var gameOver = false
var timeConsumed = 1
if (cmd == Ifc.cmdForward) {
timeConsumed = forward.call()
} else if (cmd == Ifc.cmdRight) {
right.call()
} else if (cmd == Ifc.cmdLeft) {
left.call()
} else if (cmd == Ifc.cmdGet) {
get.call()
} else if (cmd == Ifc.cmdDrop) {
// game over only detected by drop command
gameOver = drop.call()
}
// for all commands, send stop event after all other processing is complete
stream.send(Ifc.evStop)
Fiber.yield()
return [gameOver, timeConsumed]
}
 
var World = Fn.new { |s|
stream = s
rowLen = maze[1..-1].indexOf("\n") + 1
var cols = (rowLen/3).floor
var rows = ((((maze.count + 1)/rowLen).floor + 2)/3).floor
if (maze.count != (rows*3 - 2) * cols * 3 - 1) Log.fatal("mis-shaped maze")
agentPos = Lst.indexOfAny(maze, directions)
if (agentPos == -1) Log.fatal("agent not in maze")
 
// initialize quantized time as specified
var time = 0
logTime.call(time)
 
// handshake as specified
stream.send(Ifc.handshake)
Fiber.yield()
var hs = stream.rec()
if (hs != Ifc.handshake) Log.fatal("world: that's no handshake.")
 
// log initial configuration of maze
Log.print(maze.join())
 
// top level world simulation loop
var gameOver = false
var timeConsumed = 0
while (!gameOver) {
Fiber.yield()
var res = process.call(stream.rec())
gameOver = res[0]
timeConsumed = res[1]
time = time + timeConsumed
logTime.call(time)
Log.print(maze.join())
}
}</syntaxhighlight>
<br>
Finally, we need a 'driver' script to run the various 'remote agent' modules (world, agent and ifc) as a whole assuming they've all been placed in the same directory.
 
The following supplies a concrete implementation of the Ifc abstract class. I've used queues and fibers in place of channels and goroutines respectively to run a simulation in a single process. The Agent and World functions run on separate fibers, yielding to each other at appropriate times, until the game is over.
 
To run a simulation between two processes (on the same or different machines) would require an embedded script though the interface should be the same.
 
{{libheader|Wren-queue}}
<syntaxhighlight lang="wren">/* Remote_agent_driver.wren */
 
import "./ifc" for Streamer, Ifc, Log
import "./agent" for Agent
import "./world" for World
import "./queue" for Queue
 
// Concrete implementation of Streamer abstract class.
class QueueStreamer is Streamer {
construct new(name, qin, qout) {
_name = name
_qin = qin
_qout = qout
}
 
send(ch) {
Log.print("%(_name) sends %(Ifc.text[ch])")
_qout.push(ch)
}
 
rec() {
var ch = _qin.pop()
if (ch) Log.print("%(_name) receives %(Ifc.text[ch])")
return ch
}
}
 
var cmd = Queue.new()
var ev = Queue.new()
 
var aqs = QueueStreamer.new("agent", ev, cmd)
var wqs = QueueStreamer.new("world", cmd, ev)
 
var af = Fiber.new(Agent)
var wf = Fiber.new(World)
 
wf.call(wqs)
 
while(!wf.isDone) {
af.call(aqs)
wf.call(wqs)
}</syntaxhighlight>
 
{{out}}
Sample game (abridged):
<pre>
...
000169: world receives command forward
000169: world sends event color red
000169: agent receives event color red
000169: world sends event stop
000169: agent receives event stop
000169: agent sends command drop
000170:
WWWWWWWWWWWWWWWW
W W W
W W W
W R W R B W
W ^r W
W W
W G G Bb Gg W
W W
W W
W B G W R W
W W W
W W W
WWWWWWWWWWWWWWWW
000170: world receives command drop
000170: world sends event game over
000170: agent receives event game over
000170: world sends event stop
000170: agent receives event stop
000171:
WWWWWWWWWWWWWWWW
W W W
W W W
W Rr W R B W
W ^ W
W W
W G G Bb Gg W
W W
W W
W B G W R W
W W W
W W W
WWWWWWWWWWWWWWWW
</pre>
9,476

edits