1

I have created this code and for the life of me I can't figure out why the rows are working just fine and yet the columns will not work, it just doesn't make sense to me.

#sudoku game
import random
#generate board
def build_board():
    board=[]
    for i in range(9):
        block=[[" "," "," "],
               [" "," "," "],
               [" "," "," "]]
        board.append(block)
    return board
#add numbers
def fill_board(board):
    current_num=1
    block_counter=0
    block_row=1
    column_counter=0
    block_column=1
    for block in board: #for each block
        #check rows
        TF_rows=[]
        if block_row==1: #if in first block row
            block_list=[0,1,2]
        elif block_row==2:
            block_list=[3,4,5]
        elif block_row==3:
            block_list=[6,7,8]
        row=0 #row index
        row1=[] #capture statements from blocks
        row2=[] #capture statements from blocks
        row3=[] #capture statements from blocks
        for i in block_list: #block index
            check_block=board[i] #block
            for ROW in check_block:
                if current_num in ROW: #if current_num in row
                    add="false"
                else:
                    add="true"
                if row==0:
                    row1.append(add)
                elif row==1:
                    row2.append(add)
                elif row==2:
                    row3.append(add)
                row+=1
            row=0
        if "false" in row1:
            TF_rows.append("false")
        else:
            TF_rows.append("true")
        if "false" in row2:
            TF_rows.append("false")
        else:
            TF_rows.append("true")
        if "false" in row3:
            TF_rows.append("false")
        else:
            TF_rows.append("true")
        #check column
        TF_columns=[]
        if block_column==1:
            block_col=[0,3,6]
        elif block_column==2:
            block_col=[1,4,7]
        elif block_column==3:
            block_col=[2,5,8]
        column=0
        column1=[]
        column2=[]
        column3=[]
        for i in block_col:
            check_blocks=board[i]
            for RoW in check_blocks: #each row
                item=RoW[column]
                if item==current_num:
                    add="false"
                else:
                    add="true"
                if column==0:
                    column1.append(add)
                elif column==1:
                    column2.append(add)
                elif column==2:
                    column3.append(add)
                column+=1
            column=0
        if "false" in column1:
            TF_columns.append("false")
        else:
            TF_columns.append("true")
        if "false" in column2:
            TF_columns.append("false")
        else:
            TF_columns.append("true")
        if "false" in column3:
            TF_columns.append("false")
        else:
            TF_columns.append("true")
        #evaluate responses
        row_num=0 #index number
        col_num=0 #index number
        positions=[]
        for i in TF_rows: #for item in true false rows
            row_cur=i
            for i2 in TF_columns: #for item in true false columns
                col_cur=i2
                if row_cur=="true" and col_cur=="true": #good position
                    add_pos=[row_num,col_num]
                    #check if spot is clear
                    check_row=block[row_num]
                    check_pos=check_row[col_num]
                    if isinstance(check_pos,str)==True:
                        positions.append(add_pos)
                col_num+=1
            col_num=0
            row_num+=1
        #add number
        change_pos=random.choice(positions)
        change_row=block[change_pos[0]]
        change_row[change_pos[1]]=current_num
        del block[change_pos[0]]
        block.insert(change_pos[0],change_row)
        #update values
        block_counter+=1
        if block_counter in (3,6):
            block_row+=1
        column_counter+=1
        if column_counter in (0,3,6):
            block_column=1
        elif column_counter in (1,4,7):
            block_column=2
        elif column_counter in (2,5,8):
            block_column=3
    return board
#display board
def display(board):
    num=[]
    for i in board: #block level
        for subI in i: #row
            for subsubI in subI: #item
                num.append(subsubI)
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[0],num[1],num[2],num[9],num[10],num[11],num[18],num[19],num[20]))
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[3],num[4],num[5],num[12],num[13],num[14],num[21],num[22],num[23]))
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[6],num[7],num[8],num[15],num[16],num[17],num[24],num[25],num[26]))
    print("---------------------------------------")
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[27],num[28],num[29],num[36],num[37],num[38],num[45],num[46],num[47]))
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[30],num[31],num[32],num[39],num[40],num[41],num[48],num[49],num[50]))
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[33],num[34],num[35],num[42],num[43],num[44],num[51],num[52],num[53]))
    print("---------------------------------------")
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[54],num[55],num[56],num[63],num[64],num[65],num[72],num[73],num[74]))
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[57],num[58],num[59],num[66],num[67],num[68],num[75],num[76],num[77]))
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[60],num[61],num[62],num[69],num[70],num[71],num[78],num[79],num[80]))
    print("---------------------------------------")  

