def test_coordsFromIndexAgainstValue(self):
     self.sudokuBoard.clearBoard()
     self.sudokuBoard.loadBoard('preloads/sudoku1.txt')
     for index in range(81):
         valByIndex = self.sudokuBoard.getDigit(index)
         coords = SudokuBoard.coordsFromIndex(index)
         index2 = SudokuBoard.indexFromCoords(coords)
         valByIndex2 = self.sudokuBoard.getDigit(index2)
         self.assertTrue(valByIndex == valByIndex2)
Example #2
0
def resolve(sudokuStr):
        sudokuStr = sudokuStr.replace("x", "0")
        
        board = SudokuBoard(sudokuStr)
        if board.isValid() == False: 
            print  "The board is not valid, give me a break!"
#        
        think(board, 0, 0);
        
        return board.toString()
 def test_squareFromCoords(self):
     self.assertTrue(SudokuBoard.squareFromCoords((0,0)) == 0)
     self.assertTrue(SudokuBoard.squareFromCoords((4,1)) == 1)
     self.assertTrue(SudokuBoard.squareFromCoords((8,2)) == 2)
     self.assertTrue(SudokuBoard.squareFromCoords((0,3)) == 3)
     self.assertTrue(SudokuBoard.squareFromCoords((4,4)) == 4)
     self.assertTrue(SudokuBoard.squareFromCoords((8,5)) == 5)
     self.assertTrue(SudokuBoard.squareFromCoords((0,6)) == 6)
     self.assertTrue(SudokuBoard.squareFromCoords((4,7)) == 7)
     self.assertTrue(SudokuBoard.squareFromCoords((8,8)) == 8)
Example #4
0
def solveUsingIntersect(sb):
    alg2 = AlgIntersectValue2(sb)
    
    goodRun = False
    solutions = []
    contSolving = True
    iteration = 0

    while contSolving:
        # Check each place
        anyFound = False;
        for index in range(81):
            place = sb.getDigit(index)
            if place is None:
                # Place is empty, check if we can solve it
                solution = alg2.runAlg(SudokuBoard.coordsFromIndex(index))
                if solution is not None:
                    solutions.append((index, solution))
                    anyFound = True
                    goodRun = True
        print("Iteration {0}: Found {1} solutions!".format(iteration, len(solutions)))
        for i in solutions:
            print("Index: {0} Solution: {1}".format(i[0], i[1]))
            sb.setDigit(i[1], i[0])
        solutions.clear()
        contSolving = anyFound
        iteration += 1

    # was this good run?
    return goodRun
class Test_testAlgIntersectValue(unittest.TestCase):
    
    def setUp(self):
        self.board = SudokuBoard()
        self.board.loadBoard('preloads/sudoku3.txt')
        self.alg = AlgIntersectValue(self.board)
    
    def test_AlgIntersectNonBlankValue(self):
        coords = (0,1)
        self.assertTrue(self.alg.runAlg(coords) == None)

    def test_AlgIntersectNotSolvable(self):
        coords = (8,8)
        self.assertTrue(self.alg.runAlg(coords) == None)

    def test_AlgIntersectSolve(self):
        coords = (1,1)
        self.assertTrue(self.alg.runAlg(coords) == 9)
    def runAlg(self, coords):
        # Get digit at coords
        n = self.board.getDigit(SudokuBoard.indexFromCoords(coords))

        # Should we solve it?
        if n is not None:
            return None

        # Get candidates at the square
        cands = self.getCand(coords)

        if len(cands) != 1:
            return None
        else:
            return cands.pop()
Example #7
0
from SudokuBoard import SudokuBoard
from AlgIntersectValue2 import AlgIntersectValue2
from AlgNumbersInLayers import AlgNumbersInLayers

# Create and load board
sb = SudokuBoard()
sb.loadBoard('preloads/sudoku1.txt')
sb.printBoard()

def solveUsingIntersect(sb):
    alg2 = AlgIntersectValue2(sb)
    
    goodRun = False
    solutions = []
    contSolving = True
    iteration = 0

    while contSolving:
        # Check each place
        anyFound = False;
        for index in range(81):
            place = sb.getDigit(index)
            if place is None:
                # Place is empty, check if we can solve it
                solution = alg2.runAlg(SudokuBoard.coordsFromIndex(index))
                if solution is not None:
                    solutions.append((index, solution))
                    anyFound = True
                    goodRun = True
        print("Iteration {0}: Found {1} solutions!".format(iteration, len(solutions)))
        for i in solutions:
Example #8
0
from SudokuBoard import SudokuBoard

def cross(A, B):
    "Cross product of elements in A and elements in B."
    return [a+b for a in A for b in B]

