Brian Blais wrote:
Hello,
I've been thinking about implementing some simple games, where one can
program agents to play the game. I thought that the multiprocessing
module would be perfect for it, organized with a main simulator engine
spawning processes for each agent. However, I am having trouble
wrapping my head around the organization of the code. I haven't found a
lot of examples of using multiprocessing, and no game implementations.
There are two types of games that I would like to implement. In both
cases, I'd like to be able to run something like:
results=Sim.run('agent1.py','agent2.py')
where the Sim object is initialized before with the board size,
placement of pieces, etc... The files agent1.py and agent2.py would
have the code to run the agent. The two types of games are different in
terms of the organization of the agent code. In the first, which I
think should be more straightforward, there will be one function defined
in the file with syntax like:
def agent(board,my_player_number):
# stuff here for the agent
return move
Think "tic-tac-toe" here. The simulator would have to spawn processes,
which load these files and handle the communication to the main
simulator. The main simulator would loop through the agents, get moves,
and then update the board with these moves. In the case of tic-tac-toe,
then each agent is called in serial, and the update after each move. In
the case of something like Civilization or Tron, the moves are all
collected and then the board is updated.
The other type of game, which would work like Tron or Civilization, the
agent file would not contain a function but a list of commands, like:
North()
North()
if Neighbor['North']:
East()
# etc...
I am not sure what the best way to organize the code, in either case,
for the main simulator or the best way to use multiprocessing here. I
thought that maybe Pipe would be the best choice, and for each move
there would be a send() and recv() between each agent and the main
simulator, where the agent would receive updated information after each
move. What happens if an agent has an infinite loop (ignores a signal
from the simulator that it has lost)? Can the simulator catch this, and
kill the process? Does that happen if either side closes the pipe? Is
there an obvious way to structure this sort of game engine? Is there an
implementation already out there that I am reinventing? What
information would be best to send to the agent? I was finding myself
using more global variables than I was comfortable, so I figured I was
thinking about this incorrectly.
Any help would be great! Pointers to other examples of using
multiprocessing, especially with games, would be fantastic.
Forget about global variables, they're not worth it! :-)
Think in terms of messages, sent via pipes, sockets or multiprocessing
queues.
In a game like "tic-tac-toe" (also known as "noughts and crosses", BTW),
the sim sends a message to an agent requesting a move ("what's your
move"). The agent can send requests for the state of the board ("what's
at position (x, y)?") and get replies ("it's a X"/"it's a O"/"it's
empty"), but at some point it must send the sim its move ("put a piece
at (x, y)") and the sim can say whether it's valid ("OK"/"bad move").
If the agent takes too long then the sim sends just tells the agent that
it took too long and should quit ("quit").
--
http://mail.python.org/mailman/listinfo/python-list