diff options
author | Walter Bender <walter.bender@gmail.com> | 2011-03-04 20:40:06 (GMT) |
---|---|---|
committer | Walter Bender <walter.bender@gmail.com> | 2011-03-04 20:40:06 (GMT) |
commit | c3311778cd7237bdff59f9106eca3dc367737772 (patch) | |
tree | 2c677b7ed02e69fbd207ec0f96e74c65e8985357 /game.py |
new project
Diffstat (limited to 'game.py')
-rw-r--r-- | game.py | 256 |
1 files changed, 256 insertions, 0 deletions
@@ -0,0 +1,256 @@ +# -*- coding: utf-8 -*- +#Copyright (c) 2011 Walter Bender + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +import gtk +from gettext import gettext as _ +import logging +_logger = logging.getLogger('paths-activity') + +try: + from sugar.graphics import style + GRID_CELL_SIZE = style.GRID_CELL_SIZE +except ImportError: + GRID_CELL_SIZE = 0 + +from grid import Grid +from deck import Deck +from card import error_card +from sprites import Sprites + +N = 0 +E = N + 1 +S = E + 1 +W = S + 1 +CARD_WIDTH = 55 +CARD_HEIGHT = 55 +ROW = 8 +COL = 8 + + +class Game(): + + def __init__(self, canvas, parent=None): + self.activity = parent + + # Starting from command line + if parent is None: + self.sugar = False + self.canvas = canvas + # Starting from Sugar + else: + self.sugar = True + self.canvas = canvas + parent.show_all() + + self.canvas.set_flags(gtk.CAN_FOCUS) + self.canvas.add_events(gtk.gdk.BUTTON_PRESS_MASK) + self.canvas.add_events(gtk.gdk.BUTTON_RELEASE_MASK) + self.canvas.connect("expose-event", self._expose_cb) + self.canvas.connect("button-press-event", self._button_press_cb) + self.canvas.connect("button-release-event", self._button_release_cb) + self.canvas.connect("key_press_event", self._keypress_cb) + self.width = gtk.gdk.screen_width() + self.height = gtk.gdk.screen_height()-GRID_CELL_SIZE + self.scale = self.height / (8.0 * CARD_HEIGHT) + self.card_width = CARD_WIDTH * self.scale + self.card_height = CARD_HEIGHT * self.scale + self.sprites = Sprites(self.canvas) + self.last_spr_moved = [] + self.errormsg = [] + + for i in range(4): + self.errormsg.append(error_card(self.sprites)) + + def new_game(self, saved_state=None, deck_index=0): + ''' Start a new game. ''' + + # If there is already a deck, hide it. + if hasattr(self, 'deck'): + self.deck.hide() + + # Initialize the grid and create a deck of cards. + if not hasattr(self, 'grid'): + self.grid = Grid(self.width, self.height, self.card_width, + self.card_height) + + if not hasattr(self, 'deck'): + self.deck = Deck(self.sprites, self.scale) + self.deck.board.spr.move((self.grid.left, self.grid.top)) + + # Shuffle the deck and deal a hand of tiles. + self.deck.shuffle() + self.grid.deal(self.deck) + self.last_spr_move = [None] + self._hide_errormsgs() + + def _button_press_cb(self, win, event): + win.grab_focus() + x, y = map(int, event.get_coords()) + self.start_drag = [x, y] + + self._hide_errormsgs() + + spr = self.sprites.find_sprite((x, y)) + if spr is None or spr == self.deck.board.spr: + self.press = None + self.release = None + return True + if self.grid.spr_to_hand(spr) is not None: + self.last_spr_moved.append(spr) + if spr != self.last_spr_moved[-1]: + self.press = None + self.release = None + return True + self.press = spr + return True + + def _button_release_cb(self, win, event): + win.grab_focus() + + if self.press is None: + return + + x, y = map(int, event.get_coords()) + spr = self.sprites.find_sprite((x, y)) + + if spr is None: # Returning tile to hand + i = self.grid.find_empty_slot() + if i is not None: + card = self.deck.spr_to_card(self.press) + card.spr.move(self.grid.hand_to_xy(i)) + self.grid.hand[i] = card + if self.grid.spr_to_grid(self.press) is not None: + self.grid.grid[self.grid.spr_to_grid(self.press)] = None + if spr in self.last_spr_moved: + self.last_spr_moved.remove(spr) + self.press = None + self.release = None + return True + + self.release = spr + if self.press == self.release: + + card = self.deck.spr_to_card(spr) + card.rotate_clockwise() + + if self.last_spr_moved[-1] != card.spr: + self.last_spr_moved.append(card.spr) + + elif self.release == self.deck.board.spr: + card = self.deck.spr_to_card(self.press) + card.spr.move(self.grid.grid_to_xy(self.grid.xy_to_grid(x, y))) + + i = self.grid.spr_to_grid(self.press) + if i is not None: + self.grid.grid[i] = None + self.grid.grid[self.grid.xy_to_grid(x, y)] = card + + i = self.grid.spr_to_hand(self.press) + if i is not None: + self.grid.hand[i] = None + + if self.last_spr_moved[-1] != card.spr: + self.last_spr_moved.append(card.spr) + + self._test_for_bad_paths() + self.press = None + self.release = None + + if self.grid.cards_in_hand() == 0: + self.grid.redeal(self.deck) + return True + + def _game_over(self): + pass + + def _test_for_bad_paths(self): + ''' Is there a path to no where? ''' + i = self.grid.spr_to_grid(self.press) + if i is not None: + self._check_north(i) + self._check_east(i) + self._check_south(i) + self._check_west(i) + + def _check_north(self, i): + # Is it in the top row? + if int(i / COL) == 0: + if self.grid.grid[i].connections[N] == 1: + self._error(i, N) + else: + if self.grid.grid[i-COL] is not None: + if self.grid.grid[i].connections[N] != \ + self.grid.grid[i-COL].connections[S]: + self._error(i, N) + + def _check_east(self, i): + # Is it in the right column? + if int(i % ROW) == ROW - 1: + if self.grid.grid[i].connections[E] == 1: + self._error(i, E) + else: + if self.grid.grid[i+1] is not None: + if self.grid.grid[i].connections[E] != \ + self.grid.grid[i+1].connections[W]: + self._error(i, E) + + def _check_south(self, i): + # Is it in the bottom row? + if int(i / COL) == COL - 1: + if self.grid.grid[i].connections[S] == 1: + self._error(i, S) + else: + if self.grid.grid[i+COL] is not None: + if self.grid.grid[i].connections[S] != \ + self.grid.grid[i+COL].connections[N]: + self._error(i, S) + + def _check_west(self, i): + # Is it in the left column? + if int(i % ROW) == 0: + if self.grid.grid[i].connections[W] == 1: + self._error(i, W) + else: + if self.grid.grid[i-1] is not None: + if self.grid.grid[i].connections[W] != \ + self.grid.grid[i-1].connections[E]: + self._error(i, W) + + def _error(self, i, direction): + ''' Display an error message where and when appropriate. ''' + offsets = [[0.375, -0.125], [0.875, 0.375], [0.375, 0.875], + [-0.125, 0.375]] + x, y = self.press.get_xy() + self.errormsg[direction].move( + (x + offsets[direction][0] * self.card_width, + y + offsets[direction][1] * self.card_height)) + self.errormsg[direction].set_layer(3000) + + def _hide_errormsgs(self): + ''' Hide all the error messages. ''' + for i in range(4): + self.errormsg[i].move((self.grid.left, self.grid.top)) + self.errormsg[i].set_layer(0) + + # + # Callbacks + # + def _keypress_cb(self, area, event): + return True + + def _expose_cb(self, win, event): + self.sprites.redraw_sprites() + return True + + def _destroy_cb(self, win, event): + gtk.main_quit() |