copied langtons ant into own repo
557
Main.py
Executable file
@ -0,0 +1,557 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import pygame
|
||||
from OpenGL.GL import *
|
||||
from pygame.locals import *
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import random
|
||||
import time
|
||||
|
||||
#TODO: remove global vars
|
||||
|
||||
pygame.init()
|
||||
|
||||
window_w = 1600
|
||||
window_h = 900
|
||||
|
||||
livingSpaceWidth = 64
|
||||
livingSpaceHeight = 36
|
||||
|
||||
creatureW = window_w/(livingSpaceWidth)
|
||||
creatureH = window_h/(livingSpaceHeight)
|
||||
|
||||
FPS = 30
|
||||
|
||||
NORTH = 0
|
||||
EAST = 1
|
||||
SOUTH = 2
|
||||
WEST = 3
|
||||
|
||||
livingSpace = []
|
||||
livingSpaceColor = []
|
||||
|
||||
update_queue = []
|
||||
old_update_queue = []
|
||||
|
||||
# doubled draw buffer because of display double buffering
|
||||
draw_buffer = []
|
||||
draw_buffer_old = []
|
||||
|
||||
antPosition = (livingSpaceWidth // 2, livingSpaceHeight // 2)
|
||||
antRotation = NORTH
|
||||
|
||||
num_colors = 2
|
||||
color_list = []
|
||||
code = [False,True]
|
||||
|
||||
# store number of active cells
|
||||
num_active_cells = 0
|
||||
|
||||
# helper function for colors:
|
||||
def HSVtoRGB(h,s,v):
|
||||
c = v*s
|
||||
x = c*(1-abs((h/60)% 2 -1))
|
||||
m = v-c
|
||||
rr=0
|
||||
gg=0
|
||||
bb=0
|
||||
if(h<60):
|
||||
rr=c
|
||||
gg=x
|
||||
bb=0
|
||||
elif (h < 120):
|
||||
rr = x
|
||||
gg = c
|
||||
bb = 0
|
||||
elif (h < 180):
|
||||
rr = 0
|
||||
gg = c
|
||||
bb = x
|
||||
elif (h < 240):
|
||||
rr=0
|
||||
gg=x
|
||||
bb=c
|
||||
elif (h < 300):
|
||||
rr = x
|
||||
gg = 0
|
||||
bb = c
|
||||
elif (h < 360):
|
||||
rr = c
|
||||
gg = 0
|
||||
bb = x
|
||||
|
||||
return(rr+m,gg+m,bb+m)
|
||||
|
||||
def generate_colors():
|
||||
global color_list
|
||||
global num_colors
|
||||
color_list = []
|
||||
for i in range(num_colors):
|
||||
color_list.append(HSVtoRGB(i * 360.0 / num_colors,1,1))
|
||||
|
||||
|
||||
def resize(shape):
|
||||
width, height = shape
|
||||
if height == 0:
|
||||
height = 1
|
||||
glViewport(0, 0, width, height)
|
||||
glMatrixMode(GL_PROJECTION)
|
||||
glLoadIdentity()
|
||||
glOrtho(0.0, livingSpaceWidth * creatureW, livingSpaceHeight * creatureH, 0.0, -6.0, 0.0)
|
||||
glMatrixMode(GL_MODELVIEW)
|
||||
glLoadIdentity()
|
||||
|
||||
def init():
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0)
|
||||
|
||||
def initLivingSpace():
|
||||
for x in range(livingSpaceWidth):
|
||||
livingSpace.append([])
|
||||
livingSpaceColor.append([])
|
||||
for y in range(livingSpaceHeight):
|
||||
livingSpace[x].append(0)
|
||||
rgba = [float(x)/float(livingSpaceWidth), float(livingSpaceWidth-x)/float(livingSpaceWidth), float(y)/float(livingSpaceHeight),0.15]
|
||||
livingSpaceColor[x].append(rgba)
|
||||
draw_buffer.append((x,y))
|
||||
|
||||
def isAlive(x,y):
|
||||
return livingSpace[x][y] != 0
|
||||
|
||||
def draw():
|
||||
global draw_buffer
|
||||
global draw_buffer_old
|
||||
#glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
||||
glLoadIdentity()
|
||||
glTranslatef(0.0,0.0,3.0)
|
||||
|
||||
|
||||
glBegin(GL_QUADS)
|
||||
|
||||
for column,row in draw_buffer + draw_buffer_old:
|
||||
r,g,b,a = livingSpaceColor[column][row]
|
||||
|
||||
#glColor4f(255, 0, 0, 1.0)
|
||||
glColor4f(a * r, a * g, a * b, 1.0)
|
||||
x = column * creatureW
|
||||
y = row * creatureH
|
||||
|
||||
glVertex3f(x,y,0.0)
|
||||
glVertex3f(x + creatureW-1.0,y,0.0)
|
||||
glVertex3f(x+creatureW-1,y+creatureH-1,0.0)
|
||||
glVertex3f(x,y+creatureH-1,0.0)
|
||||
|
||||
# draw langton's ant quad:
|
||||
x = antPosition[0] * creatureW
|
||||
y = antPosition[1] * creatureH
|
||||
|
||||
offX = creatureW / 2
|
||||
offY = creatureH / 2
|
||||
|
||||
glColor4f(1,1,1,0.5)
|
||||
|
||||
glVertex3f(x + offX, y, 0.0) if antRotation != SOUTH else glVertex3f(x + offX, y + creatureH/2, 0.0)
|
||||
glVertex3f(x + creatureW - 1, y + offY, 0.0) if antRotation != WEST else glVertex3f(x + creatureW/2, y + offY, 0.0)
|
||||
glVertex3f(x + offX, y + creatureH - 1, 0.0) if antRotation != NORTH else glVertex3f(x + offX, y + creatureH/2, 0.0)
|
||||
glVertex3f(x, y + offY, 0.0) if antRotation != EAST else glVertex3f(x + creatureW/2, y + offY, 0.0)
|
||||
|
||||
glEnd()
|
||||
|
||||
draw_buffer_old = draw_buffer
|
||||
draw_buffer = []
|
||||
|
||||
|
||||
def activate(i,j,key = 1):
|
||||
global num_active_cells
|
||||
if livingSpace[i][j] == 0:
|
||||
num_active_cells += 1
|
||||
|
||||
livingSpace[i][j] = key
|
||||
if num_colors > 2:
|
||||
livingSpaceColor[i][j] = [
|
||||
color_list[key - 1][0],
|
||||
color_list[key - 1][1],
|
||||
color_list[key - 1][2],
|
||||
1.0
|
||||
]
|
||||
else:
|
||||
livingSpaceColor[i][j][3] = 1.0
|
||||
update_queue.append((i,j))
|
||||
|
||||
def deactivate(i,j):
|
||||
global num_active_cells
|
||||
if livingSpace[i][j] != 0:
|
||||
num_active_cells -= 1
|
||||
livingSpace[i][j] = 0
|
||||
# correct color:
|
||||
livingSpaceColor[i][j] = [
|
||||
float(i) / float(livingSpaceWidth),
|
||||
float(livingSpaceWidth - i) / float(livingSpaceWidth),
|
||||
float(j) / float(livingSpaceHeight),
|
||||
0.6
|
||||
]
|
||||
|
||||
update_queue.append((i,j))
|
||||
|
||||
def update_field():
|
||||
global old_update_queue
|
||||
global update_queue
|
||||
|
||||
old_update_queue = update_queue
|
||||
update_queue = []
|
||||
for i,j in old_update_queue:
|
||||
draw_buffer.append((i,j))
|
||||
if livingSpace[i][j] <= 0 and livingSpaceColor[i][j][3] > 0.15:
|
||||
livingSpaceColor[i][j][3] *= 0.98
|
||||
if livingSpaceColor[i][j][3] < 0.15:
|
||||
livingSpaceColor[i][j][3] = 0.15
|
||||
update_queue.append((i,j))
|
||||
elif livingSpace[i][j] > 0 and livingSpaceColor[i][j][3] > 0.6:
|
||||
livingSpaceColor[i][j][3] *= 0.98
|
||||
if livingSpaceColor[i][j][3] < 0.6:
|
||||
livingSpaceColor[i][j][3] = 0.6
|
||||
update_queue.append((i,j))
|
||||
|
||||
def move_ant(dx, dy):
|
||||
global antPosition
|
||||
global antRotation
|
||||
|
||||
# finally move:
|
||||
antPosition = (antPosition[0] + dx, antPosition[1] + dy)
|
||||
|
||||
# wrap around:
|
||||
if antPosition[0] < 0:
|
||||
antPosition = (livingSpaceWidth - 1, antPosition[1])
|
||||
elif antPosition[0] >= livingSpaceWidth:
|
||||
antPosition = (0, antPosition[1])
|
||||
if antPosition[1] < 0:
|
||||
antPosition = (antPosition[0], livingSpaceHeight - 1)
|
||||
elif antPosition[1] >= livingSpaceHeight:
|
||||
antPosition = (antPosition[0], 0)
|
||||
|
||||
update_queue.append(antPosition)
|
||||
|
||||
|
||||
|
||||
def update_ant():
|
||||
global antPosition
|
||||
global antRotation
|
||||
# if we have only two colors, we will switch between on and off
|
||||
if num_colors == 2:
|
||||
# switch cell
|
||||
if isAlive(antPosition[0], antPosition[1]):
|
||||
deactivate(antPosition[0], antPosition[1])
|
||||
else:
|
||||
activate(antPosition[0], antPosition[1])
|
||||
|
||||
# turn
|
||||
code_index = 1 if isAlive(antPosition[0], antPosition[1]) else 0
|
||||
|
||||
if code[code_index]:
|
||||
# turn right
|
||||
antRotation = (antRotation + 3) % 4
|
||||
else:
|
||||
# turn left
|
||||
antRotation = (antRotation + 1) % 4
|
||||
|
||||
else:
|
||||
# if we have more than 3 colors, we use the color code
|
||||
old_key = livingSpace[antPosition[0]][antPosition[1]] - 1
|
||||
new_key = (livingSpace[antPosition[0]][antPosition[1]]) % num_colors + 1 # avoiding key zero, it is deactivated
|
||||
if not isAlive(antPosition[0], antPosition[1]):
|
||||
# first activation time, increase key:
|
||||
new_key += 1
|
||||
old_key += 1
|
||||
|
||||
#determine direction:
|
||||
if code[old_key]:
|
||||
# turn left:
|
||||
antRotation = (antRotation + 3) % 4
|
||||
else:
|
||||
# turn right:
|
||||
antRotation = (antRotation + 1) % 4
|
||||
|
||||
# then activate with new key
|
||||
activate(antPosition[0], antPosition[1], new_key)
|
||||
|
||||
|
||||
# move on step:
|
||||
dx = 0
|
||||
dy = 0
|
||||
if antRotation == NORTH:
|
||||
dy = -1
|
||||
elif antRotation == SOUTH:
|
||||
dy = +1
|
||||
elif antRotation == EAST:
|
||||
dx = +1
|
||||
elif antRotation == WEST:
|
||||
dx = -1
|
||||
|
||||
move_ant(dx,dy)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
global livingSpaceWidth
|
||||
global livingSpaceHeight
|
||||
global creatureW
|
||||
global creatureH
|
||||
global antPosition
|
||||
global antRotation
|
||||
global window_w
|
||||
global window_h
|
||||
global color_list
|
||||
global num_colors
|
||||
global code
|
||||
|
||||
# parsing args:
|
||||
parser = argparse.ArgumentParser(description="langton\'s ant simulation tool", formatter_class=argparse.RawTextHelpFormatter)
|
||||
parser.add_argument('--steps', dest='steps', default = 20 , help='steps per second. Default = 20')
|
||||
parser.add_argument('--w', dest='w', default = livingSpaceWidth, help = 'field width')
|
||||
parser.add_argument('--h', dest='h', default=livingSpaceHeight, help = 'field height')
|
||||
parser.add_argument('--calc', dest='calc', default=0, help='calculate steps and only display result')
|
||||
parser.add_argument('--fullscreen', dest='fullscreen', action='store_true')
|
||||
parser.add_argument('--window_w', dest='win_w', default=window_w, help='window width')
|
||||
parser.add_argument('--window_h', dest='win_h', default=window_h, help='window height')
|
||||
parser.add_argument('--configurator', dest='configurator', action='store_true', help='start in field edit mode')
|
||||
parser.add_argument('--code', dest='code', default='10', help='binary code for the ant (\'10\' corresponds to the starndard ant behaviour). 1 means \'turn left\', 0 means \'turn right\'')
|
||||
parser.add_argument('--file', dest='file', default='', help='writing number of living cells per step in this file')
|
||||
parser.add_argument('--pattern', dest='pattern', default='0',
|
||||
help='initial pattern for the field. Possible values:\n' +
|
||||
'\t * 0: all fields inactive\n' +
|
||||
'\t * 1: all fields active\n' +
|
||||
'\t * check: checkboard pattern\n' +
|
||||
'\t * horizontal: horizontal stripes\n' +
|
||||
'\t * vertical: vertical stripes\n' +
|
||||
'\t * random: random values\n')
|
||||
|
||||
parser.set_defaults(fullscreen=False)
|
||||
parser.set_defaults(configurator=False)
|
||||
|
||||
if (len(sys.argv) == 1):
|
||||
|
||||
# no parameters given. Print help and ask user at runtime for options:
|
||||
|
||||
settings = {}
|
||||
settings["steps"] = 20
|
||||
settings["w"] = livingSpaceWidth
|
||||
settings["h"] = livingSpaceHeight
|
||||
settings["calc"] = 0
|
||||
settings["fullscreen"] = False
|
||||
settings["window_w"] = window_w
|
||||
settings["window_h"] = window_h
|
||||
settings["configurator"] = False
|
||||
settings["code"] = '10'
|
||||
settings["file"] = ""
|
||||
settings["pattern"] = '0'
|
||||
|
||||
while True:
|
||||
parser.print_help()
|
||||
print("current settings:")
|
||||
for key in settings.keys():
|
||||
print(str(key) + " = " + str(settings[key]))
|
||||
a = input("enter parameter to change. press enter to continue:")
|
||||
if len(a) == 0:
|
||||
break
|
||||
val = input("enter new value:")
|
||||
settings[a] = val
|
||||
# passing settings to parser:
|
||||
parser.set_defaults(steps=settings["steps"])
|
||||
parser.set_defaults(w=settings["w"])
|
||||
parser.set_defaults(h=settings["h"])
|
||||
parser.set_defaults(calc=settings["calc"])
|
||||
parser.set_defaults(fullscreen=settings["fullscreen"])
|
||||
parser.set_defaults(window_w=settings["window_w"])
|
||||
parser.set_defaults(window_h=settings["window_h"])
|
||||
parser.set_defaults(configurator=settings["configurator"])
|
||||
parser.set_defaults(code=settings["code"])
|
||||
if len(settings["file"]) > 0:
|
||||
parser.set_defaults(file=settings["file"])
|
||||
parser.set_defaults(pattern=settings["pattern"])
|
||||
|
||||
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
steps_per_sec = int(args.steps)
|
||||
livingSpaceWidth = int(args.w)
|
||||
livingSpaceHeight = int(args.h)
|
||||
calc = int(args.calc)
|
||||
filename = args.file
|
||||
fileobj = None
|
||||
if len(filename) > 0:
|
||||
fileobj = open(filename, mode='w')
|
||||
|
||||
video_flags = OPENGL | HWSURFACE | DOUBLEBUF
|
||||
|
||||
# parse code:
|
||||
code = []
|
||||
for c in args.code:
|
||||
if c == '0':
|
||||
code.append(False)
|
||||
else:
|
||||
code.append(True)
|
||||
|
||||
# generate colors:
|
||||
num_colors = len(code)
|
||||
generate_colors()
|
||||
|
||||
|
||||
if args.fullscreen:
|
||||
video_flags = OPENGL | HWSURFACE | DOUBLEBUF | FULLSCREEN
|
||||
dinfo = pygame.display.Info()
|
||||
window_w = dinfo.current_w
|
||||
window_h = dinfo.current_h
|
||||
else:
|
||||
window_w = int(args.win_w)
|
||||
window_h = int(args.win_h)
|
||||
|
||||
|
||||
creatureW = window_w / (livingSpaceWidth)
|
||||
creatureH = window_h / (livingSpaceHeight)
|
||||
|
||||
antPosition = (livingSpaceWidth // 2, livingSpaceHeight // 2)
|
||||
|
||||
|
||||
pygame.display.set_mode((window_w,window_h),video_flags)
|
||||
|
||||
initLivingSpace()
|
||||
|
||||
resize((window_w, window_h))
|
||||
init()
|
||||
|
||||
clock = pygame.time.Clock()
|
||||
|
||||
frames = 0
|
||||
counter = 0
|
||||
logic_frame_pause = FPS / steps_per_sec
|
||||
configurator_mode = bool(args.configurator)
|
||||
|
||||
field_draws = 0
|
||||
|
||||
# apply pattern
|
||||
if args.pattern == '0':
|
||||
# nothing to do
|
||||
pass
|
||||
elif args.pattern == '1':
|
||||
for i in range(livingSpaceWidth):
|
||||
for j in range(livingSpaceHeight):
|
||||
activate(i,j)
|
||||
elif args.pattern == 'check':
|
||||
for i in range(livingSpaceWidth):
|
||||
for j in range(livingSpaceHeight):
|
||||
if (i + j) % 2 == 0:
|
||||
activate(i,j)
|
||||
elif args.pattern == 'horizontal':
|
||||
for i in range(livingSpaceWidth):
|
||||
for j in range(livingSpaceHeight):
|
||||
m = j % num_colors
|
||||
if num_colors > 2:
|
||||
m += 1
|
||||
if m != 0:
|
||||
activate(i,j,m)
|
||||
elif args.pattern == 'vertical':
|
||||
for i in range(livingSpaceWidth):
|
||||
for j in range(livingSpaceHeight):
|
||||
m = i % num_colors
|
||||
if num_colors > 2:
|
||||
m += 1
|
||||
if m != 0:
|
||||
activate(i,j,m)
|
||||
elif args.pattern == 'random':
|
||||
r = random.Random(time.time())
|
||||
for i in range(livingSpaceWidth):
|
||||
for j in range(livingSpaceHeight):
|
||||
k = r.randint(0,num_colors - 1)
|
||||
if num_colors > 2:
|
||||
k += 1
|
||||
if k != 0:
|
||||
activate(i,j,k)
|
||||
else:
|
||||
print("error. unknown pattern")
|
||||
parser.print_help()
|
||||
sys.exit(-1)
|
||||
|
||||
if (calc > 0):
|
||||
for i in range(calc):
|
||||
update_ant()
|
||||
|
||||
#main loop:
|
||||
while True:
|
||||
|
||||
|
||||
ticktime = clock.tick(FPS)
|
||||
#print ticktime
|
||||
event = pygame.event.poll()
|
||||
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
|
||||
break
|
||||
|
||||
update_field()
|
||||
draw()
|
||||
|
||||
field_draws += len(draw_buffer) + len(draw_buffer_old)
|
||||
frames += 1
|
||||
|
||||
if frames % FPS == 0:
|
||||
print("average field draws per frame: " + str(field_draws/FPS))
|
||||
field_draws = 0
|
||||
|
||||
|
||||
pygame.display.flip()
|
||||
|
||||
if configurator_mode:
|
||||
# move with keys:
|
||||
if event.type == KEYDOWN:
|
||||
draw_buffer.append((antPosition[0],antPosition[1]))
|
||||
if event.key == K_DOWN:
|
||||
move_ant(0,+1)
|
||||
elif event.key == K_UP:
|
||||
move_ant(0,-1)
|
||||
elif event.key == K_LEFT:
|
||||
move_ant(-1,0)
|
||||
elif event.key == K_RIGHT:
|
||||
move_ant(+1,0)
|
||||
elif event.key == K_SPACE:
|
||||
new_key = (livingSpace[antPosition[0]][antPosition[1]]) % num_colors + 1
|
||||
if not isAlive(antPosition[0], antPosition[1]):
|
||||
new_key += 1
|
||||
activate(antPosition[0], antPosition[1], new_key)
|
||||
elif event.key == K_BACKSPACE:
|
||||
deactivate(antPosition[0],antPosition[1])
|
||||
elif event.key == K_LCTRL:
|
||||
antRotation = (antRotation - 1) % 4
|
||||
move_ant(0,0)
|
||||
elif event.key == K_RCTRL:
|
||||
antRotation = (antRotation + 1) % 4
|
||||
move_ant(0,0)
|
||||
elif event.key == K_RETURN:
|
||||
configurator_mode = False
|
||||
|
||||
else:
|
||||
|
||||
if (calc == 0):
|
||||
counter += 1
|
||||
|
||||
if logic_frame_pause >= 1:
|
||||
if counter > logic_frame_pause:
|
||||
update_ant()
|
||||
if fileobj != None:
|
||||
fileobj.write(str(num_active_cells) + '\n')
|
||||
counter = 0
|
||||
else:
|
||||
# multiple calculations per frame:
|
||||
for i in range(int(1 / logic_frame_pause)):
|
||||
update_ant()
|
||||
if fileobj != None:
|
||||
fileobj.write(str(num_active_cells) + '\n')
|
||||
|
||||
# switch to configurator mode:
|
||||
if event.type == KEYDOWN and event.key == K_RETURN:
|
||||
configurator_mode = True
|
||||
if fileobj != None:
|
||||
fileobj.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
104
README.md
Normal file
@ -0,0 +1,104 @@
|
||||
# Langton's Ant Simulator
|
||||
|
||||
## install dependencies:
|
||||
|
||||
this python program needs pygame and PyOpenGL for the displaying stuff.
|
||||
|
||||
this can be done via pip (on ubuntu-linux pip3 for using python 3):
|
||||
|
||||
```
|
||||
pip install PyOpenGL PyOpenGL_accelerate pygame
|
||||
```
|
||||
|
||||
## run the program:
|
||||
|
||||
```
|
||||
usage: Main.py [-h] [--steps STEPS] [--w W] [--h H] [--calc CALC]
|
||||
[--fullscreen] [--window_w WIN_W] [--window_h WIN_H]
|
||||
[--configurator] [--code CODE] [--file FILE]
|
||||
[--pattern PATTERN]
|
||||
|
||||
langton's ant simulation tool
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
--steps STEPS steps per second
|
||||
--w W field width
|
||||
--h H field height
|
||||
--calc CALC calculate steps and only display result
|
||||
--fullscreen
|
||||
--window_w WIN_W window width
|
||||
--window_h WIN_H window height
|
||||
--configurator start in field edit mode
|
||||
--code CODE binary code for the ant ('10' corresponds to the starndard ant behaviour). 1 means 'turn left', 0 means 'turn right'
|
||||
--file FILE writing number of living cells per step in this file
|
||||
--pattern PATTERN initial pattern for the field. Possible values:
|
||||
* 0: all fields inactive
|
||||
* 1: all fields active
|
||||
* check: checkboard pattern
|
||||
* horizontal: horizontal stripes
|
||||
* vertical: vertical stripes
|
||||
* random: random values
|
||||
```
|
||||
|
||||
* if no arguments are given, the program will ask the user at the runtime for the requested arguments.
|
||||
|
||||
## keys
|
||||
|
||||
| key | function |
|
||||
| ---------------------- | ---------------------------------------- |
|
||||
| return | enter/leave configuration mode |
|
||||
| arrow keys | move langton's ant (in configuration mode) |
|
||||
| space | activate field or switch field's color (in configuration mode) |
|
||||
| backspace | deactivate field (in configuration mode) |
|
||||
| ctrl left / ctrl right | rotate ant (in configuration mode) |
|
||||
| escape | exit program |
|
||||
|
||||
## patterns:
|
||||
|
||||
| pattern name | with standard ant | with multicolor ant |
|
||||
| ------------ | -------------------- | -------------------- |
|
||||
| 0 | ![](doc/p0a.png) | ![](doc/p0a.png) |
|
||||
| 1 | ![](doc/p1a.png) | ![](doc/p1b.png) |
|
||||
| check | ![](doc/pchecka.png) | ![](doc/pcheckb.png) |
|
||||
| horizontal | ![](doc/pha.png) | ![](doc/phb.png) |
|
||||
| vertical | ![](doc/pva.png) | ![](doc/pvb.png) |
|
||||
|
||||
|
||||
|
||||
## examples
|
||||
|
||||
* run standard langton's ant and write number of living cells per timestep to 'out.txt':
|
||||
|
||||
```
|
||||
./Main.py --file out.txt
|
||||
```
|
||||
|
||||
* run standard langton's and with checkboard pattern:
|
||||
|
||||
```
|
||||
./Main.py --pattern check
|
||||
```
|
||||
|
||||
* run on a fieldsize of 16x9 and start in configuration mode to adjust the ant's position and rotation:
|
||||
|
||||
```
|
||||
./Main.py --w 16 --h 9 --configurator
|
||||
```
|
||||
|
||||
* run the multicolored ant 'RRLLLRLLLRRR' on a field with size 320x180 and perform 1000 steps per second:
|
||||
|
||||
```
|
||||
./Main.py --w 320 --h 180 --code 110001000111 --steps 1000
|
||||
```
|
||||
|
||||
* run the multicolored ant 'RRLLLRLLLRRR' on a field with size 320x180 and calculate the result after 10.000 steps
|
||||
|
||||
```
|
||||
./Main.py --w 320 --h 180 --code 110001000111 --calc 100000
|
||||
```
|
||||
|
||||
* result:
|
||||
|
||||
![](doc/example.png)
|
||||
|
BIN
doc/example.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
doc/p0a.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
doc/p1a.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
doc/p1b.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
doc/pchecka.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
doc/pcheckb.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
doc/pha.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
doc/phb.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
doc/pva.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
doc/pvb.png
Normal file
After Width: | Height: | Size: 14 KiB |