Queens on a chessboard was decided randomly in Python

The idea is to try to solve the queen’s problem by completely placing the queens completely by accident in each line of the chessboard and see how many repetitions are required to solve it. A chessboard can be any size.

My idea is to create s-lists, each of which contains "empty" characters (underscores). Then, for each line, randomly select the position to insert the queen (value "I"), and then mark all the positions below and diagonally down (I go along the lines, so I do not need to worry about the lines above) with X. If at any iteration it is random the position chosen for the queen matches the position of any X on this line, I start a new chessboard from scratch.

I have something like this, but it looks like it is stuck on line 19 (marked with a comment), but that does not give me any error. What could be wrong? Is my solution also correct (other than this line)?

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)
+4
source share
3 answers

Some problems:

  • The second argument to the function rangeis the first number that will not be visited, so most of the time you have a short one.
  • You need to exit the loop on y on an unsuccessful attempt: you do not want to continue the next line, but restart
  • You need to reset the board after each unsuccessful attempt or otherwise put: before each attempt
  • , , . 1, 2 3 .
  • , , ( ), : 8 , 100 000 !

. , :

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)

, repl.it

+2

, :

import random, itertools

def clashes(p,q):
    a,b = p
    c,d = q
    return a == c or b == d or abs(a-c) == abs(b-d)

def solution(queens):
    #assumes len(queens) == 8
    return not any(clashes(p,q) for p,q in itertools.combinations(queens,2)) 

def randSolve():
    counter = 0
    while True:
        counter += 1
        queens = [(i,random.randint(1,8)) for i in range(1,9)]
        if solution(queens): return counter, queens

print(randSolve())

:

(263528, [(1, 4), (2, 7), (3, 3), (4, 8), (5, 2), (6, 5), (7, 1), (8, 6)])

, 263527. 182360, .

+2

After you try another line and exit this time, you need to create a new empty board, and if success is 0, you must break the for loop as follows.

while success == 0:
    board = [[0 for x in range(s)] for y in range(s)]
    for y in range (0, s):
        pos = randint(0,s-1)    #line 19
        if board[y][pos] != block:
            board[y][pos] = queen
            for i in range(y+1, s):
                board[i][pos] = block
            success = 1
        else:
            success = 0
            break
    trials += 1

You can follow the same logic to implement diagonal cases.

0
source

Source: https://habr.com/ru/post/1666944/


All Articles