#test
board=build_board()
board=fill_board(board)
display=display(board)

any help would be most welcome thanks and this isn't near complete

Edit: here is an example of the output
---------------------------------------
|   | 1 |   ||   |   |   ||   |   |   |
---------------------------------------
|   |   |   ||   |   |   ||   |   | 1 |
---------------------------------------
|   |   |   || 1 |   |   ||   |   |   |
---------------------------------------
---------------------------------------
|   |   |   ||   |   |   || 1 |   |   |
---------------------------------------
|   |   |   || 1 |   |   ||   |   |   |
---------------------------------------
|   |   | 1 ||   |   |   ||   |   |   |
---------------------------------------
---------------------------------------
|   |   |   ||   |   |   ||   |   | 1 |
---------------------------------------
|   | 1 |   ||   |   |   ||   |   |   |
---------------------------------------
|   |   |   ||   |   | 1 ||   |   |   |
---------------------------------------
Community
  • 1
  • 1
BlendingJake
  • 155
  • 7
  • What does typical output look like? – Milo P Feb 14 '14 at 00:51
  • Can you explain the goal? Are you trying to fill the entire thing in with random numbers following the rules of Sudoku? Are you trying to fill it in a particular way? All cells? Only some cells? – CodeMonkey Feb 14 '14 at 00:57
  • the goal of the current code is to place just the number 1 in all the correct places, never repeating in the same block, row, or column – BlendingJake Feb 14 '14 at 01:04
  • @MiloPrice if you run the code, it will print out the result, I can't copy in what the output is – BlendingJake Feb 14 '14 at 01:06
  • @CodeMonkey: That won't have the expected result. – Joel Cornett Feb 14 '14 at 01:15
  • Ya know, I put it in there and ran it and surprisingly it doesn't work. Yet when I print out the results of board and compare to what I said, it claims they're equal. What the heck? – CodeMonkey Feb 14 '14 at 01:23
  • @CodeMonkey: See this post: http://stackoverflow.com/questions/240178/unexpected-feature-in-a-python-list-of-lists – Joel Cornett Feb 14 '14 at 01:33
  • I've not been able to sort through your complicated code to find out what's going wrong, but I thought I'd suggest a simpler data format that might save your some trouble. You can easily store your data in a single 1-dimensional list, rather than a three-level nested list. If you number your cells with `0` at the top left and `80` at the bottom right, you can get the row of cell `i` with `i//9`, the column with `i%9` and the block with `i // 27 * 3 + i % 9 // 3`. – Blckknght Feb 14 '14 at 01:35
  • Ok, I will do a rewrite of it. Thanks for the to – BlendingJake Feb 14 '14 at 01:41
  • @Blckknght Thank you so much for that last one, I have been using it in my rewrite and it is a lifesaver. Thanks again – BlendingJake Feb 14 '14 at 16:07

1 Answers1

0

No offense intended, but your code was just too complex to understand easily. Below is an optimized version of what you are trying to do. It is not a complete solution, however, because a Sudoku game apparently cannot be created completely randomly as this program illustrates. I hope what you can take from this is not the solution as handed to you, but a means to understand how math, loops, and functions can aid in readability, optimization, and simplicity. Try to understand what I did here and not simply use it. Then, perhaps you can further find ways to improve it to actually do what you want to do. It does solve your '1' problem though. It just may not solve your 5 and up problem :-D. Good luck and I hope this helps!!

#sudoku game
from random import randint

#generate board
def build_board():
    board=[]
    for i in range(9):
        block=[[" "," "," "],
               [" "," "," "],
               [" "," "," "]]
        board.append(block)
    return board


##
## Ensure no other block in the same row has the value
##
def row_available(block, row, board, num):
    # Determine which of the main 3 rows this 3x3 block is at
    boardRow = int(block / 3);
    good = True
    for b in range(boardRow * 3, (boardRow * 3) + 3):
        if b != block:
            if num in board[b][row]:
                good = False
                break
    return good


