Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/game.py
diff options
context:
space:
mode:
Diffstat (limited to 'game.py')
-rw-r--r--game.py436
1 files changed, 0 insertions, 436 deletions
diff --git a/game.py b/game.py
deleted file mode 100644
index c44296d..0000000
--- a/game.py
+++ /dev/null
@@ -1,436 +0,0 @@
-# -*- coding: utf-8 -*-
-#Copyright (c) 2011-12 Walter Bender
-#Copyright (c) 2012 Ignacio Rodríguez
-# 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 General Public License
-# along with this library; if not, write to the Free Software
-# Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA
-
-
-from gi.repository import Gtk, GdkPixbuf, GObject, Gdk
-import cairo
-
-from random import uniform
-
-from gettext import gettext as _
-
-import logging
-_logger = logging.getLogger('reflection-activity')
-
-try:
- from sugar3.graphics import style
- GRID_CELL_SIZE = style.GRID_CELL_SIZE
-except ImportError:
- GRID_CELL_SIZE = 0
-
-from sprites import Sprites, Sprite
-
-
-# Grid dimensions must be even
-TEN = 10
-SIX = 6
-DOT_SIZE = 40
-
-
-class Game():
-
- def __init__(self, canvas, parent=None, colors=['#A0FFA0', '#FF8080']):
- self._activity = parent
- self._colors = [colors[0]]
- self._colors.append(colors[1])
- self._colors.append('#FFFFFF')
- self._colors.append('#000000')
- self._colors.append('#FF0000')
- self._colors.append('#FF8000')
- self._colors.append('#FFFF00')
- self._colors.append('#00FF00')
- self._colors.append('#00FFFF')
- self._colors.append('#0000FF')
- self._colors.append('#FF00FF')
-
- self._canvas = canvas
- if parent is not None:
- parent.show_all()
- self._parent = parent
-
- self._canvas.add_events(Gdk.EventMask.BUTTON_PRESS_MASK)
- self._canvas.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK)
- self._canvas.add_events(Gdk.EventMask.POINTER_MOTION_MASK)
- self._canvas.connect("draw", self.__draw_cb)
- self._canvas.connect("button-press-event", self._button_press_cb)
- self._canvas.connect("button-release-event", self._button_release_cb)
- self._canvas.connect("motion-notify-event", self._mouse_move_cb)
- self._width = Gdk.Screen.width()
- self._height = Gdk.Screen.height() - (GRID_CELL_SIZE * 1.5)
- self._scale = self._width / (10 * DOT_SIZE * 1.2)
- self._dot_size = int(DOT_SIZE * self._scale)
- self._space = int(self._dot_size / 5.)
- self._orientation = 'horizontal'
- self.we_are_sharing = False
- self.playing_with_robot = False
- self._press = False
- self.last_spr = None
- self._timer = None
- self.roygbiv = False
-
- # Generate the sprites we'll need...
- self._sprites = Sprites(self._canvas)
- self._dots = []
- for y in range(SIX):
- for x in range(TEN):
- xoffset = int((self._width - TEN * self._dot_size - \
- (TEN - 1) * self._space) / 2.)
- self._dots.append(
- Sprite(self._sprites,
- xoffset + x * (self._dot_size + self._space),
- y * (self._dot_size + self._space),
- self._new_dot(self._colors[2])))
- self._dots[-1].type = 2 # not set
- self._dots[-1].set_label_attributes(40)
-
- self.vline = Sprite(self._sprites,
- int(self._width / 2.) - 1,
- 0, self._line(vertical=True))
- n = SIX / 2.
- self.hline = Sprite(
- self._sprites, 0,
- int(self._dot_size * n + self._space * (n - 0.5)) - 1,
- self._line(vertical=False))
- self.hline.hide()
-
- # and initialize a few variables we'll need.
- self._all_clear()
-
- def _all_clear(self):
- ''' Things to reinitialize when starting up a new game. '''
- for dot in self._dots:
- dot.type = 2
- dot.set_shape(self._new_dot(self._colors[2]))
- dot.set_label('')
-
- self._set_orientation()
-
- def _set_orientation(self):
- ''' Set bar and message for current orientation '''
- if self._orientation == 'horizontal':
- self.hline.hide()
- self.vline.set_layer(1000)
- elif self._orientation == 'vertical':
- self.hline.set_layer(1000)
- self.vline.hide()
- else:
- self.hline.set_layer(1000)
- self.vline.set_layer(1000)
-
- '''
- if self._orientation == 'horizontal':
- self._set_label(
- _('Click on the dots to make a horizontal reflection.'))
- elif self._orientation == 'vertical':
- self._set_label(
- _('Click on the dots to make a vertical reflection.'))
- else:
- self._set_label(
- _('Click on the dots to make a bilateral reflection.'))
- '''
-
- def _initiating(self):
- return self._activity.initiating
-
- def new_game(self, orientation='horizontal'):
- ''' Start a new game. '''
- self._orientation = orientation
-
- self._all_clear()
-
- # Fill in a few dots to start
- for i in range(int(TEN * SIX / 2)):
- n = int(uniform(0, TEN * SIX))
- if self.roygbiv:
- self._dots[n].type = int(uniform(2, len(self._colors)))
- else:
- self._dots[n].type = int(uniform(0, 4))
- self._dots[n].set_shape(self._new_dot(
- self._colors[self._dots[n].type]))
-
- if self.we_are_sharing:
- _logger.debug('sending a new game')
- self._parent.send_new_game()
-
- def restore_game(self, dot_list, orientation):
- ''' Restore a game from the Journal or share '''
- for i, dot in enumerate(dot_list):
- self._dots[i].type = dot
- self._dots[i].set_shape(self._new_dot(
- self._colors[self._dots[i].type]))
- self._orientation = orientation
- self._set_orientation()
-
- def save_game(self):
- ''' Return dot list and orientation for saving to Journal or
- sharing '''
- dot_list = []
- for dot in self._dots:
- dot_list.append(dot.type)
- return [dot_list, self._orientation]
-
- def _set_label(self, string):
- ''' Set the label in the toolbar or the window frame. '''
- self._activity.status.set_label(string)
-
- def _button_press_cb(self, win, event):
- win.grab_focus()
- x, y = map(int, event.get_coords())
- self._press = True
-
- spr = self._sprites.find_sprite((x, y))
- if spr == None:
- return True
-
- self.last_spr = spr
- if spr.type is not None:
- if not self._timer is None:
- GObject.source_remove(self._timer)
- self._increment_dot(spr)
- return True
-
- def _button_release_cb(self, win, event):
- self._press = False
- if not self._timer is None:
- GObject.source_remove(self._timer)
-
- def _increment_dot(self, spr):
- spr.type += 1
- if self.roygbiv:
- if spr.type >= len(self._colors):
- spr.type = 2
- else:
- spr.type %= 4
- spr.set_shape(self._new_dot(self._colors[spr.type]))
-
- if self.playing_with_robot:
- self._robot_play(spr)
-
- self._test_game_over()
-
- if self.we_are_sharing:
- _logger.debug('sending a click to the share')
- self._parent.send_dot_click(self._dots.index(spr), spr.type)
-
- self._timer = GObject.timeout_add(1000, self._increment_dot, spr)
-
- def _mouse_move_cb(self, win, event):
- """ Drag a tile with the mouse. """
- if not self._press:
- return
- x, y = map(int, event.get_coords())
- spr = self._sprites.find_sprite((x, y))
- if spr == self.last_spr:
- return True
- if spr is None:
- return True
- if spr.type is not None:
- self.last_spr = spr
- if not self._timer is None:
- GObject.source_remove(self._timer)
- self._increment_dot(spr)
-
- def _robot_play(self, dot):
- ''' Robot reflects dot clicked. '''
- x, y = self._dot_to_grid(self._dots.index(dot))
- if self._orientation == 'horizontal':
- x = TEN - x - 1
- i = self._grid_to_dot((x, y))
- self._dots[i].type = dot.type
- self._dots[i].set_shape(self._new_dot(self._colors[dot.type]))
- if self.we_are_sharing:
- _logger.debug('sending a robot click to the share')
- self._parent.send_dot_click(i, dot.type)
- elif self._orientation == 'vertical':
- y = SIX - y - 1
- i = self._grid_to_dot((x, y))
- self._dots[i].type = dot.type
- self._dots[i].set_shape(self._new_dot(self._colors[dot.type]))
- if self.we_are_sharing:
- _logger.debug('sending a robot click to the share')
- self._parent.send_dot_click(i, dot.type)
- else:
- x = TEN - x - 1
- i = self._grid_to_dot((x, y))
- self._dots[i].type = dot.type
- self._dots[i].set_shape(self._new_dot(self._colors[dot.type]))
- if self.we_are_sharing:
- _logger.debug('sending a robot click to the share')
- self._parent.send_dot_click(i, dot.type)
- y = SIX - y - 1
- i = self._grid_to_dot((x, y))
- self._dots[i].type = dot.type
- self._dots[i].set_shape(self._new_dot(self._colors[dot.type]))
- if self.we_are_sharing:
- _logger.debug('sending a robot click to the share')
- self._parent.send_dot_click(i, dot.type)
- x = TEN - x - 1
- i = self._grid_to_dot((x, y))
- self._dots[i].type = dot.type
- self._dots[i].set_shape(self._new_dot(self._colors[dot.type]))
- if self.we_are_sharing:
- _logger.debug('sending a robot click to the share')
- self._parent.send_dot_click(i, dot.type)
-
- def remote_button_press(self, dot, color):
- ''' Receive a button press from a sharer '''
- self._dots[dot].type = color
- self._dots[dot].set_shape(self._new_dot(self._colors[color]))
-
- def set_sharing(self, share=True):
- _logger.debug('enabling sharing')
- self.we_are_sharing = share
-
- def _smile(self):
- for dot in self._dots:
- dot.set_label(':)')
-
- def _test_game_over(self):
- ''' Check to see if game is over '''
- if self._orientation == 'horizontal':
- for y in range(SIX):
- for x in range(SIX):
- if self._dots[y * TEN + x].type != \
- self._dots[y * TEN + TEN - x - 1].type:
- self._set_label(_('keep trying'))
- return False
- self._set_label(_('good work'))
- self._smile()
- return True
- if self._orientation == 'vertical':
- for y in range(int(SIX / 2)):
- for x in range(TEN):
- if self._dots[y * TEN + x].type != \
- self._dots[(SIX - y - 1) * TEN + x].type:
- self._set_label(_('keep trying'))
- return False
- self._set_label(_('good work'))
- else:
- for y in range(SIX):
- for x in range(SIX):
- if self._dots[y * TEN + x].type != \
- self._dots[y * TEN + TEN - x - 1].type:
- self._set_label(_('keep trying'))
- return False
- for y in range(int(SIX / 2)):
- for x in range(TEN):
- if self._dots[y * TEN + x].type != \
- self._dots[(SIX - y - 1) * TEN + x].type:
- self._set_label(_('keep trying'))
- return False
- self._set_label(_('good work'))
- self._smile()
- return True
- def __draw_cb(self,canvas,cr):
- self._sprites.redraw_sprites(cr=cr)
- def _grid_to_dot(self, pos):
- ''' calculate the dot index from a column and row in the grid '''
- return pos[0] + pos[1] * TEN
-
- def _dot_to_grid(self, dot):
- ''' calculate the grid column and row for a dot '''
- return [dot % TEN, int(dot / TEN)]
-
- def _expose_cb(self, win, event):
- self.do_expose_event(event)
-
- def do_expose_event(self, event):
- ''' Handle the expose-event by drawing '''
- # Restrict Cairo to the exposed area
- cr = self._canvas.window.cairo_create()
- cr.rectangle(event.area.x, event.area.y,
- event.area.width, event.area.height)
- cr.clip()
- # Refresh sprite list
- self._sprites.redraw_sprites(cr=cr)
-
- def _destroy_cb(self, win, event):
- Gtk.main_quit()
-
- def _new_dot(self, color):
- ''' generate a dot of a color color '''
- self._dot_cache = {}
- if not color in self._dot_cache:
- self._stroke = color
- self._fill = color
- self._svg_width = self._dot_size
- self._svg_height = self._dot_size
- pixbuf = svg_str_to_pixbuf(
- self._header() + \
- self._circle(self._dot_size / 2., self._dot_size / 2.,
- self._dot_size / 2.) + \
- self._footer())
-
- surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
- self._svg_width, self._svg_height)
- context = cairo.Context(surface)
- Gdk.cairo_set_source_pixbuf(context, pixbuf, 0, 0)
- context.rectangle(0, 0, self._svg_width, self._svg_height)
- context.fill()
- self._dot_cache[color] = surface
-
- return self._dot_cache[color]
-
- def _line(self, vertical=True):
- ''' Generate a center line '''
- if vertical:
- self._svg_width = 3
- self._svg_height = self._height
- return svg_str_to_pixbuf(
- self._header() + \
- self._rect(3, self._height, 0, 0) + \
- self._footer())
- else:
- self._svg_width = self._width
- self._svg_height = 3
- return svg_str_to_pixbuf(
- self._header() + \
- self._rect(self._width, 3, 0, 0) + \
- self._footer())
-
- def _header(self):
- return '<svg\n' + 'xmlns:svg="http://www.w3.org/2000/svg"\n' + \
- 'xmlns="http://www.w3.org/2000/svg"\n' + \
- 'xmlns:xlink="http://www.w3.org/1999/xlink"\n' + \
- 'version="1.1"\n' + 'width="' + str(self._svg_width) + '"\n' + \
- 'height="' + str(self._svg_height) + '">\n'
-
- def _rect(self, w, h, x, y):
- svg_string = ' <rect\n'
- svg_string += ' width="%f"\n' % (w)
- svg_string += ' height="%f"\n' % (h)
- svg_string += ' rx="%f"\n' % (0)
- svg_string += ' ry="%f"\n' % (0)
- svg_string += ' x="%f"\n' % (x)
- svg_string += ' y="%f"\n' % (y)
- svg_string += 'style="fill:#000000;stroke:#000000;"/>\n'
- return svg_string
-
- def _circle(self, r, cx, cy):
- return '<circle style="fill:' + str(self._fill) + ';stroke:' + \
- str(self._stroke) + ';" r="' + str(r - 0.5) + '" cx="' + \
- str(cx) + '" cy="' + str(cy) + '" />\n'
-
- def _footer(self):
- return '</svg>\n'
-
-
-def svg_str_to_pixbuf(svg_string):
- try:
- pl = GdkPixbuf.PixbufLoader.new_with_type('svg')
- pl.write(svg_string)
- pl.close()
- pixbuf = pl.get_pixbuf()
- return pixbuf
- except:
- print svg_string
- return None