--- a/python30/Demo/curses/life.py 2008-07-29 12:14:57.000000000 +1000 +++ b/python30/Demo/curses/life.py 2008-07-29 11:45:14.000000000 +1000 @@ -16,9 +16,73 @@ # Use colour if available # Make board updates faster # +# +# Revision history +# +# 2008-07-23 Minh Van Nguyen +# Parse the command line for an argument specifying the character +# used to render live cells. The table below specifies those +# characters that can be given at the command line, as well as the +# format in which those characters can be passed (at least under +# GNU bash 3.2.39). An "X" under any of the four formats "as is", +# "single quotes", "double quotes" or "back slash" means that the +# character in question can be given in that format. For example, +# any alphabetic character can be given as is on the command line, +# be enclosed within a pair of single or double quotation marks, +# or be prefixed with the back slash character. But the ampersand +# character "&" cannot be given as is, since a command like +# +# $ ./life.py & +# +# would start life.py as a background process. To make "&" the +# character used for rendering, you can do this +# +# $ ./life.py '&' +# +# | as is single quotes double quotes back slash +# ---------------------------------------------------------- +# a...z | X X X X +# A...Z | X X X X +# 0...9 | X X X X +# ~ | X X X +# ` | X X +# ! | X X X +# @ | X X X X +# # | X X X +# $ | X X X X +# % | X X X X +# ^ | X X X X +# & | X X X +# * | X X X +# ( | X X X +# ) | X X X +# - | X X X X +# _ | X X X X +# = | X X X X +# + | X X X X +# \ | X X +# | | X X X +# { | X X X X +# } | X X X X +# [ | X X X X +# ] | X X X X +# ; | X X X +# : | X X X X +# ' | X X +# " | X X +# , | X X X X +# < | X X X +# > | X X X +# . | X X X X +# / | X X X X +# ? | X X X X +# space | X X +# tab | + import random, string, traceback import curses +import sys class LifeBoard: """Encapsulates a Life board @@ -63,14 +127,14 @@ class LifeBoard: def set(self, y, x): """Set a cell to the live state""" if x<0 or self.X<=x or y<0 or self.Y<=y: - raise ValueError("Coordinates out of range %i,%i"% (y,x)) + raise ValueError, "Coordinates out of range %i,%i"% (y,x) self.state[x,y] = 1 def toggle(self, y, x): """Toggle a cell's state between live and dead""" if x<0 or self.X<=x or y<0 or self.Y<=y: - raise ValueError("Coordinates out of range %i,%i"% (y,x)) - if (x,y) in self.state: + raise ValueError, "Coordinates out of range %i,%i"% (y,x) + if self.state.has_key( (x,y) ): del self.state[x,y] self.scr.addch(y+1, x+1, ' ') else: @@ -89,7 +153,7 @@ class LifeBoard: if not update_board: for i in range(0, M): for j in range(0, N): - if (i,j) in self.state: + if self.state.has_key( (i,j) ): self.scr.addch(j+1, i+1, self.char) else: self.scr.addch(j+1, i+1, ' ') @@ -102,10 +166,10 @@ class LifeBoard: L = range( max(0, i-1), min(M, i+2) ) for j in range(0, N): s = 0 - live = (i,j) in self.state + live = self.state.has_key( (i,j) ) for k in range( max(0, j-1), min(N, j+2) ): for l in L: - if (l,k) in self.state: + if self.state.has_key( (l,k) ): s += 1 s -= live if s == 3: @@ -145,7 +209,7 @@ def display_menu(stdscr, menu_y): stdscr.addstr(menu_y+1, 4, 'E)rase the board, R)andom fill, S)tep once or C)ontinuously, Q)uit') -def keyloop(stdscr): +def keyloop(stdscr, char=ord('*')): # Clear the screen and display the menu of keys stdscr.clear() stdscr_y, stdscr_x = stdscr.getmaxyx() @@ -154,11 +218,11 @@ def keyloop(stdscr): # Allocate a subwindow for the Life board and create the board object subwin = stdscr.subwin(stdscr_y-3, stdscr_x, 0, 0) - board = LifeBoard(subwin, char=ord('*')) + board = LifeBoard(subwin, char) board.display(update_board=False) # xpos, ypos are the cursor's position - xpos, ypos = board.X//2, board.Y//2 + xpos, ypos = board.X/2, board.Y/2 # Main loop: while (1): @@ -208,9 +272,14 @@ def keyloop(stdscr): pass -def main(stdscr): - keyloop(stdscr) # Enter the main loop +def main(stdscr, char=ord('*')): + keyloop(stdscr, char) # Enter the main loop -if __name__ == '__main__': - curses.wrapper(main) +if __name__ == "__main__": + firstArgIndex = 1 + if sys.argv[firstArgIndex:]: + curses.wrapper(main, ord(sys.argv[firstArgIndex])) + else: + # default rendering character is the asterisk character "*" + curses.wrapper(main, ord('*'))