[gcompris/gcomprixogoo] New activity lights off by Bruno and Clement Coudoin.



commit 77fadbb35a6cad4fac4c1cd20ec0d1334ce38913
Author: Bruno Coudoin <bruno coudoin free fr>
Date:   Sun Feb 21 20:37:20 2010 +0100

    New activity lights off by Bruno and Clement Coudoin.

 configure.ac                                       |    3 +
 src/Makefile.am                                    |    1 +
 src/lightsoff-activity/.gitignore                  |    1 +
 src/lightsoff-activity/Makefile.am                 |   32 +
 src/lightsoff-activity/gcompris                    |    1 +
 src/lightsoff-activity/init_path.sh                |    8 +
 src/lightsoff-activity/lightsoff.py                |  843 ++++++++++++++++++++
 src/lightsoff-activity/lightsoff.svg               |  314 ++++++++
 src/lightsoff-activity/lightsoff.xml.in            |   18 +
 src/lightsoff-activity/resources/Makefile.am       |    1 +
 .../resources/lightsoff/Makefile.am                |    6 +
 src/lightsoff-activity/resources/lightsoff/README  |    2 +
 .../resources/lightsoff/back.svgz                  |  Bin 0 -> 59208 bytes
 .../resources/lightsoff/onoff.svgz                 |  Bin 0 -> 8000 bytes
 14 files changed, 1230 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 2e2965e..c0b7804 100644
--- a/configure.ac
+++ b/configure.ac
@@ -722,6 +722,9 @@ src/imagename-activity/resources/imagename/Makefile
 src/leftright-activity/Makefile
 src/leftright-activity/resources/Makefile
 src/leftright-activity/resources/leftright/Makefile
+src/lightsoff-activity/Makefile
+src/lightsoff-activity/resources/Makefile
+src/lightsoff-activity/resources/lightsoff/Makefile
 src/login-activity/Makefile
 src/login-activity/resources/Makefile
 src/login-activity/resources/login/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index ef57a63..da9b291 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -34,6 +34,7 @@ SUBDIRS = goocanvas gcompris boards \
 	imageid-activity \
 	imagename-activity \
 	leftright-activity \
+	lightsoff-activity \
 	magic_hat_minus-activity \
 	magic_hat_plus-activity \
 	maze-activity \
