Generate all possible board positions of tic tac toe - python

This is somewhat similar to this question : Python generate all possible configurations of numbers on a "board" but I'm trying to implement in Python and I want to include generated boards that are just partially complete.
In tic tac toe there are 3^9 (19683) board positions.
Here is my code to generate each board where each element of the board array is a single board :
boards = []
temp_boards = []
for i in range(0 , 19683) :
c = i
temp_boards = []
for ii in range(0 , 9) :
temp_boards.append(c % 3)
c = c // 3
boards.append(temp_boards)
0 corresponds to O
1 corresponds to X
2 corresponds to 'position not yet filled'
Could I have missed any positions ?

If you consider that players take turns and the game stops when someone wins, there will be fewer possible boards than the maximum combinations of X, O and blank cells would suggest. You also cannot count boards filled with all Xs or all Os or any combinations that would have a difference greater than 1 between the number of Xs and Os.
You can obtain that number by recursively simulating moves starting with X and starting with O:
axes = [(0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6)]
def isWin(board):
return any("".join(board[p] for p in axis) in ["XXX","OOO"] for axis in axes)
def validBoards(board="."*9,player=None):
if player == None:
yield board # count the empty board
for b in validBoards(board,player="X"): yield b # X goes 1st
for b in validBoards(board,player="O"): yield b # O goes 1st
return
opponent = "XO"[player=="X"]
for pos,cell in enumerate(board):
if cell != ".": continue
played = board[:pos]+player+board[pos+1:] # simulate move
yield played # return the new state
if isWin(played): continue # stop game upon winning
for nextBoard in validBoards(played,opponent):
yield nextBoard # return boards for subsequent moves
output:
distinctBoards = set(validBoards()) # only look at distinct board states
allStates = len(distinctBoards)
print(allStates) # 8533 counting all intermediate states
winningStates = sum(isWin(b) for b in distinctBoards)
print(winningStates) # 1884 (so 942 for a specific starting player)
filledStates = sum(("." not in b) for b in distinctBoards)
print(filledStates) # 156 states where all cells are filled
finalStates = sum(isWin(b) or ("." not in b) for b in distinctBoards)
print(finalStates) # 1916 end of game states (win or draw)
earlyWins = sum(isWin(b) and ("." in b) for b in distinctBoards)
print(earlyWins) # 1760 wins before filling the board
draws = finalStates - winningStates
print(draws) # 32 ways to end up in a draw
lastWins = filledStates-draws
print(lastWins) # 124 wins on the 9th move (i.e filling the board)
fastWins = sum( isWin(b) and b.count(".") == 4 for b in distinctBoards)
print(fastWins) # 240 fastest wins by 1st player (in 3 moves)
fastCounters = sum( isWin(b) and b.count(".") == 3 for b in distinctBoards)
print(fastCounters) # 296 fastest wins by 2nd player (in 3 moves)
If you need a faster implementation, here is an optimized version of the function that only returns distinct states and leverages this to skip whole branches of the move sequence tree:
def validBoards(board="."*9,player=None,states=None):
if player == None:
result = {board} # count the empty board
result |= validBoards(board,player="X",states=set()) # X goes 1st
result |= validBoards(board,player="O",states=set()) # O goes 1st
return result
opponent = "XO"[player=="X"]
for pos,cell in enumerate(board):
if cell != ".": continue
played = board[:pos]+player+board[pos+1:] # simulate move
if played in states : continue # skip duplicate states
states.add(played) # return the new state
if isWin(played): continue # stop game upon winning
validBoards(played,opponent,states) # add subsequent moves
return states

Related

How do I make a function that replaces Characters in a randomly generated 2D List?