if __name__ == "__main__":

    easy = SudokuBoard("..3.2.6..9..3.5..1..18.64....81.29..7.......8..67.82....26.95..8..2.3..9..5.1.3..")
    print "This is an easy puzzle ..."
    print easy.pretty_initial_state()
    easy.solve()
    print easy.pretty()
    print "done"

    hard = SudokuBoard("4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......")
    print "This is a very HARD puzzle ..."
    print hard.pretty_initial_state()
    hard.solve()
    print hard.pretty_values()
    print "done"
 def setUp(self):
     self.sudokuBoard = SudokuBoard()
Example #10
0
class TestSudokuBoard(unittest.TestCase):
    def setUp(self):
        self.sudokuBoard = SudokuBoard()

    # Init the object
    def test_initAllToNone(self):
        self.setUp()
        vals = []
        for k in range(81):
            vals.append(self.sudokuBoard.baseData[k])
        #self.assertIsInstance(self.sudokuBoard.baseData[0], NoneType)
        self.assertTrue(all(vals[0] == item for item in vals))
    def test_startAtVer0(self):
        self.setUp()
        self.assertEqual(self.sudokuBoard.version, 0)
    
    # Get the value
    def test_getDigitIndexIsInt(self):
        with self.assertRaises(TypeError):
            self.sudokuBoard.getDigit("string")
    def test_getDigitIndexMin(self):
        with self.assertRaises(ValueError):
            self.sudokuBoard.getDigit(-1)
    def test_getDigitIndexMax(self):
        with self.assertRaises(ValueError):
            self.sudokuBoard.getDigit(81)
    def test_getDigitIndexWork(self):
        index = 5
        value = 5
        self.sudokuBoard.baseData[index] = value
        self.assertEqual(self.sudokuBoard.getDigit(index), value)
    def test_getDigitIndexRetNone(self):
        self.setUp()
        self.assertIsNone(self.sudokuBoard.getDigit(1))
    def test_getDigitIndexRetInt(self):
        index = 1
        value = 1
        self.sudokuBoard.baseData[index] = value
        self.assertIsInstance(self.sudokuBoard.getDigit(index), int)

    # Set the value
    def test_setDigitIndexIsInt(self):
        with self.assertRaises(TypeError):
            self.sudokuBoard.setDigit(1, "string")
    def test_setDigitValueIsInt(self):
        with self.assertRaises(TypeError):
            self.sudokuBoard.setDigit("string", 1)
    def test_setDigitIndexMin(self):
        with self.assertRaises(ValueError):
            self.sudokuBoard.setDigit(1, -1)
    def test_setDigitIndexMax(self):
        with self.assertRaises(ValueError):
            self.sudokuBoard.setDigit(1, 81)
    def test_setDigitValueMin(self):
        with self.assertRaises(ValueError):
            self.sudokuBoard.setDigit(0, 1)
    def test_setDigitValueMax(self):
        with self.assertRaises(ValueError):
            self.sudokuBoard.setDigit(10, 1)
    def test_setDigitValueSet(self):
        index = 1
        value = 2
        self.sudokuBoard.setDigit(value, index)
        self.assertEqual(self.sudokuBoard.baseData[index], value)
    def test_setDigitVerIncr(self):
        verOld = self.sudokuBoard.version
        self.sudokuBoard.setDigit(1, 1)
        self.assertTrue(self.sudokuBoard.version > verOld)

    # Get row
    def test_getRowNumIsInt(self):
        with self.assertRaises(TypeError):
            for i in self.sudokuBoard.getRow("string"):
                a = i
    def test_getRowNumMin(self):
        with self.assertRaises(ValueError):
            for i in self.sudokuBoard.getRow(-1):
                a = i
    def test_getRowNumMax(self):
        with self.assertRaises(ValueError):
            for i in self.sudokuBoard.getRow(9):
                a = i
    def test_getRowReturnIter(self):
        i = self.sudokuBoard.getRow(1)
        iter(i)

    # Get col
    def test_getColNumIsInt(self):
        with self.assertRaises(TypeError):
            for i in self.sudokuBoard.getCol("string"):
                a = i
    def test_getColNumMin(self):
        with self.assertRaises(ValueError):
            for i in self.sudokuBoard.getCol(-1):
                a = i
    def test_getColNumMax(self):
        with self.assertRaises(ValueError):
            for i in self.sudokuBoard.getCol(9):
                a = i
    def test_getColReturnIter(self):
        i = self.sudokuBoard.getCol(1)
        iter(i)

    # Get square
    def test_getSqrNumIsInt(self):
        with self.assertRaises(TypeError):
            for i in self.sudokuBoard.getSqr("string"):
                a = i
    def test_getSqrNumMin(self):
        with self.assertRaises(ValueError):
            for i in self.sudokuBoard.getSqr(-1):
                a = i
    def test_getSqrNumMax(self):
        with self.assertRaises(ValueError):
            for i in self.sudokuBoard.getSqr(9):
                a = i
    def test_getSqrReturnIter(self):
        i = self.sudokuBoard.getSqr(1)
        iter(i)
    def test_getSqrReturnVal(self):
        self.sudokuBoard.clearBoard()
        self.sudokuBoard.loadBoard('preloads/sudoku1.txt')
        actual = list(i for i in self.sudokuBoard.getSqr(0))
        expected = [None, None,None, 8, None, None, None, 4, 9]
        self.assertTrue(actual == expected)

    # Multitest for coords - index translation
    def test_coordsFromIndexAgainstValue(self):
        self.sudokuBoard.clearBoard()
        self.sudokuBoard.loadBoard('preloads/sudoku1.txt')
        for index in range(81):
            valByIndex = self.sudokuBoard.getDigit(index)
            coords = SudokuBoard.coordsFromIndex(index)
            index2 = SudokuBoard.indexFromCoords(coords)
            valByIndex2 = self.sudokuBoard.getDigit(index2)
            self.assertTrue(valByIndex == valByIndex2)

    # Validity test
    def test_testGroup(self):
        # Empty iterator
        self.assertFalse(self.sudokuBoard.testGroup([]))
        # Too short iterator
        self.assertFalse(self.sudokuBoard.testGroup(range(5)))
        # Too long iterator
        self.assertFalse(self.sudokuBoard.testGroup(range(11)))
        # Good length wrong numbers
        self.assertFalse(self.sudokuBoard.testGroup(range(9)))
        # Good length, some Nones
        self.assertFalse(self.sudokuBoard.testGroup([1,2,3,4,5,6,7,8,None]))
        # Valid group
        self.assertTrue(self.sudokuBoard.testGroup(range(1,10)))

    def test_indexFromCoords(self):
        self.assertTrue(SudokuBoard.indexFromCoords((0,0)) == 0)
        self.assertTrue(SudokuBoard.indexFromCoords((1,1)) == 10)
        self.assertTrue(SudokuBoard.indexFromCoords((8,8)) == 80)
    def test_squareFromCoords(self):
        self.assertTrue(SudokuBoard.squareFromCoords((0,0)) == 0)
        self.assertTrue(SudokuBoard.squareFromCoords((4,1)) == 1)
        self.assertTrue(SudokuBoard.squareFromCoords((8,2)) == 2)
        self.assertTrue(SudokuBoard.squareFromCoords((0,3)) == 3)
        self.assertTrue(SudokuBoard.squareFromCoords((4,4)) == 4)
        self.assertTrue(SudokuBoard.squareFromCoords((8,5)) == 5)
        self.assertTrue(SudokuBoard.squareFromCoords((0,6)) == 6)
        self.assertTrue(SudokuBoard.squareFromCoords((4,7)) == 7)
        self.assertTrue(SudokuBoard.squareFromCoords((8,8)) == 8)
