Brian Blais wrote:
On Feb 13, 2010, at 12:54 , MRAB wrote:

Brian Blais wrote:
I've been thinking about implementing some simple games

Forget about global variables, they're not worth it! :-)

Think in terms of messages, sent via pipes, sockets or multiprocessing
queues.


okay...let's make this concrete. given your ideas, I have it working for the first type of agent, namely one that is called like:

move=agent(board,player)

For a specific example, I'm using the simplest version of a game called Nim. You start with a number of sticks, players take turns taking 1, 2, or 3 sticks, and you lose if you take the last stick. Two agents for this are:

# agent1.py - simple take 1 agent
def agent(board,player):
return 1 # agent2.py - perfect player
def agent(board,player):
    move=(board-1)%4
    if move==0:
        return 1
    else:
        return move
I run my simulator like (complete code below):

s=Sim('agent1','agent2')
winner=s.run()

and it spawns two processes, passes messages between the sim and the agents, and closes the agents nicely when the game is over. I'm not sure how I catch errors in the agents, especially accidental infinite loops.

Now the second type of agent is structured differently. I'd like something like:

# agent3.py - simple take 1 agent
def agent(state):
while True:
        Take(1)

# agent4.py - perfect player
def agent(state):

    N=state['board']  # get the current information
    while True:
move=(N-1)%4 if move==0:
            Take(1)
        else:
            Take(move)
I tried to implement this in the second wrapper below, but I can't get the agent function to "see" local functions in the wrapper. I probably need an import somewhere, but I haven't quite figured out the scoping with multiprocessing, etc...

I include the code below. The two message-passing wrappers are there, and it works for the first two agents, but not the second two because of scoping issues.

Is there a better way to be doing this? Are there other examples like this that I can look at to improve what I am doing?

[snip]
I would try to have more separation between the agents and the
simulator.

The simulator would start the agents, something like this:

    def run_agent(agent_name, connection):
        agent_module = __import__(agent_name)
        agent_module.run(agent_name, connection)

...

    for agent_name in self.agent_files:
        parent, child = Pipe()
        connections.append(parent)
        proc = Process(target=run_agent, args=(agent_name, child))
        processes.append(proc)

The logic for an agent would be in its own module:

agent1.py
---------

    def get_move(board, player):
        return 1

    def run(agent_name, connection):
        end = False
        while not end:
            state = connection.recv()
            if state['done']:
                break

            move = get_move(state['board'], state['player'])

            connection.send(move)

        print "%s done" % agent_name

        connection.close()

If I wanted the agents to share some logic (functions) then I would put
it (them) in a common module which the agents would import.
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to