diff -urN v2/kon.py v3/kon.py --- v2/kon.py 2017-10-06 22:00:00.000000000 +0900 +++ v3/kon.py 2017-10-17 03:15:30.000000000 +0900 @@ -84,9 +84,11 @@ rl = rlock() e = extends(rl) e.cond_f = cond_f if cond_f else lambda: True + e.en = True + chk = lambda: e.cond_f() and e.en def wrap_f(*args): rl.lock() - r = f(*args) if e.cond_f() else None + r = f(*args) if chk() else None rl.unlock() return r e.f = wrap_f @@ -148,37 +150,52 @@ e = Empty() e.hz = hz e.run = run - ev = evt() + kill_ev = threading.Event() def loop(): - while not ev.wait( hz_to_sec(e.hz) ): - # sec == 0 when hz == 0 + while not kill_ev.is_set(): if e.run: f( *args ) + kill_ev.wait( hz_to_sec(e.hz) ) # sec == 0 when hz == 0 + th = threading.Thread( target=loop ) th.daemon = True - e.stop = lambda: set(e, 'run', False) e.start = lambda: set(e, 'run', True) - e.kill = lambda: ev.set('kill') + e.kill = lambda: kill_ev.set() e.join = th.join e.kill_join = lambda: ( e.kill(), e.join() )[-1] + e.set_hz = lambda hz: set(e, 'hz', hz) + e.get_hz = lambda: e.hz th.start() return e -def flicker(hz=1.0, f=None, args=[], run=False): +def counter(n, hz=1.0, f=None, run=False, repeat=True): + ev = threading.Event() def th_f(): - set(e, 'v', not e.v) - if has(e, 'f'): - e.f( *e.args ) - - #e = extends( th_loop(th_f, [], hz*2, run) ) - e = extends( th_loop(th_f, [], hz, run) ) - e.v = False - e.get = lambda: e.v + e.i = (e.i + 1) % n if e.i != None else 0 + if e.f: + e.f() + if not repeat and e.i == n - 1: + e.stop() + ev.set() + th = th_loop(th_f, [], hz, False) + e = extends(th) e.f = f - e.args = args - e.set_hz = lambda hz: set(e, 'hz', hz*2) + e.i = None + e.get = lambda: e.i if e.i != None else 0 + e.wait = ev.wait # for no repeat + e.set_f = lambda f: set(e, 'f', f) + e.start = lambda: ( set(e, 'i', None), th.start() )[-1] + e.restart = lambda: ( e.stop(), e.start() )[-1] + if run: + e.start() + return e + +def slider(lst, hz=1.0, f=None, run=False, repeat=True): + ctr = counter( len(lst), hz, f, run, repeat ) + e = extends(ctr) + e.get = lambda: lst[ ctr.get() ] return e def term_raw(sigint=True): @@ -226,7 +243,7 @@ buf += getkey(tmout) return '' -cls = lambda : out( esc('2J') ) +clr = lambda : out( esc('2J') ) loc = lambda x, y: out( esc( '{};{}H'.format(y+1, x+1) ) ) rev = lambda v: out( esc( '7m' if v else '0m' ) ) cursor = lambda v: out( esc_ex(25, v) ) @@ -261,6 +278,8 @@ show = lambda x, y, s, col, r, flush_f=False: lock_show.f(x, y, s, col, r, flush_f) +mk_slst = lambda s, col='', r=False: [ (s, col, r) ] + def sum_show_lst(lst): # lst = [ (s, col, r), (s, col, r) ... ] @@ -270,7 +289,7 @@ a = (s, col, r) = lst[0] lst = sum_show_lst( lst[1:] ) (s_, col_, r_) = lst[0] - return [ (s + s_, col, r) ] + lst[1:] if col == col_ and r == r_ else [a] + lst + return mk_slst(s + s_, col, r) + lst[1:] if col == col_ and r == r_ else [a] + lst split_show_lst = lambda lst: sum( map( lambda (s, col, r): map( lambda c: (c, col, r), s ), lst ), [] ) @@ -279,7 +298,7 @@ def fit_show_lsts(show_lsts): ns = map( show_lst_len, show_lsts ) max_n = max(ns) - return map( lambda (lst, n): sum_show_lst( lst + [ (' ', '', False) ] * (max_n - n) ), zip( show_lsts, ns ) ) + return map( lambda (lst, n): sum_show_lst( lst + mk_slst(' ') * (max_n - n) ), zip( show_lsts, ns ) ) def shows(x, y, lst, flush_f=False): x = reduce( lambda x, (s, col, r): show(x, y, s, col, r), sum_show_lst(lst), x ) @@ -290,11 +309,10 @@ def over_show_lst(l, h): get_col = lambda (s, col, r): col f = lambda l, h: l if get_col(h) == 'trans' else h - l = split_show_lst(l) h = split_show_lst(h) n = max( len(l), len(h) ) - apd = [ (' ', 'trans', False) ] * n + apd = mk_slst(' ', 'trans') * n l = ( l + apd )[:n] h = ( h + apd )[:n] o = map( lambda (l, h): f(l, h), zip(l, h) ) @@ -325,11 +343,13 @@ lst_xywh = lambda x, y, w, h: loop_xywh( x, y, w, h, lambda x, y: (x, y) ) chk_xy = lambda x, y, w, h: x in range(w) and y in range(h) -chk_xywh = lambda x, y, sx, sy, w, h: chk_xy(x-sx, y-sy) +chk_xywh = lambda x, y, sx, sy, w, h: chk_xy(x-sx, y-sy, w, h) into_x = lambda x, w, ow: max( min( ow - w, x ), 0 ) into_xy = lambda x, y, w, h, ow, oh: ( into_x(x, w, ow), into_x(y, h, oh) ) +cen_xywh = lambda x, y, w, h: (x + w/2, y + h/2) + def arr_xy_new(w, h, v): e = Empty() e.data = data = map( lambda _: [ v ] * w, range(h) ) @@ -337,39 +357,53 @@ e.chk_xy = lambda x, y: chk_xy(x, y, w, h) e.get = lambda x, y, v=None: data[y][x] if e.chk_xy(x, y) else v e.set = lambda x, y, c: set( data[y], x, c ) if e.chk_xy(x, y) else None - e.clear = lambda c: loop_xy( w, h, lambda x, y: e.set(x, y, c) ) - def pos(c): - lst = filter( lambda (x, y): e.get(x, y) == c, lst_xy(w, h) ) - return lst[0] if len(lst) == 1 else lst - e.pos = pos + e.clear = lambda v: loop_xy( w, h, lambda x, y: e.set(x, y, v) ) + e.poss = lambda v: filter( lambda (x, y): e.get(x, y) == v, lst_xy(w, h) ) + e.pos = lambda v: next( iter( e.poss(v) ), (-1, -1) ) return e def arr_xy_bit_new(w, h): pat = lambda bit: 1 << bit if bit >= 0 else 0 chg = lambda v, bit, bv: v | pat(bit) if bv else v & ~pat(bit) arr = arr_xy_new(w, h, 0) + pos_d = {} + + def set_(x, y, bit, bv): + if not e.chk_xy(x, y): + return + arr.set(x, y, chg(arr.get(x, y), bit, bv) ) + + if bit not in pos_d: + pos_d[bit] = [] + lst = pos_d.get(bit) + p = (x, y) + if bv and p not in lst: + lst.append(p) + if not bv and p in lst: + lst.remove(p) e = extends(arr) e.get = lambda x, y, bit: arr.get(x, y, 0) & pat(bit) - e.set_ = lambda x, y, bit, bv: arr.set( x, y, chg( arr.get(x, y), bit, bv ) ) - e.set = lock_wrap( e.set_ ).f + e.set = lock_wrap( set_ ).f e.clear = lambda: arr.clear(0) e.gets = lambda x, y: filter( lambda bit: e.get(x, y, bit), range( bit_w( arr.get(x, y, 0) ) ) ) + e.poss = lambda bit: pos_d.get(bit, []) + e.pos = lambda bit: next( iter( e.poss(bit) ), (-1, -1) ) return e def arr_xy_bit_c_new(w, h, bit_cs): - arr_bit = arr_xy_bit_new(w, h) - e = extends(arr_bit) - e.to_bit = to_bit = dict( zip( bit_cs, range( len(bit_cs) ) ) ) - e.get = lambda x, y, c: arr_bit.get( x, y, to_bit.get(c, -1) ) - e.set = lambda x, y, c, v: arr_bit.set( x ,y, to_bit.get(c, -1), v ) - e.gets = lambda x, y: map( lambda bit: bit_cs[bit], arr_bit.gets(x, y) ) + arr = arr_xy_bit_new(w, h) + e = extends(arr) + e.to_bit = to_bit = lambda c: bit_cs.index(c) if c in bit_cs else -1 + e.get = lambda x, y, c: arr.get( x, y, to_bit(c) ) + e.set = lambda x, y, c, v: arr.set( x ,y, to_bit(c), v ) + e.gets = lambda x, y: map( lambda bit: bit_cs[bit], arr.gets(x, y) ) + e.poss = lambda c: arr.poss( to_bit(c) ) + e.pos = lambda c: next( iter( e.poss(c) ), (-1, -1) ) return e -def arr_xy_bit_c_show_new(w, h, bit_cs, c_to_show_lst, xy_to_view, update_border=(0,0)): - # c_to_show_lst(c, x, y) return [ (s, col, r), (s, col, r) ... ] - - arr_bit_c = arr_xy_bit_c_new(w, h, bit_cs) - e = extends(arr_bit_c) +def arr_xy_bit_c_show_new(w, h, bit_cs, xy_to_view): + arr = arr_xy_bit_c_new(w, h, bit_cs) + e = extends(arr) e.xy_to_view = xy_to_view def view_to_wh(vw, vh): @@ -380,53 +414,146 @@ return ( updiv(vw * w, vw_), updiv(vh * h, vh_) ) e.view_to_wh = view_to_wh - def update_arg(x, y): - if not e.chk_xy(x, y): - return - cs = [] - if update_border != (0,0): - (bw, bh) = update_border - xys = map( lambda (dx, dy): (x+dx-bw, y+dy-bh), lst_xy(bw*2+1, bh*2+1) ) - cs = sum( map( lambda (x, y): e.gets(x, y), xys ), [] ) - cs = reduce( lambda cs, c: cs if c in cs else cs + [c], cs, [] ) - cs.sort( key=lambda c: bit_cs.index(c) ) - else: - cs = e.gets(x, y) - - show_lsts = map( lambda c: c_to_show_lst(c, x, y), cs ) - show_lst = reduce( over_show_lst, reversed( show_lsts ), [] ) - show_lst = trans_to_spc_show_lst(show_lst) if show_lst else [ (' ', '', False) ] - - (x, y) = xy_to_view(x, y) - return (x, y, show_lst) - - def update(x, y, f=shows, flush_f=False): - f( *update_arg(x, y) ) - if flush_f: - flush() - e.update = update - e.update_xys = lambda xys, f=shows, flush_f=False: map( lambda (x, y): e.update(x, y, f, flush_f), xys ) - e.update_area = lambda x, y, w, h, f=shows, flush_f=False: e.update_xys( lst_xywh(x, y, w, h), f, flush_f ) - e.update_line = lambda x, y, w, f=shows, flush_f=False: e.update_area(x, y, w, 1, f, flush_f) + sdic = {} + e.get_sdic = lambda c: sdic.get( c, (None, None) ) + e.set_sdic = lambda c, v: set(sdic, c, v) + + def get_show_lst(c, x, y): + (t, o) = e.get_sdic(c) + if not o: + return mk_slst(' ') + if t == 'func': + return o(c, x, y) + if t == 'slider': + return o.get() + return o + e.get_show_lst = get_show_lst e.get_w = lambda vw: view_to_wh( vw, 0 )[0] e.show_lst_wh = lambda show_lst: ( e.get_w( show_lst_len(show_lst) ), 1 ) - def shows_(x, y, show_lst, xcen=False, restore=False, flush_f=False): + def show_lst_area(x, y, show_lst, xcen=False): (w, h) = e.show_lst_wh(show_lst) if xcen: x -= (w - 1) / 2 (ow, oh) = e.size() (x, y) = into_xy(x, y, w, h, ow, oh) + return (x, y, w, h) + e.show_lst_area = show_lst_area - if restore: - e.update_area(x, y, w, h) - else: - (vx, vy) = xy_to_view(x, y) - shows( vx, vy, show_lst ) - if flush_f: - flush() + def shows_(x, y, show_lst, xcen=False, flush_f=False): + (x, y, w, h) = e.show_lst_area(x, y, show_lst, xcen) + (vx, vy) = xy_to_view(x, y) + shows(vx, vy, show_lst, flush_f) e.shows = shows_ + e.flush = lambda flush_f=True: flush() if flush_f else None + return e + +def arr_xy_bit_c_update_new(w, h, bit_cs, xy_to_view, get_dx=None): + arr = arr_xy_bit_c_show_new(w, h, bit_cs, xy_to_view) + e = extends(arr) + + def update(x, y, flush_f=False): + if not e.chk_xy(x, y): + return + lst = [] + if get_dx: + for ix in (-1, 0, 1): + x_ = (x + ix + w) % w + cs = filter( lambda c: ix == 0 or get_dx(c) == -ix, e.gets(x_, y) ) + lst += map( lambda c: ( c, x_, ix if ix else get_dx(c) ), cs ) + + TRANS = mk_slst(' ', 'trans') + shift = lambda lst, dx: split_show_lst( lst + TRANS if dx < 0 else TRANS + lst )[1:3] if dx else lst + lst = map( lambda (c, x_, dx): ( c, shift( e.get_show_lst(c, x_, y), dx ) ), lst ) + else: + lst = map( lambda c: ( c, e.get_show_lst(c, x, y) ), e.gets(x, y) ) + + lst.sort( key=lambda (c, show_lst): e.to_bit(c) ) + show_lsts = zip(*lst)[1] if lst else [] + show_lst = reduce( over_show_lst, reversed( show_lsts ), [] ) + show_lst = trans_to_spc_show_lst(show_lst) if show_lst else mk_slst(' ') + e.shows(x, y, show_lst, flush_f) + + e.update = update + e.update_xys = lambda xys, flush_f=False: ( map( lambda (x, y): e.update(x, y), xys ), e.flush(flush_f) )[-1] + e.update_area = lambda x, y, w, h, flush_f=False: e.update_xys( lst_xywh(x, y, w, h), flush_f ) + e.update_line = lambda x, y, w, flush_f=False: e.update_area(x, y, w, 1, flush_f) + e.update_all = lambda flush_f=False: e.update_area(0, 0, w, h, flush_f) + + def update_c(c, flush_f=False): + dx = get_dx(c) if get_dx else 0 + xys = e.poss(c) + #xys += map( lambda (x, y): (x+dx, y), xys ) if dx else [] + if dx: + xys = xys + map( lambda (x, y): (x+dx, y), xys ) + e.update_xys(xys, flush_f) + e.update_c = update_c + + def set_sdic(c, v): + (t, o) = e.get_sdic(c) + if t == 'slider' and o: + o.kill_join() + + arr.set_sdic(c, v) + + (t, o) = e.get_sdic(c) + if t == 'slider' and o: + o.set_f( lambda: e.update_c(c, flush_f=True) ) + + e.update_c(c, flush_f=True) + + e.set_sdic = set_sdic + return e + +def arr_xy_bit_c_move_new(w, h, bit_cs, xy_to_view): + dx_d = {} + get_dx = lambda c: dx_d.get(c, 0) + arr = arr_xy_bit_c_update_new(w, h, bit_cs, xy_to_view, get_dx) + e = extends(arr) + dir_d = {} + + e.get_dir = lambda c: dir_d.get(c, '') + e.set_dir = lambda c, d: set(dir_d, c, d) + + def move(c, d, hz=None): + (x, y) = e.pos(c) + if not e.chk_xy(x, y): + return + + (nx, ny) = step_to(x, y, d) + (nx, ny) = ( (nx + w) % w, (ny + h) % h ) + arr.set(x, y, c, False) + arr.set(nx, ny, c, True) + e.set_dir(c, d) + + if hz: + dx_d[c] = { R: -1, L: 1 }.get(d, 0) + + xys = [ (x, y), (nx, ny) ] + arr.update_xys(xys, flush_f=True) + + if hz: + sec = hz_to_sec( hz * 2 ) + tmr_f = lambda: ( set(dx_d, c, 0), arr.update_xys(xys, flush_f=True) )[-1] + timer_new(tmr_f, [], sec).start() + e.move = move + + def set_(x, y, c, v=True, flush_f=False, d=''): + arr.set(x, y, c, v) + e.set_dir(c, d) + arr.update(x, y, flush_f) + e.set = set_ + + e.rm = lambda c, flush_f=False: map( lambda (x, y): e.set(x, y, c, False, flush_f), e.poss(c) ) + + def msg_pause(x, y, show_lst, sec, xcen=False): + e.shows(x, y, show_lst, xcen, flush_f=True) + sleep(sec) + (x, y, w, h) = e.show_lst_area(x, y, show_lst, xcen) + e.update_area(x, y, w, h, flush_f=True) + e.msg_pause = msg_pause + return e def rbuf(fname): diff -urN v2/pac.py v3/pac.py --- v2/pac.py 2017-10-06 22:00:00.000000000 +0900 +++ v3/pac.py 2017-10-17 03:15:30.000000000 +0900 @@ -4,72 +4,25 @@ import os import threading import kon -from kon import dbg, DIRS, U, D, L, R, flush, has, set, get +from kon import dbg, DIRS, U, D, L, R, flush, has, set, get, mk_slst NO_DIE = '-m' in sys.argv -(pac_buf, mon_ret_buf, warp_buf) = map( kon.rbuf, ['pac.txt', 'mon_ret.txt', 'warp.txt'] ) +txts = map( lambda s: s + '.txt', [ 'pac', 'mon_ret', 'warp', 'pato' ] ) +(pac_buf, mon_ret_buf, warp_buf, pato_buf) = map(kon.rbuf, txts) -MONS = 'MRCY' +MONS = 'RCMY' MOVES = 'P' + MONS -def stat_dic(c): - d = {} - if c == 'P': - d = { - 'dir': L, - 'pos': pac_buf.pos('P'), - 'dx': 0, - 'hz': 3.0, - 'th': None, - 'late_tmr': kon.timer_new(), - 'dot': len( pac_buf.pos('.') + pac_buf.pos('O') ), - } - elif c in MONS: - # mon mode 'cage' 'run' 'weak' 'blink' 'ret' - d = { - 'dir': U, - 'pos': pac_buf.pos(c), - 'dx': 0, - 'hz': 4.0, - 'th': None, - 'late_tmr': kon.timer_new(), - 'mode': 'cage' if c in 'CMY' else 'run', - 'timer': kon.timer_new(), - 'flick': kon.flicker(), - 'rl': kon.rlock() - } - elif c == 'O': - d = { 'flick': kon.flicker( 2.0, lambda: arr.update_xys( pac_buf.pos('O'), flush_f=True ), run=True ) } - return d - -stat_cs = MOVES + 'O' -stat_inf = dict( map( lambda c: ( c, kon.dic_to_cls( stat_dic(c) ) ), stat_cs ) ) +stat_inf = dict( map( lambda c: ( c, kon.Empty() ), MOVES ) ) stat_get = lambda c: stat_inf.get(c) -stat_gets = lambda cs: map( stat_get, cs ) -c_stat_gets = lambda cs: zip( cs, stat_gets(cs) ) def pac_show(c, x, y): (s, col, r) = ('()', 'yellow', True) - (x, y) = stat_get(c).pos if (x + y) % 2: - s = { L: '>)', R: '(<', U: '(/', D: '/)' }.get( stat_get(c).dir ) - return (s, col, r) + s = { L: '>)', R: '(<', U: '(/', D: '/)' }.get( arr.get_dir(c), s ) + return mk_slst(s, col, r) -def mon_show(c, x, y): - col = { 'M': 'magenta', 'R': 'red', 'C': 'cyan', 'Y': 'white' }.get(c) - d = { - 'run': ( 'oo', col, True ), - 'weak': ( '><', 'blue', True ), - 'blink_True': ( '><', 'blue', True ), - 'blink_False': ( '--', 'white', True ), - 'ret': ( 'oo', 'white', False ), - } - mode = mon_mode(c) - if mode == 'blink': - mode += '_' + str( stat_get(c).flick.get() ) - return d.get(mode if mode in d else 'run') - def blk_show(c, x, y): k = filter( lambda d: pac_buf.get( *kon.step_to(x, y, d) ) == c, DIRS ) # 'udlr' s = '==' @@ -80,23 +33,9 @@ ( 'udlr', ): ' ', } s = dict( sum( map( lambda (ks, v): map( lambda k: (k, v), ks ), d.items() ), [] ) ).get(k, s) - return (s, 'blue', False) - -show_inf = { - 'M': mon_show, - 'R': mon_show, - 'C': mon_show, - 'Y': mon_show, - 'P': pac_show, - 'O': lambda c, x, y: ('O ', 'yellow', stat_get(c).flick.get()), - '.': lambda c, x, y: ('. ', 'white', False), - '=': lambda c, x, y: ('==', 'yellow', False), - '#': blk_show, -} + return mk_slst(s, 'blue', False) SPC = (' ', '', False) -TRANS = (' ', 'trans', False) -get_show_inf = lambda c, x, y: show_inf.get(c)(c, x, y) if c in show_inf else SPC def mon_price_new(): e = kon.Empty() @@ -113,55 +52,36 @@ def mon_mode(c, v='get'): stat = stat_get(c) - def update(): - (x, y) = stat.pos - arr.update(x, y) - dx = stat.dx - if dx: - arr.update( x + dx, y ) - flush() - - mode = stat.mode + mode = stat.mode if has(stat, 'mode') else None if v == 'get' or v == mode: return mode - if mode == 'blink': - stat.flick.stop() - stat.mode = v - update() - if v == 'blink': - stat.flick.f = update - stat.flick.set_hz( stat.hz ) - stat.flick.start() + col = { 'M': 'magenta', 'R': 'red', 'C': 'cyan', 'Y': 'white' }.get(c) + blinks= [ mk_slst('><', 'blue', True), mk_slst('--', 'white', True) ] + d = { + 'cage': ( '', mk_slst('oo', col, True) ), + 'run': ( '', mk_slst('oo', col, True) ), + 'weak': ( '', mk_slst('><', 'blue', True) ), + 'blink': ( 'slider', kon.slider(blinks, stat.hz, None, True) ), + 'ret': ( '', mk_slst('oo', 'white', False) ), + } + arr.set_sdic( c, d.get(v) ) mon_price.check() + stat.th.set_hz( get_hz( c, *arr.pos(c) ) ) + mon_hz_rate = { 'weak': 0.3, 'blink': 0.3, 'ret': 1.5 } warp_rate = { '1': 0.8, '2': 0.6, '3': 0.4, '4': 0.3, 'L': 0.2, 'R': 0.2 } arr_xy_to_show_xy = lambda x, y: (x * 2, y + 1) # for aspect and score -def c_to_show_lst(c, x, y): - inf = get_show_inf(c, x, y) - stat = stat_get(c) - - if c not in MOVES or stat.dx == 0: - return [ inf ] if arr.get(x, y, c) else [ TRANS ] - - (px, py) = stat.pos - dx = stat.dx - if x not in [ px, px + dx ] or y != py: - return [ TRANS ] - - conn = [ inf, TRANS ] if (x == px) != (dx == 1) else [ TRANS, inf ] - return kon.split_show_lst( conn )[1:3] - (w, h) = pac_buf.size() -bit_cs = MONS + 'PO.=#' -arr = kon.arr_xy_bit_c_show_new( w, h, bit_cs, c_to_show_lst, arr_xy_to_show_xy, (1,0) ) +bit_cs = MOVES + 'O.=#' +arr = kon.arr_xy_bit_c_move_new( w, h, bit_cs, arr_xy_to_show_xy) is_warp = lambda x, y, d: ( lambda wc: wc if wc in ('L', 'R') and wc.lower() == d else False )( warp_buf.get(x, y) ) @@ -184,32 +104,35 @@ (nx, ny) = step_to(px, py, d) + # gate chk + nc = pac_buf.get(nx, ny) + if c in MONS and mon_mode(c) == 'cage' and nc == '=' and MONS.index(c) > gate.get(): + return False + v = one_way(nx, ny, d) if v != None: return v - return pac_buf.get(nx, ny) not in (None, '#') + return nc != '#' next_ds = lambda x, y, c: filter( lambda d: is_step(x, y, c, d), DIRS ) -def line_msg_pause(x, y, s, col, r, sec, xcen=True): - lock_move.lock() - show_lst = [ (s, col, r) ] - arr.shows(x, y, show_lst, xcen, flush_f=True) - kon.sleep(sec) - arr.shows(x, y, show_lst, xcen, restore=True, flush_f=True) - lock_move.unlock() - -def show_anime(x, y, lsts, hz, restore=True, n=1): - lock_move.lock() - lsts = kon.fit_show_lsts(lsts) - for i in range(n): - for lst in lsts: - arr.shows(x, y, lst, flush_f=True) - kon.sleep_hz(hz) - if restore and lsts: - arr.shows(x, y, lsts[0], flush_f=True) - lock_move.unlock() +def arr_msg_pause(show_lst, x=None, y=None, sec=1.0, xcen=True): + game_ev.set('stop') + (bx, by) = pac_buf.pos('B') + x = bx if x == None else x + y = by if y == None else y + arr.msg_pause(x, y, show_lst, sec, xcen) + game_ev.set('start') + +def pac_slider(slider): + game_ev.set('stop') + c = 'P' + bak = arr.get_sdic(c) + arr.set_sdic( c, ('slider', slider) ) + slider.wait() + game_ev.set('start') + return bak game_ev = kon.evt() @@ -222,63 +145,63 @@ mode = mon_mode(c) if mode in ('weak', 'blink'): + mov.en = False ss = [ '. ', 'o ', 'O ', '<>', '()', '^^' ] - lsts = map( lambda s: [ (s, 'yellow', True) ], ss ) - show_anime(x, y, lsts, 8.0, restore=False) + lsts = map( lambda s: mk_slst(s, 'yellow', True), ss ) + bak = pac_slider( kon.slider(lsts, 8.0, None, True, repeat=False) ) add = mon_price.get() * 200 mon_price.twice() + arr_msg_pause( mk_slst( str(add) ), x, y-1, 1.0 ) score(add) - line_msg_pause(x, y-1, str(add), '', False, 1.0) mon_mode(c, 'ret') + arr.set_sdic('P', bak) + mov.en = True + break elif mode != 'ret' and not NO_DIE: + mov.en = False ss = [ '()', '||', ')(', '><', '--', '><', '--', '><', '--', '__', ' ' ] - lsts = map( lambda s: [ (s, 'yellow', True) ], ss ) + lsts = map( lambda s: mk_slst(s, 'yellow', True), ss ) lsts.append( [ SPC ] ) - show_anime(x, y, lsts, 5.0, restore=False) + bak = pac_slider( kon.slider(lsts, 5.0, None, True, repeat=False) ) v = 'over' if spare(-1) == 'over' else 'die' game_ev.set(v) + arr.set_sdic('P', bak) + break def get_hz(c, nx, ny): hz = stat_get(c).hz if c in MONS: - hz *= mon_hz_rate.get( mon_mode(c), 1.0 ) - hz *= warp_rate.get( warp_buf.get(nx, ny), 1.0 ) + mode = mon_mode(c) + hz *= mon_hz_rate.get(mode, 1.0) + if mode != 'ret': + hz *= warp_rate.get( warp_buf.get(nx, ny), 1.0 ) return hz -def move(px, py, nx, ny, c): - arr.set(px, py, c, False) - arr.set(nx, ny, c, True) - - dx = nx - px - if dx in (1, -1): # for warp - dx = -dx - stat = stat_get(c) - stat.dx = dx - arr.update(px, py) - arr.update(nx, ny) - - def late_update(): - stat.dx = 0 - arr.update(px, py) - arr.update(nx, ny, flush_f=True) - - sec = kon.hz_to_sec( get_hz(c, nx, ny) * 2 ) - stat.late_tmr.start( late_update, [], sec ) - else: - arr.update(px, py) - arr.update(nx, ny) - flush() - - meet_chk(nx, ny) +def move_new(): + e = kon.Empty() + e.en = True + def f(c, d, hz): + if e.en: + arr.move(c, d, hz) + (x, y) = arr.pos(c) + meet_chk(x, y) + e.f = f + return e +mov = move_new() +move = mov.f -lock_move = kon.lock_wrap( move ) +def short_sec(sec): + c = 'P' + hz = stat_get(c).hz + init_hz = 3.0 + return sec * init_hz / hz def mon_weak(): def tmr_f(c): mode = mon_mode(c) if mode == 'weak': mon_mode(c, 'blink') - stat_get(c).timer.start( tmr_f, [c], 5.0 ) + stat_get(c).timer.start( tmr_f, [c], short_sec(3.0) ) elif mode == 'blink': mon_mode(c, 'run') @@ -286,8 +209,8 @@ if mon_mode(c) not in ('cage', 'ret'): mon_mode(c, 'weak') stat = stat_get(c) - stat.dir = kon.bak_dir( stat.dir ) - stat.timer.start( tmr_f, [c], 15.0 ) + arr.set_dir( c, kon.bak_dir( arr.get_dir(c) ) ) + stat.timer.start( tmr_f, [c], short_sec(15.0) ) def try_eat(x, y): c = '.' if arr.get(x, y, '.') else 'O' if arr.get(x, y, 'O') else '' @@ -296,20 +219,18 @@ arr.set(x, y, c, False) stat_get('P').dot -= 1 - score( 20 if c == 'O' else 5 ) + score( 50 if c == 'O' else 10 ) if c == 'O': mon_weak() if stat_get('P').dot <= 0: + mov.en = False c = '#' - pos = pac_buf.pos(c) - - def shows(x, y, lst): - lst = map( lambda (s, col, r): (s, col, r) if flick.get() else ('==', 'white', False), lst ) - kon.shows(x, y, lst) - - flick = kon.flicker( 3.0, arr.update_xys, [ pos, shows ], True ) - kon.sleep(1.0) - flick.kill_join() + bak = arr.get_sdic(c) + lst = map( lambda col: mk_slst('==', col, False), ('white', 'blue') ) + slider = kon.slider(lst, 4.0, None, True) + arr.set_sdic( c, ('slider', slider) ) + kon.sleep(2.0) + arr.set_sdic(c, bak) game_ev.set('clear') kdir = kon.gval('') @@ -321,8 +242,8 @@ def th_pac(c): stat = stat_get(c) - (px, py) = stat.pos - pd = stat.dir + (px, py) = arr.pos(c) + pd = arr.get_dir(c) ds = next_ds(px, py, c) kd = kdir() @@ -330,64 +251,96 @@ d = kd if kd and kd in ds else pd if pd in ds else '' (nx, ny) = step_to(px, py, d) if d: - stat.dir = d - stat.pos = (nx, ny) - lock_move.f(px, py, nx, ny, c) + hz = get_hz(c, nx, ny) + move(c, d, hz) try_eat(nx, ny) -def sel_mon_way(c, x, y, ds): - def rand(n): - v = sum( sum( map( lambda c: list( stat_get(c).pos ), MOVES ), [] ) ) - return ( v / 4 ) % n - rand_sel = lambda lst: lst[ rand( len(lst) ) ] - - (tx, ty) = stat_get('P').pos - xd = R if tx - x > 0 else L - yd = D if ty - y > 0 else U +def rand(n): + v = sum( sum( map( lambda c: list( arr.pos(c) ), MOVES ), [] ) ) + return ( v / 4 ) % n + +rand_sel = lambda lst: lst[ rand( len(lst) ) ] + +def ways(x, y, tx, ty, ds, rev=False): + (dx, dy) = (tx - x, ty - y) + xd = R if dx > 0 else L + yd = D if dy > 0 else U + if rev: + (xd, yd) = ( kon.bak_dir(xd), kon.bak_dir(yd) ) rd = rand_sel(ds) + ds_ = [ xd, yd, rd ] if abs(dx) > abs(dy) else [ yd, xd, rd ] + return next( ( d for d in ds_ if d in ds ), ds[0] ) - return { - 'M': lambda: yd if yd in ds else rd, - 'R': lambda: xd if xd in ds else yd if yd in ds else rd, - 'C': lambda: xd if xd in ds else rd, - 'Y': lambda: rd, - }.get(c)() +def sel_mon_way(c, x, y, ds): + mode = mon_mode(c) + if mode == 'ret': + return mon_ret_buf.get(x, y) + + pd = arr.get_dir(c) + ds_ = filter( lambda d: d != kon.bak_dir(pd), ds ) + ds = ds_ if ds_ else ds + + (tx, ty) = arr.pos('P') + + if mode in ('weak', 'blink'): + return ways(x, y, tx, ty, ds, rev=True) + + if mode == 'run' and run_mode.get() == 'pato': + # MONS = 'RCMY' + (w2, h2) = (w/2, h/2) + area_d = { + 'R': (w2, 0, w2, h2), + 'C': (w2, h2, w2, h2), + 'M': (0, 0, w2, h2), + 'Y': (0, h2, w2, h2), + } + area = area_d.get(c) + d = pato_buf.get(x, y) + if kon.chk_xywh(x, y, *area) and d in DIRS: + return d + (ax, ay) = kon.cen_xywh(*area) + return ways(x, y, ax, ay, ds) + + if c == 'R': + return ways(x, y, tx, ty, ds) + if c == 'C': + return ways(x, y, 2*x-tx, 2*y-ty, ds) + if c == 'M': + (dx, dy) = kon.dir_to_xy( arr.get_dir('P') ) + return ways(x, y, tx + dx * 3, ty + dy * 3, ds) + return rand_sel(ds) def th_mon(c): stat = stat_get(c) - (px, py) = stat.pos - pd = stat.dir - mode = mon_mode(c) - + (px, py) = arr.pos(c) ds = next_ds(px, py, c) - d = ds[0] - if mode == 'ret': - d = mon_ret_buf.get(px, py) - else: - ds_ = filter( lambda d: d != kon.bak_dir(pd), ds ) - ds = ds_ if ds_ else ds - d = ds[0] if len(ds) == 1 else sel_mon_way(c, px, py, ds) + + d = sel_mon_way(c, px, py, ds) (nx, ny) = step_to(px, py, d) - stat.dir = d - stat.pos = (nx, ny) - lock_move.f(px, py, nx, ny, c) + hz = get_hz(c, nx, ny) + move(c, d, hz) + mode = mon_mode(c) if mode == 'cage' and pac_buf.get(px, py) == '=': mon_mode(c, 'run') elif mode == 'ret' and mon_ret_buf.get(nx, ny) == ' ': mon_mode(c, 'cage') - stat.th.hz = get_hz(c, nx, ny) - def score_new(): (x, y, lb, col, r) = (0, 0, 'score ', 'white', False) e = kon.Empty() e.v = 0 + def chk_1up(add): + t = 10000 + if e.v >= t and e.v - add < t: + spare(1) + arr_msg_pause( mk_slst('1UP') ) def f(add=0): e.v += add (dx, s) = (0, lb) if add == 0 else ( len(lb), str(e.v) ) kon.show(x + dx, y, s, col, r, flush_f=True) + chk_1up(add) return f score = score_new() @@ -422,76 +375,113 @@ spare = spare_new(2) +gate = kon.counter(4) + +mon_turn = lambda: map( lambda c: arr.set_dir( c, kon.bak_dir( arr.get_dir(c) ) ), MONS ) +run_mode = kon.slider( ['pato', 'chase'], f=mon_turn ) + def work(): - kon.lock_show.cond_f = lambda: not game_ev.get() + kon.clr() + + dot_n = len( pac_buf.poss('.') + pac_buf.poss('O') ) def init_map(): (w, h) = pac_buf.size() arr.clear() def f(x, y): c = pac_buf.get(x, y) - arr.set(x, y, c, True) - arr.update(x, y) + arr.set(x, y, c) kon.loop_xy(w, h, f) flush() def init_stat(clear=False): for c in MOVES: - stat = stat_get(c) - stat.dir = L if c == 'P' else U - stat.pos = pac_buf.pos(c) - stat.dx = 0 + (x, y) = pac_buf.pos(c) + d = L if c == 'P' else U + arr.set(x, y, c, True, True, d) + if c in MONS: - stat.mode = 'cage' if c in 'CMY' else 'run' - stat.flick.stop() + mon_mode( c, 'cage' if c in 'CMY' else 'run' ) if clear: + stat = stat_get(c) stat.hz *= 1.2 - stat.th.hz = stat.hz + stat.th.set_hz(stat.hz) if c == 'P': - stat.dot = len( pac_buf.pos('.') + pac_buf.pos('O') ) + stat.dot = dot_n + mon_r_hz = stat_get('R').hz + gate.set_hz( mon_r_hz / 10.0 ) + gate.restart() + + run_mode.set_hz( mon_r_hz / 100.0 ) + run_mode.restart() + + lst = map( lambda r: mk_slst('O ', 'yellow', r), (False, True) ) + arr.set_sdic( 'O', ( 'slider', kon.slider(lst, 2.0, None, True) ) ) + + arr.set_sdic( 'P', ('func', pac_show) ) + arr.set_sdic( '#', ('func', blk_show) ) + arr.set_sdic( '.', ( '', mk_slst('. ', 'white', False) ) ) + arr.set_sdic( '=', ( '', mk_slst('==', 'yellow', False) ) ) kon.th_loop(th_key) score() spare() - init_map() - for (c, stat) in c_stat_gets(MOVES): + stat_get('P').dot = dot_n + map( lambda c: set( stat_get(c), 'hz', 3.0 if c == 'P' else 3.3 ), MOVES ) + map( lambda c: set( stat_get(c), 'timer', kon.timer_new() ), MONS ) + + for c in MOVES: + stat = stat_get(c) f = th_pac if c == 'P' else th_mon - stat.th = kon.th_loop(f, [c], stat.hz, False) + stat.th = kon.th_loop(f, [c], stat.hz, run=False) - run = True - while run: - (x, y) = pac_buf.pos('B') - line_msg_pause(x, y, 'READY!', 'yellow', False, 1.0) + hdl_ready = lambda: arr_msg_pause( mk_slst('READY!', 'yellow'), *pac_buf.pos('B') ) + hdl_start = lambda: map( lambda c: stat_get(c).th.start(), MOVES ) + hdl_stop = lambda: map( lambda c: stat_get(c).th.stop(), MOVES ) + hdl_timer_cancel = lambda: map( lambda c: stat_get(c).timer.cancel(), MONS ) + hdl_rm = lambda: ( map( lambda c: arr.rm(c), MOVES ), arr.update_all(flush_f=True) )[-1] - map( lambda stat: stat.th.start(), stat_gets(MOVES) ) + init_map() + init_stat() + hdl_ready() + hdl_start() + while True: while not game_ev.wait(1.0): kon.sleep_hz(1.0) # for ^C - for stat in stat_gets(MOVES): - stat.th.stop() - stat.late_tmr.cancel() - if has(stat, 'timer'): - stat.timer.cancel() - kon.sleep(1.0) - v = game_ev.get() - game_ev.clear() - - for (c, stat) in c_stat_gets(MOVES): - (x, y) = stat.pos - arr.set(x, y, c, False) - xys = [(x, y)] + map( lambda d: step_to(x, y, d), DIRS ) - arr.update_xys( xys, flush_f=True ) - - if v == 'die': + if v == 'start': + hdl_start() + elif v == 'stop': + hdl_stop() + + elif v == 'die': + hdl_stop() + hdl_timer_cancel() + kon.sleep(2.0) + hdl_rm() init_stat() + hdl_ready() + hdl_start() + mov.en = True + elif v == 'clear': - init_stat(clear=True) + hdl_stop() + hdl_timer_cancel() + kon.sleep(2.0) + hdl_rm() init_map() + init_stat(clear=True) + hdl_ready() + hdl_start() + mov.en = True + elif v == 'over': - run = False + break + + game_ev.clear() if __name__ == "__main__": kon.main( work, '[-bw] [-m]' ) diff -urN v2/pato.txt v3/pato.txt --- v2/pato.txt 1970-01-01 09:00:00.000000000 +0900 +++ v3/pato.txt 2017-10-17 03:15:12.000000000 +0900 @@ -0,0 +1,23 @@ +##################### +#dllll # rrrrd# +#d###u### # ###u###d# +#d###u### # ###u###d# +#d###u### # ###u###d# +#rrrru ullll# +# ### # ##### # ### # +# # # # # +##### ### # ### ##### + # # # # +##### # ## ## # ##### + # # +##### # ##### # ##### + # # # # +##### # ##### # ##### +#rrrrd # dllll# +#u###d### # ###d###u# +#ull#d d#rru# +###u#d# ##### #d#u### +# ull# # #rru # +# ####### # ####### # +# # +##################### diff -urN v2/warp.txt v3/warp.txt --- v2/warp.txt 2017-10-06 22:00:00.000000000 +0900 +++ v3/warp.txt 2017-10-17 03:15:12.000000000 +0900 @@ -4,9 +4,9 @@ # ### ### # ### ### # # ### ### # ### ### # # # -# ### #u#####u# ### # +# ### # ##### # ### # # # # # # -##### ### # ### ##### +##### ###d#d### ##### # # # # ##### # ##u## # ##### L4321 # # 1234R @@ -14,7 +14,7 @@ # # # # ##### # ##### # ##### # # # -# ### ### # ### ### # +# ### ###d#d### ### # # # # # ### # # ##### # # ### # # # # #