This article has been dead for over three months
You
""" Defining solitaire board based on wikipedia article
http://en.wikipedia.org/wiki/Peg_solitaire, checking for moves,
printing the solutions given in wikipedia from the given solution string
in columnar format
"""
from pprint import pprint
def make_board_from_shape(board_string):
return [line for line in board_string.splitlines() if line]
def make_board(empty):
return dict((symbol, '.') if symbol in empty else (symbol, symbol)
for symbol in positions)
def make_moves(board_style):
moves = []
# original board and transpose and remove spacing between letters
# (top-down and left-right)
for sol in (solitaire, zip(*(s[::2] for s in solitaire))):
moves += [''.join((a,b,c))
for line_a, line_b, line_c in zip(sol, sol[1:], sol[2:])
for a, b, c in zip(line_a, line_b, line_c)
if not ' ' in a + b + c]
# reversed directions also possible (down-top and right-left)
moves += [m[::-1] for m in moves]
return moves
def get_by_iter(data, iterable):
for t in iterable:
data = data[t]
return data
def is_hole(c):
return c == '.'
def board_string(board, solitaire):
return [''.join(board[c] if not is_hole(c) else '.' for c in row)
for row in solitaire]
def print_board(board, solitaire):
print('\n'.join(board_string(board, solitaire)))
def valid_move(board, m):
return (len(m) == 3 and
is_hole(board[m[2]]) and
not(is_hole(board[m[0]])) and
not(is_hole(board[m[1]])))
def move2_to_move3(move, moves):
return next(m for m in moves if m[0]+m[-1]== move)
def possible_moves(board, moves):
return (m for m in moves if valid_move(board, m))
def make_dicts(solitaire):
positions = dict((c, (line_ind, column_ind))
for line_ind, line in enumerate(solitaire)
for column_ind, c in enumerate(line))
return (positions, dict((indexes, c) for c, indexes in positions.items()))
def pack_lines_and_print(new_lines, old_lines=None, limit=80,
separator=5*' ', group_separator='\n\n'):
if old_lines is None:
return new_lines
elif len(old_lines[0])+len(new_lines[0])+len(separator) > limit:
print '\n'.join(old_lines) + group_separator
return new_lines
else:
return [separator.join(line) for line in zip(old_lines, new_lines)]
def print_packed(data, separator=5*' '):
lines = pack_lines_and_print(data[0], separator=separator)
for d in data[1:]:
lines = pack_lines_and_print(d, lines, separator=separator)
print '\n'.join(lines)
def apply_moves(board, *moves):
for move in moves:
#assert valid_move(board, move)
board[move[0]], board[move[1]], board[move[2]] = '.', '.', move[2]
def count_pieces(board):
return sum(not is_hole(p) for p in board.values())
def show_solution(solution_string, moves, solitaire):
empty, colon, rest = solution_string.partition(':')
board = make_board(empty)
end, eq, move2 = rest.partition('=')
move2 = move2.replace('/', ',')
solution = []
for move in (move2_to_move3(m, moves) for m in move2.split(',')):
apply_moves(board, move)
b = board_string(board, solitaire)
b.insert(0,move.center(len(b[0])))
solution.append(b)
print_packed(solution)
solitaire = make_board_from_shape("""
a b c
d e f
g h i j k l m
n o p x P O N
M L K J I H G
F E D
C B A
""")
print('Board style')
print('\n'.join(solitaire))
print('')
solutions = '''
x:x=ex,lj,ck,Pf,DP,GI,JH,mG,GI,ik,gi,LJ,JH,Hl,lj,jh,CK,pF,AC,CK,Mg,gi,ac,ck,kI,dp,pF,FD,DP,Pp,ox
x:x=ex,lj,xe/hj,Ki,jh/ai,ca,fd,hj,ai,jh/MK,gM,hL,Fp,MK,pF/CK,DF,AC,JL,CK,LJ/PD,GI,mG,JH,GI,DP/Ox
j:j=lj,Ik,jl/hj,Ki,jh/mk,Gm,Hl,fP,mk,Pf/ai,ca,fd,hj,ai,jh/MK,gM,hL,Fp,MK,pF/CK,DF,AC,JL,CK,LJ/Jj
i:i=ki,Jj,ik/lj,Ik,jl/AI,FD,CA,HJ,AI,JH/mk,Hl,Gm,fP,mk,Pf/ai,ca,fd,hj,ai,jh/gi,Mg,Lh,pd,gi,dp/Ki
e:e=xe/lj,Ik,jl/ck,ac,df,lj,ck,jl/GI,lH,mG,DP,GI,PD/AI,FD,CA,JH,AI,HJ/pF,MK,gM,JL,MK,Fp/hj,ox,xe
d:d=fd,xe,df/lj,ck,ac,Pf,ck,jl/DP,KI,PD/GI,lH,mG,DP,GI,PD/CK,DF,AC,LJ,CK,JL/MK,gM,hL,pF,MK,Fp/pd
b:b=jb,lj/ck,ac,Pf,ck/DP,GI,mG,JH,GI,PD/LJ,CK,JL/MK,gM,hL,pF,MK,Fp/xo,dp,ox/xe/AI/BJ,JH,Hl,lj,jb
b:x=jb,lj/ck,ac,Pf,ck/DP,GI,mG,JH,GI,PD/LJ,CK,JL/MK,gM,hL,pF,MK,Fp/xo,dp,ox/xe/AI/BJ,JH,Hl,lj,ex
a:a=ca,jb,ac/lj,ck,jl/Ik,pP,KI,lj,Ik,jl/GI,lH,mG,DP,GI,PD/CK,DF,AC,LJ,CK,JL/dp,gi,pd,Mg,Lh,gi/ia
a:p=ca,jb,ac/lj,ck,jl/Ik,pP,KI,lj,Ik,jl/GI,lH,mG,DP,GI,PD/CK,DF,AC,LJ,CK,JL/dp,gi,pd,Mg,Lh,gi/dp
'''.strip().splitlines()
moves = make_moves(solitaire)
#pprint(moves)
positions, symbols = make_dicts(solitaire)
#print('x', positions['x'], symbols[positions['x']], get_by_iter(solitaire, positions['x']))
print('Board middle empty')
board = make_board('x')
print_board(board,solitaire)
# demonstrate move check by alternative first moves
print '\nPossible moves\n'
for move in possible_moves(board, moves):
new_board = dict(board.items())
apply_moves(new_board, move)
print_board(new_board, solitaire)
print('Pieces left: %i' % count_pieces(new_board))
print('Next moves available:')
print(', '.join(possible_moves(new_board, moves)))
print('')
# showing first of solutions
show_solution(solutions[0], moves, solitaire)