Title. Essentially I want to replace the characters that would be randomly generated in a 2d List I made. Here's an example, I'd like to replace 0 with 9
0 0 0 0
1 1 1 1
2 2 2 2
3 3 3 3
9 9 9 9
1 1 1 1
2 2 2 2
3 3 3 3
But I am not entirley familiar with how I am supposed to do this because I am rather new at programming.
My first attempt was to make a function with a parameter that wiuld Identify and characters that had 0 and then make a seperate funtinon that would return it and replace it with 9, but it wouldn't even start it, and I have no idea where to go from there. Any help would be
appreciated.
code:
import random
SIZE = 4
EMPTY = " "
PERSON = "P"
PET = "T"
POOP = "O"
ERROR = "!"
CLEANED = "."
MAX_RANDOM = 10
def clean(world,endRow,endColumn):
if world == POOP, POOP == CLEAN:
print("Scooping the poop")
# #args(reference to a alist of characters,integer,integer)
# Function will count the number of occurences of the character specified by the user up the specified
# end point (row/column specified by the user).
# #return(character,integer)
def count(world,endRow,endColumn):
print("Counting number of occurances of a character")
number = 0
element = input("Enter character: ")
return(element,number)
# Randomly generates an 'occupant' for a location in the world
# #args(none)
# Randomly generates and returns a character according to the specified probabilities.
# *50% probability empty space
# *20% probability of a person
# *10% probability of a pet
# *20% probability of fecal matter
# #return(character)
def createElement():
tempNum = random.randrange(MAX_RANDOM)+1
# 50% chance empty
if ((tempNum >= 1) and (tempNum <= 5)):
tempElement = EMPTY
# 20% of a person
elif ((tempNum >= 6) and (tempNum <= 7)):
tempElement = PERSON
# 10% chance of pet
elif (tempNum == 8):
tempElement = PET
# 20% chance of poop in that location (lots in this world)
elif ((tempNum >= 9) and (tempNum <= 10)):
tempElement = POOP
# In case there's a bug in the random number generator
else:
tempElement = ERROR
return(tempElement)
# Creates the SIZExSIZE world. Randomly populates it with the
# return values from function createElement
# #args(none)
# Randomly populates the 2D list which is returned to the caller.
# #return(reference to a list of characters)
def createWorld():
world = [] # Create a variable that refers to a 1D list.
r = 0
# Outer 'r' loop traverses the rows.
# Each iteration of the outer loop creates a new 1D list.
while (r < SIZE):
tempRow = []
world.append(tempRow) # Create new empty row
c = 0
# The inner 'c' loop traverses the columns of the newly
# created 1D list creating and initializing each element
# to the value returned by createElement()
while (c < SIZE):
element = createElement()
tempRow.append(element)
c = c + 1
r = r + 1
return(world)
# Shows the elements of the world. All the elements in a row will
# appear on the same line.
# #args(reference to a list of characters)
# Displays the 2D list with each row on a separate line.
# #return(nothing)
def display(world):
print("OUR WORLD")
print("========")
r = 0
while (r < SIZE): # Each iteration accesses a single row
c = 0
while (c < SIZE): # Each iteration accesses an element in a row
print(world[r][c], end="")
c = c + 1
print() # Done displaying row, move output to the next line
r = r + 1
# #args(none)
# #return(integer,integer)
def getEndPoint():
#Declaring local variables
endRow = -1
endColumn = -1
return(endRow,endColumn)
# Starting execution point for the program.
def start():
world = createWorld()
display(world)
endRow,endColumn = getEndPoint()
element,number = count(world,endRow,endColumn)
print("# occurances of %s=%d" %(element,number))
clean(world,endRow,endColumn)
display(world)
start()

What is the best way to generate random ships in an array in Python?