diff --git a/src/lightsoff-activity/.gitignore b/src/lightsoff-activity/.gitignore
new file mode 100644
index 0000000..e933fe6
--- /dev/null
+++ b/src/lightsoff-activity/.gitignore
@@ -0,0 +1 @@
+pythontemplate.xml
diff --git a/src/lightsoff-activity/Makefile.am b/src/lightsoff-activity/Makefile.am
new file mode 100644
index 0000000..8dc9204
--- /dev/null
+++ b/src/lightsoff-activity/Makefile.am
@@ -0,0 +1,32 @@
+SUBDIRS = resources
+
+pythondir = $(PYTHON_PLUGIN_DIR)
+
+dist_python_DATA= 	lightsoff.py
+
+
+
+xmldir = $(pkgdatadir)/@PACKAGE_DATA_DIR@
+
+xml_in_files = \
+	lightsoff.xml.in
+
+
+xml_DATA = $(xml_in_files:.xml.in=.xml)
+
+# Do not use the INTLTOOL_XML_RULE, we don't need to embed the translations
+# in the file themselves. GCompris pick the translations from the po file at
+# runtime.
+#
+$(xml_DATA): %.xml: %.xml.in
+	sed -e "s/\(<\{1\}\/*\)_/\1/g" $< > $@
+
+# Use this directive and instead of the one above to embed the translations
+# in the xml files directly, this is needed for the tool gcompris2spip
+# INTLTOOL_XML_RULE@
+
+icondir = $(pkgdatadir)/@PACKAGE_DATA_DIR@
+icon_DATA = lightsoff.svg
+
+EXTRA_DIST = $(icon_DATA) ${xml_in_files} init_path.sh
+CLEANFILES = $(xml_DATA)
diff --git a/src/lightsoff-activity/gcompris b/src/lightsoff-activity/gcompris
new file mode 120000
index 0000000..6a7dc8a
--- /dev/null
+++ b/src/lightsoff-activity/gcompris
@@ -0,0 +1 @@
+../boards/python/gcompris
\ No newline at end of file
diff --git a/src/lightsoff-activity/init_path.sh b/src/lightsoff-activity/init_path.sh
new file mode 100755
index 0000000..9d01f80
--- /dev/null
+++ b/src/lightsoff-activity/init_path.sh
@@ -0,0 +1,8 @@
+# Set the different path for this activity
+# This is sourced by runit.sh
+path=$1
+activity=lightsoff
+plugindir=$path/../boards/.libs
+pythonplugindir=$path 
+resourcedir=$path/resources
+section="/puzzle"
diff --git a/src/lightsoff-activity/lightsoff.py b/src/lightsoff-activity/lightsoff.py
new file mode 100644
index 0000000..4eeb046
--- /dev/null
+++ b/src/lightsoff-activity/lightsoff.py
@@ -0,0 +1,843 @@
+#  gcompris - lightsoff.py
+#
+# Copyright (C) 2010 Bruno and Clement Coudoin
+#
+#   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.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# lightsoff Board module
+import gtk
+import gtk.gdk
+import gcompris
+import gcompris.utils
+import gcompris.skin
+import gcompris.bonus
+import goocanvas
+
+from gcompris import gcompris_gettext as _
+
+class Gcompris_lightsoff:
+  """Empty gcompris python class"""
+
+
+  def __init__(self, gcomprisBoard):
+    # Save the gcomprisBoard, it defines everything we need
+    # to know from the core
+    self.gcomprisBoard = gcomprisBoard
+
+    self.rootitem = None
+
+    # These are used to let us restart only after the bonus is displayed.
+    # When the bonus is displayed, it call us first with pause(1) and then with pause(0)
+    self.board_paused  = False;
+    self.gamewon       = False;
+
+    self.data = [
+      [[1,1,0,1,1],
+       [1,0,1,0,1],
+       [0,1,1,1,0],
+       [1,0,1,0,1],
+       [1,1,0,1,1]],
+      [[0,1,0,1,0],
+       [1,1,0,1,1],
+       [0,1,0,1,0],
+       [1,0,1,0,1],
+       [1,0,1,0,1]],
+      [[1,0,0,0,1],
+       [1,1,0,1,1],
+       [0,0,1,0,0],
+       [1,0,1,0,0],
+       [1,0,1,1,0]],
+      [[1,1,0,1,1],
+       [0,0,0,0,0],
+       [1,1,0,1,1],
+       [0,0,0,0,1],
+       [1,1,0,0,0]],
+      # 5
+      [[1,1,1,1,1],
+       [1,1,1,1,1],
+       [1,1,1,1,1],
+       [1,1,1,1,1],
+       [1,1,1,1,1]],
+      # 6
+      [[0,0,0,1,1],
+       [0,0,0,1,1],
+       [0,0,0,0,0],
+       [1,1,0,0,0],
+       [1,1,0,0,0]],
+      # 7
+      [[0,0,0,0,0],
+       [0,1,1,1,0],
+       [1,1,1,1,1],
+       [0,1,1,1,0],
+       [0,0,0,0,0]],
+      # 8
+      [[0,0,0,0,0],
+       [0,1,1,1,0],
+       [0,1,1,1,0],
+       [0,1,1,1,0],
+       [0,0,0,0,0]],
+      # 9
+      [[1,1,0,1,1],
+       [1,1,0,1,1],
+       [0,0,0,0,0],
+       [1,1,0,1,1],
+       [1,1,0,1,1]],
+      # 10
+      [[1,1,1,1,1],
+       [0,1,1,1,0],
+       [0,0,1,0,0],
+       [0,1,1,1,0],
+       [1,1,1,1,1]],
+      # 11
+      [[1,1,1,1,1],
+       [1,0,0,0,1],
+       [1,0,0,0,1],
+       [1,0,0,0,1],
+       [1,1,1,1,1]],
+      # 12
+      [[0,0,1,1,1],
+       [0,0,0,1,1],
+       [1,0,0,0,1],
+       [1,1,0,0,0],
+       [1,1,1,0,0]],
+      # 13
+      [[1,0,0,0,1],
+       [0,1,0,1,0],
+       [0,0,1,0,0],
+       [0,1,0,1,0],
+       [1,0,0,0,1]],
+      # 14
+      [[1,1,1,1,1],
+       [1,0,1,0,1],
+       [1,1,1,1,1],
+       [1,0,1,0,1],
+       [1,1,1,1,1]],
+      # 15
+      [[1,0,0,0,0],
+       [1,1,1,1,0],
+       [1,1,1,1,0],
+       [1,1,1,1,0],
+       [1,1,1,1,1]],
+      # 16
+      [[1,1,1,1,1],
+       [1,1,1,1,1],
+       [1,1,0,1,1],
+       [1,1,1,1,1],
+       [1,1,1,1,1]],
+      # 17
+      [[1,0,1,0,1],
+       [0,1,0,1,0],
+       [0,0,1,0,0],
+       [0,1,0,1,0],
+       [1,0,1,0,1]],
+      # 18
+      [[1,1,1,0,1],
+       [1,1,1,0,1],
+       [0,0,0,0,0],
+       [1,0,1,1,1],
+       [1,0,1,1,1]],
+      # 19
+      [[1,1,0,1,1],
+       [1,1,0,1,1],
+       [1,1,0,1,1],
+       [1,1,0,1,1],
+       [1,1,0,1,1]],
+      # 20
+      [[1,1,1,1,1],
+       [1,0,0,0,1],
+       [1,1,0,1,1],
+       [1,1,0,1,1],
+       [1,1,1,1,1]],
+      # 21
+      [[1,1,1,1,1],
+       [1,1,1,1,1],
+       [0,0,0,1,1],
+       [0,0,0,1,1],
+       [0,0,0,1,1]],
+      # 22
+      [[1,1,1,0,1],
+       [1,1,1,0,0],
+       [1,1,1,0,0],
+       [1,1,1,0,0],
+       [1,1,1,0,1]],
+      # 23
+      [[1,1,1,1,1],
+       [0,0,1,0,0],
+       [0,0,1,0,0],
+       [0,0,1,0,0],
+       [1,1,1,1,1]],
+      # 24
+      [[0,0,0,0,0],
+       [0,1,1,0,0],
+       [0,1,1,1,0],
+       [0,0,1,1,0],
+       [0,0,0,0,0]],
+      # 25
+      [[0,0,0,1,1],
+       [0,0,1,1,1],
+       [0,0,1,0,0],
+       [1,1,1,0,0],
+       [1,1,0,0,0]],
+      # 26
+      [[0,0,0,1,1],
+       [1,1,0,1,1],
+       [1,1,0,0,0],
+       [1,1,0,0,0],
+       [1,1,0,1,1]],
+      # 27
+      [[1,0,0,0,1],
+       [0,1,1,1,0],
+       [0,1,1,1,0],
+       [0,1,1,1,0],
+       [1,0,0,0,1]],
+      # 28
+      [[1,0,1,0,1],
+       [0,1,0,1,0],
+       [1,0,1,0,1],
+       [0,1,0,1,0],
+       [1,0,1,0,1]],
+      # 29
+      [[0,0,1,0,0],
+       [1,0,0,1,0],
+       [0,1,1,1,1],
+       [1,0,0,0,0],
+       [1,1,0,1,0]],
+      # 30
+      [[0,0,0,0,1],
+       [0,0,0,1,1],
+       [0,0,1,0,1],
+       [0,1,0,0,1],
+       [1,1,1,1,1]],
+      # 31
+      [[1,1,0,1,1],
+       [0,1,0,1,0],
+       [1,1,1,1,1],
+       [1,1,0,1,1],
+       [1,0,0,0,1]],
+      # 32
+      [[0,1,1,0,0],
+       [0,1,1,0,1],
+       [0,1,0,0,1],
+       [1,1,0,0,0],
+       [1,1,1,1,0]],
+      # 33
+      [[0,0,0,0,1],
+       [1,1,1,0,0],
+       [1,0,1,1,1],
+       [1,1,1,1,0],
+       [1,0,0,1,0]],
+      # 34
+      [[1,0,1,1,1],
+       [0,0,1,0,1],
+       [0,0,0,0,0],
+       [1,1,1,1,0],
+       [1,1,0,1,0]],
+      # 35
+      [[1,1,0,1,1],
+       [0,1,0,1,1],
+       [0,0,0,1,0],
+       [1,1,0,0,0],
+       [1,1,1,1,0]],
+      # 36
+      [[1,1,1,1,1],
+       [0,0,0,1,0],
+       [0,1,0,1,1],
+       [1,1,1,0,1],
+       [1,0,1,0,0]],
+      # 37
+      [[0,0,0,1,1],
+       [1,0,1,1,0],
+       [0,0,1,0,0],
+       [0,1,1,1,1],
+       [1,0,0,1,0]],
+      # 38
+      [[0,0,0,0,1],
+       [0,0,1,1,1],
+       [1,1,0,0,1],
+       [1,1,1,0,0],
+       [0,0,1,0,0]],
+      # 39
+      [[0,0,1,1,1],
+       [1,0,1,1,1],
+       [1,1,1,0,0],
+       [0,0,1,0,0],
+       [1,1,0,1,1]],
+      # 40
+      [[0,1,1,1,1],
+       [0,0,1,1,1],
+       [0,0,1,1,1],
+       [1,1,1,1,0],
+       [0,0,0,1,0]],
+      # 41
+      [[1,1,1,1,1],
+       [1,0,0,0,0],
+       [0,1,0,0,1],
+       [0,0,0,1,1],
+       [1,1,1,1,1]],
+      # 42
+      [[1,1,1,1,1],
+       [1,0,0,0,0],
+       [0,0,1,0,0],
+       [0,1,1,1,0],
+       [0,1,0,0,1]],
+      # 43
+      [[0,0,0,0,0],
+       [0,0,0,1,0],
+       [1,1,0,1,1],
+       [0,1,1,0,0],
+       [1,1,1,1,1]],
+      # 44
+      [[0,0,0,1,1],
+       [0,1,1,0,0],
+       [0,1,0,0,0],
+       [1,1,1,1,0],
+       [1,1,1,1,0]],
+      # 45
+      [[0,0,0,1,0],
+       [1,1,1,1,1],
+       [0,0,0,0,0],
+       [0,0,1,0,0],
+       [1,1,1,1,0]],
+      # 46
+      [[0,1,0,1,0],
+       [0,0,0,1,0],
+       [0,1,0,1,0],
+       [0,0,1,0,0],
+       [0,1,1,1,0]],
+      # 47
+      [[1,0,0,1,0],
+       [0,0,0,0,1],
+       [0,1,0,0,0],
+       [0,0,0,0,0],
+       [1,0,1,0,0]],
+      # 48
+      [[1,1,0,0,1],
+       [0,1,0,0,1],
+       [0,1,1,1,1],
+       [0,1,0,1,0],
+       [1,1,1,1,1]],
+      # 49
+      [[1,1,1,1,1],
+       [0,0,1,0,0],
+       [0,1,1,0,0],
+       [0,0,1,1,0],
+       [1,1,1,0,1]],
+      # 50
+      [[1,0,1,0,1],
+       [1,0,1,0,0],
+       [0,0,0,1,1],
+       [0,1,0,1,0],
+       [1,0,0,1,0]],
+      # 51
+      [[0,1,0,1,0],
+       [1,0,0,1,0],
+       [0,1,1,1,1],
+       [1,0,1,0,0],
+       [0,1,1,0,0]],
+      # 52
+      [[1,1,1,1,1],
+       [1,1,0,0,0],
+       [0,0,0,1,1],
+       [0,1,1,1,0],
+       [0,0,1,0,0]],
+      ]
+
+
+  def start(self):
+    self.gcomprisBoard.level=1
+    self.gcomprisBoard.maxlevel=len(self.data)
+    self.gcomprisBoard.sublevel=1
+    self.gcomprisBoard.number_of_sublevel=1
+
+    # Create our rootitem. We put each canvas item in it so at the end we
+    # only have to kill it. The canvas deletes all the items it contains
+    # automaticaly.
+    self.backroot = goocanvas.Group(parent = \
+                                      self.gcomprisBoard.canvas.get_root_item())
+
+    # A color changing background
+    self.background = goocanvas.Rect(
+      parent = self.backroot,
+      x = 0,
+      y = 0,
+      width = gcompris.BOARD_WIDTH,
+      height = 200,
+      fill_color_rgba = 0xFFFFFFFFL
+      )
+
+    svghandle = gcompris.utils.load_svg("lightsoff/back.svgz")
+    goocanvas.Svg(
+      parent = self.backroot,
+      svg_handle = svghandle,
+      svg_id = "#BACKGROUND",
+      pointer_events = goocanvas.EVENTS_NONE
+      )
+
+    # The Sun
+    self.sunitem = goocanvas.Svg(
+      parent = self.backroot,
+      svg_handle = svghandle,
+      svg_id = "#SUN",
+      )
+    self.sunitem_offset = 0
+
+    # TUX
+    self.tuxitem = goocanvas.Svg(
+      parent = self.backroot,
+      svg_handle = svghandle,
+      svg_id = "#TUX",
+      )
+    self.tuxitem.connect("button_press_event", self.solve_event)
+    gcompris.utils.item_focus_init(self.tuxitem, None)
+
+    # The Buble
+    self.bubbleitem = goocanvas.Svg(
+      parent = self.backroot,
+      svg_handle = svghandle,
+      svg_id = "#BUBBLE1",
+      )
+
+    self.textitem = goocanvas.Text(
+      parent = self.backroot,
+      x = gcompris.BOARD_WIDTH/2 + 80,
+      y = gcompris.BOARD_HEIGHT - 80,
+      width = 400,
+      font = gcompris.skin.get_font("gcompris/content"),
+      text = _("Switch off all the lights, I have to go to sleep.\n"
+               "If you need help, click on me."),
+      fill_color = "black",
+      anchor = gtk.ANCHOR_CENTER
+      )
+
+    # The Tipi
+    self.tipiitem = goocanvas.Svg(
+      parent = self.backroot,
+      svg_handle = svghandle,
+      svg_id = "#TIPI",
+      )
+
+    # The image foreground
+    goocanvas.Svg(
+      parent = self.backroot,
+      svg_handle = svghandle,
+      svg_id = "#FOREGROUND",
+      pointer_events = goocanvas.EVENTS_NONE
+      )
+
+    # Set the buttons we want in the bar
+    gcompris.bar_set(gcompris.BAR_LEVEL|gcompris.BAR_REPEAT)
+    gcompris.bar_location(gcompris.BOARD_WIDTH/2 - 90, -1, 0.6)
+    gcompris.bar_set_level(self.gcomprisBoard)
+
+    self.display_game()
+
+  def end(self):
+    self.backroot.remove()
+    self.backroot = None
+    self.rootitem = None
+
+
+  def ok(self):
+    print("lightsoff ok.")
+
+
+  def repeat(self):
+    self.display_game()
+
+  def config(self):
+    print("lightsoff config.")
+
+
+  def key_press(self, keyval, commit_str, preedit_str):
+   pass
+
+  def pause(self, pause):
+    self.board_paused = pause
+
+    # When the bonus is displayed, it call us first
+    # with pause(1) and then with pause(0)
+    # the game is won
+    if(self.gamewon == True and pause == False):
+      self.gamewon = False
+      if(self.increment_level()):
+        self.display_game()
+
+
+
+  def set_level(self, level):
+    self.gcomprisBoard.level = level
+    gcompris.bar_set_level(self.gcomprisBoard)
+    self.display_game()
+
+
+  # Code that increments the sublevel and level
+  # And bail out if no more levels are available
+  # return 1 if continue, 0 if bail out
+  def increment_level(self):
+    self.gcomprisBoard.sublevel += 1
+
+    if(self.gcomprisBoard.sublevel>self.gcomprisBoard.number_of_sublevel):
+      # Try the next level
+      self.gcomprisBoard.sublevel=1
+      self.gcomprisBoard.level += 1
+      gcompris.bar_set_level(self.gcomprisBoard)
+
+      if(self.gcomprisBoard.level>self.gcomprisBoard.maxlevel):
+        self.gcomprisBoard.level = self.gcomprisBoard.maxlevel
+
+    return 1
+
+  def create_empty_list(self):
+    items = []
+    for x in range(5):
+      items.append(range(5))
+    for y in range(len(items)):
+      for x in range(len(items[0])):
+        items[y][x] = 0
+    return items
+
+  # Display the board game
+  def display_game(self):
+      # The grid we display
+      # It contains all the graphic items
+      self.items = self.create_empty_list()
+
+      # The grid of hints items
+      self.hints = self.create_empty_list()
+
+      # Do we display the hints
+      self.hints_mode = False
+
+      if self.rootitem:
+        self.rootitem.remove()
+
+      self.tipiitem.props.visibility = goocanvas.ITEM_INVISIBLE
+      self.textitem.props.visibility = goocanvas.ITEM_VISIBLE
+      self.tuxitem.props.visibility = goocanvas.ITEM_VISIBLE
+      self.bubbleitem.props.visibility = goocanvas.ITEM_VISIBLE
+
+      # Create our rootitem. We put each canvas item in it so at the end we
+      # only have to kill it. The canvas deletes all the items it contains
+      # automaticaly.
+      self.rootitem =  \
+          goocanvas.Group(parent = self.gcomprisBoard.canvas.get_root_item())
+
+      svghandle = gcompris.utils.load_svg("lightsoff/onoff.svgz")
+      iwidth = svghandle.props.width
+      iheight = svghandle.props.height
+
+      gap = 10
+      x_start = (gcompris.BOARD_WIDTH - len(self.items) * (iwidth + gap) ) / 2
+      y_start = (gcompris.BOARD_HEIGHT - len(self.items[0]) \
+                   * (iheight + gap) ) / 2 - 40
+
+      goocanvas.Rect(
+        parent = self.rootitem,
+        x = x_start - gap,
+        y = y_start - gap,
+        width = len(self.items) * (iwidth + gap) + gap,
+        height = len(self.items[0]) * (iheight + gap) + gap,
+        fill_color_rgba = 0x445533AAL,
+        stroke_color_rgba = 0xC0C0C0AAL,
+        radius_x = 10,
+        radius_y = 10,
+        line_width = 2
+        )
+
+      data = self.data[self.gcomprisBoard.level - 1]
+      for y in range(len(self.items)):
+        for x in range(len(self.items[0])):
+          item = goocanvas.Rect(
+            parent = self.rootitem,
+            x = x_start + (iwidth + gap) * x - gap/2,
+            y = y_start + (iheight + gap) * y - gap/2,
+            width = iwidth + gap,
+            height = iheight + gap,
+            stroke_color_rgba = 0xC0C0C0FAL,
+            fill_color_rgba = 0x5050509AL,
+            line_width = 2,
+            radius_x = 10,
+            radius_y = 10,
+            )
+          self.hints[y][x] = item
+          item.props.visibility = goocanvas.ITEM_INVISIBLE
+
+          state = data[y][x]
+          svg_id = "#off"
+          if state:
+            svg_id = "#on"
+          item = goocanvas.Svg(
+            parent = self.rootitem,
+            svg_handle = svghandle,
+            svg_id = svg_id,
+            )
+          item.set_data("state", state)
+          item.translate(x_start + (iwidth + gap) * x,
+                         y_start + (iheight + gap) * y)
+          item.connect("button_press_event", self.button_press_event, [y,x])
+          self.items[y][x] = item
+
+      self.solve_it()
+
+  def is_on(self, item):
+    return item.get_data("state")
+
+  def switch(self, item):
+    if not item:
+      return
+    mystate =  self.is_on(item)
+    if mystate == False:
+      item.set_properties(svg_id = "#on")
+    else:
+      item.set_properties(svg_id = "#off")
+    item.set_data("state", not mystate)
+
+  def get_item_up(self, y, x):
+    if y == 0:
+      return None
+    return self.items[y-1][x]
+
+  def get_item_down(self, y, x):
+    if y == len(self.items[0])-1:
+      return None
+    return self.items[y+1][x]
+
+  def get_item_left(self, y, x):
+    if x == 0:
+      return None
+    return self.items[y][x-1]
+
+  def get_item_right(self, y, x):
+    if x == len(self.items)-1:
+      return None
+    return self.items[y][x+1]
+
+  # Returns True when complete
+  def is_done(self):
+    for y in range(len(self.items)):
+      for x in range(len(self.items[0])):
+        if self.is_on(self.items[y][x]):
+          return False
+
+    return True
+
+  def button_press_event(self, widget, target, event, spot):
+    self.switch(target)
+    self.switch(self.get_item_up(spot[0], spot[1]))
+    self.switch(self.get_item_left(spot[0], spot[1]))
+    self.switch(self.get_item_right(spot[0], spot[1]))
+    self.switch(self.get_item_down(spot[0], spot[1]))
+
+    self.solve_it()
+
+    if self.is_done():
+      self.tipiitem.props.visibility = goocanvas.ITEM_VISIBLE
+      self.textitem.props.visibility = goocanvas.ITEM_INVISIBLE
+      self.tuxitem.props.visibility = goocanvas.ITEM_INVISIBLE
+      self.bubbleitem.props.visibility = goocanvas.ITEM_INVISIBLE
+      self.gamewon = True
+      gcompris.bonus.display(gcompris.bonus.WIN, gcompris.bonus.FLOWER)
+
+  def solution_switch(self, items, clicks, y, x):
+    items[y][x] = not items[y][x]
+    clicks[y][x] = not clicks[y][x]
+    if y >= 1:
+      items[y-1][x] = not items[y-1][x]
+    if y <= 3:
+      items[y+1][x] = not items[y+1][x]
+    if x >= 1:
+      items[y][x-1] = not items[y][x-1]
+    if x <= 3:
+      items[y][x+1] = not items[y][x+1]
+
+
+  def chase_light(self, items, clicks):
+    for y in range(1, len(items)):
+      for x in range(len(items[0])):
+        if items[y-1][x]:
+          self.solution_switch(items, clicks, y, x)
+
+  def is_solution_pattern(self, s, a, b, c, d, e):
+    if s[4][0] == a and \
+          s[4][1] == b and \
+          s[4][2] == c and \
+          s[4][3] == d and \
+          s[4][4] == e:
+      return True
+    return False
+
+
+  # Return False if the is no solution
+  def solution_wrap(self, solution, clicks):
+    if self.is_solution_pattern(solution, 1, 0, 0 , 0, 1):
+      self.solution_switch(solution, clicks, 0, 0)
+      self.solution_switch(solution, clicks, 0, 1)
+    elif self.is_solution_pattern(solution, 0, 1, 0, 1, 0):
+      self.solution_switch(solution, clicks, 0, 0)
+      self.solution_switch(solution, clicks, 0, 3)
+    elif self.is_solution_pattern(solution, 1, 1, 1, 0, 0):
+      self.solution_switch(solution, clicks, 0, 1)
+    elif self.is_solution_pattern(solution, 0, 0, 1, 1 , 1):
+      self.solution_switch(solution, clicks, 0, 3)
+    elif self.is_solution_pattern(solution, 1, 0, 1, 1, 0):
+      self.solution_switch(solution, clicks, 0, 4)
+    elif self.is_solution_pattern(solution, 0, 1, 1, 0, 1):
+      self.solution_switch(solution, clicks, 0, 0)
+    elif self.is_solution_pattern(solution, 1, 1, 0, 1, 1):
+      self.solution_switch(solution, clicks, 0, 2)
+    else:
+      return False
+    return True
+
+  def items2list(self, items):
+    list = []
+    for y in range(len(items[0])):
+      line = []
+      for x in range(len(items)):
+        if self.is_on(items[y][x]):
+          line.append(1)
+        else:
+          line.append(0)
+      list.append(line)
+    return list
+
+  # We check only the last line
+  def solution_found(self, solution):
+    for x in range(len(solution[0])):
+      if solution[4][x]:
+        return False
+    return True
+
+  def solution_length(self, clicks):
+    click = 0
+    for y in range(0, len(clicks)):
+      for x in range(len(clicks[0])):
+        if clicks[y][x]:
+          click += 1
+    return click
+
+  def solve_one(self, solution, clicks):
+    found = False
+    for index in range(0, 5):
+
+      self.chase_light( solution, clicks )
+
+      if self.solution_found(solution):
+        found = True
+        break
+
+      if not self.solution_wrap(solution, clicks):
+        break
+
+    if found:
+      return clicks
+    else:
+      return None
+
+  # Solving algorithm is the one described here:
+  # http://www.haar.clara.co.uk/Lights/solving.html To begin, you turn
+  # out all the lights on the top row, by pressing the buttons on the
+  # second row that are directly underneath any lit buttons on the top
+  # row. The top row will then have all it's lights off.  Repeat this
+  # step for the second, third and fourth row. (i.e. chase the lights
+  # all the way down to the bottom row). This may have solved the
+  # puzzle already ( click here for an example of this ), but is more
+  # likely that there will now be some lights left on in the bottom
+  # row. If so, there are only 7 posible configurations. Depending on
+  # which configuration you are left with, you need to press some
+  # buttons in the top row. You can determine which buttons you need
+  # to press from the following table.
+  # Light on bottom row     Press on this on top row
+  # 10001                   11000
+  # 01010                   10010
+  # 11100                   01000
+  # 00111                   00010
+  # 10110                   00001
+  # 01101                   10000
+  # 11011                   00100
+
+  def solve_it(self):
+    clicks = None
+
+    # Our solving algorithm does not find the shortest solution. We
+    # don't really care but we'd like to keep the proposed solution
+    # stable (not propose a complete new solution when one light
+    # changes).  To achieve this (closely), we test here all the
+    # combination of the first line, trying to find the shortest
+    # solution.
+    for x in range(64):
+      solution = self.items2list(self.items)
+      clicks2 = self.create_empty_list()
+      if x & 1:
+        self.solution_switch(solution, clicks2, 0, 0)
+      if x & 2:
+        self.solution_switch(solution, clicks2, 0, 1)
+      if x & 4:
+        self.solution_switch(solution, clicks2, 0, 2)
+      if x & 8:
+        self.solution_switch(solution, clicks2, 0, 3)
+      if x & 16:
+        self.solution_switch(solution, clicks2, 0, 4)
+
+      clicks2 = self.solve_one(solution, clicks2)
+      if clicks == None and clicks2:
+        clicks = clicks2
+      elif clicks2 and \
+            self.solution_length(clicks2) < self.solution_length(clicks):
+        clicks = clicks2
+
+    if self.hints_mode:
+      self.show_hints(clicks)
+    self.update_background(clicks)
+
+
+
+  def solve_event(self, widget, target, event):
+    clicks = self.create_empty_list()
+    self.hints_mode = not self.hints_mode
+    if not self.hints_mode:
+      self.show_hints(clicks)
+    else:
+      self.solve_it()
+
+
+  def update_background(self, clicks):
+    length = self.solution_length(clicks)
+    c = int(length * 0xFF / 18.0)
+    color = 0X33 << 24 | 0x11 << 16 | c << 8 | 0xFFL
+    self.background.set_properties(fill_color_rgba = color)
+
+    self.sunitem.translate(0, self.sunitem_offset)
+    self.sunitem_offset = length * 10
+    self.sunitem.translate(0, self.sunitem_offset * -1)
+
+
+  def show_hints(self, clicks):
+    for y in range(len(clicks)):
+      for x in range(len(clicks[0])):
+        if clicks[y][x]:
+          self.hints[y][x].props.visibility = goocanvas.ITEM_VISIBLE
+        else:
+          self.hints[y][x].props.visibility = goocanvas.ITEM_INVISIBLE
+
+  def print_sol(self, clicks):
+    for y in range(len(clicks)):
+      s = ""
+      for x in range(len(clicks[0])):
+        if clicks[y][x]:
+          s += "1"
+        else:
+          s += "0"
+      print s
+    print ""
diff --git a/src/lightsoff-activity/lightsoff.svg b/src/lightsoff-activity/lightsoff.svg
new file mode 100644
index 0000000..c5ec8f0
--- /dev/null
+++ b/src/lightsoff-activity/lightsoff.svg
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="75.147919"
+   height="88.927628"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.47pre4 r22446"
+   sodipodi:docname="lightsoff.svg"
+   inkscape:export-filename="D:\Cliparts\ampoule.png"
+   inkscape:export-xdpi="22.235786"
+   inkscape:export-ydpi="22.235786">
+  <title
+     id="title2868">Ampoule</title>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="4.6949285"
+     inkscape:cx="21.455902"
+     inkscape:cy="49.650125"
+     inkscape:document-units="px"
+     inkscape:current-layer="on"
+     showgrid="false"
+     inkscape:showpageshadow="false"
+     inkscape:window-width="1024"
+     inkscape:window-height="578"
+     inkscape:window-x="0"
+     inkscape:window-y="1"
+     inkscape:window-maximized="1"
+     inkscape:snap-global="false"
+     gridtolerance="10"
+     objecttolerance="10000"
+     showguides="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid2816"
+       empspacing="5"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true" />
+  </sodipodi:namedview>
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       id="perspective3658"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3687"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3710"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3710-9"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3741"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3766"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3829"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3851"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3875"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3907"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3937"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3960"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3983"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4005"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4027"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4053"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4080"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4106"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3648"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3714"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title>Ampoule</dc:title>
+        <cc:license
+           rdf:resource="http://creativecommons.org/licenses/publicdomain/"; />
+        <dc:date>2009-12-09</dc:date>
+        <dc:creator>
+          <cc:Agent>
+            <dc:title>Jean-Victor Balin</dc:title>
+          </cc:Agent>
+        </dc:creator>
+        <dc:publisher>
+          <cc:Agent>
+            <dc:title>openclipart.org</dc:title>
+          </cc:Agent>
+        </dc:publisher>
+        <dc:language>fr-FR</dc:language>
+        <dc:subject>
+          <rdf:Bag>
+            <rdf:li>idea</rdf:li>
+            <rdf:li>bulb</rdf:li>
+            <rdf:li>light</rdf:li>
+            <rdf:li>electric</rdf:li>
+          </rdf:Bag>
+        </dc:subject>
+        <dc:description>jean victor balin gmail com</dc:description>
+      </cc:Work>
+      <cc:License
+         rdf:about="http://creativecommons.org/licenses/publicdomain/";>
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Reproduction"; />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Distribution"; />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#DerivativeWorks"; />
+      </cc:License>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Calque 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-293.3349,370.33399)">
+    <g
+       id="on"
+       transform="matrix(0.0893496,0,0,0.0893496,291.082,-335.8218)">
+      <path
+         sodipodi:nodetypes="ccccccccccccccccccccccccccc"
+         id="rect4095-6"
+         d="m 90.002835,-332.59322 184.069235,56.10635 35.57888,-106.11413 124.96716,79.28065 132.0241,-82.93979 70.86374,114.65205 224.05876,-46.34871 -127.02546,171.97812 131.73004,69.523015 L 725.12997,73.567771 866.26929,145.53023 732.18696,166.26517 866.26929,367.51609 680.43582,356.53876 866.26929,589.50196 581.0502,479.72874 460.49366,609.01719 281.12903,474.84993 54.717993,589.50196 158.22019,395.56924 54.717993,367.51609 228.78987,249.20495 54.717993,145.53023 165.27718,73.567771 54.717993,-76.455665 172.33415,-153.29693 90.002835,-332.59322 z"
+         style="fill:#000000;fill-opacity:0.42745098;fill-rule:nonzero;stroke:none" />
+      <path
+         sodipodi:nodetypes="ccccccccccccccccccccccccccc"
+         id="rect4095"
+         d="m 67.263315,-318.56889 178.485655,52.46225 34.49963,-99.22206 121.17638,74.13142 128.01927,-77.55288 68.71413,107.20544 217.26209,-43.33837 -123.17222,160.80818 127.73417,65.00753 L 683.12439,61.212108 819.98242,128.50063 689.96729,147.88885 819.98242,336.0686 639.78602,325.80425 819.98242,543.63659 543.41515,440.99307 426.51561,561.88432 252.59187,436.43114 33.048811,543.63659 133.41136,362.29973 33.048811,336.0686 201.84036,225.44172 33.048811,128.50063 140.25425,61.212108 33.048811,-79.06738 147.09715,-150.91782 67.263315,-318.56889 z"
+         style="fill:#f3fc6f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:15.66878891;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+      <g
+         id="g4144"
+         transform="matrix(1.5829911,0,0,1.5829911,-19.267161,214.97804)">
+        <path
+           style="fill:#ad7fa8;fill-opacity:1;fill-rule:nonzero;stroke:none"
+           d="M 422.81827,-130.63776 C 424.25919,-24.072339 295.64449,40.56644 257.47244,39.030827 226.49993,37.784843 130.31106,-57.93402 130.31106,-142.8856 c 0,-84.95158 65.39569,-139.6141 145.17291,-140.12968 110.75872,-0.72046 144.45245,62.38271 147.3343,152.37752 z"
+           id="path3642"
+           sodipodi:nodetypes="csssc" />
+        <path
+           style="fill:#cab2c7;fill-opacity:1;fill-rule:nonzero;stroke:none"
+           d="M 414.67024,-131.71345 C 416.00616,-32.915357 297.93919,38.249565 262.607,35.779835 215.16003,32.463279 140.39138,-67.085749 140.39138,-145.84539 c 0,-78.75964 69.9953,-128.6914 137.47341,-130.63639 98.63845,-2.87382 136.80545,66.00869 136.80545,144.76833 z"
+           id="path3642-5"
+           sodipodi:nodetypes="csssc" />
+        <path
+           style="fill:#fff54d;fill-opacity:1;fill-rule:nonzero;stroke:none"
+           d="m 194.38687,-187.22123 45.899,53.09132 22.51606,-44.44899 20.78231,27.72891 20.7823,-31.43329 11.24663,21.81269 32.91859,-27.88356 12.9804,31.27863 32.05159,-5.61511 -32.96441,55.91361 6.09097,36.757876 -49.36652,-27.059927 -22.51605,41.490851 -18.18167,-22.404302 -25.1167,26.108688 -16.4479,-21.221076 -43.32116,35.574658 4.34587,-52.804911 -28.59555,-31.506527 26.89624,-65.37954 z"
+           id="rect3818-5"
+           sodipodi:nodetypes="cccccccccccccccccccc" />
+        <path
+           style="fill:#cab2c7;fill-opacity:1;fill-rule:nonzero;stroke:none"
+           d="m 204.25323,-160.17168 38.14652,32.32658 18.71303,-27.06438 17.27211,16.88376 17.27211,-19.13931 9.34704,13.28145 27.35856,-16.97792 10.78796,19.04513 26.63797,-3.41895 -27.39662,34.04503 5.06219,22.381374 -41.02837,-16.476434 -18.71302,25.26322 -15.11073,-13.641676 -20.87441,15.897228 -13.6698,-12.921215 -36.00409,21.660917 3.61184,-32.152194 -23.76567,-19.18389 22.35338,-39.80872 z"
+           id="rect3818"
+           sodipodi:nodetypes="cccccccccccccccccccc" />
+        <path
+           style="fill:#fffdf5;fill-opacity:1;fill-rule:nonzero;stroke:none"
+           d="m 328.8147,-140.74502 c -0.19608,0.0115 -0.40004,0.0426 -0.59534,0.0449 -2.7404,0.51563 -5.29709,1.76206 -7.75377,3.17801 -0.24185,0.0104 -0.48426,4.5e-4 -0.77998,-0.0544 -0.3487,-0.0647 -0.70316,-0.21037 -1.05556,-0.25012 -4.91993,-0.55574 -9.10146,4.07768 -13.03154,6.14801 -0.46599,0.42328 -0.98696,0.80799 -1.41327,1.27121 -1.12698,1.22456 -2.61803,3.39723 -3.51511,4.6792 -2.78126,3.97447 -5.46635,8.00898 -8.47868,11.81658 -0.97638,1.22523 -1.95708,2.46461 -2.92325,3.6963 -0.67817,-2.58691 -0.86509,-5.28297 -1.0153,-7.9398 0.0546,-2.92321 0.008,-4.64474 0.41046,-7.52239 0.14109,-1.00844 0.31426,-2.00329 0.58862,-2.98388 0.002,-0.007 -10e-4,-0.0242 9.3e-4,-0.0312 0.51306,-0.71434 1.00354,-1.45159 1.37948,-2.24138 0.1862,-0.39113 0.23247,-0.82307 0.34939,-1.24019 -3.57055,-4.37487 -1.42973,-2.46774 -12.03106,6.14639 -0.54517,0.44297 -0.2233,1.38625 -0.28066,2.08635 -0.38896,0.59847 -0.79881,1.15994 -1.17448,1.65345 -3.0743,4.03852 -6.75617,7.56529 -10.24341,11.
 23281 -2.80123,2.97638 -3.83784,4.07953 -5.06976,5.446 -0.007,-2.91083 0.41395,-5.96571 0.82139,-8.72951 0.88613,-6.01088 2.29121,-11.93213 3.15785,-17.9456 -0.48352,-7.38318 0.78631,-5.2006 -11.70019,1.31032 -0.69759,0.36375 -0.98725,1.21496 -1.43085,1.8647 -1.28281,1.87894 -4.64081,7.40869 -5.55102,9.02706 -1.09559,1.94797 -2.09793,3.96678 -3.14607,5.94068 -0.42634,0.91064 -0.86862,1.80194 -1.29966,2.7127 -3.43509,-4.4603 -6.96215,-8.85875 -10.87209,-12.92139 -1.15707,-1.13156 -2.28902,-2.27212 -3.46377,-3.38532 -2.82808,-2.67992 -5.78392,-5.22202 -8.48448,-8.03604 -0.0243,-0.17845 -0.0557,-0.35493 -0.078,-0.5338 l -17.23803,8.83712 c 0.29925,0.42516 0.62304,0.83726 0.90007,1.27721 1.92542,3.05772 3.51515,6.33482 5.12531,9.56224 2.8368,5.68611 2.1103,4.22039 4.98371,10.12078 3.72209,7.229489 6.52002,14.895078 7.98148,22.902672 0.72158,3.953683 1.48152,10.61133 1.95101,14.345322 0.33418,3.660122 0.73414,7.339391 1.01832,11.003734 0.72,9.283675 1.34317,20.61374 1.71156,29.81
 3766 0.40411,10.092024 0.81885,24.6085841 0.65948,34.7222605 -0.078,4.9486415 -0.41559,9.8869495 -0.62702,14.8316865 -0.29483,3.567473 -0.5213,7.135861 -0.8797,10.697389 l -3.17268,1.562976 c 0.15592,0.223236 0.38504,0.415686 0.48035,0.67077 0.55454,1.484174 0.53992,2.809952 0.68258,4.397143 -0.25935,3.162687 -0.4516,4.300212 0.0946,4.192142 -0.0509,0.19626 -0.1072,0.389976 -0.14253,0.589788 -0.10758,0.60822 -0.49163,2.161668 0.0391,1.845717 17.33711,-10.321163 17.41709,-5.265717 15.8354,-14.256033 -0.26763,-2.032577 -0.3171,-3.870858 0.2043,-5.840261 l -4.15582,2.034067 c -0.71552,-3.095899 -1.16541,-6.245494 -1.75456,-9.368572 -0.51249,-4.593892 -1.23583,-9.1882994 -1.52944,-13.8013482 -0.69895,-10.981337 -0.42997,-24.0305638 -0.0577,-34.9858038 0.49512,-14.569127 1.56658,-29.119748 3.10552,-43.614659 0.37847,-6.491489 0.98686,-9.503923 -0.037,-15.632954 -0.32227,-1.92913 -0.92853,-3.79773 -1.48894,-5.671583 -1.78568,-5.970789 -4.24068,-11.714949 -6.64224,-17.454369 -0.471
 89,-1.14263 -0.93479,-2.29691 -1.39847,-3.44918 3.08132,3.08071 5.85256,6.46592 8.36278,10.03332 1.51493,2.15294 3.12518,4.62588 4.26226,7.035559 0.15052,0.31899 0.26016,0.64736 0.37738,0.98036 -0.19426,0.85705 -0.62194,2.14721 0.0354,1.97066 0.0729,-0.0196 0.14786,-0.0357 0.22051,-0.056 -0.0506,0.20798 -0.0885,0.35248 0.0541,0.28297 0.59685,-0.29085 1.21286,-0.58673 1.80824,-0.88433 3.18528,-1.16762 6.16049,-2.935689 9.0798,-4.670649 0.20315,-0.12072 -0.0472,-0.32422 -0.29663,-0.54027 0.0301,-0.0225 0.0655,-0.0371 0.0956,-0.0597 0.42659,-0.32023 -0.39115,-1.01201 -0.42319,-1.54446 -0.0641,-1.06595 -0.0244,-2.16326 0.15779,-3.21549 0.68731,-3.96986 1.93555,-6.41205 3.46028,-10.2145 1.48932,-2.86416 2.23972,-4.39402 3.11482,-5.94161 -0.004,0.30948 0.0198,0.62883 0.003,0.93801 -0.41488,7.85589 -2.21504,15.532 -3.16085,23.322879 -0.12567,1.03551 -0.16121,2.07956 -0.24873,3.119 0.15815,0.48091 -0.0204,1.61951 0.45721,1.45167 4.25357,-1.49468 8.31689,-3.56706 12.17983,-5.891869 0
 .78947,-0.47513 0.98335,-1.57336 1.5072,-2.33139 0.75398,-1.09103 1.5331,-2.16546 2.34619,-3.21317 3.0652,-3.94962 3.53522,-4.31447 7.02538,-8.13926 0.77673,-0.80488 1.56784,-1.6036 2.35336,-2.40011 0.0249,1.12669 0.0323,2.25723 0.0562,3.37815 0.11215,3.30769 0.33211,6.63195 1.0204,9.8783 0.209,0.98574 0.60324,2.5348 1.21105,3.44362 0.19538,0.292139 0.50619,0.498069 0.75962,0.741579 5.23864,0.89636 1.94632,0.53479 12.32884,-6.700319 0.52915,-0.36875 0.599,-1.13588 0.92552,-1.69208 0.48415,-0.82475 0.98909,-1.6549 1.5109,-2.45634 2.3062,-3.54201 2.45802,-3.6195 5.12344,-7.2577 2.9202,-4.03076 5.79997,-8.08815 8.8903,-11.99197 0.23053,-0.29123 0.54467,-0.6733 0.81144,-1.00766 0.1814,-0.0169 0.33776,-0.0293 0.72121,-0.0724 0.33826,-0.11284 0.72562,-0.17963 1.04191,-0.3443 1.09616,-0.57069 2.18235,-1.16447 3.27194,-1.74761 -0.3526,0.19438 0.73369,-0.35284 1.109,-0.49863 0.34727,-0.13488 0.71831,-0.22986 1.07314,-0.34337 0.70392,-0.10942 1.26398,-0.27254 1.97067,-0.0354 1.76736,0
 .59308 2.66043,3.74341 3.25297,5.22363 1.18316,3.57067 2.04957,7.27533 2.64446,10.98938 0.002,0.21799 0.009,0.4389 0.0118,0.65689 l 0.1268,-0.0588 c -2.01098,2.57844 -4.05163,5.15738 -5.98348,7.79497 -1.20885,1.65048 -2.37594,3.31917 -3.55561,4.99064 -1.81875,3.02264 -4.86091,7.801479 -6.14405,11.104162 -1.56949,4.0398 -3.25559,12.030041 -4.16435,16.039956 -2.59701,11.459426 -1.69192,7.146438 -3.75064,18.95974 -0.56091,3.180114 -1.15007,6.364102 -1.68976,9.547896 -0.52874,3.119199 -0.95807,6.253169 -1.52802,9.365105 -0.53434,2.917595 -1.20663,5.792566 -1.78971,8.700813 -0.5591,2.788635 -1.04917,5.607699 -1.62428,8.393078 -1.12989,5.472229 -2.09428,9.42073 -3.34643,14.8136418 -2.06405,8.4726195 -3.89463,17.0000968 -5.32309,25.6035862 -0.33958,1.825504 -0.43987,3.644192 -0.38154,5.491109 0.0545,2.154578 -0.36315,4.276211 -0.34683,6.430049 0.006,0.808546 0.16966,3.169635 0.22607,3.977189 0.34052,2.527434 0.59092,5.067344 0.64972,7.616333 -0.20215,1.951909 0.15277,3.909929 0.295
 48,5.855069 l 17.57492,-7.545323 c -0.35335,-1.896807 -0.28724,-3.777994 -0.26887,-5.697962 -0.17461,-2.501358 -1.10455,-4.811512 -1.40958,-7.294945 -0.0872,-1.68132 -0.16846,-2.137947 -0.0745,-3.816381 0.12563,-2.244683 0.59678,-4.456711 1.0102,-6.660503 0.13814,-0.781022 0.25091,-1.122732 0.21171,-1.869551 -0.0517,-0.984582 -1.02357,-2.285075 -0.74621,-3.304799 -0.65364,-7.9992661 0.50543,-16.0016202 1.67724,-23.89831 0.84865,-5.712213 1.25033,-8.599603 2.20897,-14.409651 0.45693,-2.769283 0.99596,-5.532591 1.43408,-8.304922 1.43331,-9.069631 2.60754,-18.171878 4.0896,-27.234581 1.97254,-9.447747 3.85187,-18.969427 7.33286,-28.013873 2.52689,-6.565467 5.98605,-12.726636 9.83617,-18.591856 1.24413,-1.67226 2.46366,-3.37159 3.74395,-5.01632 4.94289,-6.34987 10.38991,-12.3614 16.34604,-17.77371 l -14.99734,4.96428 c -0.71976,-2.35464 -1.36264,-4.73392 -2.07202,-7.09572 -0.72361,-2.38523 -1.45659,-6.46849 -4.4506,-7.00989 -0.19221,-0.0348 -0.39741,-0.0291 -0.59349,-0.0176 z M 
 239.80168,33.539031 c 0.47123,0.05847 0.14825,2.019776 -0.46438,1.955855 -0.61133,-0.06383 -0.97017,-0.636541 -1.27583,-1.257085 0.54689,-0.21899 1.0582,-0.454431 1.64557,-0.67031 0.0385,-0.01417 0.0632,-0.03236 0.0946,-0.02846 z"
