Also known as “The slowest implementation of the Game of Life in 2013″. This is what happens when you have insomnia.
[pe2-image src=”http://lh3.ggpht.com/-pIMUUJNK__k/URzHojTQSAI/AAAAAAAACxQ/MCZeLIlpebE/s144-c/IMG_20130214_031548.jpg” href=”https://picasaweb.google.com/100175922620194527589/InstantUpload#5844765915904755714″ caption=”IMG_20130214_031548.jpg” type=”image” alt=”IMG_20130214_031548.jpg” ]
What I did was first clear out the entire world, then place a plane of glass across the entire world at y=1. The actual Life cells are Cobblestone blocks on the y=0 plane (the grid is on the Minecraft x-z axis). The Life grid is initialized with a random seed, then set off to work. This code for the Game of Life is about the dumbest and slowest implementation there is. I’ve done no optimization at this point. It only updates about one generation (over the entire world) every few minutes. But it does seem to work, as you can see above.
Next time I need a break from electronics, I’ll refine the code and post it again (or you can follow the Gist). It’s way too slow to run the entire world as a Life simulation, so I think I’ll just clear out a 64×64 space in the middle of the world and confine the world to that size, which should make things run about an order of magnitude faster, I would hope. I know, this is crap code, but I’m still trying to really get into the Python frame of mind and this was a quick hack any way.
I’ll let this thing run for a while and post a screenshot of the evolved world to Twitter and G+ later on. Also, thanks to the shoutout from the new http://mcpipy.wordpress.com/ blog!
# pilife.py
#
# Jason Milldrum
# 18 Feb 2013
#
# www.nt7s.com/blog
import minecraft.minecraft as minecraft
import minecraft.block as block
import numpy
import random
mc = minecraft.Minecraft.create()
# World size in x and z axes
#worldSize = 64
# Bounds of x and z axes
negLimit = -32
posLimit = 31
# Bounds of y axis
yNegLimit = -64
yPosLimit = 64
# Y coord of Life world floor
worldFloor = 0
# Number of steps in the surrounding wall
maxWallHeight = 5
# Initialize the Life world
theWorld = numpy.zeros((posLimit - negLimit + 1, posLimit - negLimit + 1), dtype=numpy.bool)
theNextWorld = numpy.zeros((posLimit - negLimit + 1, posLimit - negLimit + 1), dtype=numpy.bool)
for x in range(posLimit - negLimit):
for y in range(posLimit - negLimit):
theWorld[x][y] = random.randint(0,1)
# Clear everything at the world surface and above inside the Life play area
mc.setBlocks(negLimit - (maxWallHeight * 2), worldFloor, negLimit - (maxWallHeight * 2), posLimit + (maxWallHeight * 2) - 1, yPosLimit, posLimit + (maxWallHeight * 2) - 1, block.AIR)
# Let's create stairsteps around the Life world
# Start with the +x direction
x = posLimit
stepHeight = worldFloor
# Up
while stepHeight <= maxWallHeight:
mc.setBlocks(x, worldFloor, negLimit - stepHeight - 1, x, stepHeight, posLimit + stepHeight, block.BEDROCK)
x += 1
stepHeight += 1
# Down
stepHeight = maxWallHeight
while stepHeight >= worldFloor:
mc.setBlocks(x, worldFloor, negLimit - stepHeight - 1, x, stepHeight, posLimit + stepHeight, block.BEDROCK)
x += 1
stepHeight -= 1
# Now the -x direction
x = negLimit - 1
stepHeight = worldFloor
# Up
while stepHeight <= maxWallHeight:
mc.setBlocks(x, worldFloor, negLimit - stepHeight - 1, x, stepHeight, posLimit + stepHeight, block.BEDROCK)
x -= 1
stepHeight += 1
# Down
stepHeight = maxWallHeight
while stepHeight >= worldFloor:
mc.setBlocks(x, worldFloor, negLimit - stepHeight - 1, x, stepHeight, posLimit + stepHeight, block.BEDROCK)
x -= 1
stepHeight -= 1
# Next the +z direction
z = posLimit
stepHeight = worldFloor
# Up
while stepHeight <= maxWallHeight:
mc.setBlocks(negLimit - stepHeight - 1, worldFloor, z, posLimit + stepHeight, stepHeight, z, block.BEDROCK)
z += 1
stepHeight += 1
# Down
stepHeight = maxWallHeight
while stepHeight >= worldFloor:
mc.setBlocks(negLimit - stepHeight - 1, worldFloor, z, posLimit + stepHeight, stepHeight, z, block.BEDROCK)
z += 1
stepHeight -= 1
# Finally the -z direction
z = negLimit - 1
stepHeight = worldFloor
# Up
while stepHeight <= maxWallHeight:
mc.setBlocks(negLimit - stepHeight - 1, worldFloor, z, posLimit + stepHeight, stepHeight, z, block.BEDROCK)
z -= 1
stepHeight += 1
# Down
stepHeight = maxWallHeight
while stepHeight >= worldFloor:
mc.setBlocks(negLimit - stepHeight - 1, worldFloor, z, posLimit + stepHeight, stepHeight, z, block.BEDROCK)
z -= 1
stepHeight -= 1
# Set the player right in the middle of the world
mc.player.setPos(0, worldFloor, 0)
# Main processing loop
while True:
# Display theWorld
for x in range(posLimit - negLimit):
for y in range(posLimit - negLimit):
if theWorld[x][y] == True:
mc.setBlock(x + negLimit, worldFloor, y + negLimit, block.DIAMOND_BLOCK)
else:
mc.setBlock(x + negLimit, worldFloor, y + negLimit, block.OBSIDIAN)
# Check number of neighbors alive
for x in range(posLimit - negLimit):
for y in range(posLimit - negLimit):
if x == 0:
xMinus = posLimit - negLimit
else:
xMinus = x - 1
if x == posLimit - negLimit:
xPlus = 0
else:
xPlus = x + 1
if y == 0:
yMinus = posLimit - negLimit
else:
yMinus = y - 1
if y == posLimit - negLimit:
yPlus = 0
else:
yPlus = y + 1
alive = 0
if theWorld[xPlus][yPlus]:
alive += 1
if theWorld[x][yPlus]:
alive += 1
if theWorld[xMinus][yPlus]:
alive += 1
if theWorld[xPlus][y]:
alive += 1
if theWorld[xMinus][y]:
alive += 1
if theWorld[xPlus][yMinus]:
alive += 1
if theWorld[x][yMinus]:
alive += 1
if theWorld[xMinus][yMinus]:
alive += 1
# Calculate which cells live and die in next generation
if theWorld[x][y] == False:
if alive == 3:
theNextWorld[x][y] = True
else:
if alive < 2:
theNextWorld[x][y] = False
elif alive > 3:
theNextWorld[x][y] = False
else:
theNextWorld[x][y] = True
# Copy array
theWorld = theNextWorld.copy()
Related