Example #11
0
 def test_indexFromCoords(self):
     self.assertTrue(SudokuBoard.indexFromCoords((0,0)) == 0)
     self.assertTrue(SudokuBoard.indexFromCoords((1,1)) == 10)
     self.assertTrue(SudokuBoard.indexFromCoords((8,8)) == 80)
Example #12
0
# import numpy as np
from SudokuBoard import SudokuBoard
from SudokuDisplay import SudokuDisplay

# input sudoku as 9x9 with 0s as empty spaces
input_board = [
    '006309005', '003000472', '805010030', '000407690', '002901008',
    '401080000', '080000204', '060570100', '030060700'
]

if __name__ == "__main__":
    # init brett
    brett = SudokuBoard(input_board)

    # display window
    window = SudokuDisplay(brett)
Example #13
0
# test_isinstance.py
"""
Not seeing SudokuData
"""
from SudokuBoard import SudokuBoard
from SudokuData import SudokuData
from SudokuPly import SudokuPly

sb = SudokuBoard()
sd = SudokuData()
sp = SudokuPly()

if isinstance(sd, SudokuData):
    print(f"Found sd{sd} to be SudokuData instance")
else:
    print(f"Did not find sd{sd} to be SudokuData instance")
 def get_sudoku_object(self):
     return SudokuBoard([
         self.board[x][y] if type(self.board[x][y]) is int else 0 for x, y
         in product(SudokuBoard.INDEX_RANGE, SudokuBoard.INDEX_RANGE)
     ])