Recently, I've been working on a battleship game for my CS2 class. The focus of this project is to create a board game using arrays, and I decided to create a battleship. I have most of the code, but I cannot figure out how to get ships to get randomly generated on a 10x10 array without the ships being...
A. The wrong length
B. Looping around the array
Below is the function I currently have.
def createShips(board):
shipLen = [5,4,3,3,2]
shipAvalible = 5
directionposibilities = ["vertical", "horizontal"]
j = 0
for i in range(shipAvalible):
boatMade = False
#REGULAR VAR STATMENTS
direction = random.choice(directionposibilities)
col = randint(0,9)
row = randint(0,9)
while boatMade == False:
if direction == "vertical":
buildCount = 0
if col + int(shipLen[i]) <= 11:
colission = False
for i in range(0, int(shipLen[i])):
buildCount += 1
if board[int(row-i)][int(col)-1] == "X":
if colission:
pass
else:
colission = True
if colission:
col = randint(0,9)
row = randint(0,9)
else:
for j in range(buildCount):
board[int(row-j)][int(col)-1] = "X"
boatMade = True
else:
col = randint(0,9)
row = randint(0,9)
if direction == "horizontal":
if col + int(shipLen[i]) <= 10:
colission = False
buildCount = 0
for i in range(0, int(shipLen[i])):
buildCount += 1
if board[int(row)][int(col)+i-1] == "X":
if colission:
pass
else:
colission = True
if colission:
col = randint(0,9)
row = randint(0,9)
else:
for j in range(buildCount):
board[int(row)][int(col)+j-1] = "X"
boatMade = True
else:
col = randint(0,9)
row = randint(0,9)
shipAvalible = shipAvalible - 1
return(board)
board = [["■"] * 10 for x in range(10)]
print(createShips(board))
If you have any idea why this may not work please let me know!
P.S. I am using another function that prints the array nicely, if you would like that for convenience, it is seen below:
def showBoard(board):
print(" A B C D E F G H I J")
print(" ------------------------------")
rownumb = 1
for r in board:
if rownumb == 10:
space = ""
else:
space = " "
print("%d|%s|" % (rownumb, space + "|".join(r)))
rownumb += 1
Edit: #Eumel was a bit faster and said it better here
First of all, you have a inner and outer loop with the variable i, which might not actually interfere but it makes it harder to read the code. Consider renaming one of the variables.
When you create a vertical ship, you check the col rather than the row for index error, and does so against a value of 11 instead of your board size 10.
In the vertical case you build the ship "backwards" from the selected position, even though you checked that your board could fit the ship in the positive direction (And you place it in a column to the left). These negative values makes it such that your ships can wrap around.
In the horizontal case you are indexing a bit strange again where board[int(row)][int(col)+i-1] this gives that when i=0 you place your ship an index further to the left than intended, again causing the ship to wrap when col=0.
Further more, you could remove a few redundant if statements and duplicate lines of code, by moving:
direction = choice(directionposibilities)
col = randint(0, 9)
row = randint(0, 9)
Inside the while loop.
Ok lets go over this:
length check
if col + int(shipLen[i]) <= 9: since arrays start at 0 in python the maximum index for a 10x10 board is 9, therefore you need to chek against 9 instead of 11
loop variables
for k in range(0, int(shipLen[i])): using the same variable name for the outer and inner loop (while working in this specific case) is really bad form
collision check
if board[row+k][col] == "X": you want to build the ships "forwards" so you use row+k, you can also forego int conversions when you only use integers to begin with
collsion check 2
if colission: pass else: colission = True This whole block can be shortened to collision = True break since you dont need to keep checking for multiple collisions
buildcount
for j in range(buildCount): unless you get a collision (then you wouldnt be in this branch) buildCount is always the same as shipLen[i] so it can be completly removed from your code
boat building
board[row+j][col] = "X": same as before we build forwards
honorable mentions
shipAvailable = len(shipLen) you could also remove this part completly and iterate over your ships directly in your out for loop
Instead of radoomising your direction row and col on every break condition you could randomize it once at the start of your while loop
j = 0 unlike C you dont have to define your variables before using them in a loop, this statement does nothing

TicTacToe code to check the state of the board not working

