# gcompris - BarGame # # # # Copyright (C) 2004 Yves Combe # # 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 . # import gnomecanvas import gcompris import gcompris.utils import gcompris.bonus import gcompris.skin import pygtk import gtk import gtk.gdk import random import math backgrounds = [ 'opt/school_bg1.jpg', 'opt/school_bg2.jpg', 'opt/school_bg3.jpg', 'opt/school_bg4.jpg' ] profs = [ 'images/tux.png', 'images/tux_teen.png', 'images/tux_graduate.png', 'images/tux_albert.png' ] class Gcompris_bargame: """The Bar Game""" def __init__(self, gcomprisBoard): random.seed() self.gcomprisBoard = gcomprisBoard self.rootitem = None # To display the bonus, we need to pause the board. self.board_paused = 0 self.number_balls = [[1,4],[2,6],[3,6]] self.board_size = [15,19,29] self.gcomprisBoard.level=1 self.gcomprisBoard.maxlevel=4 self.gcomprisBoard.sublevel=1 self.gcomprisBoard.number_of_sublevel=3 # global scale depending on the level self.scales = [0.208, 0.164, 0.107] self.holes = [] self.balls = [] self.list_win = [] self.profbutton = [] self.answer = [] self.pixmap_blue_ball = gcompris.utils.load_pixmap("bargame/blue_ball.png") self.pixmap_green_ball = gcompris.utils.load_pixmap("bargame/green_ball.png") self.pixmap_case = gcompris.utils.load_pixmap("bargame/case.png") self.pixmap_case_last = gcompris.utils.load_pixmap("bargame/case_last.png") self.pixmap_ombre = gcompris.utils.load_pixmap("bargame/ombre.png") self.pixmap_mask = gcompris.utils.load_pixmap("bargame/mask.png") self.pixmap_mask_last = gcompris.utils.load_pixmap("bargame/mask_last.png") def start(self): # load pixmaps for the ui. # pixmap = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin("button_reload.png")) if(pixmap): gcompris.bar_set_repeat_icon(pixmap) gcompris.bar_set(gcompris.BAR_LEVEL|gcompris.BAR_OK|gcompris.BAR_REPEAT_ICON) else: gcompris.bar_set(gcompris.BAR_LEVEL|gcompris.BAR_OK|gcompris.BAR_REPEAT) gcompris.bar_set_level(self.gcomprisBoard) # Create persistent over levels root item canvas for the board self.rootitem_p = self.gcomprisBoard.canvas.root().add( gnomecanvas.CanvasGroup, x=0, y=0 ) self.profbutton = self.prof_button(self, self.rootitem_p, profs[self.gcomprisBoard.level - 1]) self.answer = self.answer_button(self.rootitem_p, self.scales[self.gcomprisBoard.sublevel-1], self.pixmap_green_ball, self.number_balls[self.gcomprisBoard.sublevel-1]) # self.newGame() def end(self): self.cleanup() del self.profbutton self.profbutton = [] del self.answer self.answer = [] if self.rootitem_p: self.rootitem_p.destroy() def set_level(self,level): self.gcomprisBoard.level = level self.gcomprisBoard.sublevel = 1 gcompris.bar_set_level(self.gcomprisBoard) self.newGame() pass def ok(self): self.answer.has_focus() self.play(self.answer.value,True) pass def key_press(self, keyval, commit_str, preedit_str): return False def repeat(self): self.newGame() 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 ((pause == 0) and self.finished_sublevel): self.set_sublevel(self.gcomprisBoard.sublevel+1) return 0 #------------------------------------------------- #------------------------------------------------- #------------------------------------------------- def set_sublevel(self, sublevel): #sublevel change only in game_won if sublevel > self.gcomprisBoard.number_of_sublevel: if self.game_won: if self.gcomprisBoard.level == self.gcomprisBoard.maxlevel: gcompris.bonus.board_finished(gcompris.bonus.FINISHED_RANDOM) return 0 else: self.set_level(self.gcomprisBoard.level+1) else: self.gcomprisBoard.sublevel = 1 self.newGame() else: self.gcomprisBoard.sublevel = sublevel self.newGame() def calculate_win_places(self): winners = [] min = self.number_balls[self.gcomprisBoard.sublevel-1][0] max = self.number_balls[self.gcomprisBoard.sublevel-1][1] period = (min + max) winners_list = [(self.board_size[self.gcomprisBoard.sublevel-1] -1 -x)% period for x in range(min)] for i in range(self.board_size[self.gcomprisBoard.sublevel-1]): if ((i+1) % period) in winners_list: winners.append(i) level_win = (self.gcomprisBoard.level -1) * min if level_win == 0: winners = [] else: winners = winners[-level_win:] return winners # Remove uneeded objects def cleanup(self): if self.rootitem: self.rootitem.destroy() # Holes reinit for h in self.holes: del h del self.holes self.holes = [] # Balls reinit for h in self.balls: del h del self.balls self.balls = [] # Other variable cleanup del self.list_win self.list_win = [] def newGame(self): self.cleanup() width_ref = 256 scale = self.scales[self.gcomprisBoard.sublevel-1] self.last_played = -1 self.finished_sublevel = False self.game_won = False self.list_win = self.calculate_win_places() # Create root item canvas for the board self.rootitem = self.gcomprisBoard.canvas.root().add( gnomecanvas.CanvasGroup, x=0, y=0 ) # background gcompris.set_background(self.gcomprisBoard.canvas.root(), backgrounds[self.gcomprisBoard.level - 1]) self.profbutton.set_prof(profs[self.gcomprisBoard.level - 1]) for i in range(self.board_size[self.gcomprisBoard.sublevel-1]): self.holes.append(self.hole(self, self.rootitem, i * width_ref * scale, gcompris.BOARD_HEIGHT - 120, i, self.board_size[self.gcomprisBoard.sublevel-1], scale)) for i in range(self.number_balls[self.gcomprisBoard.sublevel-1][1]): self.balls.append(self.ball(self.rootitem, i * width_ref * scale + 150, gcompris.BOARD_HEIGHT - 160, scale, self.pixmap_blue_ball)) self.balls.append(self.ball(self.rootitem, i * width_ref * scale +150, gcompris.BOARD_HEIGHT-70, scale, self.pixmap_green_ball)) self.answer.set_number_of_balls(self.number_balls[self.gcomprisBoard.sublevel-1]) def play(self, value, human): for i in range(1,value+1): self.last_played += 1 if human: self.holes[self.last_played].isGreen() else: self.holes[self.last_played].isBlue() if self.last_played == self.board_size[self.gcomprisBoard.sublevel-1] - 1 : self.gamelost(human) return if human: self.machine_play() def machine_play(self): def accessible(x): if ((x + self.last_played) in self.list_win): return True return False playable = filter(accessible, range(self.number_balls[self.gcomprisBoard.sublevel-1][0], self.number_balls[self.gcomprisBoard.sublevel-1][1]+1)) if playable != []: self.play(random.choice(playable),False) else: self.play(random.choice(range(self.number_balls[self.gcomprisBoard.sublevel-1][0], self.number_balls[self.gcomprisBoard.sublevel-1][1]+1)), False) self.answer.new_value(self.number_balls[self.gcomprisBoard.sublevel-1][0]) def gamelost(self,human): self.finished_sublevel = True if human: gcompris.bonus.display(gcompris.bonus.LOOSE, gcompris.bonus.GNU) else: self.game_won = True gcompris.bonus.display(gcompris.bonus.WIN, gcompris.bonus.GNU) class hole: def __init__(self, board, root, x, y, index, board_size, scale): self.board = board self.itemgroup = root.add( gnomecanvas.CanvasGroup, x=x, y=y) self.scale = scale if (index == (board_size-1)): pixbuf_case = self.board.pixmap_case_last pixbuf_mask = self.board.pixmap_mask_last else: pixbuf_case = self.board.pixmap_case pixbuf_mask = self.board.pixmap_mask item = self.itemgroup.add( gnomecanvas.CanvasPixbuf, pixbuf = pixbuf_case, x=0, y=0) bounds = item.get_bounds() item.set(width = (bounds[2]-bounds[0])*scale, height = (bounds[3]-bounds[1])*scale, width_set = True, height_set = True) self.ombre = self.itemgroup.add( gnomecanvas.CanvasPixbuf, pixbuf = self.board.pixmap_ombre, x=0, y=0) self.ombre.hide() bounds = self.ombre.get_bounds() self.ombre.set(width = (bounds[2]-bounds[0])*scale, height = (bounds[3]-bounds[1])*scale, width_set = True, height_set = True) self.ball = self.itemgroup.add( gnomecanvas.CanvasPixbuf, x=0, y=0) self.ball.hide() item = self.itemgroup.add( gnomecanvas.CanvasPixbuf, pixbuf = pixbuf_mask, x=0, y=0) bounds = item.get_bounds() item.set(width = (bounds[2]-bounds[0])*scale, height = (bounds[3]-bounds[1])*scale, width_set = True, height_set = True) if ((index+1)%5 == 0): self.itemgroup.add( gnomecanvas.CanvasText, x=(bounds[2]-bounds[0])/2, y=-10, fill_color_rgba=0x000000ffL, font=gcompris.skin.get_font("gcompris/board/small bold"), anchor=gtk.ANCHOR_CENTER, text = index + 1) def isBlue(self): self.ball.set(pixbuf = self.board.pixmap_blue_ball) bounds = self.ball.get_bounds() self.ball.set(width = (bounds[2]-bounds[0])*self.scale, height = (bounds[3]-bounds[1])*self.scale, width_set = True, height_set = True) self.ball.show() self.ombre.show() def isGreen(self): self.ball.set(pixbuf = self.board.pixmap_green_ball) bounds = self.ball.get_bounds() self.ball.set(width = (bounds[2]-bounds[0])*self.scale, height = (bounds[3]-bounds[1])*self.scale, width_set = True, height_set = True) self.ball.show() self.ombre.show() class ball: def __init__(self, root, x, y, scale, image): self.ball = root.add( gnomecanvas.CanvasPixbuf, pixbuf = image, x=x, y=y) bounds = self.ball.get_bounds() self.ball.set(width = (bounds[2]-bounds[0])*scale, height = (bounds[3]-bounds[1])*scale, width_set = True, height_set = True) class answer_button: def __init__(self, root, scale, image, number_balls): self.focus = False self.number_balls = number_balls self.itemgroup = root.add( gnomecanvas.CanvasGroup, x = gcompris.BOARD_WIDTH - 200, ) self.background = self.itemgroup.add( gnomecanvas.CanvasPixbuf, pixbuf = gcompris.utils.load_pixmap("images/enumerate_answer.png"), x=0, y=0 ) answer_bounds = self.background.get_bounds() self.itemgroup.set( y = gcompris.BOARD_HEIGHT - answer_bounds[3]-answer_bounds[1] - 5) self.background_focused = self.itemgroup.add( gnomecanvas.CanvasPixbuf, pixbuf = gcompris.utils.load_pixmap("images/enumerate_answer_focus.png"), x=0, y=0 ) self.background_focused.hide() self.icone = self.itemgroup.add( gnomecanvas.CanvasPixbuf, pixbuf = image, x=10, y=20 ) bounds = self.icone.get_bounds() self.icone.set(width = (bounds[2]-bounds[0])*scale, height = (bounds[3]-bounds[1])*scale, width_set = True, height_set = True) self.value = number_balls[0] self.text = self.itemgroup.add( gnomecanvas.CanvasText, x = answer_bounds[2]-answer_bounds[0] - 50, y = 40, fill_color_rgba=0xff0000ffL, font=gcompris.skin.get_font("gcompris/board/huge bold"), anchor=gtk.ANCHOR_CENTER, text = self.value ) self.background.connect("event",self.answer_event) self.background_focused.connect("event",self.answer_event) self.icone.connect("event",self.answer_event) self.text.connect("event",self.answer_event) def new_value(self, value): self.value = value self.text.set_property('text',value) def has_focus(self): self.background_focused.show() self.focus = True def set_number_of_balls(self, number_balls): self.number_balls = number_balls self.new_value(1) def answer_event(self, item, event): if ((event.type != gtk.gdk.BUTTON_PRESS) or (event.button != 1)): return False self.has_focus() value = ( (self.value + 1 - self.number_balls[0]) % (self.number_balls[1] + 1 - self.number_balls[0]) + self.number_balls[0] ) self.new_value(value) return True class prof_button: def __init__(self, board, root, prof_image): self.board = board self.prof_item = root.add( gnomecanvas.CanvasPixbuf, y = 230 ) bounds = self.prof_item.get_bounds() self.prof_item.set(x = ((gcompris.BOARD_WIDTH - bounds[2]-bounds[0])/2 - 90)) self.prof_item.connect("event",self.event_play) # This item is clickeable and it must be seen self.prof_item.connect("event", gcompris.utils.item_event_focus) def set_prof(self, prof_image): self.prof_item.set(pixbuf = gcompris.utils.load_pixmap(prof_image)) self.prof_image = prof_image def event_play(self, item, event): if event.type == gtk.gdk.LEAVE_NOTIFY: self.set_prof(self.prof_image) if ((event.type != gtk.gdk.BUTTON_PRESS) or (event.button != 1)): return False # if answer button has been clicked, that play the human turn if self.board.last_played == -1 : self.board.machine_play() return True return False