#!/usr/bin/env python import time import random import empty import term_ut import base import arg import dbg def run(n): term = term_ut.new() key = term.key chip = empty.new( w=4, h=2 ) (w, h) = ( chip.w * n, chip.h * n ) buff = term.buff_new( w, h ) f_xy = lambda x, y: y * n + x + 1 f_y = lambda y: list( map( lambda x: f_xy( x, y ), range( n ) ) ) arr = list( map( f_y, range( n ) ) ) nn = empty.new( x=n-1, y=n-1 ) def put_chip(x, y, dx=0, dy=0, i=0): if i <= 0: i = arr[ y ][ x ] lst = [ ' ' * chip.w ] * chip.h if i < n * n: s = str( i ) pad = 2 - len( s ) s = '\tr1' + ' ' * pad + s + ' ' + '\tr0' + '|' lst = [ s, '--- ' ] s = base.to_str( lst ) if dx or dy: put_chip( x, y, i=n*n ) buff.puts( chip.w * x + dx, chip.h * y + dy, s ) def draw_init(): for y in range( n ): for x in range( n ): put_chip( x, y ) buff.update() def anime(x, y, dx, dy, sec, cnt=1): cnt_lmt = 4 if dx else 2 if cnt >= cnt_lmt: return put_chip( x, y, dx * cnt, dy * cnt ) buff.update() time.sleep( sec ) anime( x, y, dx, dy, sec, cnt + 1 ) def swap(dx, dy, sec=0.1): (tx, ty) = ( nn.x - dx, nn.y - dy ) in_n = lambda v: 0 <= v and v < n if not in_n( tx ) or not in_n ( ty ): return False anime( tx, ty, dx, dy, sec ) arr[ nn.y ][ nn.x ] = arr[ ty ][ tx ] arr[ ty ][ tx ] = n * n put_chip( nn.x, nn.y ) put_chip( tx, ty ) (nn.x, nn.y) = ( tx, ty ) buff.update() return True def shuffle(n): while n > 0: i = random.randrange( 4 ) d = 'udlr'[ i ] (dx, dy) = key.d_to_dxy( d ) if swap( dx, dy, 0 ): n -= 1 def key_func(): k = key.get_block() if k == 'q': return False (dx, dy) = key.k_to_dxy( k ) swap(dx, dy) return True def key_loop(): try: while key_func(): pass except: pass draw_init() key.init() shuffle( 1000 // ( 5 * 5 ) * n * n ) key_loop() key.fini() buff.fini() if __name__ == "__main__": a = arg.new() if a.is_pop( '-h' ): dbg.help_exit('[-h] [n]\n n: default 5') n = int( a.pop('5') ) run( n ) # EOF