Langton's ant: Difference between revisions

→‎{{header|Python}}: more pythonic version (but should use a class)
(→‎{{header|Python}}: more pythonic version (but should use a class))
Line 5,397:
 
=={{header|Python}}==
<lang python>
{{trans|D}}
"""Langton's ant implementation."""
<lang python>width = 75
from enum import Enum, IntEnum
height = 52
nsteps = 12000
 
class Dir: up, right, down, left = range(4)
class Turn: left, right = False, True
class Color: white, black = '.', '#'
M = [[Color.white] * width for _ in range(height)]
 
class Dir(IntEnum):
x = width // 2
"""Possible directions."""
y = height // 2
dir = Dir.up
 
i UP = 0
RIGHT = 1
while i < nsteps and 0 <= x < width and 0 <= y < height:
DOWN = 2
turn = Turn.left if M[y][x] == Color.black else Turn.right
LEFT = 3
M[y][x] = Color.white if M[y][x] == Color.black else Color.black
 
dir = (4 + dir + (1 if turn else -1)) % 4
dir = [Dir.up, Dir.right, Dir.down, Dir.left][dir]
if dir == Dir.up: y -= 1
elif dir == Dir.right: x -= 1
elif dir == Dir.down: y += 1
elif dir == Dir.left: x += 1
else: assert False
i += 1
 
class Color(Enum):
print ("\n".join("".join(row) for row in M))</lang>
"""Possible colors."""
The output is the same as the basic D version.
 
WHITE = " "
BLACK = "#"
 
 
def invert_color(grid, x, y):
"""Invert the color of grid at x, y coordinate."""
if grid[y][x] == Color.BLACK:
grid[y][x] = Color.WHITE
else:
grid[y][x] = Color.BLACK
 
 
def next_direction(grid, x, y, direction):
"""Compute next direction according to current position and direction."""
if grid[y][x] == Color.BLACK:
turn_right = False
else:
turn_right = True
direction_index = direction.value
if turn_right:
direction_index = (direction_index + 1) % 4
else:
direction_index = (direction_index - 1) % 4
directions = [Dir.UP, Dir.RIGHT, Dir.DOWN, Dir.LEFT]
direction = directions[direction_index]
return direction
 
 
def next_position(x, y, direction):
"""Compute next position according to direction."""
if direction == Dir.UP:
y -= 1
elif direction == Dir.RIGHT:
x -= 1
elif direction == Dir.DOWN:
y += 1
elif direction == Dir.LEFT:
x += 1
return x, y
 
 
def print_grid(grid):
"""Display grid."""
print(80 * "#")
print("\n".join("".join(v.value for v in row) for row in grid))
 
 
def ant(width, height, max_nb_steps):
"""Langton's ant."""
grid = [[Color.WHITE] * width for _ in range(height)]
x = width // 2
y = height // 2
direction = Dir.UP
 
i = 0
while i < max_nb_steps and 0 <= x < width and 0 <= y < height:
invert_color(grid, x, y)
direction = next_direction(grid, x, y, direction)
x, y = next_position(x, y, direction)
print_grid(grid)
i += 1
 
 
if __name__ == "__main__":
ant(width=75, height=52, max_nb_steps=12000)
</lang>
The output is similar to the basic D version.
 
=={{header|R}}==