Python text game - Cant exit a while loop - python

this is the main code:
import MainMod
print("Welcome!")
print("Note: In this games you use wasd+enter to move!\nYou press 1 key and then enter,if you press multiple kets it wont work.\nYou will always move by 5 meters.")
CurrentRoom = 1
#Limits work this way!1st and 2nd number are X values(1st is <---- limit,2nd is ---> limit)
#3rd and 4th are y values(1st is v limit,2nd is ^ limit)
# X and Y are coordinates; 0,0 is the starting point of every room
while True:
if CurrentRoom ==1:
print("This is room 1")
MainMod.roomlimits = [-15 , 15, -15 , 15]
MainMod.doorloc1 = [-15,10,15]
MainMod.doorloc2 = [15,-2,2]
while CurrentRoom == 1:
MainMod.MainLel()
if MainMod.door1 == 1:
print("DAMN SON")
CurrentRoom = 2
break
elif MainMod.door2 == 1:
print("Plz no")
CurrentRoom = 3
break
while CurrentRoom == 2:
MainMod.MainLel()
and this is the MainMod module is :
x = 0
y = 0
roomlimits = 0
doorloc1=0
doorloc2=0
door1 = 0
door2 = 0
direct = 0
def MainLel():
global direct
movementinput()
movement(direct)
doorcheck()
def movement(dir):
global x,y,roomlimits,door1,door2,doorloc1,doorloc2
if dir == "w":
y += 5
if y > roomlimits[3]:
y = roomlimits[3]
print("Youre current coordinates are x:",x," y:",y)
elif dir == "s":
y -= 5
if y < roomlimits[2]:
y = roomlimits[2]
print("Youre current coordinates are x:",x," y:",y)
elif dir == "d":
x += 5
if x > roomlimits[1]:
x = roomlimits[1]
print("Youre current coordinates are x:",x," y:",y)
elif dir == "a":
x -= 5
if x < roomlimits[0]:
x = roomlimits[2]
print("Youre current coordinates are x:",x," y:",y)
def movementinput():
global direct
while True:
direct = input("")
if direct in ("w","a","s","d","W","A","D","S"):
break
else:
print("You failure.")
def doorcheck():
global x,y,doorloc1,doorloc2,door1,door2
if x == doorloc1[0] and doorloc1[1] <= y <= doorloc1[2]:
door1 = 1
elif y == doorloc2[0] and doorloc2[1] <= x <= doorloc2[2]:
door2 = 1
else:
door1,door2 = 0,0
Im using a module instead of classes because i dont know how to use classes yet,anyways,what happens in the program is that if i am in the door location,it simply prints "DAMN SON" and doesnt break out of the Room loop,any help? EDIT NOTE: I added the break statement later on to try if it would help,sadly it didnt,i am also a bit tired so im guessing i made a logic mistake somewhere,thanks in advance for help.
Final edit: The code was functional all along,i was just testing it incorrectly!Thanks for the awnsers,ill close this question now.

Since I could not imagine it didn't work, I added two markers (print commands), to room 1 and 2:
while CurrentRoom == 1:
print("one")
mod.MainLel()
and
while CurrentRoom == 2:
print("two")
mod.MainLel()
This is what happened:
Youre current coordinates are x: -5 y: 15
one
a
Youre current coordinates are x: -10 y: 15
one
a
Youre current coordinates are x: -15 y: 15
DAMN SON
two
a
Youre current coordinates are x: -15 y: 15
two
It turned out to be working fine. The break is redundant however. The loop will break anyway, since the condition becomes False.

Related

Trouble implementing a flood fill algorithm in python