I made an algorithm to check whether which player won the game or is it a tie or the game is still not finished yet but it doesn't work well with some testcases.
I don't know what's wrong with my code. but it doesn't work so I think somethings off with my algorithm or the code itself.
so my algorithm basically is:
separate the moves of player1 and player 2
check if the moves of player 1 is in the winning moves if it is return 'player1'
check if the moves of player 2 is in the winning moves if it is return 'player2'
if there is no winner check if the number of moves is equal to 9. If it is return 'tie'
else if the number of moves is less than 9 return 'uncertain'
here is the code:
def match(a1,a2):
a1.sort()
for solution in a2:
if a1 == solution:
return True
return False
def ticTacToeWinner(moves, n):
# --- Variables ---
p1 = []
p2 = []
winning_moves = [
[[0,0],[0,1],[0,2]],
[[1,0],[1,1],[1,2]],
[[2,0],[2,1],[2,2]],
[[0,0],[1,0],[2,0]],
[[0,1],[1,1],[2,1]],
[[1,0],[2,1],[3,1]],
[[0,0],[1,1],[2,2]],
[[0,2],[1,1],[2,0]],
]
winner = None
# --- Loops ---
for i in range(1,n+1): # separate the moves for each player
if i % 2 == 0:
p2.append(moves[i-1])
else:
p1.append(moves[i-1])
# --- Conditionals ---
if len(p1) >= 3: # check if the player1 has more than 3 moves
if match(p1,winning_moves) == True: # check if the moves of player1 is in the winning moves
winner = 'player1' # winner is player 1
return winner
if len(p2) >= 3: # check if the player2 has more than 3 moves
if match(p2,winning_moves) == True: # check if the moves of player 2 is in the winning moves
winner = 'player2' # winner is player 2
return winner
if not winner: # there are no winners
if n == 9: # board is full so it's draw
return 'draw'
elif n < 9: # board is not full
return 'uncertain'
This code is my solution for this question:
https://www.codingninjas.com/codestudio/problems/tic-tac-toe-winner_1214545?topList=top-apple-coding-interview-questions
The code only works for 2 testcases there and incorrect for everything else
Example input and output:
ticTacToeWinner([[0,0],[2,2],[0,1],[1,1],[0,2]],5) -> 'player1'
since the moves of player1 is: [[0,0],[0,1],[0,2]] which makes a triple X at the top of the board
The match function at the top is the one that checks whether the move of a player is in the winning moves table.
here is one of the testcases that don't work with the code:
5
9
2 0
0 1
1 1
1 0
1 2
0 0
2 1
2 2
0 2
4
1 2
1 0
2 0
1 1
1
2 0
9
2 0
1 2
0 1
0 0
0 2
2 1
2 2
1 1
1 0
3
0 2
2 0
0 0
These are some issues:
winning_moves has a completely wrong row, which also has a 3 -- which is an invalid index.
Change:
[[1,0],[2,1],[3,1]],
to:
[[0,2],[1,2],[2,2]],
When len(p1) is greater than 3, you'll never find a win, because winning_moves does not have entries that have this size. Yet it is obvious that there could be a win
Even when len(p1) is equal to 3, you may still miss a win, because the order of the moves may not be like they are in winning_moves.
Not a problem, but elif n < 9 can just be else, as there are no other possible values for n.
You should really take a different approach: play the moves on a 3x3 board (a 2D list), and then use winning_moves to see what is at those winning positions. If it turns out they are all 3 a move of player1, you know that player1 won the game.
So here is what your function should look like:
def ticTacToeWinner(moves, n):
winning_moves = [
[[0,0],[0,1],[0,2]],
[[1,0],[1,1],[1,2]],
[[2,0],[2,1],[2,2]],
[[0,0],[1,0],[2,0]],
[[0,1],[1,1],[2,1]],
[[0,2],[1,2],[2,2]], # was wrong
[[0,0],[1,1],[2,2]],
[[0,2],[1,1],[2,0]],
]
# create a board:
board = [
[".", ".", "."],
[".", ".", "."],
[".", ".", "."],
]
# play the moves on the board:
for i, (row, col) in enumerate(moves):
board[row][col] = "12"[i % 2] # store the player's number in this cell
# check who has played on the winning patterns
for winning_line in winning_moves:
played = [board[row][col] for row, col in winning_line]
if played[0] != "." and played[0] == played[1] == played[2]:
return "player" + played[0]
if n == 9: # board is full so it's draw
return 'draw'
else: # board is not full
return 'uncertain'
I'm pretty sure that one of your problems is that you don't handle the case of more than 3 moves...
I'd advise to change the type of a single "move" to a tuple, which is hashable. then, you'd be able to use this elegant match code:
def match(player_moves_list: List[tuple], winning_moves:List[List[tuple]]):
for solution in winning_moves:
if set(solution).issubset(player_moves):
return True
return False
to change the list elements to tuple elements, simply turn brackets to parenthesis:
winning_moves = [
[(0,0),(0,1),(0,2)],
...,
[(0,2),(1,1),(2,0)],
]

