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