Here is my situation
import win32api
while True:
x,y = win32api.GetCursorPos()
if x < 0:
print("2")
else:
print("1")
This constantly prints '1' or '2' depending on the x co-ordinate of the mouse being less than 0 (dual monitors, RHS is primary so < 0 means mouse is on second monitor). How can I make it only print one instance of the string '1' or '2' when x becomes < 0 or x becomes >= 0?
You need to remember the last state printed so that you can detect when a new state is entered.
last_state = False
while True:
x,y = win32api.GetCursorPos()
state = x < 0
if state == last_state:
continue
last_state = state
if state:
print("2")
else:
print("1")
Related
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'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.
I have made the connections in my board where I read the state of a reed switch. When the magnet nearby it shows "0" and I store the data at the "x" variable.
I'm using this to read the state of a fridge door so I can control some relays when the door is open (0) and then turn it off when closed (1).
When I use a while loop, I get the script running but it keeps counting when the variable is 1. I need this script to count when the door opens, (one) closes, and opens again (two).
Here is the code so far with the while loop.
import RPi.GPIO as GPIO
from time import sleep
GPIO.setmode(GPIO.BOARD)
inPin=15
outPin=12
GPIO.setup(inPin,GPIO.IN)
GPIO.setup(outPin,GPIO.OUT)
counter = 0
while True:
x = GPIO.input(inPin)
previousValue = 0
print(x)
if x==1:
GPIO.output(outPin,GPIO.LOW)
if x==0:
GPIO.output(outPin,GPIO.HIGH)
if x == 1 and previousValue == 0:
counter += 1
print(counter)
You could change the previous value
if x == 1 and previousValue == 0:
counter += 1
print(counter)
previousValue == 1
elif x == 0 and previousValue == 1:
previousValue == 0
I'm trying to create a collision detection between 4 controllable characters on an RPG battle map. Here is the function I'm using
def player_collission(Lord_x,Lord_y,Journeyman_x,Journeyman_y,Archer_x,Archer_y,
Cleric_x,Cleric_y):
print("Running")
if abs(Lord_x - Journeyman_x) <= 0 and abs(Lord_y - Journeyman_y) <= 0:
print("Colission detected")
return True
elif abs(Lord_x - Archer_x) <= 0 and abs(Lord_y - Archer_y) <= 0:
print("Colission detected")
return True
elif abs(Lord_x - Cleric_x) <= 0 and abs(Lord_y == Cleric_y) <= 0:
print("Colission detected")
return True
elif abs(Journeyman_x - Archer_x) <= 0 and abs(Journeyman_y - Archer_y) <= 0:
print("Colission detected")
return True
elif abs(Journeyman_x - Cleric_x) <= 0 and abs(Journeyman_y - Cleric_y) <= 0:
print("Colission detected")
return True
elif abs(Archer_x - Cleric_x) <= 0 and abs(Archer_y == Cleric_y) <= 0:
print("Colission detected")
return True
else:
return False #I didnt use classes so it has alot of if statements
if player_up:
p_collide = player_collission(Lord_x,Lord_y,Journeyman_x,Journeyman_y,Archer_x,Archer_y,
Cleric_x,Cleric_y)
if current_player == "lord":
if p_collide != True:
Lord_y -= tile_increment
if Lord_y <= 0:
Lord_y = 50
What happens is that the characters still move into each other but it detects the collision after it has already moved into each other and freezes all movement. I'm not sure how to re arrange it to make it work properly.
You detect collision when it has already happened. This is why you see characters overlapping.
Instead, you should detect if a collision is going to happen, an prevent a motion that would lead to that.
An example:
def move(coords, velocity):
"""Moves coords according to velocity."""
x, y = coords # Unpack a 2-tuple.
vx, vy = velocity
return (x + vx, y + vy)
tom_coords = (0, 0) # Tom is in the corner.
tom_v = (1, 1) # Tom moves by diagonal.
jerry_coords = (5, 0) # Jerry is a bit away from Tom.
jerry_v = (0, 1) # Jerry moves vertically.
while True:
new_tom_coords = move(tom_coords, tom_v) # Tom moves without fear.
new_jerry_coords = move(jerry_coords, jerry_v)
if new_jerry_coords == new_tom_coords: # Would be a collision!
new_jerry_coords = jerry_coords # Back to previous tile.
vx, vy = jerry_v
jerry_v = (-vx, -vy) # Jerry runs back.
print("Collision imminent, Jerry runs away!")
else:
jerry_coords = new_jerry_coords # Only update if no collision.
# Could also check collisions with walls, etc.
tom_coords = new_tom_coords
# Not inside pygame, so just print it and wait for a key press.
print('Tom:', tom_coords, 'Jerry:', jerry_coords)
input("Enter to continue, Ctrl+C to stop ")
Run it in and see how Tom and Jerry come close to each other but never occupy the same tile.
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.