From f0e129585ebba52a134c3b72599e7709bc9bab71 Mon Sep 17 00:00:00 2001 From: Walter Bender Date: Sat, 03 Apr 2010 11:30:01 +0000 Subject: fixed cascading bead problem with Nepohualtzintzin --- diff --git a/abacus_window.py b/abacus_window.py index da04cca..9354c8b 100644 --- a/abacus_window.py +++ b/abacus_window.py @@ -66,10 +66,12 @@ class Abacus(): self.chinese = Suanpan(self) self.japanese = Soroban(self) self.russian = Schety(self) + self.mayan = Nepohualtzintzin(self) self.chinese.show() self.japanese.hide() self.russian.hide() + self.mayan.hide() self.mode = self.chinese def _button_press_cb(self, win, event): @@ -105,6 +107,158 @@ class Abacus(): gtk.main_quit() +class Nepohualtzintzin(): + + def __init__(self, abacus): + """ Create a Mayan abacus: 13 by (4,3). """ + self.abacus = abacus + self.num_rods = 13 + self.bot_beads = 4 + self.top_beads = 3 + # 4 beads + 2 spaces, divider, 3 bead + 2 spaces + h = (self.bot_beads+2+1+self.top_beads+2)*BHEIGHT*self.abacus.scale + w = (self.num_rods+1)*(BWIDTH+BOFFSET)*self.abacus.scale + dy = 5*BHEIGHT*self.abacus.scale + x = (self.abacus.width-w)/2 + y = (self.abacus.height-h)/2 + + # Draw the rods... + self.rods = [] + o = (BWIDTH+BOFFSET-5)*self.abacus.scale/2 + dx = (BWIDTH+BOFFSET)*self.abacus.scale + for i in range(self.num_rods): + self.rods.append(Sprite(self.abacus.sprites, x+i*dx+o, y, + load_image(self.abacus.path, "chinese_rod", + 10*self.abacus.scale, h))) + + for i in self.rods: + i.type = 'rod' + + # and then the beads. + self.beads = [] + o = (BWIDTH-BOFFSET)/2*self.abacus.scale/2 + for i in range(self.num_rods): + for b in range(self.top_beads): + self.beads.append(Sprite(self.abacus.sprites, x+i*dx+o, + y+b*BHEIGHT*self.abacus.scale, + load_image(self.abacus.path, "white", + BWIDTH*self.abacus.scale, + BHEIGHT*self.abacus.scale))) + for b in range(self.bot_beads): + self.beads.append(Sprite(self.abacus.sprites, x+i*dx+o, + y+(8+b)*BHEIGHT*self.abacus.scale, + load_image(self.abacus.path, "white", + BWIDTH*self.abacus.scale, + BHEIGHT*self.abacus.scale))) + + for i in self.beads: + i.type = 'bead' + i.state = 0 + + # Draw the dividing bar on top. + self.bar = Sprite(self.abacus.sprites, x, y+dy, + load_image(self.abacus.path, "divider_bar", + w, BHEIGHT*self.abacus.scale)) + + self.bar.type = 'frame' + self.bar.set_label_color('white') + + # TODO: increment by 20 + def value(self): + """ Return a string representing the value of each rod. """ + string = '' + v = [] + for r in range(self.num_rods+1): # +1 for overflow + v.append(0) + + # Tally the values on each rod. + for i, b in enumerate(self.beads): + r = i/(self.top_beads+self.bot_beads) + j = i%(self.top_beads+self.bot_beads) + if b.state == 1: + if j < self.top_beads: + v[r+1] += 5 + else: + v[r+1] += 1 + + # Carry to the left if a rod has a value > 9. + for j in range(self.num_rods): + if v[len(v)-j-1] > 9: + v[len(v)-j-1] -= 10 + v[len(v)-j-2] += 1 + + # Convert values to a string. + for j in v: + if string != '' or j > 0: + string += str(j) + return(string) + + def hide(self): + """ Hide the rod, beads and frame. """ + for i in self.rods: + i.hide() + for i in self.beads: + i.hide() + self.bar.hide() + + def show(self): + """ Show the rod, beads and frame. """ + for i in self.rods: + i.set_layer(100) + for i in self.beads: + i.set_layer(101) + self.bar.set_layer(102) + + def label(self, string): + """ Label the crossbar with the string. (Used with self.value) """ + self.bar.set_label(string) + + # TODO: top bead move need to interate + def move_bead(self, bead, dy): + """ Move a bead (or beads) up or down a rod. """ + i = self.beads.index(bead) + b = i%(self.top_beads+self.bot_beads) + + if b < self.top_beads: + if dy > 0 and bead.state == 0: + bead.move_relative((0, 2*BHEIGHT*self.abacus.scale)) + bead.state = 1 + # Make sure beads below this bead are also moved. + for ii in range(self.top_beads-b): + if self.beads[i+ii].state == 0: + self.beads[i+ii].move_relative((0, + 2*BHEIGHT*self.abacus.scale)) + self.beads[i+ii].state = 1 + elif dy < 0 and bead.state == 1: + bead.move_relative((0, -2*BHEIGHT*self.abacus.scale)) + bead.state = 0 + # Make sure beads above this bead are also moved. + for ii in range(b+1): + if self.beads[i-ii].state == 1: + self.beads[i-ii].move_relative((0, + -2*BHEIGHT*self.abacus.scale)) + self.beads[i-ii].state = 0 + else: + if dy < 0 and bead.state == 0: + bead.move_relative((0, -2*BHEIGHT*self.abacus.scale)) + bead.state = 1 + # Make sure beads above this bead are also moved. + for ii in range(b-self.top_beads+1): + if self.beads[i-ii].state == 0: + self.beads[i-ii].move_relative((0, + -2*BHEIGHT*self.abacus.scale)) + self.beads[i-ii].state = 1 + elif dy > 0 and bead.state == 1: + bead.move_relative((0, 2*BHEIGHT*self.abacus.scale)) + bead.state = 0 + # Make sure beads below this bead are also moved. + for ii in range(self.top_beads+self.bot_beads-b): + if self.beads[i+ii].state == 1: + self.beads[i+ii].move_relative((0, + 2*BHEIGHT*self.abacus.scale)) + self.beads[i+ii].state = 0 + + class Suanpan(): def __init__(self, abacus): -- cgit v0.9.1