+           id="path3808" />
+        <g
+           id="g3922"
+           transform="translate(-11.527378,5.7636888)">
+          <path
+             id="rect3645"
+             d="m 221.30908,3.6333078 9.78125,30.0937502 -12.8125,26.96875 10.25,27.03125 -12.65625,32.000002 31.65625,1.53125 10.0625,17.34375 16.90625,1.46875 10.4375,-15.8125 27.34375,2.25 L 325.0625,94.570808 313.9756,65.48048 326.74829,44.185091 335.63185,9.5969247 C 321.2982,15.880365 296.97547,21.145438 275.15283,19.477058 253.59875,17.829208 234.50602,11.863248 221.30908,3.6333078 z"
+             style="fill:#739fd0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             sodipodi:nodetypes="ccccccccccccccsc" />
+          <path
+             id="rect3645-1"
+             d="m 229.92181,14.864936 8.43824,25.988687 -11.05328,23.265807 8.84262,23.292762 -10.91848,27.633198 27.30969,1.29404 8.68087,14.98933 14.58494,1.26708 9.00437,-13.64136 23.58932,1.9141 9.7862,-27.552319 -12.05077,-26.312195 14.12663,-24.613767 4.55611,-20.489007 c -12.36469,5.416966 -29.62585,8.07078 -48.44572,6.631968 -18.59747,-1.421807 -35.06561,-6.566688 -46.45074,-13.668324 z"
+             style="fill:#adc6e3;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+          <path
+             id="path3677"
+             d="m 310.88885,46.671177 c -11.96269,9.844207 -42.84239,1.646157 -70.93155,-19.271795 -1.43506,-1.068697 -2.81877,-2.159415 -4.18483,-3.252509 4.21102,6.878003 10.32882,13.811725 17.98455,19.931103 20.73144,16.571059 44.90136,20.889987 53.99198,9.653186 1.63738,-2.02393 2.66234,-4.403435 3.13985,-7.059985 z"
+             style="fill:#739fd0;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+          <path
+             id="path3677-0"
+             d="m 305.13139,75.954459 c -10.76023,8.854689 -38.53596,1.480691 -63.80165,-17.334627 -1.29081,-0.961276 -2.53543,-1.942359 -3.76418,-2.925574 3.78774,6.186637 9.29059,12.423402 16.17678,17.927664 18.64755,14.90537 40.38796,18.790173 48.56481,8.68287 1.47279,-1.820488 2.39473,-3.960814 2.82424,-6.350333 z"
+             style="fill:#739fd0;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+          <path
+             id="path3677-4"
+             d="m 302.11116,102.42634 c -10.27923,8.45888 -36.81338,1.4145 -60.94968,-16.559759 -1.23311,-0.918307 -2.4221,-1.855535 -3.59592,-2.7948 3.61842,5.910091 8.87529,11.86807 15.45367,17.126289 17.814,14.23909 38.5826,17.95024 46.39394,8.29474 1.40696,-1.73911 2.28768,-3.78376 2.69799,-6.06647 z"
+             style="fill:#739fd0;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+        </g>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/src/lightsoff-activity/lightsoff.xml.in b/src/lightsoff-activity/lightsoff.xml.in
new file mode 100644
index 0000000..4aa2a23
--- /dev/null
+++ b/src/lightsoff-activity/lightsoff.xml.in
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<GCompris>
+  <Board
+        name="lightsoff"
+        type="python:lightsoff"
+        section="/puzzle"
+        icon="lightsoff.svg"
+        difficulty="1"
+        author="Bruno and Clément coudoin"
+        boarddir="">
+        <_title>Lights Off</_title>
+        <_description>The aim is to switch off all the lights</_description>
+        <_prerequisite></_prerequisite>
+        <_goal>The aim is to switch off all the lights.</_goal>
+	<_manual>The effect of pressing a button is to toggle the state of that button, and of its immediate vertical and horizontal neighbours. The sun and the color of the sky depend on the number of clicks needed to solve the puzzle. If you click on Tux, the solution is shown.</_manual>
+        <_credit>The solver algorithm described on the haar.clara.co.uk is a valuable resource to know more about the Lights Off game: &lt;http://www.haar.clara.co.uk/Lights/solving.html&gt;</_credit>
+  </Board>
+</GCompris>
diff --git a/src/lightsoff-activity/resources/Makefile.am b/src/lightsoff-activity/resources/Makefile.am
new file mode 100644
index 0000000..1686d03
--- /dev/null
+++ b/src/lightsoff-activity/resources/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS=lightsoff
\ No newline at end of file
diff --git a/src/lightsoff-activity/resources/lightsoff/Makefile.am b/src/lightsoff-activity/resources/lightsoff/Makefile.am
new file mode 100644
index 0000000..f173647
--- /dev/null
+++ b/src/lightsoff-activity/resources/lightsoff/Makefile.am
@@ -0,0 +1,6 @@
+imgdir = $(pkgdatadir)/@PACKAGE_DATA_DIR@/lightsoff
+img_DATA = \
+	onoff.svgz \
+	back.svgz
+
+EXTRA_DIST = $(img_DATA)
diff --git a/src/lightsoff-activity/resources/lightsoff/README b/src/lightsoff-activity/resources/lightsoff/README
new file mode 100644
index 0000000..2404cf7
--- /dev/null
+++ b/src/lightsoff-activity/resources/lightsoff/README
@@ -0,0 +1,2 @@
+The lamp icon comes from OpenClipart by Victor Balin
+The Tipi comes from OpenClipart by Iwan Gabovitch
\ No newline at end of file
diff --git a/src/lightsoff-activity/resources/lightsoff/back.svgz b/src/lightsoff-activity/resources/lightsoff/back.svgz
new file mode 100644
index 0000000..85e1b38
Binary files /dev/null and b/src/lightsoff-activity/resources/lightsoff/back.svgz differ
diff --git a/src/lightsoff-activity/resources/lightsoff/onoff.svgz b/src/lightsoff-activity/resources/lightsoff/onoff.svgz
new file mode 100644
index 0000000..aeeee4a
Binary files /dev/null and b/src/lightsoff-activity/resources/lightsoff/onoff.svgz differ



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]