I'm trying to make a 'smart' opponent in my Tic Tac Toe program. To do this I've created a 'possible win' function which will decide if there is a possible win in the next turn. My problem when running this code is that on every iteration of the for loop the variable board seems to be changed.
I want to reset potential board to the original board at the start of every iteration which is why I included potential_board = board[:] at the start of the loop. I then edit potential_board but every time the loop repeats this variable is not reset, and board is in fact changed as well. Why is this?
Many thanks!
import random,copy
board = [['o','o',' '],[' ',' ',' '],[' ',' ',' ']]
cols = [['o',' ',' '],['o','',''],['o','','']]
def possible_win(board,player):
""" This function should predict whether a winning move is possible in
the next turn. This could be done by simulating every possible next move
and running check_win() on those positions.
:param board,player: checks a win for the specified player
:return:
"""
spaces = empty_spaces(board)
print('Spaces',spaces)
winning_moves = []
for space in spaces:
potential_board = board[:]
print('PBoard',potential_board)
print(space[0],space[1])
potential_board[space[0]][space[1]] = 'o'
if check_win(potential_board,'o'):
winning_moves.append(space)
return winning_moves
def choose_space(board):
a = True
while a:
col = int(input('Choose your column of 1,2,3: ')) - 1
row = int(input('Choose your row of 1,2,3: ')) - 1
if board[row][col] == ' ':
board[row][col] = 'o'
a = False
else: print('Sorry, try again')
return board
def empty_spaces(board):
empty_spaces = []
ind = 0
for row in board:
ind1 = 0
for space in row:
if space == ' ':
empty_spaces.append((ind, ind1))
ind1 += 1
ind += 1
return empty_spaces
def comp_choose_space(board):
choice = random.choice(empty_spaces(board))
board[choice[0]][choice[1]] = 'x'
return board
def check_win(board,player):
rows = board
columns = construct_cols(board)
for row in board:
# if player fills row win = True
a = ind = 0
for space in row:
if rows[board.index(row)][ind] != player: break
else: a += 1
ind += 1
if a == 3:
return True
for col in columns:
a = ind = 0
for space in col:
if rows[columns.index(col)][ind] != player:
break
else:
a += 1
ind += 1
if a == 3:
return True
if rows[0][0] == player and rows[1][1] == player and rows[2][2] == player \
or rows[0][2] == player and rows[1][1] == player and rows[2][0] == player:
return True
return False
def construct_cols(board):
cols = [['','',''],['','',''],['','','']]
for row in range(len(board)):
for col in range(row):
cols[col][row] = board[row][col] # sounds like this should work
return cols
def print_board(board):
for row in board:
print('| {} {} {} |'.format(row[0],row[1],row[2]))
def main():
turns = 0
board = [[' ',' ',' '],[' ',' ',' '],[' ',' ',' ']]
print_board(board)
win = False
while win == False and turns < 9:
turns += 1
board = choose_space(board)
if check_win(board,'o'): win,winner = True,'won'
board = comp_choose_space(board)
if check_win(board,'x'): win,winner = True,'lost'
print_board(board)
if turns == 9: print('You drew!')
else:
print('{}, you {}'.format('Congratulations' if winner == 'won' else 'Sorry',winner))
print(possible_win(board,'o'))
# print(empty_spaces(board))
# print(check_win(board,'o'))
# print_board(board)
# print(comp_choose_space(board))
# main()
# Future project - make the computer smarter than just randomly choosing a space
# ie seeing how close i am to winning
EDIT:
By using copy.deepcopy() I managed to fix this, but I dont understand why this works and copy.copy() and board[:] did not work? Could somebody explain this?
This is what copy.deepcopy is for. It will traverse the structure, creating copies of each mutable object within. Using a slice [:] or shallow copy duplicated only the top level, leaving the list for each row shared.
Basically, if we start out with a list:
l = [a, b, c]
shallow = l[:]
shallow2 = copy(l)
deep = deepcopy(l)
The two shallow copies have operated only on l, not on a, b or c. They both have the value [a, b, c] but are distinct lists. All of them refer to the same a, b and c objects (the only change from their perspective is that there are more references).
The deep copy has gone deeper and copied each element; it is a new list with the shape [deepcopy(a), deepcopy(b), deepcopy(c)], whatever those values turned into.
Related
I don't know why but the code I wrote isn't running. I'm trying to generate a random index and deleting it from the string. It's not giving me an error message so I don't know what's wrong. Here's what I have:
def delete_randomly(string):
i = 0
while i < len(string):
if string[i] == randint(0, 10):
return string.remove(string[i])
This infinite loop will never break depending on the input. Is this what you trying to achieve?
from random import randint
def delete_randomly(string):
print(f'input string = {string}')
ran_int = randint(0, len(string))
print(f'removing index = ({ran_int})')
new_str = ''
for idx, val in enumerate(string):
if idx == ran_int:
continue
new_str+=val
return new_str
print(delete_randomly('abakdkemnaskakac'))
As an addition for #Juan Antonio Martinez Lopez answer's, you could also use the following code:
def delete_randomly(string):
randomIndex = randint(0, len(string) - 1)
return string[:randomIndex] + string[randomIndex + 1:]
You are in an infinite loop. Imagine the string is 'stackoverflow', your code is always comparing string[0] (because i == 0 everytime) with a random number between 0-10. For example
First iteration:
string[0] = 's'
randint(0, 10) = 3
Second iteration:
string[0] = 's'
randint(0, 10) = 7
Infinite iteration
string[0] = 's'
randint(0, 10) = number
Never 's' would be equals to number.
It is also wrong because string class in python has no method named remove.
So if you want remove a valid letter the code is:
def delete_randomly(string):
temp = list(string)
temp[randint(0, len(string) - 1)] = ""
return "".join(temp)
I am having problems with CS50 pset6 DNA. It is getting all the right values and gives correct answers when I use the small.csv file but not when I use the large one. I have been going through it with debug50 for over a week and can't figure out the problem. I assume the problem is somewhere in the loop through the samples to find the STRS but I just don't see what it is doing wrong when walking through it.
If you are unfamiliar with CS50 DNA problemset, the code is supposed to look through a dna sequence (argv[1]) and compare it with a CSV file containing people DNA STRs to figure out which person (if any) it belongs to.
Note; My code fails within the case; (Python dna.py databases/large.csv sequences/5.txt) if this helps.
from sys import argv
from csv import reader
#ensures correct number of arguments
if (len(argv) != 3):
print("usage: python dna.py data sample")
#dict for storage
peps = {}
#storage for strands we look for.
types = []
#opens csv table
with open(argv[1],'r') as file:
data = reader(file)
line = 0
number = 0
for l in data:
if line == 0:
for col in l:
if col[2].islower() and col != 'name':
break
if col == 'name':
continue
else:
types.append(col)
line += 1
else:
row_mark = 0
for col in l:
if row_mark == 0:
peps[col] = []
row_mark += 1
else:
peps[l[0]].append(col)
#convert sample to string
samples = ""
with open(argv[2], 'r') as sample:
for c in sample:
samples = samples + c
#DNA STR GROUPS
dna = { "AGATC" : 0,
"AATG" : 0,
"TATC" : 0,
"TTTTTTCT" : 0,
"TCTAG" : 0,
"GATA" : 0,
"GAAA" : 0,
"TCTG" : 0 }
#go through all the strs in dna
for keys in dna:
#the longest run of sequnace
longest = 0
#the current run of sequances
run = 0
size = len(keys)
#look through sample for longest
i = 0
while i < len(samples):
hold = samples[i:(i + size)]
if hold == keys:
run += 1
#ensure the code does not go outside len of samples
if ((i + size) < len(samples)):
i = i + size
continue
if run > longest:
longest = run
run = 0
i += 1
dna[keys] = longest
#see who it is
positive = True
person = ''
for key in peps:
positive = True
for entry in types:
x = types.index(entry)
test = dna.get(entry)
can = int(peps.get(key)[x])
if (test != can):
positive = False
if positive == True:
person = key
break
if person != '':
print(person)
else:
print("No match")
Problem is in this while loop. Look at this code carefully.
while i < len(samples):
hold = samples[i:(i + size)]
if hold == keys:
run += 1
#ensure the code does not go outside len of samples
if ((i + size) < len(samples)):
i = i + size
continue
if run > longest:
longest = run
run = 0
i += 1
You have a missing logic here. You are supposed to check the longest consecutive DNA sequence. So when you have a repetition of dna sequence back to back, you need to find how many times it is repeated. When it is no longer repeated, only then, you need to check if this is the longest sequence.
Solution
You need to add else statement after if hold==keys: statement. This would be the right fix;
while i < len(samples):
hold = samples[i:(i + size)]
if hold == keys:
run += 1
#ensure the code does not go outside len of samples
if ((i + size) < len(samples)):
i = i + size
continue
else: #only if there is no longer sequence match, check this.
if run > longest:
longest = run
run = 0
else: #if the number of sequence match is still smaller then longest, then make run zero.
run = 0
i += 1
earik87 is absolutely right! Just I like to add, the code is missing an = to work for all the cases especially when you have redundant sequences.
while i < len(samples):
hold = samples[i:(i + size)]
if hold == keys:
run += 1
#ensure the code does not go outside len of samples **( I added =)**
if ((i + size) <= len(samples)):
i = i + size
continue
else: #only if there is no longer sequence match, check this.
if run > longest:
longest = run
run = 0
else: #if the number of sequence match is still smaller then longest, then make run zero.
run = 0
i += 1
So I have code with two functions. The first one prints an empty 20x20 board and the second one prints a word in the middle. Now I'm trying to write a function that checks if an input word will intersect with another word at the same letter (like crossword).
This is the code for the first two functions(it works no changes needed here):
blank = ' '
board = [[' '] * 20 for i in range(20)]
def printboard(board):
columns = '01234567890123456789'
rows = '_' * 20
print(' ' + columns)
print(' ' + rows)
for i in range(20):
s = ''.join(board[i])
print('|' + s +'|' + str(i))
print(' ' + rows)
print(' ' + columns)
def addFirstWord(board, word):
n = len(word)
if n > 20:
return False
row = 10
col = (20 - n) // 2
board[row][col:col+n] = word
return True
addFirstWord(board, 'hippopotamus')
And this is what I've tried so far,but it only checks 1st position with 1st letter etc..
def checkvertical(board, word, row, col):
n = len(word)
if n > 20: #checks if word is larger than board
return False
for i in range (len(word)):
if board[row+i][col] == word[i]:
return True
else:
return False
print(checkvertical(board, 'horse', 10, 15))
printboard(board)
What I want is a function to check if a word that's printed vertically will properly intersect with an existing word on the board when it's printed starting at a specific row and column and going downwards.
This should work:
def checkvertical(board, word, row, col):
intersects = False
n = len(word)
if n > 20: #checks if word is larger than board
return False
for i, c in enumerate(word):
if board[row+i][col] not in [' ', word[i]]:
return False
elif board[row+i][col] == word[i]:
intersects = True
return intersects
Gives:
>>> print(checkvertical(board, 'horse', 7, 14))
False
>>> print(checkvertical(board, 'horse', 7, 15))
True
>>> print(checkvertical(board, 'horse', 10, 4))
True
Basically, we loop over the word using enumerate and check that the place we want to put that piece either holds the same letter or is blank. If we never find a place where that is the case, we return True.
I'm new to Python and programming, and I'm trying to make a tic tac toe game based on specific guidelines.
This is my code:
import random
import time
marker = {'Player 1 ': 'X', 'Player 2 ': 'O', }
board = [' ',' ',' ',' ',' ',' ',' ',' ',' ']
turn = '0'
game_round ='0'
def display_board(board):
print('7 |8 |9')
print(' ' + board[7] + ' | ' + board[8] + ' | ' + board[9])
print(' | |')
print('-----------')
print('4 |5 |6')
print(' ' + board[4] + ' | ' + board[5] + ' | ' + board[6])
print(' | |')
print('-----------')
print('1 |2 |3')
print(' ' + board[1] + ' | ' + board[2] + ' | ' + board[3])
print(' | |')
def choose_first():
if random.randint(0, 1) == 0:
return 'Player 1 '
elif random.randint(0, 1) == 1:
return 'Player 2 '
def display_score(score):
score = 0
if score(board,mark):
score += 1
#Prints final score after each round
def place_marker(board, marker, position):
board[position] = marker
#places marker (X or O) in position
def win_check(board,mark):
win_combs = (
[1, 2, 3], [4, 5, 6], [7, 8, 9], [3, 6, 9], [1, 4, 7], [2, 5, 8],
[1, 5, 9], [3, 5, 7],)
for comb in win_combs:
if (board[comb[0]] == board[comb[1]] == board[comb[2]] == mark):
return True
return False
#returns True if 3 same marks (X or O) are in line(win)
def board_check(board):
if board != [' '] :
return False
else:
return True
#returns False if there are still empty blocks in the board
#or True otherwise.
def player_choice(board, turn):
first = turn
while turn not in '1 2 3 4 5 6 7 8 9'.split():
turn = input(turn +'Insert number 1-9 :')
return int(turn)
#Player (turn) selects a block
#An int is returned [1,9]
#Checks if value is already submitted in the same block
def replay():
print('Do you want to play again? (yes or no)')
return input().lower().startswith('y')
#Asks players to play again
def next_player(turn):
first=turn
if first == 'Player 1 ':
return 'Player 2 '
else:
return 'Player 1 '
def main():
score = {} # dictionary containing players scores
print('Getting ready to start!\nCoin Toss ', end = '')
for t in range(10):
print(".", flush='True', end=' ')
time.sleep(0.2)
print()
# turn variable reffers to the player whos currently playing
turn = choose_first()
print("\n " + turn + ' goes first!!')
# first variable reffers to the player who played first
first = turn
game_round = 1
while True:
theBoard = [' '] * 10
game_on = True
while game_on:
display_board(theBoard)
position = player_choice(theBoard, turn)
place_marker(theBoard, marker[turn], position)
if win_check(theBoard, marker[turn]):
display_board(theBoard)
print(turn+ "Won")
score[turn] = score.get(turn, 0) + 1
game_on = False
elif board_check(theBoard):
display_board(theBoard)
print('Draw')
game_on = False
else:
turn = next_player(turn)
if not replay():
ending = ''
if game_round>1 : ending = 's'
print("After {} round{}".format(game_round, ending))
display_score(score)
break
else :
game_round += 1
#in the next round the other player plays first
turn = next_player(first)
first = turn
main()
Issues:
The def board_check is not working properly and when the board is full the program still accepts submissions.
I want to prevent user from submitting a value in a block that's already occupied by another value within the def player_choice.
I can't get the def display_score to work.
The theBoard board is just too long: your grid is supposed to be 3x3, but it has ten cells...
More precisely, you assign markers to the cells by accessing the cells with their indices, which is comprised between 1 and 9. However, Python's lists are indexed from 0, so the first cell at index 0 is never assigned.
The problem with your board_check function is that it tests if board is equal to [' '], while you want to check if board still contains a ' '. Therefore, your function should be:
def board_check(board):
if ' ' not in board:
return False
else:
return True
But Pythons supports boolean, so this should be:
def board_check(board):
return ' ' not in board
Going back to the theBoard board, now that board_check is alright. You need to change theBoard = [' '] * 10 into theBoard = [' '] * 9. Then, when accessing the cells, you must pass the index minus 1, because the elements will be shifted by one to the left.
The easiest fix, because of dependancies at other places of your code, is to pass theBoard[1:] instead of theBoard to board_check. This means "the sublist of theBoard that goes from 1 to the end".
Additionally, your choose_first function is wrong, and has a chance of returning None, ending in an exception. Your function is defined as follows:
def choose_first():
if random.randint(0, 1) == 0:
return 'Player 1 '
elif random.randint(0, 1) == 1:
return 'Player 2 '
Semantically, your code means:
Toss a coin. If it's head, Player 1 begins. If it's tails, you toss another coin. If that second coin is tails, Player 2 begins.
What if the first randint gives you 1, and the second gives you 0? Nobody begins.
You need to produce a single random number (toss a single coin), and make your decision according to this value:
def choose_first():
value = random.randint(0, 1)
if value == 0:
return 'Player 1 '
else:
return Player 2 '
This answer will be far from complete, but as you are trying to learn it should at least allow you to start thinking about some next steps.
1.
I don't think you need to define "board" as a global list. If you want your functions to accept a board state then passing them "theBoard" as you do in main() should be sufficient.
Also the reason that the program still accepts submissions is that you are not performing any kind of check to see if a space is already occupied.
def place_marker(board, marker, position):
board[position] = marker
#places marker (X or O) in position
Should be something like:
def place_marker(board, marker, position):
if board[position] == ' ':
board[position] = marker
else:
print("That space is already occupied.")
Then you need to think about what you want the program to do when someone tries to put a piece on top of another piece.
If board check is supposed to check if the board is full (and thus the game is over but no one has won) then one way to achieve this is to loop over the spaces checking if they are equal to ' ', if they all are then the board is full. However a quicker way to do this is with:
def board_full(board):
if ' ' not in board:
return True
else:
return False
2.
I think you are referring to what I suggested for your place_marker function?
3.
Display score: Okay, here your mistake is that your function takes only score as an argument but then uses board. Board is globally defined as an empty board (well actually it is full of spaces, this is also unecessary you can just use empty quotes).
This function is also changing the value of the score but really what I think you want to do is change the value of the score when you perform your win_check. If Player 1 wins then add 1 to player 1's score.
Finally display_score doesn't display anything because there is no print function. print(score) is probably what you are after.
I would appreciate if someone helps me understand how to change the Breadth First Search to Depth First Search, or which steps I need to follow.
The algorithm is basically in the next functions:
canPlace
getpositions
loopBoard
CODE:
import sys
import copy
from os import system
#Set the console title
system("title Michael Fiford - Breadth First N-Queen Solver")
class QueenSolver:
#Store for the amount of queens we're placing, or table size
tableSize = 0
#The alphabet, for nice cell referencing on the output
alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
#The queue of possible moves that we will create and loop through
queue = []
#Whether or not the solver can be ran
canRun = False
def setup(self, queenNumber):
#Set the number of queens/table size
self.tableSize = queenNumber
#Can run, so long as there are no errors
self.canRun = True
#Show error if there is no solution, or would take too long
if queenNumber < 4:
print "ERROR: A solution is not available for this few number of queens"
self.canRun = False
elif queenNumber > 13:
print "ERROR: This solution would take too long to calculate, and your computer would probably run out of memory first!"
self.canRun = False
#Create an empty table
def blankTable(self):
table = []
for row in xrange(self.tableSize):
new = []
for col in xrange(self.tableSize):
new.append(0);
table.append(new)
return table
#Place a queen in a table
def placeQueen(self, table, row, col):
#Copy the table, as python is annoying and will change both
t2 = copy.deepcopy(table)
t2[row][col] = 1
return t2
#The main program loop
def loopBoard(self):
#The column we are currently looking at
col = 1
#Loop while the queue isn't empty, and there are still move possibilities to explore
while len(self.queue):
#Create a new empty queue
queue2 = []
#Update status
print col, "Queens Placed"
#Loop the queue, looking for positions from each status
#s is an array containing the current queen positions for this status
for s in self.queue:
#Get what moves are available from this status
availableMoves = self.getPositions(s, col)
#If we are placing the last queen, and there are solutions available, finish
if col == self.tableSize -1 and len(availableMoves):
#Clear queue
self.queue = []
#Get the solution (or one of them, we only care about the first one)
s = availableMoves[0]
break;
#Add the possible moves to the new queue
#This a table containing all queens now placed
if len(availableMoves):
queue2 += availableMoves
#Replace the old queue with the new one
self.queue = queue2
#Increase Queen/col counter
col += 1
self.finish(s, col)
#Get an array of moves that are available, given info about the current table, and the current column
def getPositions(self, table, col):
#Create a row counter, and array to contain our position info
row = 0
possiblePositions = []
#Loop all rows on the board
while row < self.tableSize:
#If we can place in this space
if self.canPlace(table, row, col):
#Add the table with the newly added queen to the list of possible moves
possiblePositions.append(self.placeQueen(table, row, col))
row += 1
return possiblePositions
#Check whether or not we can place a queen in a position, given the table and the row and col of the desired position
#Return True if space is available
def canPlace(self, table, row, col):
# - Direction
# Check left/right
x = 0
#Loop across the table
while x < self.tableSize:
if table[x][col]:
return False
x += 1
# | Direction
#Check up/down
y = 0
#Loop down the table
while y < self.tableSize:
if table[row][y]:
return False
y += 1
# / Direction
#Check up right Diagonal
#We can start in the cell 1 up and 1 right of the cell in question, as we have already checked the actual cell in the above 2 checks
x = row + 1
y = col + 1
#Loop up/right through the table
while x < self.tableSize and y < self.tableSize:
if table[x][y]:
return False
x += 1
y += 1
#Check down left Diagonal
#Again, not starting in the cell specified
x = row - 1
y = col - 1
#Loop down/left through the table
while x >= 0 and y >= 0:
if table[x][y]:
return False
x -= 1
y -= 1
# \ Direction
#Check up left diagonal
#Again, not starting in the cell specified
x = row - 1
y = col + 1
#Loop up left through the table
while x >= 0 and y < self.tableSize:
if table[x][y]:
return False
x -= 1
y += 1
#Check down right diagonal
#Again, not starting in the cell specified
x = row + 1
y = col - 1
#Loop down right through the table
while x < self.tableSize and y >= 0:
if table[x][y]:
return False
x += 1
y -= 1
return True
#Output a table to a user, looking all pretty
def display(self, table):
#Max Number Length, so we can indent our table nicely later
mnl = len(str(len(table)))
#New Line
print ""
#Top of the table, E.g " A B C D"
print " "*mnl, " ",
for x in range(self.tableSize):
print self.alphabet[x],
#New Line
print ""
#Row spacer, E.g " * - - - - *
print " " * mnl, " *",
for x in range(self.tableSize):
print "-",
print "*"
#Row Counter
#Print the actual table, with the Queens as 1's, empty space as 0
#Also prefixed by the row number, E.g " 3 | 0 1 0 0 |
x = 1
for row in table:
#If numbers are shorter than the largest number, give them extra spaces so the rows still line up
extraPadding = mnl - len(str(x))
#Show the number prefix, spaces, and | symbol, E.g " 6 | "
print "", x, " "*int(extraPadding) + "|",
#Show the value of the cell (1 or 0)
for col in row:
print col,
#End of the row
print "|"
#Next Row
x += 1
#Show the same row spacer as at the top of the table, E.g " * - - - - *
print " " * mnl, " *",
for x in range(self.tableSize):
print "-",
print "*"
#We're done! Show output to the user
def finish(self, table, col):
#If we found the right number of queens
if col == self.tableSize:
print ""
print "Total of", self.tableSize, "Queens placed!"
print "Solution:"
self.display(table)
else:
print ""
print "ERROR: Could not place all queens for some unknown reason =["
#Run the script
def run(self):
if not self.canRun:
print "ERROR: Can not run"
else:
print ""
print "Working..."
print ""
self.queue = self.getPositions(self.blankTable(), 0)
self.loopBoard()
#Ask the user how many Queens they want to use
def ask():
while True:
print ""
print "How many Queens would you like use? [8]"
input = raw_input()
#Check if the input given is an integer
if input.isdigit():
return int(input)
#If no input is given, use the standard 8
elif input == "":
return 8;
print "ERROR: Invalid Input"
#Run the program
def run():
#Instantiate the solver
qs = QueenSolver()
#While ask hasn't given a valid input
while(not qs.canRun):
qs.setup(ask())
print ""
#GO!
qs.run()
#Prompt the user if they want to run the program again
def prompt():
#Has valid input been received?
while True:
print ""
print "Would you like to run the script again? Please enter Y/N [N]"
input = raw_input()
#Check if the input given is Y or N
if input == "Y" or input == "y":
return True
#Also accept an empty string in place of N
elif input == "N" or input == "n" or input == "":
return False
print "ERROR: Invalid Input"
if __name__ == "__main__":
print ""
print ""
print " #######################################"
print " ## Breadth First Search Queen Solver ##"
print " ## By: Michael Fiford - COMF3 ##"
print " ## Date: 03/12/2013 ##"
print " #######################################"
#Run the script, and prompt them after if they want to run it again
shouldRun = True
while(shouldRun):
run()
shouldRun = prompt()
The difference between DFS and BFS is in the way you are exploring the nodes of the graph.
In the DFS algorithm, you are first exploring the last node added into the stack (last in first out) whereas in the BFS algorithm, you are exploring it on the basis of first in first out (queue).
The resulting change is the code shoud be quite small: in the BFS algorithm, you could use a list to implement the stack, appending new node at the top of the stack and then exploring them:
l=[]
while len(l)>0:
new_node=l.pop()
l.extend(new_node.get_neighbors())
The change is quite small to switch to the BFS algorithm: you switch from a stack to queue. This is implemented in Python in the collections module as a deque (with an efficient implementation of popleft (getting the first item of the list and remove it) and append (appending an item at the end of the queue):
import collections
l=collections.deque()
while len(l)>0:
new_node=l.popleft()
l.extend(new_node.get_neighbors())
Your code can be rewritten to fit with the previous description:
while len(self.queue):
#Create a new empty queue
#queue2 = []
#Update status
print col, "Queens Placed"
#Loop the queue, looking for positions from each status
#s is an array containing the current queen positions for this status
s=queue.pop()
#Get what moves are available from this status
availableMoves = self.getPositions(s, col)
#If we are placing the last queen, and there are solutions available, finish
if col == self.tableSize -1 and len(availableMoves):
#Clear queue
self.queue = []
#Get the solution (or one of them, we only care about the first one)
s = availableMoves[0]
break;
#Add the possible moves to the new queue
#This a table containing all queens now placed
#if len(availableMoves):
# queue2 += availableMoves
queue.extend(availableMoves)
#Replace the old queue with the new one
#self.queue = queue2
#Increase Queen/col counter
col += 1
Let me know if you need more explanations. Hope this helps.