Beispiel #1
0
    def getValidNum(self, posX, posY):
        '''
        get (posX,posY) valid number list
        Example:
        012045                         012045
        000090                            090
        000100   -> (posX=3,posY=0) ->    100   -> valid list = (3,6,7)
        000000                            0
        001000                            0
        200800                            8

        Return:
            number list : [1,2,3,...]
        '''
        #Check grid
        self._initLineBoolNum()
        g = boxer_util.grid(posX/3,posY/3, self.num)
        for i in app.rgGRID:
            for j in app.rgGRID:
                if g[i][j] != 0:
                    self._lineBoolNum[ g[i][j]-1 ] = True
        #Check vertical line
        line = [self.num[posX][i] for i in app.rgLINE]
        for num in line:
            if num != 0:
                self._lineBoolNum[ num-1 ] = True
        #Check horizantol line
        line = [self.num[i][posY] for i in app.rgLINE]
        for num in line:
            if num != 0:
                self._lineBoolNum[ num-1 ] = True

        res = [ i for i in range(1, app.nLINE+1) if not self._lineBoolNum[i-1] ]
        return res
Beispiel #2
0
 def _markBoolNumByGrid(self, i, j):
     self._initLineBoolNum()
     g = boxer_util.grid(i,j, self.num)
     for x in app.rgGRID:
         for y in app.rgGRID:
             if g[x][y] != 0:
                 self._lineBoolNum[ g[x][y]-1 ] = True
     return self._lineBoolNum
Beispiel #3
0
    def _checkLine(self, num):
        self._initBoolNum()
        self._markBoolNoVal()
        numPosList = []
        #mark num in all grid
        for i in app.rgGRID:
            for j in app.rgGRID:
                g = boxer_util.grid(i,j, self.num)
                x, y = self._queryGridBoolNum(g, num)
                if (x,y) == (-1,-1):
                    continue
                pos = i*3+x, j*3+y
                self._markBoolNumByXY(*pos)
                numPosList.append( {'pos':pos, 'grid':(i,j)} ) #for boxerInfo

        #check all grid which only one space
        for i in app.rgGRID:
            for j in app.rgGRID:
                g = boxer_util.grid(i,j, self._boolNum)
                g_num = boxer_util.grid(i,j, self.num)
                if self._countGridBoolNum(g,False) == 1 and self._countGridBoolNum(g_num,num) == 0:
                    x, y = self._queryGridBoolNum(g,False)

                    #set boxer info
                    bi = BoxerInfo()
                    bi.add('cell grid', i, j)
                    for np in numPosList:
                        if np['grid'][0] == i and not self.checkGridLineFull(i,j,'v',np['pos'][0]%3,g_num):
                            if np['pos'][1]/3 < j:
                                start, end = np['pos'][1]+1, (j+1)*3
                            else:
                                start, end = j*3, np['pos'][1]
                            bi.add('line', 'v', np['pos'][0], start, end)
                            bi.add('cell', np['pos'][0], np['pos'][1])
                        elif np['grid'][1] == j and not self.checkGridLineFull(i,j,'h',np['pos'][1]%3,g_num):
                            if np['pos'][0]/3 < i:
                                start, end = np['pos'][0]+1, (i+1)*3
                            else:
                                start, end = i*3, np['pos'][0]
                            bi.add('line', 'h', np['pos'][1], start, end)
                            bi.add('cell', np['pos'][0], np['pos'][1])
                    return (i*3+x, j*3+y), bi

        return (-1, -1), None
Beispiel #4
0
    def checkValidInput(self, num, posX, posY):
        '''
        Check is grid valid, vertical/horizantol line valid
        '''
        g = boxer_util.grid(posX/3,posY/3, self.num)
        if self._countGridBoolNum(g,num) > 1:
            return False

        line = [self.num[posX][i] for i in app.rgLINE]
        if self._countLineBoolNum(line, num) > 1:
            return False

        line = [self.num[i][posY] for i in app.rgLINE]
        if self._countLineBoolNum(line, num) > 1:
            return False

        return True
Beispiel #5
0
    def checkGridLineFull(self, i, j, direction, idx, gridNum=None):
        '''
        check the line is full or not in a grid
        Ex:
        grid (0,0) -> 010
                      203 -> check direction='h', idx=1 -> '203' -> not full (have 1 space)
                      864 -> check direction='h', idx=2 -> '864' -> full (no space)
        '''
        assert direction in ('v', 'h')
        if not gridNum:
            gridNum = boxer_util.grid(i,j, self.num)

        full = True
        for i in app.rgGRID:
            if direction == 'v':
                full = full and (gridNum[idx][i]!=0)
            else:
                full = full and (gridNum[i][idx]!=0)
        return full