##
## Ensure no other block in the same col has the value
##
def col_available(block, row, col, board, num):
    # Determine which of the main 3 columns this 3x3 block is at
    boardCol = block % 3;
    good = True
    for b in (boardCol, boardCol + 3, boardCol + 6):
        if b != block:
            if num == board[b][row][col]:
                good = False
                break
    return good


def fill_board(board):
    # to fill all numbers 1 through 9
    for num in range(1,10):
        # for each of the 9 3x3 blocks
        for block in range(len(board)):
            triedRow = [-1]
            foundSpot = False
            for i in range(3):
                row = -1
                while row in triedRow:
                    row = randint(0,2)
                triedRow.append(row)
                if " " in board[block][row] and row_available(block, row, board, num):
                    triedCol = [-1]
                    for j in range(3):
                        col = -1
                        while col in triedCol:
                            col = randint(0,2)
                        triedCol.append(col)
                        if " " == board[block][row][col] and col_available(block, row, col, board, num):
                            board[block][row][col] = num
                            foundSpot = True
                        if foundSpot:
                            break
                if foundSpot:
                    break
            if not foundSpot:
                print("Never Found a Spot for " + str(num) + " in block " + str(block))
    return board


#display board
def display(board):
    num=[]
    for i in board: #block level
        for subI in i: #row
            for subsubI in subI: #item
                num.append(subsubI)
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[0],num[1],num[2],num[9],num[10],num[11],num[18],num[19],num[20]))
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[3],num[4],num[5],num[12],num[13],num[14],num[21],num[22],num[23]))
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[6],num[7],num[8],num[15],num[16],num[17],num[24],num[25],num[26]))
    print("---------------------------------------")
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[27],num[28],num[29],num[36],num[37],num[38],num[45],num[46],num[47]))
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[30],num[31],num[32],num[39],num[40],num[41],num[48],num[49],num[50]))
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[33],num[34],num[35],num[42],num[43],num[44],num[51],num[52],num[53]))
    print("---------------------------------------")
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[54],num[55],num[56],num[63],num[64],num[65],num[72],num[73],num[74]))
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[57],num[58],num[59],num[66],num[67],num[68],num[75],num[76],num[77]))
    print("---------------------------------------")
    print("| {} | {} | {} || {} | {} | {} || {} | {} | {} |".format(num[60],num[61],num[62],num[69],num[70],num[71],num[78],num[79],num[80]))
    print("---------------------------------------")  

#test
board=build_board()
board=fill_board(board)
display=display(board)

Typical Output:

Never Found a Spot for 5 in block 5
Never Found a Spot for 9 in block 4
---------------------------------------
| 7 | 9 | 1 || 4 | 6 | 8 || 5 | 3 | 2 |
---------------------------------------
| 6 | 8 | 3 || 2 | 5 | 9 || 4 | 1 | 7 |
---------------------------------------
| 2 | 5 | 4 || 3 | 7 | 1 || 8 | 6 | 9 |
---------------------------------------
---------------------------------------
| 3 | 2 | 9 || 7 | 8 |   || 6 | 4 | 1 |
---------------------------------------
| 1 | 7 | 6 || 5 | 3 | 4 || 9 | 8 | 2 |
---------------------------------------
| 8 | 4 | 5 || 6 | 1 | 2 ||   | 7 | 3 |
---------------------------------------
---------------------------------------
| 4 | 3 | 6 || 5 | 9 | 2 || 7 | 1 | 8 |
---------------------------------------
| 5 | 1 | 2 || 3 | 7 | 8 || 6 | 9 | 4 |
---------------------------------------
| 7 | 9 | 8 || 1 | 6 | 4 || 5 | 3 | 2 |
---------------------------------------
CodeMonkey
  • 1,795
  • 3
  • 16
  • 46
  • thanks for the tip, I completely agree that you can't use a random process, at least not a completely random process to try and get numbers, I tried and was left with it running thousands of combinations. I am planning a rewrite, so thanks for showing this. It helps be get an idea on how to start out – BlendingJake Feb 14 '14 at 15:40