Example #1
0
    def startCells(
        self,
        nFilled=None,
        symRules=None,
    ):
        """ Find legal list of cells
        Sets data
        To provide atleast 2-way symitry with an
        odd lengthed board, one
        adds an "odd" cell to the board center
        cell
        :returns: list of CellDesc
        """
        if nFilled is None:
            raise SelectError("startList nFilled is missing")
        if symRules is None:
            symRules = "c"
        symRules = symRules.lower()
        sym_c = True if re.search(r'c', symRules) else False
        sym_x = True if re.search(r'x', symRules) else False
        sym_y = True if re.search(r'y', symRules) else False
        nf = 0  # Number filled
        start_cells = []  # List of start cells in order
        if nFilled % 2 != 0 and (self.nRow % 2 == 1 or self.nCol % 2 == 1):
            crow = int((self.nRow + 1) / 2)
            ccol = int((self.nCol + 1) / 2)
            self.setCellVal(crow, ccol, 1)
            start_cells.append(CellDesc(row=crow, col=ccol))
            nf += 1

        while nf < nFilled:
            row = randint(1, self.nRow)
            col = randint(1, self.nCol)
            r_c = self.getNextEmpty(row=row, col=col)
            if r_c is None:
                break
            row = r_c.row  # Update iff necessary
            col = r_c.col
            if sym_c:
                srow, scol = self.symCell(symRule='c', row=row, col=col)
                if self.isEmptyCell(srow, scol):
                    self.setCellVal(srow, scol, 1)
                    start_cells.append(CellDesc(row=srow, col=scol))
                    nf += 1
                    # Add original if not there
                    if (self.isEmptyCell(row, row)):
                        self.setCellVal(row, col, 1)
                        start_cells.append(CellDesc(row=row, col=col))
                        nf += 1

        return start_cells
Example #2
0
    def getNextEmpty(self,
                     cd=None,
                     row=None,
                     col=None):  # Returns: cell descriptor, else None
        if cd is not None or row is not None:
            self.curCell(cd=cd, row=row, col=col)
        cell = self.curCell()
        row = cell.row
        col = cell.col
        if (self.isEmptyCell(cell.row, cell.col)):
            self.advanceCell()
            if self.isEmptyCell(cell.row, cell.col):
                return cell

        ncell = self.nRow * self.nCol
        ntry = 0
        if SlTrace.trace("empty"):
            SlTrace.lg("getNextEmpty()")

        while True:
            cd = self.advanceCell()
            row, col = cd.row, cd.col
            if SlTrace.trace("empty"):
                SlTrace.lg(f" getNextEmpty check row={row}, col={col}")
            ntry += 1
            val = self.getCellVal(row, col)
            if self.isEmpty(val):
                SlTrace.lg(f"getNextEmpty - got row={row}, col={col}", "empty")
                return CellDesc(row=row,
                                col=col)  # Return empty cell descriptor

            if ntry >= ncell:
                SlTrace.lg("getNextEmpty - NONE FOUND")
                return None
Example #3
0
    def getCell(self, row=None, col=None, quiet=False):
        """ get Sudoku cell may be EMPTY
        :row:          # 1-nRow
        :col:          # 1-nCol
        :quiet:,        # supress trace and cell movement default: False
        :returns: cell
        """
        val = self.vals.getCellVal(row=row, col=col)

        return CellDesc(row=row, col=col, val=val)
Example #4
0
    def curCell(self,
                cd=None,
                row=None,
                col=None):  # Returns: r_c ref to cell structure
        if cd is not None and (row is not None or col is not None):
            raise SelectError(
                "curCell: cd and row,col specified - allow only cd or row,col")

        if cd is None and row is None and col is None:
            return CellDesc(row=self.curRow, col=self.curCol)

        if cd is not None:
            self.curRow = cd.row
            self.curCol = cd.col
            return cd

        self.curRow = row
        self.curCol = col
        return CellDesc(row=self.curRow, col=self.curCol)
Example #5
0
 def setData(self, r_ds=None):
     """Set data
     clear if no  data array
     :r_ds: array
     """
     if self.cells is not None:  # Clear
         del self.cells
     self.cells = [[
         CellDesc(row=ri + 1, col=ci + 1) for ci in range(self.nCol)
     ] for ri in range(self.nRow)]
     if r_ds is not None:
         for ic in range(self.nRow):
             for ir in range(self.nCol):
                 clds = r_ds[ir][ic]
                 self.cells[ir][ic] = clds.copy()
Example #6
0
 def advanceCell(self):  # Returns CellDesc array (row,col)
     """ Advance to next data cell
     Current and only pattern is row1 col1->nCol, row2 col1->nCol, ...
     wrapping at nRow,nCol to row1,col1
     curRow, curCol are updated
     :returns: CellDesc
     """
     row = self.curRow
     col = self.curCol
     col += 1
     if col > self.nCol:
         row += 1
         col = 1
         if row > self.nRow:
             row = 1
     self.curRow = row
     self.curCol = col
     return CellDesc(row=row, col=col)