# gcompris - hangman.py # -*- coding: utf-8 -*- # # Copyright (C) 2003, 2008 Bruno 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 . # # PythonTemplate Board module import gtk import gtk.gdk import gcompris import gcompris.utils import gcompris.skin import gcompris.bonus import gcompris.score import goocanvas import pango from gcompris import gcompris_gettext as _ fles = None class Gcompris_hangman: """Empty gcompris python class""" def __init__(self, gcomprisBoard): # Save the gcomprisBoard, it defines everything we need # to know from the core self.gcomprisBoard = gcomprisBoard # 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 = 0; self.gamewon = 0; # global parameter to access object structures from global fonctions global fles fles=self # The current word to search self.word = "" # The list of letter to find self.letters = [] # The list of virtual keys displayed self.keys = [] # the number of trials left to the user self.trial = 0 # All the vowel of your language (keep empty if non applicable) self.vowels = unicode(_("aeiouy"), encoding="utf8") # All the consonants of your language (keep empty if non applicable) self.consonants = unicode(_("bcdfghjklmnpqrstvwxz"), encoding="utf8") # Letters equivallence for the hangman activity. It has the # form of a space separated list like: "e=éè a=àâ" # Keep the word NONE if not available in your language self.equivs = unicode(_("NONE"), encoding="utf8") if self.equivs == "NONE": self.equivs = "" # Create equivs list self.equivList = [] for equiv in self.equivs.split(' '): try: (k, v) = equiv.split('=') self.equivList.append(k + v) except: print ("ERROR: Bad equivalence liste '%s'" %(self.equivs, )) def start(self): # 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.backitem = goocanvas.Group(parent = self.gcomprisBoard.canvas.get_root_item()) svghandle = gcompris.utils.load_svg("hangman/back.svgz") goocanvas.Svg( parent = self.backitem, svg_handle = svghandle, pointer_events = goocanvas.EVENTS_NONE ) # 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.backitem) # Get the name of the language for the current locale self.wordlist = None try: self.language = gcompris.gcompris_gettext( gcompris.get_locale_name(gcompris.get_locale()) ) self.wordlist = gcompris.get_wordlist("wordsgame/default-$LOCALE.xml") except: pass if not self.wordlist: # Fallback to english self.wordlist = gcompris.get_wordlist("wordsgame/default-en.xml") self.language = _("English") if not self.wordlist: gcompris.utils.dialog(_("Could not find the list of words."), stop_board) return; self.gcomprisBoard.level = 1 self.gcomprisBoard.maxlevel = self.wordlist.number_of_level * 3 self.gcomprisBoard.sublevel = 1 self.gcomprisBoard.number_of_sublevel = 10 # Set the buttons we want in the bar gcompris.bar_set(gcompris.BAR_LEVEL) gcompris.bar_location(gcompris.BOARD_WIDTH - 160, -1, 0.6) # Set a background image gcompris.set_default_background(self.gcomprisBoard.canvas.get_root_item()) self.display_level() def end(self): # Remove the root item removes all the others inside it self.backitem.remove() gcompris.score.end() def ok(self): print("hangman ok.") def repeat(self): print("hangman repeat.") def config(self): print("hangman config.") def key_press(self, keyval, commit_str, preedit_str): if not commit_str: return for k in self.keys: if k.click(commit_str): break return True 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 1, lost if 2 if(self.gamewon >= 1 and pause == 0): if self.gamewon == 1: self.increment_level() self.gamewon = 0 self.next_level() return def set_level(self, level): self.gcomprisBoard.level = level; self.gcomprisBoard.sublevel = 1; gcompris.bar_set_level(self.gcomprisBoard) self.next_level() #------- 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 if(self.gcomprisBoard.level > self.gcomprisBoard.maxlevel): self.gcomprisBoard.level = self.gcomprisBoard.maxlevel def next_level(self): gcompris.score.end() self.rootitem.remove() self.rootitem = goocanvas.Group(parent = self.backitem) self.display_level() def display_letter_set(self, letter_set, y, fill_color, stroke_color): group = goocanvas.Group(parent = self.rootitem) w = 40 max_per_line =gcompris.BOARD_WIDTH / w - 2 x = (gcompris.BOARD_WIDTH - (max_per_line * w)) / 2 wc = 0 line = 0 for line in range(0, len(letter_set) / max_per_line + 1): for i in range(0, max_per_line): if wc < len(letter_set): self.keys.append( Key(self, group, x + i*w, y + line*w, letter_set[wc], self.get_equiv(letter_set[wc]), fill_color, stroke_color) ) wc += 1 return (group, y + (line + 1 )* w) def display_level(self): w = 40 # Less trial when the level increases self.trial = 12 - (self.gcomprisBoard.level - 1) / self.wordlist.number_of_level gcompris.bar_set_level(self.gcomprisBoard); gcompris.score.start(gcompris.score.STYLE_NOTE, gcompris.BOARD_WIDTH / 2 - 100, 170, self.trial) gcompris.score.set(self.trial) # Display the word to find self.word = self.get_next_word() self.letters = [] self.keys= [] x = (gcompris.BOARD_WIDTH - (len(self.word) * w)) / 2 for i in range(0, len(self.word)): self.letters.append(Letter(self, x + i*w, 70, self.word[i], self.get_equiv(self.word[i]))) # Display the language goocanvas.Text( parent = self.rootitem, x = gcompris.BOARD_WIDTH / 2, y = gcompris.BOARD_HEIGHT / 2 - 30, text = self.language, fill_color = "white", anchor = gtk.ANCHOR_CENTER, alignment = pango.ALIGN_CENTER ) # Display the virtual keyboard (group_vowels, y_vowels) = self.display_letter_set(self.vowels, 0, 0xFF6633AAL, 0xFF33CCBBL) (group_cons, y_cons) = self.display_letter_set(self.consonants, y_vowels + 20, 0x66FF33AAL, 0xFF33CCBBL) group_vowels.translate(0, gcompris.BOARD_HEIGHT - y_cons - 40) group_cons.translate(0, gcompris.BOARD_HEIGHT - y_cons - 40) def get_next_word(self): return unicode(gcompris.get_random_word(self.wordlist, self.gcomprisBoard.level), encoding="utf8") def found_all_letters(self): retval = True for letter in self.letters: if not letter.found: retval = False return retval def check_letters(self, targetLetter): retval = False for letter in self.letters: if letter.check(targetLetter): retval = True return retval def hide_letters(self, status): for letter in self.letters: letter.hide(status) def get_equiv(self, letter): """ Return equivallence for the given letter """ letters = letter for v in self.equivList: if v.count(letter): letters += v return letters def ok_event(self, widget, target, event=None): if self.gamewon == 2: gcompris.bonus.display(gcompris.bonus.LOOSE, gcompris.bonus.TUX) else: gcompris.bonus.display(gcompris.bonus.WIN, gcompris.bonus.TUX) def display_ok(self): # The OK Button item = goocanvas.Svg(parent = self.rootitem, svg_handle = gcompris.skin.svg_get(), svg_id = "#OK" ) zoom = 0.8 item.translate( (item.get_bounds().x1 * -1) + ( gcompris.BOARD_WIDTH - 300 ) / zoom, (item.get_bounds().y1 * -1) + 190.0 / zoom) item.scale(zoom, zoom) item.connect("button_press_event", self.ok_event) gcompris.utils.item_focus_init(item, None) # A letter to find displayed on the screen class Letter: def __init__(self, hangman, x, y, letter, letters): self.found = False parent = hangman.rootitem fill_color = 0xFF3366AAL stroke_color = 0xFF33CCAAL w = 30 h = 30 self.letters = letters self.rect = goocanvas.Rect( parent = parent, x = x, y = y, width = w, height = h, fill_color_rgba = fill_color, stroke_color_rgba = stroke_color, line_width = 1.0) self.letterItem = goocanvas.Text( parent = parent, x = x + w/2, y = y + h/2, text = letter, fill_color = "black", anchor = gtk.ANCHOR_CENTER, alignment = pango.ALIGN_CENTER ) self.hide(True) def hide(self, status): if status: self.letterItem.props.visibility = goocanvas.ITEM_INVISIBLE else: self.letterItem.props.visibility = goocanvas.ITEM_VISIBLE def check(self, targetLetter): if (self.letters.count(targetLetter) > 0): self.rect.set_properties(fill_color_rgba = 0x66CC33AAL) self.letterItem.props.visibility = goocanvas.ITEM_VISIBLE self.found = True return True return False # A virtual key on screen class Key: def __init__(self, hangman, parent, x, y, letter, letters, fill_color, stroke_color): self.hangman = hangman self.letter = letter self.letters = letters self.disabled = False w = 30 h = 30 self.rect = goocanvas.Rect( parent = parent, x = x, y = y, width = w, height = h, fill_color_rgba = fill_color, stroke_color_rgba = stroke_color, line_width = 1.0) self.letterItem = goocanvas.Text( parent = parent, x = x + w/2, y = y + h/2, text = letter, fill_color = "black", anchor = gtk.ANCHOR_CENTER, alignment = pango.ALIGN_CENTER ) self.letterItem.connect("button_press_event", self.letter_event, letter) self.rect.connect("button_press_event", self.letter_event, letter) def click(self, letter): if(self.hangman.gamewon): return False # Check we are the correct key for the given letter if not self.letters.count(letter): return False # Already done if self.disabled: return True # disable this key, mark it as used self.disabled = True self.rect.set_properties(fill_color_rgba = 0xCCCCCCCCL, line_width = 3.0) self.rect.disconnect_by_func(self.letter_event) self.letterItem.disconnect_by_func(self.letter_event) # Decrease user lives and trig bonus if needed if not self.hangman.check_letters(letter): self.hangman.trial -= 1 gcompris.score.set(self.hangman.trial) if self.hangman.trial == 0: self.hangman.gamewon = 2 self.hangman.hide_letters(False) self.hangman.display_ok() elif self.hangman.found_all_letters(): self.hangman.gamewon = 1 self.hangman.display_ok() return True # # Event on a letter # def letter_event(self, item, target, event, letter): self.click(letter) def stop_board(): global fles fles.end() gcompris.end_board()