Remote agent/Simulation: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added PicoLisp)
(Simplified: Binary I/O not necessary)
Line 2: Line 2:


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
Here is my first attempt on the server part. It works, you can connect with 'telnet' and type the commands.
Here is my first attempt on the server part. It works, you can connect with 'telnet', type the commands, and see the responses.
<lang PicoLisp>(load "@lib/simul.l")
<lang PicoLisp>(load "@lib/simul.l")


Line 59: Line 59:
(seed *Pid) # Ensure private random sequence
(seed *Pid) # Ensure private random sequence
(in *Sock
(in *Sock
(out *Sock (wr `(char "A"))) # Greeting
(out *Sock (prin "A")) # Greeting
(when (= `(char "A") (rd 1))
(when (= "A" (char))
(newGame 12 9 10)
(newGame 12 9 10)
(while (rd 1)
(while (char)
(out *Sock
(out *Sock
(case @ # Command character
(case @ # Command character
(`(char "F") # Forward
("F" # Forward
(ifn ((car *Dir) *Agent) # Hit wall?
(ifn ((car *Dir) *Agent) # Hit wall?
(wr `(char "|")) # Bump event
(prin "|") # Yes: Bump event
(with (setq *Agent @) # Else go to new position
(with (setq *Agent @) # Else go to new position
(wr (char (: field)))
(prin (: field))
(and (: ball) (wr (char (lowc @)))) ) ) )
(and (: ball) (prin (lowc @))) ) ) )
(`(char ">") # Turn right
(">" # Turn right
(pop '*Dir) )
(pop '*Dir) )
(`(char "<") # Turn left
("<" # Turn left
(do 3 (pop '*Dir)) )
(do 3 (pop '*Dir)) )
(`(char "@") # Get ball
("@" # Get ball
(cond
(with *Agent
((not (: ball)) (wr `(char "s"))) # No ball in sector
(cond
(*Ball (wr `(char "A"))) # Agent full
((not (: ball)) (prin "s")) # No ball in sector
(T (setq *Ball (: ball))) ) )
(*Ball (prin "A")) # Agent full
(`(char "!") # Drop ball
(T (setq *Ball (: ball))) ) ) )
(cond
("!" # Drop ball
((not *Ball) (wr `(char "a"))) # No ball in agent
(with *Agent
((: ball) (wr `(char "S"))) # Sector full
(cond
((ending?) (wr `(char "+"))) ) ) ) # Game over
((not *Ball) (prin "a")) # No ball in agent
(wr `(char ".")) ) ) ) ) # Stop event
((: ball) (prin "S")) # Sector full
((ending?) (prin "+")) # Game over
(bye) )
(T (=: ball *Ball) (off *Ball)) ) ) ) )

(prin ".") ) ) ) ) # Stop event

(bye) )</lang>
# Visualize (debug)
(de showWorld (Balls)
(disp *World 0
'((This)
(pack " " (if Balls (or (: ball) " ") (: field)) " ") ) ) )</lang>

Revision as of 17:20, 16 December 2010

Remote agent/Simulation is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

As described in Remote agent, generate a map, accept and respond to commands from an agent using an unbuffered stream.

PicoLisp

Here is my first attempt on the server part. It works, you can connect with 'telnet', type the commands, and see the responses. <lang PicoLisp>(load "@lib/simul.l")

  1. Global variables:
  2. '*Port' is the port where the server is listening
  3. '*Sock' is the TCP socket after a client connected
  4. '*World' holds the current world
  5. '*Agent' is the field where the agent is in
  6. '*Ball' is the ball the agent is holding
  7. '*Dir' is a circular list of directions (north east south west .)
  1. The server port

(setq *Port (port 6789))

  1. Return a random Field

(de randomField ()

  (get *World (rand 1 DX) (rand 1 DY)) )
  1. Create a world of size 'DX' * 'DY' with 'Percent' balls in it

(de makeWorld (DX DY Percent)

  (for Column (setq *World (grid DX DY))
     (for This Column
        (let Color (get '(R G Y B) (rand 1 4))
           (=: field Color)
           (when (>= Percent (rand 1 100))
              (until
                 (with (randomField DX DY)
                    (unless (=: ball)
                       (=: ball Color) ) ) ) ) ) ) ) )
  1. Test for ending condition

(de ending? ()

  (nor
     *Ball
     (find
        '((Column)
           (find
              '((This)
                 (and (: ball) (n== (: field) (: ball))) )
              Column ) )
        *World ) ) )
  1. Initialize for a new game

(de newGame (DX DY Percent)

  (makeWorld DX DY Percent)
  (setq
     *Agent (randomField DX DY)
     *Dir (do (rand 1 4) (rot '(north east south west .))) ) )
  1. Start the game server

(de gameServer ()

  (loop
     (setq *Sock (listen *Port))
     (NIL (fork) (close *Port))
     (close *Sock) )
  (seed *Pid)  # Ensure private random sequence
  (in *Sock
     (out *Sock (prin "A"))  # Greeting
     (when (= "A" (char))
        (newGame 12 9 10)
        (while (char)
           (out *Sock
              (case @  # Command character
                 ("F"  # Forward
                    (ifn ((car *Dir) *Agent)  # Hit wall?
                       (prin "|")             # Yes: Bump event
                       (with (setq *Agent @)  # Else go to new position
                          (prin (: field))
                          (and (: ball) (prin (lowc @))) ) ) )
                 (">"  # Turn right
                    (pop '*Dir) )
                 ("<"  # Turn left
                    (do 3 (pop '*Dir)) )
                 ("@"  # Get ball
                    (with *Agent
                       (cond
                          ((not (: ball)) (prin "s"))  # No ball in sector
                          (*Ball (prin "A"))           # Agent full
                          (T (setq *Ball (: ball))) ) ) )
                 ("!"  # Drop ball
                    (with *Agent
                       (cond
                          ((not *Ball) (prin "a"))  # No ball in agent
                          ((: ball) (prin "S"))     # Sector full
                          ((ending?) (prin "+"))    # Game over
                          (T (=: ball *Ball) (off *Ball)) ) ) ) )
              (prin ".") ) ) ) )  # Stop event
  (bye) )</lang>