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
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
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
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
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
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
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