Determine three in a row regardless of the board size

I have programmed a program of tic tac toe in python where I use the following code to determine if a row / column / diagonal consists of only ones or twos to determine if any of player one or two have won (I use ones and twos instead of x and o). The problem is that I want the winner to be chosen when there are three in a row regardless of the size of the board and with this code this only works for a board of size 3x3.
def check_row(board, player):
'''
Checks row for a win
'''
return any(all(row == player)
for row in board)
def check_column(board, player):
'''
Checks column for a win
'''
# We use transpose() to be able to check the column by using the definition
# for check_row
return check_row(board.transpose(), player)
def check_diagonal(board, player):
'''
Checks diagonal for a win
'''
# We use np.diag() and np.fliplr() to be able to check the diagonals
# of the game board
return any(all(np.diag(board_rotation) == player)
for board_rotation in [board, np.fliplr(board)])
For example, if I choose a board with size 5x5, the winner will be, with this code, when it is five in a row and not three in a row. I use np.zeros ((board_size, board_size), dtype = int) to create a game board and I have considered whether you can use something like column_1 == column_2 == column_3 to determine if there are three in a row:
if board[1][1] != 0:
if board[1][1] == board[0][0] == board[2][2]:
return board[1][1]
elif board[1][1] == board[0][2] == board[2][0]:
return board[1][1]
But also for this to work in a 5x5 game board I have to write down all possible ways to get three in a row in a 5x5 board which will give an extremely long code. Any tips to improve this?
This is my fully code now:
''' 403-0047-MPO '''
import numpy as np
import random
import matplotlib.pyplot as plt
# scenario = What scenario you would like to play, scenario one or scenario two
# game_size = The size of game board, 3x3, 5x5 or 7x7
# games = The number of game rounds you would like to play
# board = The game board
def create_board(board_size):
'''
Creating an empty board
'''
return np.zeros((board_size,board_size), dtype=int)
def available_spaces(board):
'''
Looking for available spaces on the game board
This is used in both scenario one and two
'''
lst = []
for i in range(len(board)):
for j in range(len(board)):
if board[i][j] == 0:
lst.append((i, j))
return(lst)
def make_random_move(board, player):
'''
Randomly places the player's marker on the game board
This is used in both scenario one and two
'''
spaces = available_spaces(board)
space = random.choice(spaces)
board[space] = player
return board
def available_space_middle(board, board_size):
'''
Checks that the center position is available for all game boards
This is only used in scenario two
'''
# Using if-statements to find the middle for all board_size ∈ {3, 5, 7}
# and check that they are empty, this also avoids placing the marker there repeatedly.
lst = []
for i in range(len(board)):
for j in range(len(board)):
if board_size == 3:
if board[i][j] == 0:
lst.append((1, 1))
if board_size == 5:
if board[i][j] == 0:
lst.append((2, 2))
if board_size == 7:
if board[i][j] == 0:
lst.append((3, 3))
return(lst)
def make_move_middle(board, player, board_size):
'''
Places the first marker for player one in the center of the game board.
This is only used in scenario two
'''
# Using player = 1 we define that the first move in scenario two should be
# made by player one using the marker 1
player = 1
selection = available_space_middle(board, board_size)
current_loc = random.choice(selection)
board[current_loc] = player
return board
def check_row(board, player):
'''
Checks row for a win
'''
return any(all(row == player)
for row in board)
def check_column(board, player):
'''
Checks column for a win
'''
# We use transpose() to be able to check the column by using the definition
# for check_row
return check_row(board.transpose(), player)
def check_diagonal(board, player):
'''
Checks diagonal for a win
'''
# We use np.diag() and np.fliplr() to be able to check the diagonals
# of the game board
return any(all(np.diag(board_rotation) == player)
for board_rotation in [board, np.fliplr(board)])
def evaluate(board):
'''
Evaluates the game board for a winner
'''
# Here we bring out the winner and define 1 for when player one wins,
# 2 for when player two wins and -1 for ties.
winner = 0
for player in [1, 2]:
if (check_row(board, player) or
check_column(board,player) or
check_diagonal(board,player)):
winner = player
if np.all(board != 0) and winner == 0:
winner = -1
return winner
def play_game(scenario, board_size):
'''
Defines the game for scenario one and scenario two
'''
# By using if-statements and a while-loop we define how the game should
# go in scenario one and scenario two respectively.
# By using break, we also ensure that the loop (game) ends if a winner has been found.
board, winner, counter = create_board(board_size), 0, 1
if scenario == 1:
while winner == 0:
for player in [1, 2]:
board = make_random_move(board, player)
# Remove the hashtags below to check the game board step by step
print("Board after " + str(counter) + " move")
print(board)
counter += 1
winner = evaluate(board)
if winner != 0:
break
return winner
if scenario == 2:
while winner == 0:
for player in [2, 1]:
board = make_move_middle(board, player, board_size)
board = make_random_move(board, player)
# Remove the hashtags below to check the game board step by step
print("Board after " + str(counter) + " move")
print(board)
counter += 1
winner = evaluate(board)
if winner != 0:
break
return winner
def save_stats(games, scenario, board_size):
'''
Saves data from all game rounds
'''
# By using the previously defined 1,2 and -1 we add one point for each win
# for player1wins, player2wins and ties.
player1wins=0
player2wins=0
ties=0
for game in range(games):
result=play_game(scenario, board_size)
if result==-1: ties+=1
elif result==1: player1wins+=1
else: player2wins+=1
return [player1wins, player2wins, ties] # for returning
def print_stats(games, scenario, board_size):
'''
Presents data from all game rounds
'''
player1wins, player2wins, ties = save_stats(games, scenario, board_size)
print('Player 1 wins:',player1wins)
print('Player 2 wins:',player2wins)
print('Tie:',ties)
# Data
height = [player1wins, player2wins, ties]
bars = ('Player 1', 'Player 2', 'Tie')
y_pos = np.arange(len(bars))
# Create bars and choose color
plt.bar(y_pos, height, color = (0.5,0.1,0.5,0.6))
# Limits for the Y axis
plt.ylim(0,games)
# Create names
plt.xticks(y_pos, bars)
# Saves a pdf with data
plt.savefig('utfall.pdf') # Saves the data as 'utfall.pdf'
plt.close()
def main():
'''
This is the main body of the program
'''
# Using try: and except: to raise ValueError and
# while-loops to handle incorrect input. The question will be asked again
# if the input value is wrong and continue via break if it is correct.
try:
while True:
games = int(input("How many games do you want to simulate? "))
if games <1:
print('The number of game rounds should be grater than zero, try again')
else:
break
while True:
board_size = int(input("How big playing surface (3/5/7)? "))
if not (board_size == 3 or board_size == 5 or board_size == 7):
print('Board size does not exist, try again')
else:
break
while True:
scenario = int(input('What scenario (1/2)? '))
if not (scenario == 1 or scenario == 2):
print('Scenario does not exist, try again')
else:
break
print_stats(games, scenario, board_size)
except ValueError:
print('All questions must be answered correctly for the game to start, try again')
main()
I will post a idea using numpy.split
You split your board in chunks of 3, but starting in different positions: 0, 1 and 2.
Explanation: Consider [a,b,c,d,f,g]
Starting from 0 -> [a,b,c], [d,f,g]
Starting from 1 -> [b,c,d]
Starting from 2 -> [c,d,f]
so, all possibilities are there
You check if the elements are equal 1 or 2 and sum over the boolean mask. If the sum is 3, then there is a chunk with 3 equal elements.
Example code to search from winners on the rows:
import numpy as np
#random array just for test
board = np.array([[1,-1,-1,-1,1,0],
[1,1,0,1,1,0],
[1,1,0,1,1,0],
[1,1,0,1,1,0],
[1,1,0,1,1,0]])
winner = None
#iterate on i to start from position 0, 1 and 2
for i in range(3):
#We want the lengh of the array a multiple of 3, so we must correct were it ends:
rest = -(board[:,i:].shape[1]%3)
if rest == 0:
#0 would return a empty list, so if it is the case, we will change to None
rest = None
#Now, we calculate how manny divisions we need to get chunks of 3 (on the rows)
n = (board[:,i:].shape[1])//3
#Now divide the board in chunks
chunks = np.split(board[:,i:rest],n,axis = 1)
for matrix in chunks:
#sum over all rows of 3 elements
sumation = np.sum(matrix == 1,axis = 1)
if 3 in sumation:
winner = 1
sumation = np.sum(matrix == 2,axis = 1)
if 3 in sumation:
winner = 2
Well, maybe a little confusing, but i believe it will work, or at least give you some idea

