Description
Your task is to imitate a turn-based variation of the popular "Snake" game.
You are given the initial configuration of the board and a list of commands which the snake follows one-by-one. The game ends if one of the following happens:
- the snake tries to eat its tail
- the snake tries to move out of the board
- it executes all the given commands.
Output the board configuration after the game ends. With the snake replaced by 'X' if the game ends abnormally.
Examples
input:
snakeGame([['.', '.', '.', '.'],
['.', '.', '<', '*'],
['.', '.', '.', '*']],
"FFFFFRFFRRLLF")
output:
[['.', '.', '.', '.'],
['X', 'X', 'X', '.'],
['.', '.', '.', '.']]
input:
snakeGame([['.', '.', '^', '.', '.'],
['.', '.', '*', '*', '.'],
['.', '.', '.', '*', '*']],
"RFRF")
output:
[['.', '.', 'X', 'X', '.'],
['.', '.', 'X', 'X', '.'],
['.', '.', '.', 'X', '.']]
input:
snakeGame([['.', '.', '*', '>', '.'],
['.', '*', '*', '.', '.'],
['.', '.', '.', '.', '.']],
"FRFFRFFRFLFF")
output:
[['.', '.', '.', '.', '.'],
['<', '*', '*', '.', '.'],
['.', '.', '*', '.', '.']]
Code
def snakeGame(gameBoard, commands):
heads = {'v': (1, 0), '^': (-1, 0), '<': (0, -1), '>': (0, 1)}
new_direc = {'v': {'L': '>', 'R': '<'},
'^': {'L': '<', 'R': '>'},
'<': {'L': 'v', 'R': '^'},
'>': {'L': '^', 'R': 'v'}}
def find_snake():
def get_next(x, y):
for key, direc in heads.items():
new_x, new_y = x + direc[0], y + direc[1]
if new_x in range(len(gameBoard)) and new_y in range(len(gameBoard[0])):
if (new_x, new_y) not in snake:
if gameBoard[new_x][new_y] == '*':
return (new_x, new_y)
# Get the head and the next body opposite of snake's direction
snake = []
for i, row in enumerate(gameBoard):
for head in heads:
if head in row:
snake.append((i, row.index(head)))
snake.append((snake[0][0] + heads[head][0] * -1, snake[0][1] + heads[head][1] * -1))
# Append the rest of the body
while True:
n = get_next(snake[-1][0], snake[-1][1])
if n is None:
break
snake.append(n)
return snake
def move_snake(snake):
head = gameBoard[snake[0][0]][snake[0][1]]
new_x, new_y = snake[0][0] + heads[head][0], snake[0][1] + heads[head][1]
new_snake = []
if new_x in range(len(gameBoard)) and new_y in range(len(gameBoard[0])) and (new_x, new_y) not in snake:
new_snake.append((new_x, new_y))
for pos in snake[:-1]:
new_snake.append(pos)
return new_snake
# Find starting snake
snake = find_snake()
for command in commands:
if command in "LR":
# Change the head
gameBoard[snake[0][0]][snake[0][1]] = new_direc[gameBoard[snake[0][0]][snake[0][1]]][command]
else:
temp = move_snake(snake)
# if not valid move return dead snake
if temp is None:
for pos in snake:
x, y = pos
gameBoard[x][y] = 'X'
return gameBoard
# else move snake
for a, b in zip(snake, temp):
gameBoard[b[0]][b[1]] = gameBoard[a[0]][a[1]]
gameBoard[snake[-1][0]][snake[-1][1]] = '.'
snake = temp
return gameBoard