#!/usr/bin/env python # # A classic game; don't know how it's called in english. You have to # restore the original configuration: # # 1 2 3 4 5 6 # 7 8 9 10 11 12 # 13 14 15 16 17 18 # 19 20 21 22 23 24 # 25 26 27 28 29 . # # or any variant of it. This is my first Tkinter program, I'm sure # you'll be forgiving... # # $Id: taquin.py,v 1.5 1998/01/04 18:14:16 bousch Exp $ # # Written by Thierry Bousch and placed # in the public domain. from Tkinter import * from Canvas import * BACKGROUND = 'orange' TSIZE = 90 MARGIN = 5 FONT = '-bitstream-charter-bold-r-normal--70-0-0-0-p-0-iso8859-1' LINES = 5 COLUMNS = 6 def permute(array): # Generate an even permutation, randomly from whrandom import random n = len(array) signature = +1 for i in range(n-2): j = int(random()*(n-1-i)) + (i+1) if j <> i: signature = -signature array[i], array[j] = array[j], array[i] # There's no choice for the last two elements, if we want # an even permutation if signature < 0: array[n-2], array[n-1] = array[n-1], array[n-2] # # Class definitions # class Tile: def __init__(self, text, canvas): self.rect = Rectangle(canvas, 0, 0, TSIZE, TSIZE, outline='black', fill='white') self.text = CanvasText(canvas, TSIZE/2, TSIZE/2, anchor=CENTER, text=text, font=FONT) self.group = Group(canvas) self.group.addtag_withtag(self.rect) self.group.addtag_withtag(self.text) self.group.move(MARGIN, MARGIN) self.line = self.column = 0 def moveto(self, line, column): S = MARGIN+TSIZE self.group.move(S*(column-self.column), S*(line-self.line)) self.line = line self.column = column class Counter(Label): def __init__(self, parent, template): Label.__init__(self, parent) self.template = template self.n = 0 self.redisplay() def reset(self): self.n = 0 self.redisplay() def increment(self): self.n = self.n + 1 self.redisplay() def redisplay(self): self['text'] = self.template % self.n class Board: def __init__(self, root, counter, lines, columns, bg): S = MARGIN+TSIZE self.lines = lines self.columns = columns self.counter = counter self.canvas = Canvas(root, background=bg, height=MARGIN+S*lines, width=MARGIN+S*columns) self.tiles = [] for t in range(lines*columns-1): tile = Tile(`t+1`, self.canvas) self.tiles.append(tile) self.shuffle() self.canvas.bind('<1>', self.clickhandler) self.canvas.pack() def shuffle(self): permute(self.tiles) for t in range(len(self.tiles)): i,j = divmod(t, self.columns) self.tiles[t].moveto(i,j) self.hl = self.lines-1 self.hc = self.columns-1 self.counter.reset() def clickhandler(self, event): S = MARGIN+TSIZE line = (event.y - MARGIN/2) / S column = (event.x - MARGIN/2) / S line = max(line, 0) line = min(line, self.lines-1) column = max(column, 0) column = min(column, self.columns-1) if line == self.hl: if column <> self.hc: self.move_line(line, column) else: if column == self.hc: self.move_column(line, column) def move_line(self, l, c): hc = self.hc n = abs(hc - c) if c < hc: for i in range(n): self.move_tile(l, hc-1-i, 0, 1) else: for i in range(n): self.move_tile(l, hc+1+i, 0, -1) self.counter.increment() def move_column(self, l, c): hl = self.hl n = abs(hl - l) if l < hl: for i in range(n): self.move_tile(hl-1-i, c, 1, 0) else: for i in range(n): self.move_tile(hl+1+i, c, -1, 0) self.counter.increment() def move_tile(self, l, c, dl, dc): for tile in self.tiles: if tile.line == l and tile.column == c: tile.moveto(l+dl, c+dc) self.hl = l self.hc = c def bg_color(self, color): self.canvas['background'] = color class Game: def __init__(self, lines, columns, bg): self.win = Frame() self.win.master.title('Taquin') self.make_menubar() self.board = Board(self.win, self.counter, lines, columns, bg) self.make_menu_options() self.make_menu_colors() self.win.pack() self.win.mainloop() def make_menubar(self): self.menubar = Frame(self.win, relief=RAISED, bd=2) self.menubutton1 = Menubutton(self.menubar, text='Options') self.menubutton1.pack(side=LEFT) self.menubutton2 = Menubutton(self.menubar, text='Colors') self.menubutton2.pack(side=LEFT) self.counter = Counter(self.menubar, 'Moves: %d') self.counter.pack(side=RIGHT) self.menubar.pack(side=TOP, fill=X) def make_menu_options(self): menu = Menu(self.menubutton1) menu.add_command(label='About this program...', command=self.about) menu.add_command(label='New game', command=self.board.shuffle) menu.add_command(label='Quit', command=self.win.quit) self.menubutton1['menu'] = menu def make_menu_colors(self): menu = Menu(self.menubutton2) menu.add_command(label='Burlywood', command=self.bg_burlywood) menu.add_command(label='Forest Green', command=self.bg_fgreen) menu.add_command(label='Orange', command=self.bg_orange) self.menubutton2['menu'] = menu def about(self): from Dialog import Dialog Dialog(self.win, title='Program Info', text= "C'est un jeu oł l'on pousse\n" "Avec le pouce\n" 'Sans jamais dire "pouce!"', bitmap='info', default=0, strings=('OK',)) def bg_burlywood(self): self.board.bg_color('burlywood') def bg_fgreen(self): self.board.bg_color('Forest Green') def bg_orange(self): self.board.bg_color('orange') # # Main routine # if __name__ == '__main__': Game(LINES, COLUMNS, BACKGROUND)