I am rather new to python and am attempting to create a terminal based minesweeper clone. Everything has been going well other than implementing the flood fill algorithm. Whenever I run the flood fill it just gets stuck looping indefinitely. If anyone could help with this it would be greatly appreciated.
import random
from queue import Queue
'⚑'
fieldY = 10
fieldX = 5
validFloodFills = ['1','2','3','4','5','6','7','8','◼']
visibleField = []
internalField = []
#creates blank fields with the ◼ character
def generateField(grid, y , x):
for i in range(y):
tempList = []
for i in range(x):
tempList.append("◼")
grid.append(tempList)
#places bombs into the internal field according to the numOfBombs argument
def placeBombs(numOfBombs):
generateField(internalField, fieldY, fieldX)
placed = 0
#while loop is use becuase you cannot step an iter back with a for loop
while placed != numOfBombs:
y = random.randint(0, fieldY-1)
x = random.randint(0, fieldX-1)
if internalField[y][x] == 'X':
continue
else:
internalField[y][x] = 'X'
placed += 1
#loops through all tiles and numbers them according to the number of adjacent bombs
def placeInternalNumbers():
global fieldY
global fieldX
#loop through all tiles and check all 8 neighbours
#if neighbour is a bomb then add 1 to int
#after checking all neighbours the value of that int is assigned to that tile
for idxY, y in enumerate(internalField):
for idxX, x in enumerate(y):
#makes indexes in range
fieldY -= 1
fieldX -= 1
idxY -= 1
idxX -= 1
adjacentBomb = 0
if internalField[idxY][idxX] == 'X':
continue
#look down one
if idxY != fieldY:
if internalField[idxY+1][idxX] == 'X':
adjacentBomb += 1
#look up one
if idxY != 0:
if internalField[idxY-1][idxX] == 'X':
adjacentBomb += 1
#look right one
if idxX != fieldX:
if internalField[idxY][idxX+1] == 'X':
adjacentBomb += 1
#look left one
if idxX != 0:
if internalField[idxY][idxX-1] == 'X':
adjacentBomb += 1
#look down right
if idxY != fieldY and idxX != fieldX:
if internalField[idxY+1][idxX+1] == 'X':
adjacentBomb += 1
#look down left
if idxY != fieldY and idxX != 0:
if internalField[idxY+1][idxX-1] == 'X':
adjacentBomb += 1
#look up right
if idxY != 0 and idxX != fieldX:
if internalField[idxY-1][idxX+1] == 'X':
adjacentBomb += 1
#look up left
if idxY != 0 and idxX != 0:
if internalField[idxY-1][idxX-1] == 'X':
adjacentBomb += 1
#checks if the adjacent bombs are zero and does not update the tile if there are no adjacent bombs
if adjacentBomb == 0:
continue
internalField[idxY][idxX] = str(adjacentBomb)
#prints the field parsed to the function
def printField(field):
for i in field:
print(i)
#floodFill
def floodFill(y, x):
#TODO needs to read and compare with the internal board and then write changes to the visible board
n = len(visibleField)
m = len(visibleField[0])
if y < 0 or y >= n or x < 0 or x >= m or internalField[y][x] not in validFloodFills:
return
else:
visibleField[y][x] = internalField[y][x]
floodFill(y+1, x)
floodFill(y-1, x)
floodFill(y, x+1)
floodFill(y, x-1)
#main loop
def mainLoop():
cont = True
while cont:
printField(visibleField)
print()
printField(internalField)
print("To select a tile type 'S' then the x coordinate and y coordinate all seperated by spaces\nTo flag a tile type 'F' then the x coordinate and y coordinate all seperated by spaces")
select = input().split(' ') #TODO input validation, use length to check for multiple spaces
operator = select[0]
x = int(select[1])
y = int(select[2])
if operator == 'S':
if internalField[y][x] == 'X':
break
else:
floodFill(y, x)
continue
elif operator == 'F':
pass
#TODO more stuff on fail eg printing revealed minefield
print("You hit a bomb, better luck next time")
generateField(visibleField, fieldY, fieldX)
placeBombs(5)
placeInternalNumbers()
mainLoop()
printField(visibleField)
print()
printField(internalField)

I am trying to make a mini game. The movement is in X and Y coordinates that range between -5 and 5 inclusively in python. How do I fit this in a loop

#The Commands are going North and South in the Y - variable and East and West in the X - variable and X - to exit the game
x = 0
y = 0
print("Welcome to sloth quest!")
print("________________________________________")
print()
print("You're currently at position (0, 0) in the world.")
print("Available commands:
N - go north, S - go south, E - go east, W - go west, X - exit game)
command = input("Enter a command: ")
if command == ("N"):
y = y + 1
elif command == ("E"):
x = x + 1
elif command == ("S"):
y = y -1
elif command == ("W"):
x = x -1
#I want to make a loop so that these commands can be input together so that the goal or hazard is reached.
Can I get help on this?
The game is similar to Zork
The commands and what I want to do are already listed , and I think that the only thing that is left is trying to fit in into a loop with the ranges [-5, 5] inclusively.
# The Commands are going North and South in the Y - variable and East and West in the X - variable and X - to exit the game
x = 0
y = 0
print("Welcome to sloth quest!")
print("________________________________________")
print()
print("You're currently at position (0, 0) in the world.")
print(
"Available commands: N - go north, S - go south, E - go east, W - go west, X - exit game")
while True: # run untill the user enters X
# limit play area to -5 x 5
command = input("Enter a command: ")
command = command.upper() # Ensure user input is upper case
if command == ("N"):
y = y + 1
elif command == ("E"):
x = x + 1
elif command == ("S"):
y = y - 1
elif command == ("W"):
x = x - 1
elif command == 'X': # Exit the loop
break
if x < -5 or x > 5 or y < -5 or y > 5:
# What should happen?
print("error you have left the play area")
print('Thanks for playing') # Exit the game.
# I want to make a loop so that these commands can be input together so that the goal or hazard is reached.

How to nest a function that responds to outside of function call?

I'm trying to figure out how I can solve this issue. I have a Raspberry Pi that is set up with a breadboard that consists of:
1 RGB light
2 buttons (left and right)
1 OLED screen
Each component works and I can run each one. What I'm trying to do is write a script that will allow me to select the "mode" with the left button (everything off vs lights vs screen on).
When a mode is selected, the right button then allows me to select between options within that mode. Below is the code as I have it:
def off():
lights = [red,green,blue]
for light in lights:
light.off()
def lightSelector():
off()
number = 0
while number < 5:
if rightButton.is_pressed:
if number == 0:
off()
red.on()
sleep(1)
number += 1
elif number == 1:
off()
green.on()
sleep(1)
number += 1
elif number == 2:
off()
blue.on()
sleep(1)
number += 1
elif number == 3:
off()
row()
sleep(1)
number+= 1
else:
number = 0
def picture():
image = Image.open('grant.jpeg')
image_r = image.resize((width,height), Image.BICUBIC)
image_bw = image_r.convert("1")
for x in range(width):
for y in range(height):
oled.pixel(x,y,bool(int(image_bw.getpixel((x,y)))))
oled.show()
def oledOff():
oled.fill(0)
oled.show()
def buttons():
x = 0
y = 0
while y is 0:
print('x = ' , x)
print('y = ' , y)
if leftButton.is_pressed:
if x == 0 :
oledOff()
off()
sleep(0.5)
x += 1
elif x == 1:
oledOff()
off()
lightSelector()
sleep(0.5)
x += 1
elif x == 2:
oledOff()
off()
picture()
sleep(0.5)
x += 1
else:
x = 0
oledOff()
off()
buttons()
The idea is that the buttons() function is the main overall function and will call the others as needed. My issue is that once I get to y == 1, or the lightSelector() function, it no longer registers that the leftButton is being pressed and won't switch to the next mode and I'm stuck in the lightSelector() function.
I know at baseline I can spell out lightSelector within the buttons function instead of calling another function but I'm trying to not be as verbose. I don't have any experience with threading or multprocessing and looked into it but couldn't see how that would help.

Mastermind Python coding

Ok I have a feeling that this is a simple simple issue but I have been staring at this code for about 10 hours now.
The issue I am having is in mastermind is that once I get it to recognize that I have the correct colors in the right spot I can get it to display the right spots with X and the wrong spots with O. I need to be able to convert that so instead of X and O I need it to tell the user that he/she has 2 blacks and one white
For example: The secret code is RGYB The user enters RGOY so then Python relays "You have 2 blacks(The R and G spots) and one 1 White (The Y because it's the right color just in the wrong index) As of right now I got it to display X for the right color in the right spot and anything else it is an O
I will post what I have been working with now but today I am at my wit's end
https://pastebin.com/HKK0T7bQ
if correctColor != "XXXX":
for i in range(4):
if guess[i] == tempCode[i]:
correctColor += "X"
if guess[i] != tempCode[i] in tempCode:
correctColor += "O"
print (correctColor + "\n")
if correctColor == "XXXX":
if attempts == 1:
print ("You think you are sweet because you got it right on the first try? Play me again!")
else:
print ("Well done... You needed " + str(attempts) + " attempts to guess.")
game = False
A few comments
X and O
you use X and 0 to denote the success, it will be easier and faster to use a list or tuple or booleans for this, that way you can use sum() to count how many colors and locations were correct. Then whether you represent that with X and O or red and white pins is a matter for later
compartmentalization
Your game logic (guess input, input validation, do you want to continue, etc) is mixed with the comparison logic, so it would be best to separate the different functions of your program into different methods.
This is an fineexample to introduce object oriented programming, but is so simple it doesn't need OO, but it can help. What you need is a method which takes a series of colours and compares it to another series of colours
Standard library
Python has a very extended standard library, so a lot of stuff you want to do probably already exists
Correct colours
to count the number of letters which occur in 2 strings, you can use collections.Counter
guess = "RGOY "
solution = "RGYB"
a = collections.Counter(guess)
b = collections.Counter(solution)
a & b
Counter({'G': 1, 'R': 1, 'Y': 1})
correct_colours = sum((a & b).values())
3
So the user guessed 3 colours correctly
Correct locations
can be solved with an easy list comprehension
[g == s for g, s in zip(guess, solution)]
[True, True, False, False]
sum(g == s for g, s in zip(guess, solution))
2
so the used put 2 colours on the correct location
This is a MasterMind I made in Python. Hope you like it and it helped you! :)
import random
import time
from tkinter import *
def select_level():
global level
level = level_selector.get()
root.destroy()
root = Tk()
level_selector = Scale(root, from_=1, to=3, tickinterval=1)
level_selector.set(0)
level_selector.pack()
Button(root, text="Select a difficulty level", command=select_level).pack()
mainloop()
cpc_1_digit = 0
cpc_2_digit = 0
cpc_3_digit = 0
cpc_4_digit = 0
p_1_digit = 0
p_2_digit = 0
p_3_digit = 0
p_4_digit = 0
correct_correct = 0
correct_wrong = 0
chances = 0
if level == 1:
chances = 15
elif level == 2:
chances = 10
else:
chances = 7
cpc_1_digit = random.randint(0, 9)
while cpc_2_digit == cpc_1_digit or cpc_2_digit == cpc_3_digit or cpc_2_digit ==
cpc_4_digit:
cpc_2_digit = random.randint(0, 9)
while cpc_3_digit == cpc_1_digit or cpc_3_digit == cpc_2_digit or cpc_3_digit ==
cpc_4_digit:
cpc_3_digit = random.randint(0, 9)
while cpc_4_digit == cpc_1_digit or cpc_4_digit == cpc_2_digit or cpc_4_digit ==
cpc_3_digit:
cpc_4_digit = random.randint(0, 9)
while chances > 0:
correct_correct = 0
correct_wrong = 0
answer = input("Enter a four-digit number with different digits (e.g 1476): ")
p_1_digit = int(answer[0])
p_2_digit = int(answer[1])
p_3_digit = int(answer[2])
p_4_digit = int(answer[3])
if p_1_digit == cpc_1_digit:
correct_correct = int(correct_correct) + 1
elif p_1_digit == cpc_2_digit or p_1_digit == cpc_3_digit or p_1_digit ==
cpc_4_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
if p_2_digit == cpc_2_digit:
correct_correct = correct_correct + 1
elif p_2_digit == cpc_1_digit or p_2_digit == cpc_3_digit or p_2_digit ==
cpc_4_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
if p_3_digit == cpc_3_digit:
correct_correct = int(correct_correct) + 1
elif p_3_digit == cpc_1_digit or p_3_digit == cpc_2_digit or p_3_digit ==
cpc_4_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
if p_4_digit == cpc_4_digit:
correct_correct = int(correct_correct) + 1
elif p_4_digit == cpc_1_digit or p_4_digit == cpc_3_digit or p_4_digit ==
cpc_2_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
print("")
if int(correct_correct) == 4:
print("Congratsulations! You found the computer's number!")
break
elif int(correct_wrong) > 0 or int(correct_correct) >= 1 and int(correct_correct)
< 4:
print("You got " + str(correct_correct) + " correct digit(s) in the correct
place, and " + str(correct_wrong) + " correct digit(s) but in wrong place.")
elif int(correct_correct) == 0 and int(correct_wrong) == 0:
print("You didn't guess any number, try again!")
else:
raise Exception("CheckError: line 69, something went wrong with the
comparings.")
exit()
print("")
chances = chances - 1
if chances == 0:
print("You lost... The secret number was " + str(cpc_1_digit) + str(cpc_2_digit)
+ str(cpc_3_digit) + str(cpc_4_digit) + ". Try again by rerunning the program.")
time.sleep(4)

Using a while loop to add and subtract a current location

def main():
global currentX,currentY
currentX = 0
currentY = 0
currentlocation = currentX,currentY
print("Starting Location is", currentX,currentY)
print()
#Main menu dialouge
print("Please select direction:")
print("1, North;")
print("2, East;")
print("3, South;")
print("4, West;")
print("5, End this program")
#Loop = to 1 so while loop will go on indefitly until option 5 is pressed.
loop = 1
#try: handles all errors along with except:
try:
while loop == 1:
direction = input("--> ")
print()
direction = int(direction)
if direction == 1:
moveN = currentY + 1
print("Moved North.",currentlocation)
elif direction == 2:
currentX + 1
print("Moved East.",currentlocation)
elif direction == 3:
currentY - 1
print("Moved South.",currentlocation)
elif direction == 4:
currentX - 1
print("Moved West.",currentlocation)
elif direction == 5:
loop = 0
print("Final location is", currentlocation)
else:
print("ERROR:", choice, "is an invalid input.\n"
"Enter a number from 1 to 5.")
except: ValueError
print("Please enter a whole number between 1-5")
main()
I can't figure out why the loop doesn't add to the currentlocation.
I get an output like
Starting Location is 0 0
Please select direction:
1, North;
2, East;
3, South;
4, West;
5, End this program
--> 3
Moved South. (0, 0)
--> 4
Moved West. (0, 0)
You aren't actually changing currentX and currentY, you're merely evaluating the values you want them to have. To change them, you need to assign to them:
currentX = currentX + 1
or, more concisely:
currentX += 1
Your direction 1 case also looks off. For some reason you're assigning to moveN. I have no idea what that's supposed to do.
Edit: You also need to update currentlocation to reflect the changes in position.
When you say
currentlocation = currentX,currentY
You're not actually creating a tuple with references to currentX and currentY, you're creating a tuple with whatever values were in currentX and currentY at the time it was declared. So every time you change those, it's not updated.
One way to fix this is turn currentlocation into a function.
def currentlocation():
return currentX,currentY
Then, instead of
print(currentlocation)
Just put
print(currentlocation())

Categories

Resources