Remote agent/Simulation

From Rosetta Code
Revision as of 17:20, 16 December 2010 by rosettacode>Abu (Simplified: Binary I/O not necessary)
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>