1 s# Copyright (C) 2001-2008, The Perl Foundation.
6 examples/library/ncurses_life.pir - Conway's Game of Life (ncurses version)
10 % ./parrot examples/library/ncurses_life.pir examples/library/acorn.l
14 An C<ncurses> version of Conway's Life. F<acorn.l> is a I<life> file.
16 This version can load F<life.l> files (#P, #A, #R formats only). You get
17 a lot of .l files by installing C<xlife>.
27 =item C<8>, C<2>, C<UP>, C<DOWN>
29 Move world up or down.
31 =item C<4>, C<6>, C<LEFT>, C<RIGHT>
33 Move world left or right
41 Toggle running the game.
45 Single step one generation.
62 load_bytecode "library/ncurses.pasm"
63 # should autogenerate these
64 .globalconst int KEY_DOWN = 258
65 .globalconst int KEY_UP = 259
66 .globalconst int KEY_LEFT = 260
67 .globalconst int KEY_RIGHT= 261
68 .globalconst int KEY_HOME = 262
69 # set generation count
70 .const int MAX_GEN = 5000
71 # kill the space ship flag
72 .const int COLLIDE = 1
79 .local int SUPRESS_PRINT
91 # 15 * sizef is real size of world
100 # If true, we don't print
102 stop = 0 # -1 start with <g>o
106 ENDWIN = global "ncurses::endwin"
107 CURS_SET = global "ncurses::curs_set"
114 if $I0 <= 1 goto def_world
115 (S15, err) = _load_file(argv, size)
121 S15 = _def_world(sizef, size, COLLIDE)
124 STDSCR = _init_curses()
129 _dump(S15, SUPRESS_PRINT, x_offs, y_offs, size, GEN_COUNT, STDSCR, delay)
131 if GEN_COUNT >= MAX_GEN goto getout
132 (stop, x_offs, y_offs, delay) = _check_key(stop, x_offs, y_offs, delay)
134 if stop != -2 goto not_one
138 if stop < 0 goto no_gen
142 I31 = GEN_COUNT % 100
147 (S15, stop) = _generate(S15, size, stop)
155 TIME_DIFF = CUR_TIME - START_TIME
157 # sleeping invalidates these data
160 print " generations in "
163 GPS = GEN_COUNT / TIME_DIFF
166 print " generations/sec\n"
171 print " bytes were allocated\n"
176 print " DOD runs were made\n"
181 print " collection runs were made\n"
184 print "Copying a total of "
191 print " active Buffer structs\n"
196 print " total Buffer structs\n"
208 # S15 has the incoming string, S0 is scratch
211 .param int SUPRESS_PRINT
219 if SUPRESS_PRINT goto dumpend
226 WCLEAR = global "ncurses::wclear"
227 MVWADDSTR = global "ncurses::mvwaddstr"
228 MVWADDCH = global "ncurses::mvwaddch"
229 WREFRESH = global "ncurses::wrefresh"
232 MVWADDSTR(STDSCR, 0, 0, "Generation: ")
234 MVWADDSTR(STDSCR, 0, 13, $S0)
238 .local int CHARACTER_OFFSET
239 CHARACTER_OFFSET = $I0
261 # TODO skip unprintable out of screen
262 if CHARACTER_OFFSET >= total goto dumpend
264 substr_r $S0, world, CHARACTER_OFFSET, 1
265 if $S0 != "*" goto incit
266 X_COORD = CHAR_POS % size
267 Y_COORD = CHAR_POS / size
268 Y_COORD = Y_COORD + 2
269 if X_COORD > cols goto incit
270 if Y_COORD > rows goto dumpend
271 MVWADDCH(STDSCR, Y_COORD, X_COORD, 42) # behold, the lowly star
273 incit: inc CHARACTER_OFFSET
275 if CHARACTER_OFFSET < total goto printloop
279 if delay < 100 goto dumpend
280 # as we gonna sleep here, lets burn some cycles to
281 # check if usleep is available
284 dlfunc USLEEP, $P0, "usleep", "vi"
297 .local pmc START_COLOR
299 .local pmc COLOR_PAIR
306 INITSCR = global "ncurses::initscr"
307 START_COLOR = global "ncurses::start_color"
308 INIT_PAIR = global "ncurses::init_pair"
309 COLOR_PAIR = global "ncurses::COLOR_PAIR"
310 WATTRON = global "ncurses::wattron"
311 CURS_SET = global "ncurses::curs_set"
312 NODELAY = global "ncurses::nodelay"
313 KEYPAD = global "ncurses::keypad"
319 # Color pair 1, dark green fg, black background
323 # We pass what's returned from COLOR_PAIR straight on
326 CURS_SET(0) # turn off cursor
327 NODELAY(STDSCR, 1) # set nodelay mode
328 KEYPAD(STDSCR, 1) # set keypad mode
350 .local int check # pos in world
351 .local string new_world
353 # allocate new world with all space
354 repeat new_world, " ", len
364 # $S0 is always overwritten, so reuse it
365 substr_r $S0, world, check, 1
366 if $S0 != "*" goto North
373 substr_r $S0, world, check, 1
374 if $S0 != "*" goto NE
382 substr_r $S0, world, check, 1
383 if $S0 != "*" goto West
390 substr_r $S0, world, check, 1
391 if $S0 != "*" goto East
398 substr_r $S0, world, check, 1
399 if $S0 != "*" goto SW
407 substr_r $S0, world, check, 1
408 if $S0 != "*" goto South
415 substr_r $S0, world, check, 1
416 if $S0 != "*" goto SE
424 substr_r $S0, world, check, 1
425 if $S0 != "*" goto checkl
428 substr_r $S0, world, pos, 1
429 if $S0 == "*" goto check_alive
431 # If eq 3, put a star in else a space
433 if count == 3 goto star
437 if count < 2 goto space
438 if count > 3 goto space
440 substr new_world, pos, 1, "*"
441 space: # is space already
443 if pos < len goto genloop
445 if new_world != world goto dif
449 .return(new_world, stop)
458 unless $I0 goto nosize
531 err = "File not found " . file
539 repeat world, " ", $I0
547 .const int PICTURE = 1
557 eq $S0, "#", check_format
560 if format != PICTURE goto not_pic
561 substr world, pos, len, line
565 if format != ABS goto not_abs
568 if format != REL goto not_rel
570 # parse \s(\d+) (\d+)
571 # I really want PCRE or better inside Parrot :)
578 if s >= len goto space
581 if $I0 == 32 goto space
582 if $I0 == 9 goto space
583 if $I0 == 43 goto cont_d # ignore +
584 if $I0 == 45 goto dig # sing, start dig
585 if $I0 >= 0x30 goto dig1
586 err = "Found junk at " . $S0
590 if $I0 <= 0x39 goto dig
591 err = "Found junk at " . $S0
594 dig: if in_digit == 1 goto cont_d
595 if in_digit == 3 goto cont_d
603 if in_digit == 0 goto cont_d
604 if in_digit == 2 goto cont_d
607 substr $S1, line, start, $I1
610 if s >= len goto loop
618 err = "Unhandled file format"
623 if $S0 == "C" goto loop # comment
624 if $S0 == "#" goto loop # comment
625 if $S0 == "N" goto loop # name of pattern
626 if $S0 == "O" goto loop # owner
627 if $S0 == "U" goto loop # use format
628 unless format goto f1
629 err = "Mixed formats found"
632 if $S0 != "P" goto not_P # picture
635 if $S0 != "A" goto not_A # absolute
637 points = new 'ResizableIntegerArray'
639 if $S0 != "R" goto not_R # relative
641 points = new 'ResizableIntegerArray'
647 if format == PICTURE goto done
648 # we have an array of x,y pairs now
668 if x >= min_x goto no_min_x
671 if x <= max_x goto no_max_x
674 if y >= min_y goto no_min_y
677 if y <= max_y goto no_max_y
707 # TODO abs/rel and bounds checking
723 GETCH = global "ncurses::getch"
725 if key == KEY_LEFT goto is_4
726 if key == KEY_RIGHT goto is_6
727 if key == KEY_UP goto is_8
728 if key == KEY_DOWN goto is_2
729 if key == KEY_HOME goto is_5
730 if key != 113 goto no_q
733 if key != 81 goto no_Q
737 if key != 0x38 goto no_8
742 if key != 0x32 goto no_2
744 if y_offs < 10 goto key_done
748 if key != 0x34 goto no_4
753 if key != 0x36 goto no_6
755 if x_offs < 10 goto key_done
759 if key != 0x35 goto no_5
765 if key != 103 goto no_g
773 if key != 111 goto no_o
777 if key != 115 goto no_s
782 if key != 102 goto no_f
785 if delay goto key_done
791 .return(stop, x_offs, y_offs, delay)
796 F<examples/library/acorn.l>, F<examples/pasm/life.pasm>,
797 F<library/ncurses.pasm>, F<library/ncurses.declarations>.
805 # vim: expandtab shiftwidth=4 ft=pir: