Why am I getting the variable not defined error? - python

The following is my code
n = int(input("please enter a value: "))
board = []
def make_board(n):
global board
max = n * n #the number of tiles in the board
count = 1 #a counter to change the value assigned to each tile
for i in range(n):
board.append([]) #appends a list inside the list of board. Essentially creates a row which is of type list.
for j in range(n):
num = max - count
if num == 0: #the 0 tile will display like a blank space
tile = ' '
elif num < 10: #adds a space to tile values less than 10 for formatting.
tile = ' ' + str(num)
else:
tile = str(num)
board[i].append(tile) #appends a tile value to each row, n number of times.
count += 1
if n%2 == 0:
tempvara = board[n-1][n-2]
tempvarb = board[n-1][n-3]
board[n-1][n-2]=tempvarb
board[n-1][n-3]=tempvara
#TODO
for row in board:
print(' '.join(row))
def find_blank(board):
global counterUNO
global counterDOS
global counterTRES
counterTRES = 0
#TODO
for i in range(n):
tempvari = board[i]
if ' ' in tempvari:
counterUNO = i
for z in board[counterUNO]:
counterTRES = counterTRES + 1
if ' ' in z:
counterDOS = counterTRES-1
break
tupleone = (counterUNO,counterDOS)
return(tupleone)
def find_tile(f):
counterfour = 0
tiles = str(input("tile BUBBER"))
if int(tiles)<10:
tiles = " "+tiles
counterfive = 0
countersixe = 0
countersixe = 0
for i in range(n):
chopstick = board[i]
if tiles in chopstick:
counterfour = i
for z in board[counterfour]:
countersixe = countersixe + 1
if tiles in z:
counterfive = countersixe-1
break
tupleDOS = (counterfour,counterfive)
return(tupleDOS)
def find_next_to_blank(board):
#print("here is the shit")
#print(find_tile(board))
vara = find_tile(board) #sets tile numb tuple to vara
varb = find_blank(board) #yeah
varc = int(tiles)
varaa = int(tiles[0])
varab = int(tiles[1])
varba = board[varaa+1][varab]
varbb = board[varaa][varab+1]
varbc = board[varaa-1][varab]
varbd = board[varaa][varab-1]
varbe = board[varaa+1][varab+1]
varbf = board[varaa-1][varab-1]
make_board(n)
#find_blank(board)
#find_tile(board)
find_next_to_blank(board)
Problem:
Right now I am trying to make a python Tile game where I can shift the numbers. the make board function obviously creates a board, i did it so that there are three lists in a big list and in the three list there are elements
and the find blank function identifies the coordinate of the non existing section of the board
and the find tile function is the function that the user inputs a value and the code identifies what is the coordinate of the tile that we want
So currently I am getting an error because when i am running the find next to blank function (the function is supposed to identify whether or not there is a blank spot next to the value which the user wants to input) i get the following error
Traceback (most recent call last):
File "python", line 149, in <module>
File "python", line 122, in find_next_to_blank
NameError: name 'tiles' is not defined
and i tried making "tiles" variable into a global one but it didn't work at all

The variable tiles is not defined in find_next_to_blank(board). I'd be remiss if I don't say this: consider restructuring your program to avoid using global variables.
Now that's out of the way, if you make tiles global, it ought to work.

Related

Placing a player on a Board and Moving them in Python

Im currently trying to add a player to a board in python to be able to command the player but I cant seem to figure it out.
def GenPlayer(level):
player = {}
player['name'] = GenName()
player['history'] = GenHistory() #history
player['attack'] = DieRoller(3,6) + DieRoller(level,4)
player['defense'] = DieRoller(3,6) + DieRoller(level,4)
player['health'] = DieRoller(5,6) + DieRoller(level,4)
player['row'] = 0
player['col'] = 0
character =(player['name']) + ("Health: "+str(player['health'])) + (" Defense: "+str(player['defense'])) + (" Attack: "+str(player['attack']))
return character
def CreateBoard():
board = []
while True:
x = int(input("Number of Rows: "))
y = x
break
for row in range(0,x):
board.append(["()"]*y)
return board
def ShowBoard(board):
for row in board:
print(" ".join(row))
def PlacePlayer(board,player):
row = DieRoller(1,6)
col = DieRoller(1,6)
board[row][col] = 'player'
return board,player
print(PlacePlayer(ShowBoard(CreateBoard()),GenPlayer(1)))
I keep getting this error when trying this code:
Exception has occurred: TypeError
'NoneType' object is not subscriptable
If you want to place the player object at the selected position, remove the quote marks:
board[row][col] = player
Update:
A player object is a dictionary, so you need to place the player['name'] on the board to be able to print it in the ShowBoard() function you have, as the function uses .join() , which is a string method. I made a slight change to PlacePlayer(), and simplified the code to make it a bit easier to understand what's happening:
def PlacePlayer(board,player):
row = 5
col = 4
board[row][col] = player['name']
return board
newboard= CreateBoard()
characterDescripiton , playerobject = GenPlayer(1)
boardafterPlacePlayer = PlacePlayer(newboard,playerobject)
ShowBoard(boardafterPlacePlayer)

How do I fix this list being out of range?

I'm making a game in which the player can move on a 8x8 grid, but I'm getting an error in which the values are out of range.
Here is my code:
def player_movement():
grid0 = []
grid1 = []
i = 0
n = 0
while i < 8: #this makes the grid
grid0.append("0")
i += 1
while n < 8:
grid1.append(grid0.copy())
n += 1
grid1[0][0] = "X" # this places the player on the top left of the grid
for l in grid1:
print(l)
while True:
player_movex = int(input("Move right how many?"))# instructions to move the player
player_movey = int(input("Move down how many??"))
for y, row in enumerate(grid1): #this finds the player on the grid
for x, i in enumerate(row):
if i == "X":
grid1[y][x], grid1[y + player_movey][x + player_movex] = grid1[y + player_movey][x + player_movex], grid1[y][x]
for j in grid1: #prints out the grid in the 8x8 format
print(j)
and I am entering values that are within the lists' range i.e. 0-7.
This is the error that appears on my screen:
Traceback (most recent call last):
File "D:\Python\Treasure Hunt game.py", line 83, in <module>
player_movement()
File "D:\Python\Treasure Hunt game.py", line 78, in player_movement
grid1[y][x], grid1[y + player_movey][x + player_movex] = grid1[y + player_movey][x + player_movex], grid1[y][x]
IndexError: list index out of range
The reason being the loops are executed even after the movement is made.
def player_movement():
grid0 = []
grid1 = []
i = 0
n = 0
while i < 8: #this makes the grid
grid0.append("0")
i += 1
while n < 8:
grid1.append(grid0.copy())
n += 1
grid1[0][0] = "X" # this places the player on the top left of the grid
for l in grid1:
print(l)
while True:
player_movex = int(input("Move right how many?"))# instructions to move the player
player_movey = int(input("Move down how many??"))
done = False
for y, row in enumerate(grid1): #this finds the player on the grid
for x, i in enumerate(row):
if i == "X":
print(y, x)
grid1[y][x], grid1[y + player_movey][x + player_movex] = "0", "X"
done = True
if done == True:
break
if done == True:
break
for j in grid1: #prints out the grid in the 8x8 format
print(j)
player_movement();
I would rather code as follows:
def player_movement():
n = 8
grid = [['0'] * n for _ in range(n)]
m = 'x'
grid[0][0] = m # this places the player on the top left of the grid
for i in grid:
print(i)
while True:
# instructions to move the player
player_movex = int(input("Move right how many? "))
player_movey = int(input("Move down how many?? "))
move(grid, m, n, player_movey, player_movex)
for j in grid: # prints out the grid in the 8x8 format
print(j)
def move(grid, m, n, move_y, move_x):
for y, row in enumerate(grid): # this finds the player on the grid
for x, i in enumerate(row):
if i == m:
a, b = y + move_y, x + move_x
if a >= n:
print(f'Sorry, move {move_y} down will out of range!\n')
return
if b >= n:
print(f'Sorry, move {move_x} right will out of range!\n')
return
grid[y][x], grid[a][b] = grid[a][b], grid[y][x]
return
player_movement()

How to move my character on my generated board?

