RosettaCodeData/Task/Flipping-bits-game/Python/flipping-bits-game.py

86 lines
2.4 KiB
Python

"""
Given a %i by %i sqare array of zeroes or ones in an initial
configuration, and a target configuration of zeroes and ones
The task is to transform one to the other in as few moves as
possible by inverting whole numbered rows or whole lettered
columns at once.
In an inversion any 1 becomes 0 and any 0 becomes 1 for that
whole row or column.
"""
from random import randrange
from copy import deepcopy
from string import ascii_lowercase
try: # 2to3 fix
input = raw_input
except:
pass
N = 3 # N x N Square arrray
board = [[0]* N for i in range(N)]
def setbits(board, count=1):
for i in range(count):
board[randrange(N)][randrange(N)] ^= 1
def shuffle(board, count=1):
for i in range(count):
if randrange(0, 2):
fliprow(randrange(N))
else:
flipcol(randrange(N))
def pr(board, comment=''):
print(str(comment))
print(' ' + ' '.join(ascii_lowercase[i] for i in range(N)))
print(' ' + '\n '.join(' '.join(['%2s' % j] + [str(i) for i in line])
for j, line in enumerate(board, 1)))
def init(board):
setbits(board, count=randrange(N)+1)
target = deepcopy(board)
while board == target:
shuffle(board, count=2 * N)
prompt = ' X, T, or 1-%i / %s-%s to flip: ' % (N, ascii_lowercase[0],
ascii_lowercase[N-1])
return target, prompt
def fliprow(i):
board[i-1][:] = [x ^ 1 for x in board[i-1] ]
def flipcol(i):
for row in board:
row[i] ^= 1
if __name__ == '__main__':
print(__doc__ % (N, N))
target, prompt = init(board)
pr(target, 'Target configuration is:')
print('')
turns = 0
while board != target:
turns += 1
pr(board, '%i:' % turns)
ans = input(prompt).strip()
if (len(ans) == 1
and ans in ascii_lowercase and ascii_lowercase.index(ans) < N):
flipcol(ascii_lowercase.index(ans))
elif ans and all(ch in '0123456789' for ch in ans) and 1 <= int(ans) <= N:
fliprow(int(ans))
elif ans == 'T':
pr(target, 'Target configuration is:')
turns -= 1
elif ans == 'X':
break
else:
print(" I don't understand %r... Try again. "
"(X to exit or T to show target)\n" % ans[:9])
turns -= 1
else:
print('\nWell done!\nBye.')