Example #15
0
def make_puzzle(nfilled=None):
    """ Create puzzle with number of cells filled in
    Set reset_data to this
    :nfilled: Number of cells filled in, None = random
    """
    ###global o_data, o_board

    display_close()
    if (g.o_data is None):
        g.o_data = SudokuData(
            cols=g.nCol,
            rows=g.nRow,
            gcols=g.nSubCol,
            grows=g.nSubRow,
        )

    g.o_data.clear()  # Clear data

    if g.o_board is None:
        g.o_board = SudokuBoard(mw=g.mw,
                                frame=new_main_bd_frame(),
                                data=g.o_data,
                                bdWidth=g.bSize,
                                bdHeight=g.bSize)

    ncell = g.nRow * g.nCol
    if (nfilled is None):
        nfilled = int(ncell / 3)
    if nfilled & 1 != 0 and ncell & 1 != 0:
        nfilled -= 1  # No possible symitry
        # with odd # and even row/col

    o_list = SudokuData(base=g.o_data)
    a_start_list = o_list.startCells(nFilled=nfilled, symRules=g.makePuzzleSym)
    if (a_start_list is None):
        SlTrace.lg(f"no such pattern for nRow=:{g.nRow}, nCol=:{g.nCol}" +
                   f" nFilled={nfilled} symRules={g.makePuzzleSym}")
        sys.exit("quitting")
    # Display start list
    sl = SudokuData(rows=g.nRow, grows=g.nSubRow, cols=g.nCol,
                    gcols=g.nSubCol)  # for diagnostic display
    SlTrace.lg(f"start list: ")
    n = 0
    for sc in a_start_list:
        val = n
        if (n <= ord('Z') - ord('A')):
            val = chr(ord('A') + n)
        elif (n < 2 * (ord('Z') - ord('A'))):
            val_ord = ord('a') + n - ((ord('Z') - ord('A') - 1))
            val = chr(val_ord)

        sl.setCellVal(sc.row, sc.col, val)
        SlTrace.lg(f" (r:{sc.row}, c:{sc.col})")
        n += 1

    sl.display()

    if (len(a_start_list) != nfilled):
        SlTrace.lg(f"Actual list = {len(a_start_list)}" +
                   f" Requested list = {nfilled}")

        # Set starting arrangement
    o_sol = SudokuPly(base=g.o_data)
    sols = o_sol.makePuzzle(startList=a_start_list)
    if sols is not None and len(sols) == 1 and defined(sols[0]):
        sol = sols[0]
        g.o_data = sol.getData(subset=a_start_list)
        g.o_board.showData(g.o_data)
        g.Initial_data = SudokuData(base=g.o_data)

    return sols
    def runAlg(self, layer):
        # Get numbers in each layer
        self.row = []
        self.row.append(list(self.board.getRow(3 * layer + 0)))
        self.row.append(list(self.board.getRow(3 * layer + 1)))
        self.row.append(list(self.board.getRow(3 * layer + 2)))

        # loop all numbers
        for target in range(1,10):
            #print("Analyzing target {0}".format(target))

            # Analyze the situation
            self.analyzePositions(target)
        
            # For now implement only when a single row is missing a target

            # Get a row that is missing a target
            missingRow = self.rowMissingTarget()
            #print("Missing row {0}".format(missingRow))

            if missingRow is None:
                continue

            # Get the third that should contain the missing number
            allThirds = set(range(0,3))
            if missingRow == 0:
                allThirds.remove(self.row1TargetThird)
                allThirds.remove(self.row2TargetThird)
            elif missingRow == 1:
                allThirds.remove(self.row0TargetThird)
                allThirds.remove(self.row2TargetThird)
            else:
                allThirds.remove(self.row0TargetThird)
                allThirds.remove(self.row1TargetThird)

            targetThird = allThirds.pop()
            #print("Target third {0}".format(targetThird))

            # Get the numbers in the target third in targer row
            slice = []
            if targetThird == 0:
                slice = self.row[missingRow][0:3]
            elif targetThird == 1:
                slice = self.row[missingRow][3:6]
            else:
                slice = self.row[missingRow][6:9]
            
            #print("Target slice: {0}".format(slice))

            # Get the number of Nones in the slice
            numNone = slice.count(None)
            #print("Count none {0}".format(numNone))

            # If only one - we can return now
            if numNone == 1:
                noneIndex = slice.index(None)
                #print("None index {0}".format(noneIndex))
                index = SudokuBoard.indexFromCoords(((targetThird * 3 + noneIndex), layer * 3 + missingRow))
                return (index, target)

        # Nothing found
        return None
 def setUp(self):
     self.board = SudokuBoard()
     self.board.loadBoard('preloads/sudoku3.txt')
     self.alg = AlgIntersectValue(self.board)