A few days ago a started making my simple board game. First of all, I generate a board for the game. It looks like this:
the gameboard generated for 13x13
Secondly, I place my character on the board, which is 'A':
The player placed
I made a dice for it which generates numbers from 1 to 6.
My goal right now is to get the 'A' character moving around by the dice on the '*' symbols, until it gets at the top left corner:
I need to get here by the dice
So here is my code that I tried:
import math
import random
import os
board= []
def generator(boardsize):
for row in range(boardsize+1):
brow = []
for column in range(boardsize+1):
if row == column == 0:
brow.append(' ')
elif row==0:
brow.append(str(column-1)[-1])
elif column==0:
brow.append(str(row-1)[-1])
elif ((math.ceil(boardsize/2)-1 )<= column) and(column <= (math.ceil(boardsize/2)+1)) or ((math.ceil(boardsize/2)-1 )<= row) and(row <= (math.ceil(boardsize/2)+1)):
if row == 1 or column == 1 or row == boardsize or column == boardsize:
brow.append('*')
else:
if row == (math.ceil(boardsize/2)) and column == (math.ceil(boardsize/2)):
brow.append('X')
elif row == (math.ceil(boardsize/2)) or column == (math.ceil(boardsize/2)):
brow.append('D')
else:
brow.append('*')
else:
brow.append(' ')
board.append(brow)
return board
def print_table(x):
os.system('cls')
for x in board:
print(' '.join(x))
number_from_dice= []
def dice():
min = 1
max = 6
x = random.randint(min, max)
number_from_dice[:]= [x]
return number_from_dice
def player1(x):
generator(x)
prev_char_y = 1
prev_char_x = math.ceil(x/2)+1
char_y= 1
char_x= math.ceil(x/2)+1
board[char_y][char_x] = "A"
print_table(x)
dice()
f = number_from_dice[0]
for i in range(f):
if(char_y<x):
if (board[char_y+1][char_x]) == '*':
char_y= char_y +1
board[char_y][char_x] = "A"
board[prev_char_y][prev_char_x] = '*'
prev_char_x = char_x
prev_char_y = char_y
print_table(x)
else:
if(char_x!=x):
char_x2 = char_x
if (board[char_y][char_x+1]=='*'):
char_x = char_x +1
board[char_y][char_x] = "A"
board[prev_char_y][prev_char_x] = '*'
prev_char_x = char_x
prev_char_y = char_y
print_table(x)
else:
if (board[char_y+1][char_x]) == '*':
char_y= char_y +1
board[char_y][char_x] = "A"
board[prev_char_y][prev_char_x] = '*'
prev_char_x = char_x
prev_char_y = char_y
print_table(x)
else:
if (board[char_y][char_x2-1]) == '*':
char_x2 = char_x2 -1
board[char_y][char_x2] = "A"
board[prev_char_y][prev_char_x] = '*'
prev_char_x = char_x2
prev_char_y = char_y
print_table(x)
else:
if (board[char_y+1][char_x2]) == '*':
char_y = char_y +1
board[char_y][char_x2] = "A"
board[prev_char_y][prev_char_x] = '*'
prev_char_x = char_x2
prev_char_y = char_y
print_table(x)
print('Number from dice: ', end='')
print(f)
player1(13)
Does the technic I used have potential? Or is it too complicated? How would you do it?
Just in a generic sense you've made it overly complicated.
Consider this - the board, as far as movement is concerned, is just a set of ordered spaces.
But right now you have information about how the board is created as part of the player code.
Best to separate this, and you will find that things get simpler.
Instead, have the player simply track it's progress, in other words, what numbered space is it on.
Then you can generate the board and, knowing the space numbers, you can see if it matches the player location.
And then take it one step further (and simpler still) and just draw the board on a 2D array, and then output that, instead of trying to figure out the board as you go line-by-line.

Python variable not seen by nested function

