Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@niklasf
Created July 9, 2014 16:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niklasf/03bc286211c3a7f87383 to your computer and use it in GitHub Desktop.
Save niklasf/03bc286211c3a7f87383 to your computer and use it in GitHub Desktop.
#!/usr/bin/python2
import random
import math
# Model
# =====
class TicTacToeGrid(object):
def __init__(self):
# The world - namely the tic-tac-toe grid - has 9 cells,
# each of which can be either " ", "X" or "O".
self.cells = [" ", " ", " ",
" ", " ", " ",
" ", " ", " "]
def __str__(self):
return (" " + self.cells[0] + " | " + self.cells[1] + " | " + self.cells[2] + "\n" +
"---|---|---\n" +
" " + self.cells[3] + " | " + self.cells[4] + " | " + self.cells[5] + "\n" +
"---|---|---\n" +
" " + self.cells[6] + " | " + self.cells[7] + " | " + self.cells[8])
def tick(self):
# The world does not do anything by itself.
pass
def sync(self, grids):
# When merging different grids, the one with the least empty cells
# is the right one.
self.cells = min(grids, key=lambda grid: grid.cells.count(" ")).cells
class AgentX(object):
def tick(self):
# Is it my turn?
if grid.cells.count("X") <= grid.cells.count("O"):
# Select a cell and mark if empty.
cell = random.randint(0, 8)
if grid.cells[cell] == " ":
grid.cells[cell] = "X"
class AgentO(object):
def tick(self):
# Is it my turn?
if grid.cells.count("O") < grid.cells.count("X"):
# Select a cell and mark if empty.
cell = random.randint(0, 8)
if grid.cells[cell] == " ":
grid.cells[cell] = "O"
# Initialisation: Create the objects.
grid = TicTacToeGrid()
agentx = AgentX()
agento = AgentO()
sync_objects = [ grid ]
non_sync_objects = [ agentx, agento ]
# Simulation
# ==========
from mpi4py import MPI
core_id = MPI.COMM_WORLD.Get_rank()
cores = MPI.COMM_WORLD.Get_size()
# Randomly group non-synchronized objects like [o1, o2, ...] for example as
# [[o4, o3], [o1, o2], ...] to scatter across cores.
random.shuffle(non_sync_objects)
objects_per_core = int(math.ceil(float(len(non_sync_objects)) / cores))
groups = [non_sync_objects[i:i+objects_per_core] for i in range(0, len(non_sync_objects), objects_per_core)]
# Fix luxury problem: If more cores than objects, some empty groups are needed.
while len(groups) < cores:
groups += [[]]
local_non_sync_objects = MPI.COMM_WORLD.scatter(groups)
# Simulate a few ticks.
for tick in xrange(0, 10):
# Debug output (only on core 0 to avoid mixed outputs).
if core_id == 0:
print "Tick: %s" % (tick, )
print grid
print "----------------------------------------------------"
# Go through all synchronized objects.
for instance in sync_objects:
# Gather all instances from the other cores.
instances = MPI.COMM_WORLD.allgather(instance)
# Let each instance synchronize itself with instances from the other
# cores.
instance.sync(instances)
# Execute tick for all synchronized objects.
for sync_object in sync_objects:
sync_object.tick()
# Execute tick for all non synchronized objects.
for local_non_sync_object in local_non_sync_objects:
local_non_sync_object.tick()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment