Exemplo n.º 1
0
def sudoku_backtracking(sudoku):
	variables.counter=0
	#Initialize the Stack
	stack = Stack();
	#Find where to start
	initRow, initCol = get_initial_point(sudoku)
	#Create the initial Board and add it to stack
	initBoard = Board(Copy_Board(sudoku),initRow,initCol)
	stack.put(initBoard)
	#Iterate for as long as the stack is full
	while not stack.empty():
		variables.counter+= 1
		#Get current information
		currBoard = stack.get()
		currRow = currBoard.currRow
		currCol = currBoard.currCol
		if currRow > 8 or currCol > 8:
			continue
		#Get the next point
		nexRow, nexCol = get_next_square(currRow, currCol)
		#If square is already filled, move forward
		if currBoard.sudoku[currRow][currCol] != 0:
			stack.put(Board(currBoard.sudoku, nexRow, nexCol))
		#If square is empty, look for which values to fill it
		for newLabel in range(1,10):
			if common.can_yx_be_z(currBoard.sudoku, currRow, currCol, newLabel):
				newB = Copy_Board(currBoard.sudoku)
				newB[currRow][currCol] = newLabel
				if StopCheck(newB): break
				stack.put(Board(newB, nexRow, nexCol))
		if StopCheck(newB): break
	for row in range(9):
		for col in range(9):
			sudoku[row][col] = newB[row][col]
	return variables.counter
Exemplo n.º 2
0
def helper_backtracking(sudoku, variables):
    variables.counter += 1
    #start position (y, x) = (row, col)
    (y, x) = (0, 0)

    #if board is complete, return True and exit recursion
    if (chk_result(sudoku)):
        return True

    #check full board
    for y in range(9):
        for x in range(9):
            if sudoku[y][x] == 0:  #if move is empty
                for z in range(1, 10):  #check all possible values 1-9
                    if can_yx_be_z(sudoku, y, x,
                                   z):  #if no conflict in row/col/box
                        sudoku[y][x] = z  #play the move

                        result = helper_backtracking(
                            sudoku, variables
                        )  #recursively make moves and check validity of moves
                        if result:  #if all resulting moves worked, return True and backtrack all the way out of recursion
                            return True
                        else:
                            sudoku[y][
                                x] = 0  #if playing move z didn't work, set it back to 0 and try next iteration of z
                if sudoku[y][
                        x] == 0:  #if none of the z values worked, this board not solveable. exit with return False
                    return False
Exemplo n.º 3
0
def helper_fwdchk(sudoku, domain):
    variables.counter += 1

    if (chk_result(sudoku)):
        return True

    for y in range(9):
        for x in range(9):

            if (sudoku[y][x] == 0):

                for z in range(1, 10):
                    if (common.can_yx_be_z(sudoku, y, x, (z))):

                        domain_update = remove_z_from_dneighbors(
                            domain, y, x, z
                        )  #before making the play of z at position (y,x), clear from domain of this position's neighbors

                        if (check_domain_notempty(domain_update)
                            ):  #making sure there is no empty domain

                            sudoku[y][x] = (z)  #play the move
                            result = helper_fwdchk(sudoku, domain_update)

                            if (result):
                                return result
                            else:
                                sudoku[y][x] = 0
                if sudoku[y][x] == 0:
                    return False
Exemplo n.º 4
0
def get_domain_unassigned_variables(unassigned_variables, sudoku):
    for i in range(0, len(unassigned_variables)):
        var = unassigned_variables[i]
        x = []
        for j in order_domain_values:
            if common.can_yx_be_z(sudoku, var[0], var[1], j):
                x.append(j)
        unassigned_variables[i].append(x)
Exemplo n.º 5
0
def Find_Possible_Entries(row, column, sudoku):
	returnArr = []
	if sudoku[row][column] != 0:
		return returnArr
	for num in range(1,10):
		if common.can_yx_be_z(sudoku, row, column, num):
			returnArr.append(num)
	if len(returnArr) == 0:
		return None
	return returnArr
Exemplo n.º 6
0
def chk_result(sudoku):
    result = True
    for y in range(9):
        for x in range(9):
            value = sudoku[y][x]
            sudoku[y][x] = 0
            if (value != 0 and common.can_yx_be_z(sudoku, y, x, value)):
                sudoku[y][x] = value
            else:
                result = False
            sudoku[y][x] = value
    return result
Exemplo n.º 7
0
def update_domain(sudoku, var, unassigned_variables):
    for j in range(len(unassigned_variables)):
        curr_var = unassigned_variables[j]
        if ((var[0] == curr_var[0]) or (var[1] == curr_var[1])
                or (var[0] / 3 * 3 + var[1] / 3
                    == curr_var[0] / 3 * 3 + curr_var[1])):
            for k in curr_var[2]:
                if not common.can_yx_be_z(sudoku, curr_var[0], curr_var[1], k):
                    curr_var[2].remove(k)
                if not curr_var[2]:
                    return False
    return True
Exemplo n.º 8
0
def mrv_helper(sudoku):
    spot_master = {}
    for y in range(9):
        for x in range(9):
            compat = []
            for val in range(1, 10):
                if common.can_yx_be_z(sudoku, y, x, val) and sudoku[y][x] == 0:
                    compat.append(val)
            if compat != []:
                spot_master[y, x] = compat

    return spot_master
Exemplo n.º 9
0
def verify_complete(sudoku):
	for y in range(9):
		for x in range(9):
			z = sudoku[y][x]
			if(z==0):
				return False
			sudoku[y][x] = 0
			if(z!=0 and common.can_yx_be_z(sudoku,y,x,z)):
				sudoku[y][x] = z
				pass
			else:
				sudoku[y][x] = z
				return False
	return True
Exemplo n.º 10
0
def backtracking(sudoku_in):
	variables.counter += 1
	if(verify_complete(sudoku_in)):
		return True
	for y in range(9):
		for x in range(9):
			if(sudoku_in[y][x]==0):
				for z in range(9):
					if(common.can_yx_be_z(sudoku_in,y,x,(z+1))):
						sudoku_in[y][x] = z+1
						result = backtracking(sudoku_in)
						if(result):
							return result
						else:
							sudoku_in[y][x] = 0
				return False
Exemplo n.º 11
0
def mrv(sudoku, unassigned_variables):
    variables.counter += 1
    if not unassigned_variables:
        return True
    id = get_mrv(sudoku, unassigned_variables)
    var = copy_list(unassigned_variables[id])
    unassigned_variables.pop(id)
    for val in var[2]:
        if (common.can_yx_be_z(sudoku, var[0], var[1], val)):
            sudoku[var[0]][var[1]] = val
            result = mrv(sudoku, unassigned_variables)
            if result:
                return result
            sudoku[var[0]][var[1]] = 0
    unassigned_variables.insert(0, var)
    return False
Exemplo n.º 12
0
def backtracking(sudoku, unassigned_variables):
    variables.counter += 1
    if not unassigned_variables:
        return True
    var = unassigned_variables[0]
    unassigned_variables.pop(0)
    for i in range(0, len(order_domain_values)):
        v = order_domain_values[i]
        if (common.can_yx_be_z(sudoku, var[0], var[1], v)):
            sudoku[var[0]][var[1]] = v
            result = backtracking(sudoku, unassigned_variables)
            if result:
                return result
            sudoku[var[0]][var[1]] = 0
    unassigned_variables.insert(0, var)
    return False
Exemplo n.º 13
0
def sudoku_forwardchecking(sudoku):

    variables.counter = 0

    domain = [[[0 for v in range(9)] for j in range(9)] for i in range(9)]

    for i in range(9):
        for j in range(9):
            for v in range(1, 10):
                if common.can_yx_be_z(sudoku, i, j, v):
                    domain[i][j][v - 1] = 1
                else:
                    domain[i][j][v - 1] = 0

    forward_recur(sudoku, domain)

    return variables.counter
Exemplo n.º 14
0
def check_result(sudoku, show):
    result = True
    for y in range(9):
        v = ""
        for x in range(9):
            value = sudoku[y][x]
            sudoku[y][x] = 0
            if (value != 0 and common.can_yx_be_z(sudoku, y, x, value)):
                v += bcolors.GREEN
            else:
                result = False
                v += bcolors.RED
            v += str(value)
            sudoku[y][x] = value
        if (show):
            print(v)
    return result
Exemplo n.º 15
0
def backtrack_recur(sudoku):

    variables.counter += 1

    if is_complete(sudoku):
        return True

    for i in range(9):
        for j in range(9):
            if sudoku[i][j] == 0:
                for v in range(1, 10):
                    if common.can_yx_be_z(sudoku, i, j, v):
                        sudoku[i][j] = v
                        if backtrack_recur(sudoku):
                            return True
                        sudoku[i][j] = 0
                return False
Exemplo n.º 16
0
def recursive_forwardtracking(variables, sudoku, domain):
    """ Recursive function for the forward-tracking function
    """
    # Increase counter
    variables.counter += 1

    # Check if board is complete
    if check_complete(sudoku):
        return True

    # If board not complete - check next step
    for y in range(SUDOKU_HEIGHT):
        for x in range(SUDOKU_WIDTH):
            # Check if a cell is available
            if check_available(sudoku, y, x):

                # Check available next step
                for value in range(1, SUDOKU_WIDTH + 1):

                    # Check cell for constraints
                    if common.can_yx_be_z(sudoku, y, x, value):

                        # Update a copy of the domain
                        new_domain = copy_board(domain.copy())
                        updated_domain, is_full_domain = update_domain(
                            new_domain, y, x, value)

                        if is_full_domain:
                            # Set cell with value
                            sudoku = set_cell(sudoku, y, x, value)
                            result = recursive_forwardtracking(
                                variables, sudoku, updated_domain)

                            if result:
                                return True

                            else:
                                sudoku = set_cell(sudoku, y, x, AVAILABLE_CELL)

                if check_available(sudoku, y, x):
                    return False

    return False
Exemplo n.º 17
0
def forwardchecking(sudoku_in,zs_in):
	variables.counter += 1
	if(verify_complete(sudoku_in)):
		return True
	for y in range(9):
		for x in range(9):
			if(sudoku_in[y][x]==0):
				for z in range(9):
					if(common.can_yx_be_z(sudoku_in,y,x,(z+1))):
						cp_zs = update_zs(zs_in,y,x,(z+1))
						if(verify_zs(cp_zs)):

							sudoku_in[y][x] = (z+1)
							result = forwardchecking(sudoku_in,cp_zs)
							if(result):
								return result
							else:
								sudoku_in[y][x] = 0
				return False
Exemplo n.º 18
0
def recursive_fc(sudoku):
    done = finished(sudoku)
    if done:
        return done
    # otherwise...
    # find the next empty location...
    y, x = findNext(sudoku)
    solved = False
    for nval in range(1, 10):
        canbe = common.can_yx_be_z(sudoku, y, x, nval)
        if canbe:
            variables.counter += 1
            sudoku[y][x] = nval
            solved = recursive_fc(sudoku)
            if solved == False:
                # reset the changed val to 0
                sudoku[y][x] = 0
            else:
                return solved  # True
    return solved
Exemplo n.º 19
0
def check_complete(sudoku):
    """ Checks if the board is complete.
    If complete, returns True
    """
    for y in range(SUDOKU_HEIGHT):
        for x in range(SUDOKU_WIDTH):
            if check_available(sudoku, y, x):
                return False

            # Check cell constraints
            if not (check_available(sudoku, y, x)):
                value = sudoku[y][x]
                sudoku = set_cell(sudoku, y, x, AVAILABLE_CELL)
                if common.can_yx_be_z(sudoku, y, x, value):
                    sudoku = set_cell(sudoku, y, x, value)

            else:
                return False

    return True
Exemplo n.º 20
0
def forward_recur(sudoku, domain):

    variables.counter += 1
    # print(variables.counter)

    if is_complete(sudoku):
        return True

    for i in range(9):
        for j in range(9):
            if sudoku[i][j] == 0:
                for v in range(1, 10):
                    if common.can_yx_be_z(sudoku, i, j, v):
                        old_domain = [[j[:] for j in i] for i in domain]
                        sudoku[i][j] = v
                        if update_domain(domain, sudoku, i, j, v):
                            if forward_recur(sudoku, domain):
                                return True
                        sudoku[i][j] = 0
                        domain = [[j[:] for j in i] for i in old_domain]
                return False
Exemplo n.º 21
0
def recursive_backtracking(variables, sudoku):
    """ Recursive function for the forward-tracking function
    """
    # Increase counter
    variables.counter += 1

    # Check if board is complete
    if check_complete(sudoku):
        return True

    # If board not complete - check next step
    for y in range(SUDOKU_HEIGHT):
        for x in range(SUDOKU_WIDTH):
            # Check if a cell is available
            if check_available(sudoku, y, x):

                # Check available next step
                for i in range(1, SUDOKU_WIDTH + 1):

                    # Check cell for constraints
                    if common.can_yx_be_z(sudoku, y, x, i):

                        # Copy board and check cell for index
                        new_sudoku = copy_board(sudoku)
                        new_sudoku = set_cell(sudoku, y, x, i)
                        result = recursive_backtracking(variables, new_sudoku)

                        if result:
                            # sudoku = set_cell(sudoku, y, x, i)
                            return True

                        else:
                            sudoku = set_cell(sudoku, y, x, AVAILABLE_CELL)

                if check_available(sudoku, y, x):
                    return False

    return False
Exemplo n.º 22
0
def helper_fwdchk(sudoku, d, variables):
    variables.counter += 1
    (y, x) = (0, 0)

    if (chk_result(sudoku)):
        return True

    #check full board
    for y in range(9):
        for x in range(9):
            if sudoku[y][x] == 0:
                #deepcopy domain
                d_copy = copy_domain(d)

                for z in range(1, 10):
                    if can_yx_be_z(sudoku, y, x, z):
                        print(f"z = {z} can be played\n")
                        position = (y, x)

                        z_neighbors = build_neighbors(position, sudoku)

                        d = remove_z_from_dneighbors(z_neighbors, d, z)
                        print(
                            f"z = {z}, pos = {(y, x)} and zneighbors after: {z_neighbors}\n"
                        )

                        if check_domain_notempty(d):
                            sudoku[y][x] = z
                            print(f"entered search tree at z = {z}\n")
                            result = helper_fwdchk(sudoku, d, variables)
                            if result:
                                print(f"result returned true\n")
                                return True
                            else:
                                print(f"resetting z = {z} play\n")
                                sudoku[y][x] = 0
                                d = copy_domain(d_copy)
                return False
Exemplo n.º 23
0
def get_domain(sudoku, currRow, currCol):
	returnArr = []
	for num in range(1,10):
		if common.can_yx_be_z(sudoku,currRow, currCol, num):
			returnArr.append(num)
	return returnArr
Exemplo n.º 24
0
def is_valid(board, spot, value):
    return common.can_yx_be_z(board, spot[0], spot[1], value)