I am building a program that will solve sudoku puzzles. Here is the code:
def set_table(boxes_v, boxes_h, tiles_v, tiles_h):
""" boxes_v = boxes on vertical side of the whole table;
boxes_h = boxes on horixontal side of the whole table;
tiles_v = tiles on vertical line in each box;
tiles_h = tiles on horizontal line in each box.
"""
total_boxes = boxes_v * boxes_h
tiles_in_box = tiles_v * tiles_h
return [[{None : [False, 0]} for x in range(1, tiles_in_box + 1)] for a in range(total_boxes)]
def insert_numbers(table, numbers_and_positions):
""" table = sudoku table set up in "set_table";
numbers_and_postions = dictionary containing already given numbers and their positions in the table.
"""
noPos = numbers_and_positions
for number in noPos:
box = noPos[number][0]
tile = noPos[number][1]
table[box][tile] = {None : [True, number]}
return table
def test(table, index, number):
"Tests if number is suitable in a tile on vertical and horizontal lines"
box_index, tile_index = index
lines = {
0 : [(0,1,2), (0,3,6)],
1 : [(0,1,2), (1,4,7)],
2 : [(0,1,2), (2,5,8)],
3 : [(3,4,5), (0,3,6)],
4 : [(3,4,5), (1,4,7)],
5 : [(3,4,5), (2,5,8)],
6 : [(6,7,8), (0,3,6)],
7 : [(6,7,8), (1,4,7)],
8 : [(6,7,8), (2,5,8)]
}
box_line_h, box_line_v = lines[index[0]]
tile_line_h, tile_line_v = lines[index[1]]
################################### horizontal line tester
taken_numbers_h = []
for box_index in box_line_h:
index_counter = 0
for tile in table[box_index]:
if index_counter in tile_line_h:
taken_numbers_h.append(tile[None][1])
index_counter += 1
################################### vertical line tester
taken_numbers_v = []
for box_index in box_line_v:
index_counter = 0
for tile in table[box_index]:
if index_counter in tile_line_v:
taken_numbers_v.append(tile[None][1])
index_counter += 1
################################### box tester
taken_numbers_b = []
for tile in table[box_index]:
taken_numbers_b.append(tile[None][1])
###################################
taken_numbers = taken_numbers_h + taken_numbers_v + taken_numbers_b
if number in taken_numbers:
return True
elif number not in taken_numbers:
return False
def reset_key(dictionary, old_key, new_key, value):
"Resets a key of a dictionary to a different name"
dictionary[new_key] = dictionary[old_key]
del dictionary[old_key]
return dictionary
def solve(table):
""" Solves the sudoku puzzle
"""
box_index = 0
tile_index = 0
safe = True
def repeat():
tile[None][1] += 1
if tile[None][1] > 9:
tile[None][1] = 0
safe = False
tile_index -= 1
elif tile[None][1] <= 9:
if test(table, [box_index, tile_index], tile[None][1]) is True:
repeat()
elif test(table, [box_index, tile_index], tile[None][1]) is False:
tile_index += 1
safe = True
valid = False
while valid is not True:
box = table[box_index]
tile = box[tile_index]
if tile[None][0] is True:
if safe is True:
tile_index += 1
safe = True
elif safe is False:
tile_index -= 1
elif tile[None][0] is False:
repeat()
What I do in Python shell is:
>>>table = set_table(3,3,3,3)
>>>table = insert_numbers(table, {0 : [0,4]})
>>>solve(table)
What I expect to happen is the program changing the value of every dictionary on table[0] (box 1) to {None : [False, 1]}, {None : [False, 2]}, {None : [False, 3]} and so on until it reaches 9 at the last small box within the first big box of the whole grid because the code should cause an index error. This is because when it reaches the last small box in the first big box, an negative test result for violating the rules should come up for numbers 1-8 because they are obviously already in the box. I do not see this error, however, but this one instead:
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
solve(t)
File "C:\Users\cdobr\Desktop\Sudoku Solver.py", line 153, in solve
repeat()
File "C:\Users\cdobr\Desktop\Sudoku Solver.py", line 129, in repeat
if test(table, [box_index, tile_index], tile[None][1]) is True:
UnboundLocalError: local variable 'tile_index' referenced before assignment
What am I supposed to do to fix this? It is as if the function inside the function could not see the parent's variables.
tile_index is a non-local variable, but you do not specify it to be so. You can do this explicitly using nonlocal:
def repeat():
nonlocal tile_index
Why is nonlocal to be specified for this and not for any of the other non-local variables? Because of this line:
tile_index -= 1
A recursive call causes this to be executed. However, when doing an assignment, python assumes the variable is local unless otherwise mentioned. None of the other non-local variables are assigned to/updated, so this does not apply.

why am I getting this python syntax indexerror

