Remote agent/Agent logic: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
(Added Wren)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(2 intermediate revisions by 2 users not shown)
Line 9:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package agent
 
import (
Line 175:
agentBall = noColor
return
}</langsyntaxhighlight>
 
 
Line 188:
mismatches second. Empty sectors are shown in blue, sectors with a matching ball are shown in green, and
sectors with a mismatching ball are shown in red.
<langsyntaxhighlight lang="perl">#!/usr/bin/perl
 
use strict; # https://rosettacode.org/wiki/Remote_agent
Line 410:
(time - $start) / $turns * 1e6;
 
</syntaxhighlight>
</lang>
 
=={{header|Phix}}==
<!--<langsyntaxhighlight Phixlang="phix">(noonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\Remote_Agent_Agent_Logic.exw
Line 679:
<span style="color: #000000;">register_agent</span><span style="color: #0000FF;">(</span><span style="color: #000000;">get_command</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">accept_event</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">get_agent</span><span style="color: #0000FF;">)</span>
<!--</langsyntaxhighlight>-->
For example output see [[Remote_agent/Simulation#Phix]]
 
Line 688:
Sample agent (''not'' a good or smart player of the game; just to show how to program to the interface).
{{works with|Tcl|8.6}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
package require RC::RemoteAgent
 
Line 744:
 
Agent new "localhost" 12345
vwait wonGame</langsyntaxhighlight>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-fmtstr}}
<syntaxhighlight lang="wren">/* agent.wren */
Unlike the Go entry, I've placed the 'human readable text' code inside the 'ifc' module and have also placed a basic logging facility in there too as its called by both the 'world' and 'agent' modules. It always prints to stdout.
 
import "random" for Random
The 'driver code' has been moved to the [[Remote_agent/Simulation]] task.
import "./ifc" for Ifc, Log
<lang ecmascript>/* ifc.wren */
import "./str" for Char
 
// The agent's awareness is quite limited. It has no representation of the
import "./fmt" for Fmt
// maze, which direction it is facing, or what it did last. It notices and
// remembers just three things: The color of the sector just entered, the
// presence and color of any ball there, and the presence and color of any
// ball it is holding.
var sectorColor = " "
var sectorBall = " "
var agentBall = " "
var stream = null
var noColor = "-"
 
var rand = Random.new()
// The Streamer abstract class defines how agent and world talk to each other.
 
// If implemented in Wren, send and rec will be synchronous blocking operations.
// Move moves one sector in a random direction.
class Streamer {
// It retries on bumps and doesn't return until a forward command succeeds.
send(ch) {}
// It expects a color event on a successful move and terminates if it doesn't
rec() {}
// get one.
var move = Fn.new {
while (true) {
// Randomness: 50/50 chance of turning or attempting move.
// For turns, equal chance of turning right or left.
var t = rand.int(4)
if (t == 0) {
stream.send(Ifc.cmdLeft)
Fiber.yield()
while (stream.rec() != Ifc.evStop) { Fiber.yield() }
continue
} else if (t == 1) {
stream.send(Ifc.cmdRight)
Fiber.yield()
while (stream.rec() != Ifc.evStop) { Fiber.yield() }
continue
}
stream.send(Ifc.cmdForward)
var bump = false
sectorColor = noColor
sectorBall = noColor
while (true) {
Fiber.yield()
var ev = stream.rec()
if (ev == Ifc.evBump) {
bump = true
} else if ([Ifc.evColorRed, Ifc.evColorGreen, Ifc.evColorYellow, Ifc.evColorBlue].contains(ev)) {
sectorColor = ev
} else if ([Ifc.evBallRed, Ifc.evBallGreen, Ifc.evBallYellow, Ifc.evBallBlue].contains(ev)) {
sectorBall = ev
} else if (ev == Ifc.evStop) {
break
}
}
if (bump) continue
if (sectorColor == noColor) Log.fatal("agent: expected color event after move")
return
}
}
 
// Get is only called when get is possible.
// The agent and world send and receive single characters, out of the set of
var get = Fn.new {
// constants defined here.
stream.send(Ifc.cmdGet)
class Ifc {
while (true) {
static handshake { "H" }
static cmdForward { "^" }Fiber.yield()
static cmdRight var ch = { ">" }stream.rec()
static cmdLeft if (ch == Ifc.evStop) { "<" }
static cmdGet // agent notes ball {color, "@"and }that sector is now empty
static cmdDrop agentBall = { "!" }sectorBall
static evGameOver {sectorBall "+"= }noColor
static evStop { "." }return
} else if (ch == Ifc.evNoBallInSector || ch == Ifc.evAgentFull) {
static evColorRed { "R" }
Log.fatal("agent:expected get to succeed")
static evColorGreen { "G" }
static evColorYellow { "Y" }
static evColorBlue { "B" }
static evBallRed { "r" }
static evBallGreen { "g" }
static evBallYellow { "y" }
static evBallBlue { "b" }
static evBump { "|" }
static evSectorFull { "S" }
static evAgentFull { "A" }
static evNoBallInSector { "s" }
static evNoBallInAgent { "a" }
 
// Human readable text for the above commands and events.
static init_() {
__hrText = {
handshake : "handshake",
cmdForward : "command forward",
cmdRight : "command turn right",
cmdLeft : "command turn left",
cmdGet : "command get",
cmdDrop : "command drop",
evGameOver : "event game over",
evStop : "event stop",
evColorRed : "event color red",
evColorGreen : "event color green",
evColorYellow : "event color yellow",
evColorBlue : "event color blue",
evBallRed : "event ball red",
evBallGreen : "event ball green",
evBallYellow : "event ball yellow",
evBallBlue : "event ball blue",
evBump : "event bump",
evSectorFull : "event sector full",
evAgentFull : "event agent full",
evNoBallInSector : "event no ball in sector",
evNoBallInAgent : "event no ball in agent"
}
}
}
 
// FindMatching is only called when agent has a ball.
static text { __hrText }
// FindMatching finds a sector where the color matches the ball the agent
// is holding and which does not already contain a matching ball.
// It does not necessarily find an empty matching sector.
var findMatching = Fn.new {
while (Char.lower(sectorColor) != agentBall || agentBall == sectorBall) move.call()
}
 
// FindMisplaced wanders the maze looking for a ball on the wrong sector.
class Log {
var findMisplaced = Fn.new {
static prefix=(p) { __prefix = Fmt.swrite("$06d: ", p) }
while (true) {
move.call()
 
// get ball from current sector if meaningful
static print(s) { System.print(__prefix + s) }
if ([Ifc.evBallRed, Ifc.evBallGreen, Ifc.evBallYellow, Ifc.evBallBlue].contains(sectorBall)) {
if (sectorBall != Char.lower(sectorColor)) return
}
}
}
 
// Drop is only called when the agent has a ball. Unlike get() however,
static fatal(s) { Fiber.abort(s) }
// drop() can be called whether the sector is empty or not. drop() means
// drop as soon as possible, so if the sector is full, drop() will wander
// at random looking for an empty sector.
var drop = Fn.new {
var gameOver = false
while (sectorBall != noColor) move.call()
 
// expected to work
stream.send(Ifc.cmdDrop)
while(true) {
Fiber.yield()
var ch = stream.rec()
if (ch == Ifc.evGameOver) {
gameOver = true
} else if (ch == Ifc.evStop) {
break
} else if (ch == Ifc.evNoBallInAgent || ch == Ifc.evSectorFull) {
Log.fatal("expected drop to succeed")
}
}
sectorBall = agentBall
agentBall = noColor
return gameOver
}
 
var Agent = Fn.new { |s|
Ifc.init_()</lang>
stream = s
 
// handshake
var hs = stream.rec()
if (hs != Ifc.handshake) Log.fatal("agent: that's no handshake")
stream.send(Ifc.handshake)
Fiber.yield()
 
// agent behavior main loop
var gameOver = false
while (!gameOver) {
findMisplaced.call()
get.call()
findMatching.call()
gameOver = drop.call()
}
}</syntaxhighlight>
9,485

edits