diff options
author | Walter Bender <walter@walter-laptop.(none)> | 2010-01-09 20:07:58 (GMT) |
---|---|---|
committer | Walter Bender <walter@walter-laptop.(none)> | 2010-01-09 20:07:58 (GMT) |
commit | 49141e8b29a9bb4fefb46745961c6d848b07704f (patch) | |
tree | 5b2643776b7ce2715337a9b86b6092b1e5de1d04 | |
parent | d287399b5fc873c0bd545eb5ed37cd9158a76350 (diff) |
general cleanup
-rw-r--r-- | VisualMatchActivity.py | 301 | ||||
-rw-r--r-- | deck.py | 46 | ||||
-rw-r--r-- | grid.py | 7 | ||||
-rw-r--r-- | window.py | 54 |
4 files changed, 223 insertions, 185 deletions
diff --git a/VisualMatchActivity.py b/VisualMatchActivity.py index 87f850b..5bbe05b 100644 --- a/VisualMatchActivity.py +++ b/VisualMatchActivity.py @@ -53,7 +53,7 @@ import os.path import logging _logger = logging.getLogger('visualmatch-activity') try: - _old_Sugar_system = False + _old_sugar_system = False import json json.dumps from json import load as jload @@ -64,7 +64,7 @@ except (ImportError, AttributeError): from simplejson import load as jload from simplejson import dump as jdump except: - _old_Sugar_system = True + _old_sugar_system = True from StringIO import StringIO @@ -78,7 +78,7 @@ import card level_icons = ['level1','level2'] level_labels = [_('beginner'),_('expert')] -level_decksize = [(DECKSIZE-DEAL)/3, DECKSIZE-DEAL] +level_decksize = [DECKSIZE/3, DECKSIZE] SERVICE = 'org.sugarlabs.VisualMatchActivity' IFACE = SERVICE @@ -92,43 +92,137 @@ class VisualMatchActivity(activity.Activity): def __init__(self, handle): super(VisualMatchActivity,self).__init__(handle) - # Turn sharing off - # self.share(private=True) + # Set things up. + self._read_journal_data() + datapath = self._find_datapath(_old_sugar_system) + gencards.generator(datapath, self._numberO, self._numberC) + sugar86 = False + self._setup_toolbars(sugar86) + canvas = self._setup_canvas(datapath) + self._setup_presence_service() - # Read settings from the Journal - try: + # Then start playing the game. + if not hasattr(self,'_saved_state'): + self._saved_state = None + print "calling new game for the first time" + window.new_game(self.vmw, self._saved_state, self._deck_index) + + # + # Button callbacks + # + def _select_game_cb(self, button, activity, cardtype): + if window.joiner(self.vmw): # joiner cannot change level + return + activity.vmw.cardtype = cardtype + window.new_game(activity.vmw) + + def _robot_cb(self, button, activity): + if activity.vmw.robot is True: + activity.vmw.robot = False + self.robot_button.set_tooltip(_('Play with the computer.')) + self.robot_button.set_icon('robot-off') + else: + activity.vmw.robot = True + self.robot_button.set_tooltip( + _('Stop playing with the computer.')) + self.robot_button.set_icon('robot-on') + + def _level_cb(self, button, activity): + if window.joiner(self.vmw): # joiner cannot change level + return + activity.vmw.level = 1-activity.vmw.level + self.level_label.set_text(self.calc_level_label(activity.vmw.low_score, + activity.vmw.level)) + self.level_button.set_icon(level_icons[activity.vmw.level]) + window.new_game(activity.vmw) + + def calc_level_label(self, low_score, play_level): + if low_score[play_level] == -1: + return level_labels[play_level] + else: + return "%s (%d:%02d)" % \ + (level_labels[play_level], + int(low_score[play_level]/60), + int(low_score[play_level]%60)) + + def _number_card_O_cb(self, button, activity, numberO): + if window.joiner(self.vmw): # joiner cannot change decks + return + activity.vmw.numberO = numberO + gencards.generate_number_cards(activity.vmw.path, + activity.vmw.numberO, + activity.vmw.numberC) + activity.vmw.cardtype = 'number' + window.new_game(activity.vmw) + + def _number_card_C_cb(self, button, activity, numberC): + if window.joiner(self.vmw): # joiner cannot change decks + return + activity.vmw.numberC = numberC + gencards.generate_number_cards(activity.vmw.path, + activity.vmw.numberO, + activity.vmw.numberC) + activity.vmw.cardtype = 'number' + window.new_game(activity.vmw) + + def _robot_time_spin_cb(self, button): + self.vmw.robot_time = self._robot_time_spin.get_value_as_int() + return + + ''' + def _journal_cb(self, button, path): + title_alert = NamingAlert(self, path) + title_alert.set_transient_for(self.get_toplevel()) + title_alert.show() + self.reveal() + return True + ''' + + # + # There may be data from a previous instance. + # + def _read_journal_data(self): + try: # Try reading restored settings from the Journal. self._play_level = int(self.metadata['play_level']) self._robot_time = int(self.metadata['robot_time']) self._cardtype = self.metadata['cardtype'] - _numberO = int(self.metadata['numberO']) - _numberC = int(self.metadata['numberC']) - _matches = int(self.metadata['matches']) - _robot_matches = int(self.metadata['robot_matches']) - _total_time = int(self.metadata['total_time']) - _deck_index = int(self.metadata['deck_index']) self._low_score = [int(self.metadata['low_score_beginner']),\ int(self.metadata['low_score_expert'])] - except: + self._numberO = int(self.metadata['numberO']) + self._numberC = int(self.metadata['numberC']) + self._matches = int(self.metadata['matches']) + self._robot_matches = int(self.metadata['robot_matches']) + self._total_time = int(self.metadata['total_time']) + self._deck_index = int(self.metadata['deck_index']) + except: # Otherwise, use default values. self._play_level = 0 self._robot_time = 60 self._cardtype = 'pattern' - _numberO = PRODUCT - _numberC = HASH - _matches = 0 - _robot_matches = 0 - _total_time = 0 - _deck_index = 0 self._low_score = [-1,-1] + self._numberO = PRODUCT + self._numberC = HASH + self._matches = 0 + self._robot_matches = 0 + self._total_time = 0 + self._deck_index = 0 - # Find a path to write card files - try: - datapath = os.path.join(activity.get_activity_root(), 'data') - except: - datapath = os.path.join(os.environ['HOME'], ".sugar", "default", - SERVICE, 'data') - gencards.generator(datapath, _numberO, _numberC) + # + # Find the datapath for saving card files + # + def _find_datapath(self, _old_sugar_system): + # Create the card files. + self._old_sugar_system = _old_sugar_system + if self._old_sugar_system: + return os.path.join(os.environ['HOME'], ".sugar", "default", + SERVICE, 'data') + else: + return os.path.join(activity.get_activity_root(), 'data') - # Create the toolbars + # + # Setup the toolbars. + # + def _setup_toolbars(self, sugar86): + # Create the toolbars. if sugar86 is True: toolbar_box = ToolbarBox() @@ -299,7 +393,7 @@ class VisualMatchActivity(activity.Activity): toolbar_box.toolbar.insert(separator, -1) self.deck_label = gtk.Label("%d %s" % \ - (level_decksize[self._play_level], _('cards'))) + (level_decksize[self._play_level]-DEAL, _('cards'))) self.deck_label.show() deck_toolitem = gtk.ToolItem() deck_toolitem.add(self.deck_label) @@ -361,7 +455,10 @@ class VisualMatchActivity(activity.Activity): self.toolbox.show() self.toolbox.set_current_toolbar(1) - # Create a canvas + # + # Create a canvas. + # + def _setup_canvas(self, datapath): canvas = gtk.DrawingArea() canvas.set_size_request(gtk.gdk.screen_width(), gtk.gdk.screen_height()) @@ -369,41 +466,19 @@ class VisualMatchActivity(activity.Activity): canvas.show() self.show_all() - # Initialize the canvas, game state, et al. self.vmw = window.new_window(canvas, datapath, self) self.vmw.level = self._play_level self.vmw.cardtype = self._cardtype self.vmw.robot = False self.vmw.robot_time = self._robot_time self.vmw.low_score = self._low_score - self.vmw.numberO = _numberO - self.vmw.numberC = _numberC - self.vmw.matches = _matches - self.vmw.robot_matches = _robot_matches - self.vmw.total_time = _total_time + self.vmw.numberO = self._numberO + self.vmw.numberC = self._numberC + self.vmw.matches = self._matches + self.vmw.robot_matches = self._robot_matches + self.vmw.total_time = self._total_time self.vmw.buddies = [] - if not hasattr(self,'_saved_state'): - self._saved_state = None - - # Start playing the game - window.new_game(self.vmw, self.vmw.cardtype, False, - self._saved_state, _deck_index) - - # - # A simplistic sharing model: the sharer is the master - # - - # Get the Presence Service - self.pservice = presenceservice.get_instance() - self.initiating = None # sharing (True) or joining (False) - - # Add my buddy object to the list - owner = self.pservice.get_owner() - self.owner = owner - self.vmw.buddies.append(self.owner) - self._share = "" - self.connect('shared', self._shared_cb) - self.connect('joined', self._joined_cb) + return canvas # # Write data to the Journal @@ -446,7 +521,8 @@ class VisualMatchActivity(activity.Activity): for i in self.vmw.match_list: data.append(self.vmw.deck.spr_to_card(i).index) - if _old_Sugar_system is True: + if self._old_sugar_system is True: + print "old-style Sugar" return json.write(data) else: io = StringIO() @@ -463,7 +539,8 @@ class VisualMatchActivity(activity.Activity): f.close() def _load(self, data): - if _old_Sugar_system is True: + if self._old_sugar_system is True: + print "old-style Sugar" saved_state = json.read(data) else: io = StringIO(data) @@ -472,74 +549,19 @@ class VisualMatchActivity(activity.Activity): self._saved_state = saved_state # - # Button callbacks + # Setup the Presence Service # - def _select_game_cb(self, button, activity, cardtype): - if window._joiner(self.vmw): # joiner cannot change level - return - window.new_game(activity.vmw, cardtype) - - def _robot_cb(self, button, activity): - if activity.vmw.robot is True: - activity.vmw.robot = False - self.robot_button.set_tooltip(_('Play with the computer.')) - self.robot_button.set_icon('robot-off') - else: - activity.vmw.robot = True - self.robot_button.set_tooltip( - _('Stop playing with the computer.')) - self.robot_button.set_icon('robot-on') - - def _level_cb(self, button, activity): - if window._joiner(self.vmw): # joiner cannot change level - return - activity.vmw.level = 1-activity.vmw.level - self.level_label.set_text(self.calc_level_label(activity.vmw.low_score, - activity.vmw.level)) - self.level_button.set_icon(level_icons[activity.vmw.level]) - cardtype = activity.vmw.cardtype - activity.vmw.cardtype = '' # force generation of new deck - window.new_game(activity.vmw, cardtype) - - def calc_level_label(self, low_score, play_level): - if low_score[play_level] == -1: - return level_labels[play_level] - else: - return "%s (%d:%02d)" % \ - (level_labels[play_level], - int(low_score[play_level]/60), - int(low_score[play_level]%60)) - - def _number_card_O_cb(self, button, activity, numberO): - if window._joiner(self.vmw): # joiner cannot change level - return - activity.vmw.numberO = numberO - gencards.generate_number_cards(activity.vmw.path, - activity.vmw.numberO, - activity.vmw.numberC) - activity.vmw.cardtype = '' # force generation of new deck - window.new_game(activity.vmw, 'number') - - def _number_card_C_cb(self, button, activity, numberC): - if window._joiner(self.vmw): # joiner cannot change level - return - activity.vmw.numberC = numberC - gencards.generate_number_cards(activity.vmw.path, - activity.vmw.numberO, - activity.vmw.numberC) - activity.vmw.cardtype = '' # force generation of new deck - window.new_game(activity.vmw, 'number') - - def _robot_time_spin_cb(self, button): - self.vmw.robot_time = self._robot_time_spin.get_value_as_int() - return + def _setup_presence_service(self): + self.pservice = presenceservice.get_instance() + self.initiating = None # sharing (True) or joining (False) - def _journal_cb(self, button, path): - title_alert = NamingAlert(self, path) - title_alert.set_transient_for(self.get_toplevel()) - title_alert.show() - self.reveal() - return True + # Add my buddy object to the list + owner = self.pservice.get_owner() + self.owner = owner + self.vmw.buddies.append(self.owner) + self._share = "" + self.connect('shared', self._shared_cb) + self.connect('joined', self._joined_cb) # # Sharing-related callbacks @@ -577,6 +599,7 @@ class VisualMatchActivity(activity.Activity): self.initiating = False _logger.debug('I joined a shared activity.') + print('I joined a shared activity.') self.conn = self._shared_activity.telepathy_conn self.tubes_chan = self._shared_activity.telepathy_tubes_chan @@ -622,7 +645,7 @@ class VisualMatchActivity(activity.Activity): if self.waiting_for_deck is True: self._send_event("j") - # Data is passed as tuples: cmd:text. + # Data is passed as tuples: cmd:text def event_received_cb(self, text): if text[0] == 'B': e,card_index = text.split(':') @@ -634,20 +657,28 @@ class VisualMatchActivity(activity.Activity): _logger.debug("receiving selection index: " + card_index) window._process_selection(self.vmw, self.vmw.selected[int(card_index)].spr) - elif text[0] == 'j': # request for current state from joiner - if self.initiating is True: + elif text[0] == 'j': + if self.initiating is True: # Only the sharer "shares". _logger.debug("serialize the project and send to joiner") self._send_event("P:" + str(self.vmw.level)) self._send_event("X:" + str(self.vmw.deck.index)) self._send_event("M:" + str(self.vmw.matches)) + self._send_event("C:" + self.vmw.cardtype) self._send_event("D:" + str(self._dump())) - elif text[0] == 'J': # new game, so make a request for current state + elif text[0] == 'J': # Force a request for current state. self._send_event("j") self.waiting_for_deck = True + elif text[0] == 'C': + e,text = text.split(':') + _logger.debug("receiving cardtype from sharer " + text) + self.vmw.cardtype = text elif text[0] == 'P': e,text = text.split(':') _logger.debug("receiving play level from sharer " + text) self.vmw.level = int(text) + self.level_label.set_text(self.calc_level_label( + self.vmw.low_score, self.vmw.level)) + self.level_button.set_icon(level_icons[self.vmw.level]) elif text[0] == 'X': e,text = text.split(':') _logger.debug("receiving deck index from sharer " + text) @@ -662,8 +693,8 @@ class VisualMatchActivity(activity.Activity): _logger.debug("receiving deck data from sharer") self._load(text) self.waiting_for_deck = False - window.new_game(self.vmw, self.vmw.cardtype, False, - self._saved_state, self.vmw.deck.index) + window.new_game(self.vmw, self._saved_state, + self.vmw.deck.index) # Send event through the tube def _send_event(self, entry): @@ -682,8 +713,8 @@ class ChatTube(ExportedGObject): self.stack_received_cb = stack_received_cb self.stack = '' - self.tube.add_signal_receiver(self.send_stack_cb, 'SendText', IFACE, \ - path=PATH, sender_keyword='sender') + self.tube.add_signal_receiver(self.send_stack_cb, 'SendText', IFACE, + path=PATH, sender_keyword='sender') def send_stack_cb(self, text, sender=None): if sender == self.tube.get_unique_name(): @@ -848,7 +879,7 @@ class ProjectToolbar(gtk.Toolbar): separator.show() self.activity.deck_label = gtk.Label("%d %s" % \ - (level_decksize[self.activity._play_level], _('cards'))) + (level_decksize[self.activity._play_level]-DEAL, _('cards'))) self.activity.deck_label.show() self.activity.deck_toolitem = gtk.ToolItem() self.activity.deck_toolitem.add(self.activity.deck_label) @@ -29,7 +29,7 @@ from constants import * from card import * # -# class for defining deck of cards +# Class for defining deck of cards # class Deck: def __init__(self, sprites, path, cardtype, width, height, level=HIGH): @@ -48,57 +48,59 @@ class Deck: self.cards.append(Card(sprites, path, cardtype, width, height, [shape,color,num,fill])) - # Track how many cards are in the deck. - self.count = len(self.cards) - # Remember the position in the deck. + # Remember the current position in the deck. self.index = 0 - # shuffle the deck + # Shuffle the deck. def shuffle(self): - decksize = self.count - # hide all the cards + decksize = self.count() + # Hide all the cards. for c in self.cards: c.hide_card() - # randomize the deck + # Randomize the card order. for n in range(decksize*4): i = random.randrange(decksize) j = random.randrange(decksize) self.swap_cards(i,j) - # reset the index to the beginning of the deck after a shuffle + # Reset the index to the beginning of the deck after a shuffle, self.index = 0 return - # restore deck upon resume + # Restore the deck upon resume. def restore(self, saved_deck_indices): - self.count = len(saved_deck_indices) + decksize = len(saved_deck_indices) + # If we have a short deck, then we need to abort. + if self.count() < decksize: + return False _deck = [] for i in saved_deck_indices: _deck.append(self.index_to_card(i)) - for i in range(self.count): + for i in range(decksize): self.cards[i] = _deck[i] + return True - # swap the position of two cards in the deck + # Swap the position of two cards in the deck. def swap_cards(self,i,j): tmp = self.cards[j] self.cards[j] = self.cards[i] self.cards[i] = tmp return - # given a sprite, find the corresponding card in the deck + # Given a sprite, find the corresponding card in the deck. def spr_to_card(self, spr): for c in self.cards: if c.spr == spr: return c return None - # given a card index, find the corresponding card in the deck + # Given a card index, find the corresponding card in the deck. def index_to_card(self, i): for c in self.cards: if c.index == i: return c return None - # deal the next card from the deck + # Return the next card from the deck. def deal_next_card(self): if self.empty(): return None @@ -106,22 +108,26 @@ class Deck: self.index += 1 return next_card - # is the deck empty? + # Is the deck empty? def empty(self): if self.cards_remaining() > 0: return False else: return True - # cards remaining in the deck + # Return how many cards are remaining in the deck. def cards_remaining(self): - return(self.count-self.index) + return(self.count()-self.index) - # hide the deck + # Hide the deck. def hide(self): for c in self.cards: c.hide_card() + # Return the length of the deck. + def count(self): + return len(self.cards) + @@ -85,7 +85,9 @@ class Grid: # Remove a match from the grid and replace it with new cards from the deck. def remove_and_replace(self, clicked_set, deck): for a in clicked_set: - # Find the index into the grid of the clicked card + # Move the match to the match display area + self.display_match(a, clicked_set.index(a)) + # Find the index into the grid of the match card i = self.spr_to_grid(a) # Don't add new cards if bottom row is occupied if self.cards_in_grid() == DEAL: @@ -100,9 +102,8 @@ class Grid: else: # Mark as empty the grid positions we are not refilling self.grid[i] = None - self.display_match(a, clicked_set.index(a)) - # Move clicked card to the match area + # Move card to the match area. def display_match(self, spr, i): spr.move((MATCH_POSITION, self.top + i*self.yinc)) spr.set_layer(2000) @@ -84,45 +84,45 @@ def new_window(canvas, path, parent=None): # # Start a new game. # -def new_game(vmw, cardtype, button_push=True, saved_state=None, deck_index=0): - if not hasattr(vmw, 'deck'): - # The first time through, initialize the deck, grid, and overlays. - vmw.deck = Deck(vmw.sprites, vmw.path, cardtype, vmw.card_width, - vmw.card_height, difficulty_level[vmw.level]) +def new_game(vmw, saved_state=None, deck_index=0): + + # If there is already a deck, hide it. + if hasattr(vmw, 'deck'): + vmw.deck.hide() + + # The first time through, initialize the deck, grid, and overlays. + if not hasattr(vmw, 'grid'): vmw.grid = Grid(vmw.width, vmw.height, vmw.card_width, vmw.card_height) for i in range(0,3): vmw.selected.append(Card(vmw.sprites, vmw.path, "", vmw.card_width, - vmw.card_height, [SELECTMASK,0,0,0])) + vmw.card_height, [SELECTMASK,0,0,0])) vmw.match_display_area.append(Card(vmw.sprites, vmw.path, "", - vmw.card_width, - vmw.card_height, [MATCHMASK,0,0,0])) + vmw.card_width, + vmw.card_height, + [MATCHMASK,0,0,0])) vmw.grid.display_match(vmw.match_display_area[i].spr, i) - # Joiners in share cannot initiate new games. - if button_push and _joiner(vmw): - return - - vmw.deck.hide() _unselect(vmw) - # If cardtype has changed, we need to generate a new deck. - if vmw.cardtype is not cardtype: - vmw.cardtype = cardtype - vmw.deck = Deck(vmw.sprites, vmw.path, vmw.cardtype, - vmw.card_width, vmw.card_height, - difficulty_level[vmw.level]) - # Restore saved state on resume or share. if saved_state is not None: _logger.debug("Restoring state: %s" % (str(saved_state))) + vmw.deck = Deck(vmw.sprites, vmw.path, vmw.cardtype, vmw.card_width, + vmw.card_height, difficulty_level[vmw.level]) + vmw.deck.hide() vmw.deck.index = deck_index deck_start = ROW*COL+3 - deck_stop = deck_start+vmw.deck.count + deck_stop = deck_start+vmw.deck.count() vmw.deck.restore(saved_state[deck_start:deck_stop]) vmw.grid.restore(vmw.deck, saved_state[0:ROW*COL]) _restore_selected(vmw, saved_state[ROW*COL:ROW*COL+3]) _restore_matches(vmw, saved_state[deck_stop:deck_stop+3*vmw.matches]) - else: + elif not joiner(vmw): + _logger.debug("Starting new game.") + vmw.deck = Deck(vmw.sprites, vmw.path, vmw.cardtype, + vmw.card_width, vmw.card_height, + difficulty_level[vmw.level]) + vmw.deck.hide() vmw.deck.shuffle() vmw.grid.deal(vmw.deck) if _find_a_match(vmw) is False: @@ -132,8 +132,8 @@ def new_game(vmw, cardtype, button_push=True, saved_state=None, deck_index=0): vmw.match_list = [] vmw.total_time = 0 - # If sharer starts a new game, ask joiners to request new deck. - if button_push and _sharer(vmw): + # When sharer starts a new game, joiners should be notified. + if sharer(vmw): vmw.activity._send_event("J") _update_labels(vmw) @@ -145,7 +145,7 @@ def new_game(vmw, cardtype, button_push=True, saved_state=None, deck_index=0): gobject.source_remove(vmw.match_timeout_id) _timer_reset(vmw) -def _joiner(vmw): +def joiner(vmw): if vmw.sugar is True and \ hasattr(vmw.activity, 'chattube') and \ vmw.activity.chattube is not None and \ @@ -153,7 +153,7 @@ def _joiner(vmw): return True return False -def _sharer(vmw): +def sharer(vmw): if vmw.sugar is True and \ hasattr(vmw.activity, 'chattube') and \ vmw.activity.chattube is not None and \ @@ -169,7 +169,7 @@ def _button_press_cb(win, event, vmw): return True # -# Button release, where all the work is done +# Button release # def _button_release_cb(win, event, vmw): win.grab_focus() |