Beispiel #6
0
    def run(self):
        '''
        Check line/grid in soso2 way.
        Ex:
        line===12  56 89
                 XX  X   -> check 3, if 2*X has 3, the only 1X is 3
                 XX  X   -> check 4, if 2*X has 4, the only 1X is 4
                 XX  X   -> check 7, if 2*X has 7, the only 1X is 7
        '''
        logger.info('-----------boxerNextSoSo2-----------')
        boolNumFalse = [False for i in app.rgLINE]
        #check vertical
        for i in app.rgLINE:
            boolNum = deepcopy(boolNumFalse)
            lineBoolNum = deepcopy(boolNumFalse)
            #mark bool number
            for j in app.rgLINE:
                n = self.num[i][j]
                if n > 0 :
                    boolNum[n-1] = True
                    lineBoolNum[j] = True

            for num_idx in app.rgLINE:
                if boolNum[num_idx]: continue
                checkLineBoolNum = deepcopy(lineBoolNum)
                num = num_idx+1

                #check grid
                for j in app.rgGRID:
                    grid_i = int(i / 3)
                    g = boxer_util.grid(grid_i, j, self.num)
                    pos = self._queryGridBoolNum(g, num)
                    if pos != (-1,-1):
                        checkLineBoolNum[j*3] = checkLineBoolNum[j*3+1] = checkLineBoolNum[j*3+2] = True

                #check line
                for j in app.rgLINE:
                    if self.num[i][j] > 0: continue

                    for line_i in app.rgLINE:
                        if self.num[line_i][j] == num:
                            checkLineBoolNum[j] = True
                            break

                if self._countLineBoolNum(checkLineBoolNum, False) == 1:
                    logger.info('CheckVertical line=%s\n (i,j)=%s, checkLineBoolNum=%s',
                                [int(self.num[i][n]) for n in app.rgLINE], (i,j), checkLineBoolNum)
                    j = checkLineBoolNum.index(False)
                    return (i,j), num, None

        #check horizontal
        for j in app.rgLINE:
            boolNum = deepcopy(boolNumFalse)
            lineBoolNum = deepcopy(boolNumFalse)

            #mark bool number
            for i in app.rgLINE:
                n = self.num[i][j]
                if n > 0 :
                    boolNum[n-1] = True
                    lineBoolNum[i] = True

            for num_idx in app.rgLINE:
                if boolNum[num_idx]: continue
                checkLineBoolNum = deepcopy(lineBoolNum)
                num = num_idx+1

                #check grid
                for i in app.rgGRID:
                    grid_j = int(j / 3)
                    g = boxer_util.grid(i, grid_j, self.num)
                    pos = self._queryGridBoolNum(g, num)
                    if pos != (-1,-1):
                        checkLineBoolNum[i*3] = checkLineBoolNum[i*3+1] = checkLineBoolNum[i*3+2] = True

                #check line
                for i in app.rgLINE:
                    if self.num[i][j] > 0: continue

                    for line_j in app.rgLINE:
                        if self.num[i][line_j] == num:
                            checkLineBoolNum[i] = True
                            break
                if self._countLineBoolNum(checkLineBoolNum, False) == 1:
                    logger.info('CheckVertical line=%s\n (i,j)=%s, checkLineBoolNum=%s',
                                [int(self.num[n][j]) for n in app.rgLINE], (i,j), checkLineBoolNum)
                    i = checkLineBoolNum.index(False)
                    return (i,j), num, None

        #check Grid
        for i in app.rgGRID:
            for j in app.rgGRID:
                boolNum = deepcopy(self._markBoolNumByGrid(i,j)) #represent 1~9
                gridBoolNum = deepcopy(self._markGridBoolNum(i,j)) #Grid has value

                g = boxer_util.grid(i,j, self.num)
                for num_idx in app.rgLINE:
                    if boolNum[num_idx]: continue
                    num = num_idx + 1
                    checkGridBoolNum = deepcopy(gridBoolNum)

                    for pos in self._iterGridNoVal(g):
                        gx, gy = pos[0] + i* app.nGRID, pos[1] + j* app.nGRID #global x,y
                        if self._countBoolNumByXY(gx, gy, num) > 0:
                            checkGridBoolNum[pos[0]][pos[1]] = True
                    #only one
                    if self._countGridBoolNum(checkGridBoolNum, False) == 1:
                        pos = self._queryGridBoolNum(checkGridBoolNum, False)
                        gx, gy = pos[0] + i* app.nGRID, pos[1] + j* app.nGRID #global x,y
                        logger.info('CheckGrid (i,j)=%s, GridBoolNum=%s', pos, checkGridBoolNum)
                        return (gx,gy), num, None
        return None
