gnome-games r9042 - trunk/gnome-sudoku/src/lib
- From: thomashpa svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-games r9042 - trunk/gnome-sudoku/src/lib
- Date: Sun, 12 Apr 2009 23:10:47 +0000 (UTC)
Author: thomashpa
Date: Sun Apr 12 23:10:47 2009
New Revision: 9042
URL: http://svn.gnome.org/viewvc/gnome-games?rev=9042&view=rev
Log:
Style cleanups. Patch by Zhang Sen
Modified:
trunk/gnome-sudoku/src/lib/gsudoku.py
Modified: trunk/gnome-sudoku/src/lib/gsudoku.py
==============================================================================
--- trunk/gnome-sudoku/src/lib/gsudoku.py (original)
+++ trunk/gnome-sudoku/src/lib/gsudoku.py Sun Apr 12 23:10:47 2009
@@ -10,25 +10,23 @@
TRACKER_COLORS = [
# Use tango colors recommended here:
# http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines
- tuple([x/255.0 for x in cols]) for cols in
- [(32,74,135), # Sky Blue 3
- (78,154,6), # Chameleon 3
- (206,92,0), # Orange 3
- (143,89,2), # Chocolate 3
- (92,53,102), # Plum 3
- (85,87,83), # Aluminium 5
- (196,160,0), # Butter 3
-
+ tuple([x / 255.0 for x in cols]) for cols in
+ [(32, 74, 135), # Sky Blue 3
+ (78, 154, 6), # Chameleon 3
+ (206, 92, 0), # Orange 3
+ (143, 89, 2), # Chocolate 3
+ (92, 53, 102), # Plum 3
+ (85, 87, 83), # Aluminium 5
+ (196, 160, 0), # Butter 3
]
]
-def gtkcolor_to_rgb (c):
- return c.red/float(2**16),c.green/float(2**16),c.blue/float(2**16)
-
-def overlay (color_1, color_2, method=1):
- return color_1[0]+color_2[0]*method,color_1[1]+color_2[1]*method,color_1[2]+color_2[2]*method
+def gtkcolor_to_rgb (color):
+ return (color.red / float(2**16),
+ color.green / float(2**16),
+ color.blue / float(2**16))
-ERROR_HIGHLIGHT_COLOR = (1.0,0,0)
+ERROR_HIGHLIGHT_COLOR = (1.0, 0, 0)
BASE_SIZE = 35 # The "normal" size of a box (in pixels)
@@ -52,10 +50,10 @@
class NumberSelector (gtk.EventBox):
__gsignals__ = {
- 'changed':(gobject.SIGNAL_RUN_LAST,gobject.TYPE_NONE,()),
+ 'changed':(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
}
- def __init__ (self,default=None,upper=9):
+ def __init__ (self, default = None, upper = 9):
self.value = default
gtk.EventBox.__init__(self)
self.table = gtk.Table()
@@ -66,7 +64,7 @@
for x in range(side):
b = gtk.Button()
l = gtk.Label()
- if n==self.value:
+ if n == self.value:
l.set_markup('<b><span size="x-small">%s</span></b>'%n)
else:
l.set_markup('<span size="x-small">%s</span>'%n)
@@ -74,18 +72,19 @@
b.set_relief(gtk.RELIEF_HALF)
l = b.get_children()[0]
b.set_border_width(0)
- l.set_padding(0,0)
+ l.set_padding(0, 0)
l.get_alignment()
- b.connect('clicked',self.number_clicked,n)
- self.table.attach(b,x,x+1,y,y+1)
- n+=1
+ b.connect('clicked', self.number_clicked, n)
+ self.table.attach(b, x, x+1, y, y+1)
+ n += 1
if self.value:
db = gtk.Button()
l = gtk.Label()
l.set_markup_with_mnemonic('<span size="x-small">'+_('_Clear')+'</span>')
- db.add(l); l.show()
- db.connect('clicked',self.number_clicked,0)
- self.table.attach(db,0,side,y+1,y+2)
+ db.add(l)
+ l.show()
+ db.connect('clicked', self.number_clicked, 0)
+ self.table.attach(db, 0, side, y+1, y+2)
self.show_all()
def number_clicked (self, button, n):
@@ -95,7 +94,7 @@
def get_value (self):
return self.value
- def set_value (self,n):
+ def set_value (self, n):
self.value = n
class NumberBox (gtk.Widget):
@@ -112,39 +111,41 @@
custom_background_color = None
__gsignals__ = {
- 'value-about-to-change':(gobject.SIGNAL_RUN_LAST,gobject.TYPE_NONE,()),
- 'changed':(gobject.SIGNAL_RUN_LAST,gobject.TYPE_NONE,()),
+ 'value-about-to-change':(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
+ 'changed':(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
# undo-change - A hacky way to handle the fact that we want to
# respond to undo's changes but we don't want undo to respond
# to itself...
- 'undo-change':(gobject.SIGNAL_RUN_LAST,gobject.TYPE_NONE,()),
- 'notes-changed':(gobject.SIGNAL_RUN_LAST,gobject.TYPE_NONE,()),
+ 'undo-change':(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
+ 'notes-changed':(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
}
base_state = gtk.STATE_NORMAL
npicker = None
draw_boxes = False
- def __init__ (self, upper=9, text=''):
+ def __init__ (self, upper = 9, text = ''):
gtk.Widget.__init__(self)
self.upper = upper
self.font = self.style.font_desc
self.font.set_size(BASE_FONT_SIZE)
self.note_font = self.font.copy()
self.note_font.set_size(NOTE_FONT_SIZE)
- self.set_property('can-focus',True)
- self.set_property('events',gtk.gdk.ALL_EVENTS_MASK)
- self.connect('button-press-event',self.button_press_cb)
- self.connect('key-release-event',self.key_press_cb)
- self.connect('enter-notify-event',self.pointer_enter_cb)
- self.connect('leave-notify-event',self.pointer_leave_cb)
- self.connect('focus-in-event',self.focus_in_cb)
- self.connect('focus-out-event',self.focus_out_cb)
- self.connect('motion-notify-event',self.motion_notify_cb)
+ self.set_property('can-focus', True)
+ self.set_property('events', gtk.gdk.ALL_EVENTS_MASK)
+ self.connect('button-press-event', self.button_press_cb)
+ self.connect('key-release-event', self.key_press_cb)
+ self.connect('enter-notify-event', self.pointer_enter_cb)
+ self.connect('leave-notify-event', self.pointer_leave_cb)
+ self.connect('focus-in-event', self.focus_in_cb)
+ self.connect('focus-out-event', self.focus_out_cb)
+ self.connect('motion-notify-event', self.motion_notify_cb)
self.set_text(text)
def pointer_enter_cb (self, *args):
- if not self.is_focus(): self.set_state(gtk.STATE_PRELIGHT)
+ if not self.is_focus():
+ self.set_state(gtk.STATE_PRELIGHT)
+
def pointer_leave_cb (self, *args):
self.set_state(self.base_state)
self._toggle_box_drawing_(False)
@@ -178,23 +179,24 @@
self.queue_draw()
def button_press_cb (self, w, e):
- if self.read_only: return
+ if self.read_only:
+ return
if e.type == gtk.gdk._2BUTTON_PRESS:
# ignore second click (this makes a double click in the
# middle of a cell get us a display of the numbers, rather
# than selecting a number.
return
if self.is_focus():
- x,y = e.get_coords()
+ x, y = e.get_coords()
alloc = self.get_allocation()
my_w = alloc.width
my_h = alloc.height
border_height = float(BORDER_WIDTH)/BASE_SIZE
if float(y)/my_h < border_height:
- self.show_note_editor(top=True)
+ self.show_note_editor(top = True)
elif float(y)/my_h > (1-border_height):
- self.show_note_editor(top=False)
+ self.show_note_editor(top = False)
elif not self.npicker:
# In this case we're a normal old click...
# makes sure there is only one numer selector
@@ -203,7 +205,8 @@
self.grab_focus()
def key_press_cb (self, w, e):
- if self.read_only: return
+ if self.read_only:
+ return
if self.npicker: # kill number picker no matter what is pressed
self.destroy_npicker()
txt = gtk.gdk.keyval_name(e.keyval)
@@ -214,51 +217,54 @@
if self.get_text() == txt:
# If there's no change, do nothing
return
- if txt in ['0','Delete','BackSpace']:
+ if txt in ['0', 'Delete', 'BackSpace']:
self.set_text_interactive('')
- elif txt in ['n','N']:
- self.show_note_editor(top=True)
- elif txt in ['m','M']:
- self.show_note_editor(top=False)
+ elif txt in ['n', 'N']:
+ self.show_note_editor(top = True)
+ elif txt in ['m', 'M']:
+ self.show_note_editor(top = False)
# And then add the new value if need be
- elif txt in [str(n) for n in range(1,self.upper+1)]:
+ elif txt in [str(n) for n in range(1, self.upper+1)]:
# First do a removal event -- this is something of a
# kludge, but it works nicely with old code that was based
# on entries, which also behave this way (they generate 2
# events for replacing a number with a new number - a
# removal event and an addition event)
- if self.get_text(): self.set_text_interactive('')
+ if self.get_text():
+ self.set_text_interactive('')
# Then add
self.set_text_interactive(txt)
- def note_changed_cb (self, w, top=False):
+ def note_changed_cb (self, w, top = False):
if top:
- self.set_note_text_interactive(top_text=w.get_text())
+ self.set_note_text_interactive(top_text = w.get_text())
else:
- self.set_note_text_interactive(bottom_text=w.get_text())
+ self.set_note_text_interactive(bottom_text = w.get_text())
- def show_note_editor (self, top=True):
+ def show_note_editor (self, top = True):
alloc = self.get_allocation()
w = gtk.Window()
w.set_property('skip-pager-hint', True)
w.set_property('skip-taskbar-hint', True)
w.set_decorated(False)
w.set_position(gtk.WIN_POS_MOUSE)
- w.set_size_request(alloc.width,alloc.height/2)
+ w.set_size_request(alloc.width, alloc.height/2)
f = gtk.Frame()
e = gtk.Entry()
f.add(e)
- if top: e.set_text(self.top_note_text)
- else: e.set_text(self.bottom_note_text)
+ if top:
+ e.set_text(self.top_note_text)
+ else:
+ e.set_text(self.bottom_note_text)
w.add(f)
e.connect('changed', self.note_changed_cb, top)
- e.connect('focus-out-event',lambda e, ev, w: w.destroy(), w)
- e.connect('activate',lambda e, w: w.destroy(), w)
- x,y = self.window.get_origin()
+ e.connect('focus-out-event', lambda e, ev, w: w.destroy(), w)
+ e.connect('activate', lambda e, w: w.destroy(), w)
+ x, y = self.window.get_origin()
if top:
- w.move(x,y)
+ w.move(x, y)
else:
- w.move(x,y+int(alloc.height*0.6))
+ w.move(x, y+int(alloc.height*0.6))
w.show_all()
e.grab_focus()
@@ -270,36 +276,37 @@
self.set_text_interactive(str(newval))
def show_number_picker (self):
- w = gtk.Window(type=gtk.WINDOW_POPUP)
- ns = NumberSelector(upper=self.upper,default=self.get_value())
+ w = gtk.Window(type = gtk.WINDOW_POPUP)
+ ns = NumberSelector(upper = self.upper, default = self.get_value())
ns.connect('changed', self.number_changed_cb)
w.grab_focus()
w.add(ns)
r = w.get_allocation()
my_origin = self.window.get_origin()
- x,y = self.window.get_size()
- popupx,popupy = w.get_size()
+ x, y = self.window.get_size()
+ popupx, popupy = w.get_size()
overlapx = popupx-x
overlapy = popupy-y
- w.move(my_origin[0]-(overlapx/2),my_origin[1]-(overlapy/2))
+ w.move(my_origin[0]-(overlapx/2), my_origin[1]-(overlapy/2))
w.show()
self.npicker = w
- def set_text_interactive (self,text):
+ def set_text_interactive (self, text):
self.emit('value-about-to-change')
self.set_text(text)
self.queue_draw()
self.emit('changed')
def set_font (self, font):
- if type(font)==str:
+ if type(font) == str:
font = pango.FontDescription(font)
self.font = font
- if self.text: self.set_text(self.text)
+ if self.text:
+ self.set_text(self.text)
self.queue_draw()
def set_note_font (self, font):
- if type(font)==str:
+ if type(font) == str:
font = pango.FontDescription(font)
self.note_font = font
if self.top_note_text or self.bottom_note_text:
@@ -317,11 +324,11 @@
Undo API requires a set method that is called with one
argument (the result of a get method)"""
- self.set_note_text(top_text=notes[0],
- bottom_text=notes[1])
+ self.set_note_text(top_text = notes[0],
+ bottom_text = notes[1])
self.queue_draw()
- def set_note_text (self, top_text=None,bottom_text=None):
+ def set_note_text (self, top_text = None, bottom_text = None):
if top_text is not None:
self.top_note_text = top_text
self._top_note_layout = self.create_pango_layout(top_text)
@@ -334,7 +341,7 @@
def set_note_text_interactive (self, *args, **kwargs):
self.emit('value-about-to-change')
- self.set_note_text(*args,**kwargs)
+ self.set_note_text(*args, **kwargs)
self.emit('notes-changed')
def do_realize (self):
@@ -350,11 +357,11 @@
# the event_mask
self.window = gtk.gdk.Window(
self.get_parent_window(),
- width=self.allocation.width,
- height=self.allocation.height,
- window_type=gtk.gdk.WINDOW_CHILD,
- wclass=gtk.gdk.INPUT_OUTPUT,
- event_mask=self.get_events() | gtk.gdk.EXPOSURE_MASK)
+ width = self.allocation.width,
+ height = self.allocation.height,
+ window_type = gtk.gdk.WINDOW_CHILD,
+ wclass = gtk.gdk.INPUT_OUTPUT,
+ event_mask = self.get_events() | gtk.gdk.EXPOSURE_MASK)
# Associate the gdk.Window with ourselves, Gtk+ needs a reference
# between the widget and the gdk window
@@ -387,7 +394,7 @@
side = width/pango.SCALE
else:
side = height/pango.SCALE
- requisition.width = side; requisition.height = side
+ (requisition.width, requisition.height) = (side, side)
def do_size_allocate(self, allocation):
# The do_size_allocate is called by when the actual size is known
@@ -408,11 +415,11 @@
# Create any resources in here.
x, y, w, h = self.allocation
cr = self.window.cairo_create()
- if h<w:
+ if h < w:
scale = h/float(BASE_SIZE)
else:
scale = w/float(BASE_SIZE)
- cr.scale(scale,scale)
+ cr.scale(scale, scale)
self.draw_background_color(cr)
if self.is_focus():
self.draw_highlight_box(cr)
@@ -425,9 +432,9 @@
def draw_background_color (self, cr):
if self.read_only:
if self.custom_background_color:
- r,g,b = self.custom_background_color
+ r, g, b = self.custom_background_color
cr.set_source_rgb(
- r*0.6,g*0.6,b*0.6
+ r*0.6, g*0.6, b*0.6
)
else:
cr.set_source_color(self.style.base[gtk.STATE_INSENSITIVE])
@@ -440,7 +447,7 @@
self.style.base[self.state]
)
cr.rectangle(
- 0,0,BASE_SIZE,BASE_SIZE
+ 0, 0, BASE_SIZE, BASE_SIZE
)
cr.fill()
@@ -475,7 +482,7 @@
cr.set_line_join(cairo.LINE_JOIN_MITER)
cr.stroke()
- def draw_highlight_box (self,cr):
+ def draw_highlight_box (self, cr):
cr.set_source_color(
self.style.base[gtk.STATE_SELECTED]
)
@@ -505,9 +512,9 @@
BORDER_WIDTH-NORMAL_LINE_WIDTH)
cr.stroke()
# bottom rectangle
- cr.rectangle(NORMAL_LINE_WIDTH*0.5,#x
- BASE_SIZE - BORDER_WIDTH-(NORMAL_LINE_WIDTH*0.5),#y
- BASE_SIZE-NORMAL_LINE_WIDTH,#x2
+ cr.rectangle(NORMAL_LINE_WIDTH*0.5, #x
+ BASE_SIZE - BORDER_WIDTH-(NORMAL_LINE_WIDTH*0.5), #y
+ BASE_SIZE-NORMAL_LINE_WIDTH, #x2
BASE_SIZE-NORMAL_LINE_WIDTH #y2
)
cr.stroke()
@@ -565,7 +572,7 @@
self.set_value(v)
self.emit('undo_change')
- def set_value (self,v):
+ def set_value (self, v):
if 0 < v <= self.upper:
self.set_text(str(v))
else:
@@ -573,11 +580,16 @@
self.queue_draw()
def get_value (self):
- try: return int(self.text)
- except: return None
+ try:
+ return int(self.text)
+ except:
+ return None
+
+ def get_text (self):
+ return self.text
- def get_text (self): return self.text
- def get_note_text (self): return self.top_note_text,self.bottom_note_text
+ def get_note_text (self):
+ return self.top_note_text, self.bottom_note_text
class SudokuNumberBox (NumberBox):
@@ -588,17 +600,18 @@
self.normal_color = color
self.set_text_color(self.normal_color)
- def unset_color (self): self.set_color(None)
+ def unset_color (self):
+ self.set_color(None)
def set_error_highlight (self, val):
if val:
- self.set_text_color((1.0,0,0))
+ self.set_text_color((1.0, 0, 0))
else:
self.set_text_color(self.normal_color)
def set_read_only (self, val):
self.read_only = val
- if not hasattr(self,'bold_font'):
+ if not hasattr(self, 'bold_font'):
self.normal_font = self.font
self.bold_font = self.font.copy()
self.bold_font.set_weight(pango.WEIGHT_BOLD)
@@ -609,7 +622,8 @@
self.queue_draw()
def set_impossible (self, val):
- if val: self.set_text('X')
+ if val:
+ self.set_text('X')
else: self.set_text('')
@@ -617,33 +631,35 @@
class SudokuNumberGrid (gtk.AspectFrame):
- def __init__ (self, group_size=9):
- self.table = gtk.Table(rows=group_size,columns=group_size,homogeneous=True)
+ def __init__ (self, group_size = 9):
+ self.table = gtk.Table(rows = group_size, columns = group_size, homogeneous = True)
self.group_size = group_size
self.__entries__ = {}
for x in range(self.group_size):
for y in range(self.group_size):
- e = SudokuNumberBox(upper=self.group_size)
+ e = SudokuNumberBox(upper = self.group_size)
e.x = x
e.y = y
- self.table.attach(e,x,x+1,y,y+1,
+ self.table.attach(e, x, x+1, y, y+1,
)
- self.__entries__[(x,y)] = e
- gtk.AspectFrame.__init__(self,obey_child=False)
+ self.__entries__[(x, y)] = e
+ gtk.AspectFrame.__init__(self, obey_child = False)
self.set_shadow_type(gtk.SHADOW_NONE)
self.eb = gtk.EventBox()
self.eb.add(self.table)
self.add(self.eb)
- self.connect('size-allocate',self.allocate_cb)
+ self.connect('size-allocate', self.allocate_cb)
self.show_all()
def allocate_cb (self, w, rect):
- if rect.width > rect.height: side = rect.height
+ if rect.width > rect.height:
+ side = rect.height
else: side = rect.width
# we want our small spacing to be 1/15th the size of a box
spacing = float(side) / (self.group_size * SPACING_FACTOR)
- if spacing == 0: spacing = 1
- if hasattr(self,'small_spacing') and spacing == self.small_spacing:
+ if spacing == 0:
+ spacing = 1
+ if hasattr(self, 'small_spacing') and spacing == self.small_spacing:
return
else:
self.change_spacing(spacing)
@@ -654,84 +670,88 @@
self.table.set_row_spacings(int(small_spacing))
self.table.set_col_spacings(int(small_spacing))
box_side = int(math.sqrt(self.group_size))
- for n in range(1,box_side):
- self.table.set_row_spacing(box_side*n-1,self.big_spacing)
- self.table.set_col_spacing(box_side*n-1,self.big_spacing)
+ for n in range(1, box_side):
+ self.table.set_row_spacing(box_side*n-1, self.big_spacing)
+ self.table.set_col_spacing(box_side*n-1, self.big_spacing)
self.table.set_border_width(self.big_spacing)
def get_focused_entry (self):
return self.table.focus_child
def set_bg_color (self, color):
- if type(color)==str:
- try: color = gtk.gdk.color_parse(color)
+ if type(color) == str:
+ try:
+ color = gtk.gdk.color_parse(color)
except:
- print 'set_bg_color handed Bad color',color
+ print 'set_bg_color handed Bad color', color
return
- self.eb.modify_bg(gtk.STATE_NORMAL,color)
- self.eb.modify_base(gtk.STATE_NORMAL,color)
- self.eb.modify_fg(gtk.STATE_NORMAL,color)
- self.table.modify_bg(gtk.STATE_NORMAL,color)
- self.table.modify_base(gtk.STATE_NORMAL,color)
- self.table.modify_fg(gtk.STATE_NORMAL,color)
+ self.eb.modify_bg(gtk.STATE_NORMAL, color)
+ self.eb.modify_base(gtk.STATE_NORMAL, color)
+ self.eb.modify_fg(gtk.STATE_NORMAL, color)
+ self.table.modify_bg(gtk.STATE_NORMAL, color)
+ self.table.modify_base(gtk.STATE_NORMAL, color)
+ self.table.modify_fg(gtk.STATE_NORMAL, color)
for e in self.__entries__.values():
- e.modify_bg(gtk.STATE_NORMAL,color)
+ e.modify_bg(gtk.STATE_NORMAL, color)
class ParallelDict (dict):
"""A handy new sort of dictionary for tracking conflicts.
pd = ParallelDict()
- pd[1] = [2,3,4] # 1 is linked with 2,3 and 4
- pd -> {1:[2,3,4],2:[1],3:[1],4:[1]}
- pd[2] = [1,3,4] # 2 is linked with 3 and 4 as well as 1
- pd -> {1: [2,3,4],2:[3,4],3:[1,2],4:[1,2]}
+ pd[1] = [2, 3, 4] # 1 is linked with 2, 3 and 4
+ pd -> {1:[2, 3, 4], 2:[1], 3:[1], 4:[1]}
+ pd[2] = [1, 3, 4] # 2 is linked with 3 and 4 as well as 1
+ pd -> {1: [2, 3, 4], 2:[3, 4], 3:[1, 2], 4:[1, 2]}
Now for the cool part...
del pd[1]
- pd -> {2: [2,3],3:[2],4:[2]}
+ pd -> {2: [2, 3], 3:[2], 4:[2]}
Pretty neat, no?
"""
def __init__ (self, *args):
- dict.__init__(self,*args)
+ dict.__init__(self, *args)
def __setitem__ (self, k, v):
- dict.__setitem__(self,k,set(v))
+ dict.__setitem__(self, k, set(v))
for i in v:
- if i == k: continue
+ if i == k:
+ continue
if self.has_key(i):
self[i].add(k)
else:
- dict.__setitem__(self,i,set([k]))
+ dict.__setitem__(self, i, set([k]))
def __delitem__ (self, k):
- v=self[k]
- dict.__delitem__(self,k)
+ v = self[k]
+ dict.__delitem__(self, k)
for i in v:
- if i==k: continue
+ if i == k:
+ continue
if self.has_key(i):
# Make sure we have a reference to i. If we don't
# something has gone wrong... but according to bug
# 385937 this has gone wrong at least once, so we'd
# better check for it.
- if k in self[i]: self[i].remove(k)
+ if k in self[i]:
+ self[i].remove(k)
if not self[i]:
# If k was the last value in the list of values
# for i, then we delete i from our dictionary
- dict.__delitem__(self,i)
+ dict.__delitem__(self, i)
class SudokuGameDisplay (SudokuNumberGrid, gobject.GObject):
__gsignals__ = {
- 'focus-changed':(gobject.SIGNAL_RUN_LAST,gobject.TYPE_NONE,()),
- 'puzzle-finished':(gobject.SIGNAL_RUN_LAST,gobject.TYPE_NONE,())
+ 'focus-changed':(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
+ 'puzzle-finished':(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())
}
do_highlight_cells = False
@simple_debug
- def __init__ (self,grid=None,group_size=9,
- show_impossible_implications=False):
- group_size=int(group_size)
+ def __init__ (self, grid = None, group_size = 9,
+ show_impossible_implications = False):
+ group_size = int(group_size)
self.hints = 0
self.always_show_hints = False
self.auto_fills = 0
@@ -740,17 +760,17 @@
self.impossibilities = []
self.trackers = {}
self.__trackers_tracking__ = {}
- self.__colors_used__ = [None,ERROR_HIGHLIGHT_COLOR]
+ self.__colors_used__ = [None, ERROR_HIGHLIGHT_COLOR]
gobject.GObject.__init__(self)
- SudokuNumberGrid.__init__(self,group_size=group_size)
- self.setup_grid(grid,group_size)
+ SudokuNumberGrid.__init__(self, group_size = group_size)
+ self.setup_grid(grid, group_size)
for e in self.__entries__.values():
e.show()
- e.connect('undo-change',self.entry_callback)
- e.connect('changed',self.entry_callback)
- e.connect('focus-in-event',self.focus_callback)
+ e.connect('undo-change', self.entry_callback)
+ e.connect('changed', self.entry_callback)
+ e.connect('focus-in-event', self.focus_callback)
e.connect('key-press-event', self.key_press_cb, e.x, e.y)
- self.connect('focus-changed',self.highlight_cells)
+ self.connect('focus-changed', self.highlight_cells)
def key_press_cb (self, widget, event, x, y):
key = gtk.gdk.keyval_name(event.keyval)
@@ -785,49 +805,54 @@
hsv = colors.rgb_to_hsv(*default_color)
box_s = hsv[1]
box_v = hsv[2]
- if box_v < 0.5: box_v = box_v*2
+ if box_v < 0.5:
+ box_v = box_v * 2
if box_s > 0.75:
- box_s = box_s*0.5
+ box_s = box_s * 0.5
else:
- box_s = box_s*1.5
- if box_s > 1: box_s = 1.0
- self.box_color = colors.hsv_to_rgb(
- hsv[0],box_s,box_v
- )
- self.box_and_row_color = colors.rotate_hue_rgb(*self.box_color,**{'rotate_by':0.33/2})
- self.row_color = colors.rotate_hue_rgb(*self.box_color,**{'rotate_by':0.33})
- self.col_color = colors.rotate_hue_rgb(*self.box_color,**{'rotate_by':0.66})
- self.box_and_col_color = colors.rotate_hue_rgb(*self.box_color,**{'rotate_by':1.0-(0.33/2)})
+ box_s = box_s * 1.5
+ if box_s > 1:
+ box_s = 1.0
+ self.box_color = colors.hsv_to_rgb(hsv[0], box_s, box_v)
+ self.box_and_row_color = colors.rotate_hue_rgb(*self.box_color, **{'rotate_by': 0.33 / 2})
+ self.row_color = colors.rotate_hue_rgb(*self.box_color, **{'rotate_by': 0.33})
+ self.col_color = colors.rotate_hue_rgb(*self.box_color, **{'rotate_by': 0.66})
+ self.box_and_col_color = colors.rotate_hue_rgb(*self.box_color, **{'rotate_by': 1.0 - (0.33 / 2)})
def toggle_highlight (self, val):
self.do_highlight_cells = val
self.unhighlight_cells()
- if hasattr(self,'focused') and self.focused: self.highlight_cells()
+ if hasattr(self, 'focused') and self.focused:
+ self.highlight_cells()
def unhighlight_cells (self, *args):
- for e in self.__entries__.values(): e.set_background_color(None)
+ for e in self.__entries__.values():
+ e.set_background_color(None)
def highlight_cells (self, *args):
- if not self.do_highlight_cells: return
+ if not self.do_highlight_cells:
+ return
self.unhighlight_cells()
- if not hasattr(self,'box_color'): self.get_highlight_colors()
- my_x,my_y = self.focused.x,self.focused.y
+ if not hasattr(self, 'box_color'):
+ self.get_highlight_colors()
+ my_x, my_y = self.focused.x, self.focused.y
# col_coords can sometimes be null.
- if not hasattr(self.grid, 'col_coords'): return
+ if not hasattr(self.grid, 'col_coords'):
+ return
- for x,y in self.grid.col_coords[my_x]:
- if (x,y) != (my_x,my_y):
- self.__entries__[(x,y)].set_background_color(self.col_color)
- for x,y in self.grid.row_coords[my_y]:
- if (x,y) != (my_x,my_y):
- self.__entries__[(x,y)].set_background_color(self.row_color)
- for x,y in self.grid.box_coords[self.grid.box_by_coords[(my_x,my_y)]]:
- if (x,y) != (my_x,my_y):
- e = self.__entries__[(x,y)]
- if x==my_x:
+ for x, y in self.grid.col_coords[my_x]:
+ if (x, y) != (my_x, my_y):
+ self.__entries__[(x, y)].set_background_color(self.col_color)
+ for x, y in self.grid.row_coords[my_y]:
+ if (x, y) != (my_x, my_y):
+ self.__entries__[(x, y)].set_background_color(self.row_color)
+ for x, y in self.grid.box_coords[self.grid.box_by_coords[(my_x, my_y)]]:
+ if (x, y) != (my_x, my_y):
+ e = self.__entries__[(x, y)]
+ if x == my_x:
e.set_background_color(self.box_and_col_color)
- elif y==my_y:
+ elif y == my_y:
e.set_background_color(self.box_and_row_color)
else:
e.set_background_color(self.box_color)
@@ -835,33 +860,33 @@
@simple_debug
def show_hint (self):
- if hasattr(self,'focused'):
+ if hasattr(self, 'focused'):
entry = self.focused
if entry.read_only or entry.get_text():
pass
else:
- self.show_hint_for_entry(entry,interactive=True)
+ self.show_hint_for_entry(entry, interactive = True)
- def show_hint_for_entry (self, entry, interactive=False):
+ def show_hint_for_entry (self, entry, interactive = False):
if interactive:
set_method = entry.set_note_text_interactive
else:
set_method = entry.set_note_text
- vals=self.grid.possible_values(entry.x,entry.y)
+ vals = self.grid.possible_values(entry.x, entry.y)
vals = list(vals)
vals.sort()
if vals:
''.join([str(v) for v in vals])
txt = ''.join([str(v) for v in vals])
if txt != entry.get_text():
- set_method(bottom_text=txt)
+ set_method(bottom_text = txt)
self.hints += 1
elif not entry.get_text():
if entry.get_text() != 'X':
self.hints += 1
- set_method(bottom_text='X')
+ set_method(bottom_text = 'X')
else:
- set_method(bottom_text="")
+ set_method(bottom_text = "")
@simple_debug
def reset_grid (self):
@@ -872,35 +897,35 @@
removed = []
for x in range(self.group_size):
for y in range(self.group_size):
- if not self.grid.virgin._get_(x,y):
- val = self.__entries__[(x,y)].get_value() # get the value from the user-visible grid,
+ if not self.grid.virgin._get_(x, y):
+ val = self.__entries__[(x, y)].get_value() # get the value from the user-visible grid,
if val:
- removed.append((x,y,val,self.trackers_for_point(x,y,val)))
- self.remove(x,y,do_removal=True)
+ removed.append((x, y, val, self.trackers_for_point(x, y, val)))
+ self.remove(x, y, do_removal = True)
return removed
- def clear_notes (self, clear_args={'top_text':'','bottom_text':''}):
+ def clear_notes (self, clear_args = {'top_text':'', 'bottom_text':''}):
"""Remove all notes."""
self.removed = []
for x in range(self.group_size):
for y in range(self.group_size):
- e = self.__entries__[(x,y)]
- top,bottom = e.get_note_text()
+ e = self.__entries__[(x, y)]
+ top, bottom = e.get_note_text()
if top or bottom:
- self.removed.append((x,y,(top,bottom)))
+ self.removed.append((x, y, (top, bottom)))
e.set_note_text(**clear_args)
e.queue_draw()
return self.removed
def clear_hints (self):
- self.clear_notes(clear_args={'bottom_text':''})
+ self.clear_notes(clear_args = {'bottom_text':''})
@simple_debug
def blank_grid (self):
for x in range(self.group_size):
for y in range(self.group_size):
- self.remove(x,y)
- e=self.__entries__[(x,y)]
+ self.remove(x, y)
+ e = self.__entries__[(x, y)]
e.set_read_only(False)
self.grid = None
self.clear_notes()
@@ -912,9 +937,9 @@
self.impossible_hints = 0
self.trackers = {}
self.__trackers_tracking__ = {}
- self.__colors_used__ = [None,ERROR_HIGHLIGHT_COLOR]
+ self.__colors_used__ = [None, ERROR_HIGHLIGHT_COLOR]
self.blank_grid()
- self.setup_grid(grid,group_size)
+ self.setup_grid(grid, group_size)
@simple_debug
def load_game (self, game):
@@ -925,62 +950,63 @@
"""
self.blank_grid()
if '\n' in game:
- virgin,in_prog = game.split('\n')
+ virgin, in_prog = game.split('\n')
else:
- virgin = game; in_prog = ''
- group_size=int(math.sqrt(len(virgin.split())))
- self.change_grid(virgin,group_size=group_size)
+ virgin, in_prog = game, ''
+ group_size = int(math.sqrt(len(virgin.split())))
+ self.change_grid(virgin, group_size = group_size)
# This int() will break if we go to 16x16 grids...
if in_prog:
values = [int(c) for c in in_prog.split()]
for row in range(group_size):
for col in range(group_size):
index = row * 9 + col
- if values[index] and not self.grid._get_(col,row):
- self.add_value(col,row,values[index])
+ if values[index] and not self.grid._get_(col, row):
+ self.add_value(col, row, values[index])
@simple_debug
def setup_grid (self, grid, group_size):
self.doing_initial_setup = True
self.__error_pairs__ = ParallelDict()
- if isinstance(grid,sudoku.SudokuGrid):
- self.grid = sudoku.InteractiveSudoku(grid.grid,group_size=grid.group_size)
+ if isinstance(grid, sudoku.SudokuGrid):
+ self.grid = sudoku.InteractiveSudoku(grid.grid, group_size = grid.group_size)
else:
- self.grid = sudoku.InteractiveSudoku(grid,group_size=group_size)
+ self.grid = sudoku.InteractiveSudoku(grid, group_size = group_size)
for x in range(group_size):
for y in range(group_size):
- val=self.grid._get_(x,y)
- if val: self.add_value(x,y,val)
+ val = self.grid._get_(x, y)
+ if val:
+ self.add_value(x, y, val)
self.doing_initial_setup = False
@simple_debug
def entry_callback (self, widget, *args):
if not widget.get_text():
- if self.grid and self.grid._get_(widget.x,widget.y):
- self.grid.remove(widget.x,widget.y)
- self.remove(widget.x,widget.y)
+ if self.grid and self.grid._get_(widget.x, widget.y):
+ self.grid.remove(widget.x, widget.y)
+ self.remove(widget.x, widget.y)
else:
self.entry_validate(widget)
if self.show_impossible_implications:
- self.mark_impossible_implications(widget.x,widget.y)
+ self.mark_impossible_implications(widget.x, widget.y)
if self.always_show_hints:
self.update_all_hints()
def update_all_hints (self):
for x in range(self.group_size):
for y in range(self.group_size):
- e = self.__entries__[(x,y)]
+ e = self.__entries__[(x, y)]
if e.read_only:
pass
elif e.get_text():
- e.set_note_text(bottom_text='')
+ e.set_note_text(bottom_text = '')
else:
self.show_hint_for_entry(e)
@simple_debug
def entry_validate (self, widget, *args):
val = widget.get_value()
- self.add_value(widget.x,widget.y,val)
+ self.add_value(widget.x, widget.y, val)
if self.grid.check_for_completeness():
self.emit('puzzle-finished')
@@ -989,11 +1015,11 @@
conflicts = self.grid.find_conflicts(origin.x, origin.y, origin.value)
for conflict in conflicts:
self.__entries__[conflict].set_error_highlight(True)
- self.__error_pairs__[(origin.x,origin.y)]=conflicts
+ self.__error_pairs__[(origin.x, origin.y)] = conflicts
@simple_debug
- def add_value (self, x, y, val, trackers=[]):
- """Add value val at position x,y.
+ def add_value (self, x, y, val, trackers = []):
+ """Add value val at position x, y.
If tracker is True, we track it with tracker ID tracker.
@@ -1002,47 +1028,48 @@
Providing the tracker arg is mostly useful for e.g. undo/redo
or removed items.
- To specify NO trackers, use trackers=[-1]
+ To specify NO trackers, use trackers = [-1]
"""
# Add the value to the UI to display
- self.__entries__[(x,y)].set_value(val)
+ self.__entries__[(x, y)].set_value(val)
if self.doing_initial_setup:
- self.__entries__[(x,y)].set_read_only(True)
+ self.__entries__[(x, y)].set_read_only(True)
# Handle any trackers.
if trackers:
# Explicitly specified tracker
for tracker in trackers:
- if tracker==-1: pass
- self.__entries__[(x,y)].set_color(self.get_tracker_color(tracker))
- self.trackers[tracker].append((x,y,val))
+ if tracker == -1:
+ pass
+ self.__entries__[(x, y)].set_color(self.get_tracker_color(tracker))
+ self.trackers[tracker].append((x, y, val))
elif True in self.__trackers_tracking__.values():
- for k,v in self.__trackers_tracking__.items():
+ for k, v in self.__trackers_tracking__.items():
if v:
- self.__entries__[(x,y)].set_color(self.get_tracker_color(k))
- self.trackers[k].append((x,y,val))
+ self.__entries__[(x, y)].set_color(self.get_tracker_color(k))
+ self.trackers[k].append((x, y, val))
# Add value to our underlying sudoku grid -- this will raise
# an error if the value is out of bounds with the current
# rules.
try:
- self.grid.add(x,y,val,True)
+ self.grid.add(x, y, val, True)
except sudoku.ConflictError, err:
self.complain_conflicts(err)
# Draw our entry
- self.__entries__[(x,y)].queue_draw()
+ self.__entries__[(x, y)].queue_draw()
@simple_debug
- def remove (self, x, y, do_removal=False):
- """Remove x,y from our visible grid.
+ def remove (self, x, y, do_removal = False):
+ """Remove x, y from our visible grid.
If do_removal, remove it from our underlying grid as well.
"""
- e=self.__entries__[(x,y)]
- if do_removal and self.grid and self.grid._get_(x,y):
- self.grid.remove(x,y)
- if self.__error_pairs__.has_key((x,y)):
+ e = self.__entries__[(x, y)]
+ if do_removal and self.grid and self.grid._get_(x, y):
+ self.grid.remove(x, y)
+ if self.__error_pairs__.has_key((x, y)):
e.set_error_highlight(False)
- errors_removed = self.__error_pairs__[(x,y)]
- del self.__error_pairs__[(x,y)]
+ errors_removed = self.__error_pairs__[(x, y)]
+ del self.__error_pairs__[(x, y)]
for coord in errors_removed:
# If we're not an error by some other pairing...
if not self.__error_pairs__.has_key(coord):
@@ -1051,32 +1078,34 @@
# Its possible this highlighted error was never
# added to our internal grid, in which case we'd
# better make sure it is...
- if self.grid and not self.grid._get_(linked_entry.x,linked_entry.y):
+ if self.grid and not self.grid._get_(linked_entry.x, linked_entry.y):
# entry_validate will add the value to our
# internal grid if there are no other
# conflicts
self.entry_validate(linked_entry)
# remove trackers
- for t in self.trackers_for_point(x,y):
+ for t in self.trackers_for_point(x, y):
remove = []
for crumb in self.trackers[t]:
- if crumb[0]==x and crumb[1]==y:
+ if crumb[0] == x and crumb[1] == y:
remove.append(crumb)
for r in remove:
self.trackers[t].remove(r)
- if e.get_text(): e.set_value(0)
+ if e.get_text():
+ e.set_value(0)
e.unset_color()
@simple_debug
def auto_fill (self):
- changed=self.grid.auto_fill()
+ changed = self.grid.auto_fill()
retval = []
- for coords,val in changed:
- self.add_value(coords[0],coords[1],val)
- retval.append((coords[0],coords[1],val))
+ for coords, val in changed:
+ self.add_value(coords[0], coords[1], val)
+ retval.append((coords[0], coords[1], val))
if self.show_impossible_implications:
self.mark_impossible_implications(*coords)
- if retval: self.auto_fills += 1
+ if retval:
+ self.auto_fills += 1
if self.grid.check_for_completeness():
self.emit('puzzle-finished')
return retval
@@ -1084,43 +1113,47 @@
@simple_debug
def auto_fill_current_entry (self):
e = self.get_focused_entry()
- if not e: return
- filled = self.grid.auto_fill_for_xy(e.x,e.y)
- if filled and filled!=-1:
+ if not e:
+ return
+ filled = self.grid.auto_fill_for_xy(e.x, e.y)
+ if filled and filled != -1:
e.set_text_interactive('')
e.set_text_interactive(str(filled[1]))
@simple_debug
def mark_impossible_implications (self, x, y):
- if not self.grid: return
- implications = self.grid.find_impossible_implications(x,y)
+ if not self.grid:
+ return
+ implications = self.grid.find_impossible_implications(x, y)
if implications:
- for x,y in implications:
- self.__entries__[(x,y)].set_impossible(True)
- if not (x,y) in self.impossibilities:
+ for x, y in implications:
+ self.__entries__[(x, y)].set_impossible(True)
+ if not (x, y) in self.impossibilities:
self.impossible_hints += 1
- for x,y in self.impossibilities:
- if not (x,y) in implications:
- self.__entries__[(x,y)].set_impossible(False)
+ for x, y in self.impossibilities:
+ if not (x, y) in implications:
+ self.__entries__[(x, y)].set_impossible(False)
self.impossibilities = implications
@simple_debug
- def create_tracker (self, identifier=0):
- if not identifier: identifier = 0
- while self.trackers.has_key(identifier): identifier+=1
- self.trackers[identifier]=[]
+ def create_tracker (self, identifier = 0):
+ if not identifier:
+ identifier = 0
+ while self.trackers.has_key(identifier):
+ identifier += 1
+ self.trackers[identifier] = []
return identifier
- def trackers_for_point (self, x, y, val=None):
+ def trackers_for_point (self, x, y, val = None):
if val:
# if we have a value we can do this a simpler way...
track_for_point = filter(
- lambda t: (x,y,val) in t[1],
+ lambda t: (x, y, val) in t[1],
self.trackers.items()
)
else:
track_for_point = filter(
- lambda tkr: True in [t[0]==x and t[1]==y for t in tkr[1]],
+ lambda tkr: True in [t[0] == x and t[1] == y for t in tkr[1]],
self.trackers.items())
return [t[0] for t in track_for_point]
@@ -1132,26 +1165,26 @@
while random_color in TRACKER_COLORS:
# If we have generated all possible colors, this will
# enter an infinite loop
- random_color = (random.randint(0,100)/100.0,
- random.randint(0,100)/100.0,
- random.randint(0,100)/100.0)
+ random_color = (random.randint(0, 100)/100.0,
+ random.randint(0, 100)/100.0,
+ random.randint(0, 100)/100.0)
TRACKER_COLORS.append(random_color)
return self.get_tracker_color(identifier)
@simple_debug
def toggle_tracker (self, identifier, value):
"""Toggle tracking for tracker identified by identifier."""
- self.__trackers_tracking__[identifier]=value
+ self.__trackers_tracking__[identifier] = value
def delete_by_tracker (self, identifier):
"""Delete all cells tracked by tracker ID identifer."""
ret = []
while self.trackers[identifier]:
- x,y,v = self.trackers[identifier][0]
- ret.append((x,y,v,self.trackers_for_point(x,y,v)))
- self.remove(x,y)
- if self.grid and self.grid._get_(x,y):
- self.grid.remove(x,y)
+ x, y, v = self.trackers[identifier][0]
+ ret.append((x, y, v, self.trackers_for_point(x, y, v)))
+ self.remove(x, y)
+ if self.grid and self.grid._get_(x, y):
+ self.grid.remove(x, y)
return ret
def delete_except_for_tracker (self, identifier):
@@ -1159,26 +1192,28 @@
removed = []
for x in range(self.group_size):
for y in range(self.group_size):
- val = self.grid._get_(x,y)
+ val = self.grid._get_(x, y)
if (val
- and (x,y,val) not in tracks
- and not self.grid.virgin._get_(x,y)
+ and (x, y, val) not in tracks
+ and not self.grid.virgin._get_(x, y)
):
- removed.append((x,y,val,self.trackers_for_point(x,y,val)))
- self.remove(x,y)
- if self.grid and self.grid._get_(x,y):
- self.grid.remove(x,y)
+ removed.append((x, y, val, self.trackers_for_point(x, y, val)))
+ self.remove(x, y)
+ if self.grid and self.grid._get_(x, y):
+ self.grid.remove(x, y)
return removed
- def add_tracker (self, x, y, tracker, val=None):
- self.__entries__[(x,y)].set_color(self.get_tracker_color(tracker))
- if not val: val = self.grid._get_(x,y)
- self.trackers[tracker].append((x,y,val))
-
- def remove_tracker (self, x, y, tracker, val=None):
- if not val: val = self.grid._get_(x,y)
- self.trackers[tracker].remove((x,y,val))
+ def add_tracker (self, x, y, tracker, val = None):
+ self.__entries__[(x, y)].set_color(self.get_tracker_color(tracker))
+ if not val:
+ val = self.grid._get_(x, y)
+ self.trackers[tracker].append((x, y, val))
+
+ def remove_tracker (self, x, y, tracker, val = None):
+ if not val:
+ val = self.grid._get_(x, y)
+ self.trackers[tracker].remove((x, y, val))
if __name__ == '__main__':
def test_sng ():
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]