pythonrandomn-queens

Queens on chessboard solved randomly in Python


The idea is to try solve the "queen problem" by totally placing the queens totally random in each row of the chess board, and see how many repetitions it takes to solve it. The chess board can be any size.

My idea is to create s lists, each containing s "empty" characters (underscores). Then for each line randomly pick a position to insert the queen ("I" value) and then mark all the positions below and diagonally down (I'm going row-by-row, so I don't have to bother about rows above) with X. if in any iteration the randomly chosen position for the queen matches with position of any X in that row, I start the new chessboard from scratch.

I have something like this, but it seems to get stuck on line 19 (marked with a comment), but it doesn't give me any error. What can be wrong? Also, is my solution (apart that line) correct?

from random import *


#Success flag
success = 0

#Trials counter
trials = 0


s = input ("enter board size\n")
s = int(s)
block = 1 #blockade
queen = 2 #queen
board = [[0 for x in range(s)] for y in range(s)] 

while success == 0:
    for y in range (0, s-1):
        pos = randint(0,s-1)    #line 19
        if board[y][pos] != block:
            board[y][pos] = queen
            a = 1
            for z in range (y, s-2):
                board[z + 1][pos] = block
                if pos - a >= 0:
                    board[z + 1][pos - a] = block
                if pos + a <= s-1:
                    board[z + 1][pos + a] = block
                a = a + 1
            success = 1
        else:
            success = 0


#Printing board
for y in range (0, s-1):
    print (board[y])

print ("Number of trials:\n")
print (trials)

Solution

  • Some issues:

    See the corrected code, with comments where I made changes:

    import random
    
    s = input ("enter board size\n")
    s = int(s)
    trials = 0
    block = 1
    queen = 2
    # add some maximum to the number of attempts
    max_trials = 100000 
    success = 0
    
    # add safety measure to avoid infinite looping
    while success == 0 and trials <= max_trials:
        # initialise board before every trial
        board = [[0 for x in range(s)] for y in range(s)]
        # assume success until failure
        success = 1
        # count trials
        trials += 1 
        for y in range (0, s): # use correct range
            # get the fields that are still available in this row
            available = [x for x, i in enumerate(board[y]) if i == 0]
            if len(available) == 0:
                success = 0
                # exit for loop, you want to start a next trial
                break
            # choose a random position among available spots only
            pos = available[random.randint(0, len(available)-1)]    
            board[y][pos] = queen
            a = 1
            for z in range (y+1, s): # use correct range
                board[z][pos] = block
                if pos - a >= 0:
                    board[z][pos - a] = block
                if pos + a < s:
                    board[z][pos + a] = block
                a = a + 1
    
    for y in range (0, s): # use correct range
        print (board[y])
    
    print ("Number of trials:", trials)