Beispiel #7
0
    def run(self):
        '''
        Check line/grid in soso way.
        Ex:
        line===12 456 89
                 X       -> check 3 & 7, if 3 exist, this X is 7
                     X   -> check 3 & 7, if 3 exist, this X is 7
        '''
        logger.info('-----------boxerNextSoSo-----------')
        boolNumFalse = [False for i in app.rgLINE]
        #check vertical
        for i in app.rgLINE:
            boolNum = deepcopy(boolNumFalse)
            #mark bool number
            for j in app.rgLINE:
                n = self.num[i][j]
                if n > 0 :
                    boolNum[n-1] = True

            #check non-value line
            for j in app.rgLINE:
                n = self.num[i][j]
                if n == 0:
                    numPosList = []
                    checkBoolNum = deepcopy(boolNum)
                    for line_i in app.rgLINE:
                        if line_i == i: continue
                        n = self.num[line_i][j]
                        if n > 0 and checkBoolNum[n-1]==False:
                            checkBoolNum[n-1] = True
                            numPosList.append( {'pos':(line_i,j), 'num':n} )
                    if self._countLineBoolNum(checkBoolNum,False) == 1:
                        logger.info('CheckVertical line=%s\n (i,j)=%s, checkBoolNum=%s',
                                    [int(self.num[i][n]) for n in app.rgLINE], (i,j), checkBoolNum)
                        num = checkBoolNum.index(False)+1

                        #set boxer info
                        bi = BoxerInfo()
                        bi.add('cell line', 'v', i)
                        conflitNumList = [num]
                        for _n in numPosList:
                            bi.add('cell', _n['pos'][0], _n['pos'][1])
                            conflitNumList.append(_n['num'])
                        for idx in app.rgLINE:
                            if self.num[i][idx] == 0 and idx != j:
                                bi.add('cell tips', i, idx, conflitNumList)
                        return (i,j), num, bi
            pass
        #check horizantol
        for j in app.rgLINE:
            boolNum = deepcopy(boolNumFalse)
            #mark bool number
            for i in app.rgLINE:
                n = self.num[i][j]
                if n > 0 :
                    boolNum[n-1] = True

            #check non-value line
            for i in app.rgLINE:
                n = self.num[i][j]
                if n == 0:
                    numPosList = []
                    checkBoolNum = deepcopy(boolNum)
                    for line_j in app.rgLINE:
                        if line_j == j: continue
                        n = self.num[i][line_j]
                        if n > 0 and checkBoolNum[n-1]==False:
                            checkBoolNum[n-1] = True
                            numPosList.append( {'pos':(line_i,j), 'num':n} )
                    if self._countLineBoolNum(checkBoolNum,False) == 1:
                        logger.info('CheckHorizantol line=%s\n (i,j)=%s, checkBoolNum=%s',
                                    [self.num[n][j] for n in app.rgLINE], (i,j), checkBoolNum)
                        num = checkBoolNum.index(False)+1

                        #set boxer info
                        bi = BoxerInfo()
                        bi.add('cell line', 'h', j)
                        conflitNumList = [num]
                        for _n in numPosList:
                            bi.add('cell', _n['pos'][0], _n['pos'][1])
                            conflitNumList.append(_n['num'])
                        for idx in app.rgLINE:
                            if self.num[idx][j] == 0 and idx != i:
                                bi.add('cell tips', idx, j, conflitNumList)
                        return (i,j), num, bi

        #check Grid
        for i in app.rgGRID:
            for j in app.rgGRID:
                boolNum = deepcopy(self._markBoolNumByGrid(i,j))   #represent 1~9

                g = boxer_util.grid(i,j, self.num)
                for x in app.rgGRID:
                    for y in app.rgGRID:
                        if g[x][y]!=0: continue
                        gx, gy = x + i* app.nGRID, y + j* app.nGRID #global x,y
                        conflitNumList = []
                        checkBoolNum = deepcopy(boolNum)
                        for num_idx in app.rgLINE:
                            if checkBoolNum[num_idx]: continue
                            num = num_idx+1
                            if self._countBoolNumByXY(gx,gy, num) > 0:
                                checkBoolNum[num_idx] = True
                                conflitNumList.append(num)

                        if self._countLineBoolNum(checkBoolNum, False) == 1:
                            num = checkBoolNum.index(False)+1
                            logger.info('CheckGrid (i,j)=%s checkBoolNum=%s', (gx,gy), checkBoolNum)

                            #set boxer info
                            bi = BoxerInfo()
                            bi.add('cell grid', i, j)
                            conflitNumList.append(num)
                            #mark the conflit cells out of grid
                            for _x in app.rgLINE:#vertical
                                if self.num[_x][gy] in conflitNumList:
                                    bi.add('cell', _x, gy)
                            for _y in app.rgLINE:#horizantol
                                if self.num[gx][_y] in conflitNumList:
                                    bi.add('cell', gx, _y)
                            #mark cell tips in grid
                            for _i in app.rgGRID:
                                for _j in app.rgGRID:
                                    _x, _y = _i + i* app.nGRID, _j + j* app.nGRID
                                    if self.num[_x][_y] == 0 and (_x,_y)!=(gx,gy):
                                        bi.add('cell tips', _x, _y, conflitNumList)
                            return (gx,gy), num, bi
        return None