Code: Alles auswählen
#!/usr/bin/env python
"""Program to replay a given sequence of Reversi moves.
A solution with functions only.
Main data structures are coordinates represented by tuples of x and y values
and the board represented by nested lists of field values for black, white,
and empty fields. Then there is a tuple represanting the current player
(first element) and the other player (second element).
The assignment guarantees valid moves as input, so there is virtually no
validation of the input in the program.
"""
BLACK, WHITE, EMPTY = 'B', 'W', '.'
#
# Relative coordinates used for moving one step in any of the eight directions.
#
DELTAS = [
(i, j)
for i in xrange(-1, 2) for j in xrange(-1, 2)
if not (i == 0 and j == 0)
]
def coordinate_add(coordinate_a, coordinate_b):
"""Adds two coordinates and return the resulting coordinate.
>>> coordinate_add((42, 23), (-1, 1))
(41, 24)
"""
return tuple(a + b for a, b in zip(coordinate_a, coordinate_b))
def coordinate_from_string(string):
"""Converts a string in the format given in the assignment into
a coordinate used by this program.
>>> coordinate_from_string('a1') # Upper left corner.
(0, 0)
>>> coordinate_from_string('f4') # Sixth column, fourth row.
(5, 3)
"""
return (ord(string[0]) - ord('a'), int(string[1]) - 1)
def create_board():
"""Creates the start configuration with the four pieces in the middle.
>>> from pprint import pprint
>>> pprint(create_board())
[['.', '.', '.', '.', '.', '.', '.', '.'],
['.', '.', '.', '.', '.', '.', '.', '.'],
['.', '.', '.', '.', '.', '.', '.', '.'],
['.', '.', '.', 'W', 'B', '.', '.', '.'],
['.', '.', '.', 'B', 'W', '.', '.', '.'],
['.', '.', '.', '.', '.', '.', '.', '.'],
['.', '.', '.', '.', '.', '.', '.', '.'],
['.', '.', '.', '.', '.', '.', '.', '.']]
"""
size = 8
result = [[EMPTY] * size for _ in xrange(size)]
for x, y in [(3, 4), (4, 3), (3, 3), (4, 4)]:
result[y][x] = WHITE if x == y else BLACK
return result
def board2string(board):
"""Converts the board into a string represantation required by the
assignment.
"""
return '\n'.join(''.join(row) for row in board)
def board_get(board, coordinate):
"""Gets the field value at given coordinate.
>>> board = create_board()
>>> board_get(board, (0, 0))
'.'
>>> board_get(board, (3, 3))
'W'
"""
x, y = coordinate
return board[y][x]
def board_set(board, coordinate, value):
"""Sets the field value at given coordinate."""
x, y = coordinate
board[y][x] = value
def is_within_board(board, coordinate):
"""Checks if given coordinate is within board.
>>> board = create_board()
>>> [is_within_board(board, c) for c in [(0, 0), (-1, 1), (7, 7), (8, 6)]]
[True, False, True, False]
"""
size = len(board)
return all(0 <= n < size for n in coordinate)
def _check_line(board, coordinate, delta, players):
"""Checks a line starting at given coordinate and advancing in the
direction of given delta for pieces to turn.
Returns a possibly empty sequence of coordinates of the pieces that have
to be turned.
"""
current_player, other_player = players
result = list()
while True:
coordinate = coordinate_add(coordinate, delta)
if is_within_board(board, coordinate):
current = board_get(board, coordinate)
if current != other_player:
return result if current == current_player else []
else:
return []
result.append(coordinate)
def move(board, players, coordinate):
"""Makes a move by placing a piece for the current player at the given
coordinate and the turning the tiles affected by this move.
Returns the players ordered for the next move.
"""
current_player, other_player = players
board_set(board, coordinate, current_player)
for delta in DELTAS:
for to_turn in _check_line(board, coordinate, delta, players):
board_set(board, to_turn, current_player)
return (other_player, current_player)
def main():
"""Reads moves from stdin until 'END' is read, executes the moves,
and prints the board state after each move.
"""
players = WHITE, BLACK
board = create_board()
print board2string(board), '\n'
for line in iter(raw_input, 'END'):
players = move(board, players, coordinate_from_string(line))
print line
print board2string(board), '\n'
if __name__ == '__main__':
main()