I am new to python and programming in general. I have received many syntax errors in my program. most have been Index errors. When I run it now what I get is:
"Traceback (most recent call last):
File "C:\Python33\HW3 playing around.py", line 133, in <module>
Main()
File "C:\Python33\HW3 playing around.py", line 32, in Main
EmployeeNumbers()
File "C:\Python33\HW3 playing around.py", line 69, in EmployeeNumbers
Sal[Index] = float(input("Enter Employee salary here: "))
IndexError: list assignment index out of range"
I have no idea how to solve both this error and many others that this program has, any help would be appreciated.
-Jacob
# Description: This program will Calculate the Average, Maximum, and Minimum Salaries of employees
#Declare Variables
EmpNum = 0
SalAVG = 0
Index = 0
SalTot = 0
# Start Main
def Main():
# Get Number of employees
EmpNum = int(input("Enter the number of employee's here: "))
if EmpNum <=0:
print("Please enter positive number")
while Index < EmpNum:
# Call EmployeeNames
global Name
global Index
global SalTot
Name = [Index]
EmployeeNames()
# Call EmployeeNumbers
global Sal
Sal = [Index]
EmployeeNumbers()
# Calculate SalTot
SalTot = SalTot + Sal[Index]
# Increase Index
Index = Index + 1
# Calculate and output AVG
SalAVG = SalTot / Index
print("The average salary is $", SalAVG)
# Call and output Maximum
Maximum()
print("The highest paid employee is ", EmpName, " With a salary of $")
# Call and output Minimum
global Temp
global Switch
Minimum
print("The Lowest paid employee is ", EmpName, " With a salary of $")
# Arrays
# EmployeeNames array
def EmployeeNames():
# Bind global parts
global Name
global Index
# Run EmployeeNames
Name[EmpNum] = str(input("Enter employee name here: "))
# EmployeeNumbers Array
def EmployeeNumbers():
#Bind Global parts
global Sal
#Run EmployeeNumbers
Sal[Index] = float(input("Enter Employee salary here: "))
if Sal[EmpNum] > 200000:
print("Please enter lower salary")
Sal[EmpNum] = float(input("Enter Employee salary here: "))
if Sal[EmpNum] < 0:
print("Please enter positive number")
Sal[EmpNum] = float(input("Enter Employee salary here: "))
# Maximum array
def Maximum():
# Bind global parts
global Temp
global Switch
global Name
Index = 1
Temp = 0
Switch = 1
while Switch > 0:
Index = 1
if Sal[Index] > Sal[Index + 1]:
# Call NameSwitch
global TempName
global Name
NameSwitch()
Temp = Sal[Index]
Sal[Index] = Sal[Index + 1]
Sal[Index + 1] = Temp
Switch = Switch + 1
Index = Index + 1
Switch = 1
# Minimum array
def Minimum():
# Bind global parts
global Temp
global Switch
global Name
Index = 1
Temp = 0
Switch = 1
while Switch > 0:
Index = 1
if Sal[Index] < Sal[Index + 1]:
# Call NameSwitch
global TempName
global Name
NameSwitch()
Temp = Sal[Index]
Sal[Index] = Sal[Index + 1]
Sal[Index + 1] = Temp
Switch = Switch + 1
Index = Index + 1
Switch = 1
# NameSwitch array
def NameSwitch():
#Bind global parts
global TempName
global Name
TempName = ""
TempName = Name[Index]
Name[Index] = Name[Index + 1]
Name[Index + 1] = TempName
Main()
I'm not going to fix your code, but your problem can be simplified to:
>>> some_list = []
>>> some_list[0] = "Hello World"
IndexError: list assignment index out of range
To fix it, you need to either start the list with an initial size:
>>> some_list = [None]
>>> some_list[0] = "Hello World"
Or append to the empty list:
>>> some_list = []
>>> some_list.append("Hello World")
Your major problem stems from the use of global variables. Instead of creating global variables, define your function with the variables as arguments like this:
def Maximum(Temp,Switch,Name):
Then call the function like this
Maximum(Temp,Switch,Name)
That way you can keep track of everything your function will need when defining it.
Back to your error, the problem is that Index is not defined in the function. recreate the function header like so:
def EmployeeNumbers(sal,index):
and in main, call it like this:
EmployeeNumbers(sal, index)
Last, define all of your variables inside main, so you do not need to pass them into main when you call it.

Categories

Resources