Depth First Search Python Game Solver

I have a basic maze game in python "*" are walls, "W" water buckets which allow you to travel through fire "F" (if you have none you lose), "A" is the player and " " is air and "X" and "Y" are start and endpoints. There are also numbers from 1 - 9 which have 1 other matching number so the player can teleport. Example map:
*X**********
* 1 W F*
* FFFF 1 *
**********Y*
So I have a graph (dictionary) where I go through each character in the maze and find their neighbours like {"0,0": [None, "0,1", None, "0,1"]}
{"node": "LeftNeighbour", "RightNeighbour", "NeighbourAbove", "NeighbourBelow"}
and I am using coordinates "x,y" to denote neighbours.
Then the DFS code is ...
visited = []
def DFS_recursive(graph, node, nodeToFind):
global visited
for neighbour in graph[node]:
if neighbour == nodeToFind:
visited.append(neighbour)
break
if neighbour not in visited and neighbour != None:
# get x and y by breaking up the string
x = ""
y = ""
yFlag = False
for char in neighbour:
if char == ",":
yFlag = True
elif yFlag == False:
x += str(char)
else:
y += str(char)
x, y = int(x), int(y)
if grid[y][x].display == "*": # if the neighbour's display property is a wall, append the neighbour but don't call the function again ...
visited.append(neighbour)
else:
visited.append(neighbour)
DFS_recursive(graph, neighbour, nodeToFind)
So this works until I add teleport pad code.
if neighbour == (number from 1 - 9):
find the coordinates of the other teleport pad and make the coordinates the new node
DFS_recursive(graph, newNode, nodeToFind)
And yes I haven't added in the "nodeToFind" bit yet, couldn't quite get that to work so I added a separate function to deal with that. Probably should remove the parameter but anyway that's not the point.
So 1. Not sure if this is the right way to go about it (am new to programming)
and 2. No idea how to handle the teleport pads.
Thanks in advance!

Categories

Resources