How do I prevent the barriers and the doors overlapping? - python

# Imported Modules for Randomization and Turtle
import turtle as trtl
import random as rand
from random import *
# Painter Configuration and Screen Configuration
painter = trtl.Turtle()
distanceForward = 20
painter.pensize(5)
painter.speed(10000000)
painter.screen.setup(1000, 1000)
walls = 32
#This for loop is essential--> it creates 32 lines, and based on the conditions below, adds walls, barriers, and exits
for i in range(walls):
#Register the beginning position of the Turtle.
xBeginCor = painter.xcor()
yBeginCor = painter.ycor()
#Variables for randomization of Exits and Doors
initialWallDistance = randint(1, distanceForward-5)
doorDistance = randint(1,distanceForward-18)
#Program for the Walls and their Randomization
#Prevents the last 4 lines having barriers protruding
#We feel this method of randomizing the wall distance was really innovative and that it works pretty well
if i < walls - 4:
painter.penup()
painter.forward(initialWallDistance)
painter.left(90)
painter.pendown()
painter.forward(30)
painter.backward(30)
painter.right(90)
painter.penup()
#Preventing overlapping for the Walls and Doors. This does not work perfectly, and sometimes the doors are too small as a result of this
if doorDistance == range(0, 21):
doorDistance + 20
painter.forward(distanceForward - initialWallDistance)
else:
painter.forward(distanceForward - initialWallDistance)
#Creates the randomization of the doors. This works really well, as it makes the turtle go a random distance forward from the beginning of the line, and create a door
painter.goto(xBeginCor, yBeginCor)
painter.pendown()
painter.forward(doorDistance)
painter.penup()
painter.forward(20)
painter.pendown()
painter.forward(distanceForward-doorDistance)
#Turn the turtle to create the next line
painter.right(90)
#Change the length of the line so the next one is a longer distance
distanceForward += 15
#Keeps window open
wn = trtl.Screen()
wn.mainloop()
I need help stopping these doors and barriers happening on top of each other. I have also attached an image describing what I mean.
This code here is what I am working on to prevent the two from going on top of each other:
if doorDistance == range(0, 21):
doorDistance + 20
painter.forward(distanceForward - initialWallDistance)
else:
painter.forward(distanceForward - initialWallDistance)
Nothing is working. At this point I am completely confused, and I have no idea what I am doing. Any explanations/help would be appreciated
Note: I am a beginner, so I will not be able to use any complex techniques

This code doesn't work Python-wise:
if doorDistance == range(0, 21):
doorDistance + 20
It should be something like:
if 0 <= doorDistance <= 20:
doorDistance += 20
But that's not going to fix your problem. Your logic to avoid door and barrier overlap doesn't work. As you spiral from the center, you put up barriers pointing to the next layer, and leave door gaps. But the overlaps happen on the next spiral when all memory of where those barriers are located is lost.
My rework of your code into Python (still broken):
# Imported Modules for Randomization and Turtle
from turtle import Screen, Turtle
from random import randint
WALLS = 32
# Painter Configuration and Screen Configuration
screen = Screen()
screen.setup(1000, 1000)
painter = Turtle()
painter.hideturtle()
painter.pensize(5)
painter.speed('fastest')
distanceForward = 20
# This for loop is essential--> it creates 32 lines, and based on the conditions below, adds walls, barriers, and exits
for wall in range(WALLS):
# Register the beginning position of the Turtle.
beginCor = painter.position()
# Variables for randomization of Exits and Doors
initialWallDistance = randint(1, distanceForward-5)
doorDistance = randint(1, distanceForward-18)
# Program for the Walls and their Randomization
# Prevents the last 4 lines having barriers protruding
# We feel this method of randomizing the wall distance was really innovative and that it works pretty well
if wall < WALLS - 4:
painter.penup()
painter.forward(initialWallDistance)
painter.left(90)
painter.pendown()
painter.forward(30)
painter.penup()
painter.backward(30)
painter.right(90)
# Preventing overlapping for the Walls and Doors. This does not work perfectly, and sometimes the doors are too small as a result of this
if 0 <= doorDistance <= 20:
doorDistance += 20
painter.forward(distanceForward - initialWallDistance)
# Creates the randomization of the doors. This works really well, as it makes the turtle go a random distance forward from the beginning of the line, and create a door
painter.goto(beginCor)
painter.pendown()
painter.forward(doorDistance)
painter.penup()
painter.forward(20)
painter.pendown()
painter.forward(distanceForward - doorDistance)
# Turn the turtle to create the next line
painter.right(90)
# Change the length of the line so the next one is a longer distance
distanceForward += 15
# Keeps window open
screen.mainloop()
Your logic seems like it could produce unsolvable mazes, like your example one.

Related

can't figure out a loop with some conditions

I'm starting to learn programming and trying to write my first flash game bot, but I think I can't sort things out
This game is, player click in 5 areas randomly, if player is lucky, the enemy will get shot and reduce his hp. Enemy's hp is 6, and this game requires player to finish this in no more than 7 shots, which means player has only one chance to miss the guess.
So I "cut" the HP bar into 6 jugdement areas, and use PIL in python to judge the pixel's color change in every area, then let pyautogui to do some auto clicks. Main part of this code is:
while True:
flag = 1
for i in range(6):
s = screenGrab()
pixels = s.load()
pixelJugde_1 = pixels[judgeAreas[i]] # jugde if hp is reduced after this shot
if pixelJugde_1 != (0, 0, 0): # if this shot missed
randomClick() # try again
s = screenGrab()
pixels = s.load()
pixelJugde_2 = pixels[judgeAreas[i]] # second judge of this shot
if (pixelJugde_2 != pixelJugde_1): # hp changed, second try didn't miss
flag = 1 # mark this shot has been tried twice
randomClick() # continue next shot
elif (pixelJugde_2 == pixelJugde_1 and flag == 1): # second try missed
resetResult() # restart the game
break
else:
print 'got shot' # success at first try
randomClick() # next shot
now my problem is, if the first shot has been tried twice and marked, when the next shot begins and misses, it will still try twice, just like the marking flag is not working. So how to fix this?

How do I get an image to move until it gets to a specific point in the window?

Right now I have some code in Python using Zelle graphics that has a robot image and some text scrolling upward. When the user clicks on the window, the program ends.
What I'm trying to do is have pieces of the robot image come in from opposite sides of the window (The head moving down from the top, the eyes moving up from the bottom, and the ears moving in from the left and right). They would stop moving once they come together to form the completed image.
After that, I want the text to come in from the left hand side and stop once it gets to the center of the screen, underneath the image. I don't want the animation to start until the user clicks on the window.
This is what my code looks like so far:
from graphics import *
from random import randint
from time import sleep
screen=GraphWin("Logo",500,700);
screen.setBackground("#b3e2bf");
#---------logo-----------
robotHead=Image(Point(250,250),"robotHead.png");
robotHead.draw(screen);
robotEyes=Image(Point(250,310),"robotEyes.png");
robotEyes.draw(screen);
robotLeftEar=Image(Point(150,290),"robotLeftEar.png");
robotLeftEar.draw(screen);
robotRightEar=Image(Point(350,290),"robotRightEar.png");
robotRightEar.draw(screen);
#--------credits-----------
programmer=Point(250,515);
lineOne=Text(programmer,"Programmer Name");
lineOne.draw(screen);
className=Point(250,535);
lineTwo=Text(className,"CSC 211");
lineTwo.draw(screen);
date=Point(250,555);
lineThree=Text(date,"November 30th, 2017");
lineThree.draw(screen);
copyrightName=Point(250,575);
lineFour=Text(copyrightName,"Copyright Line");
lineFour.draw(screen);
while screen.checkMouse()==None:
robotHead.move(0,-1);
robotEyes.move(0,-1);
robotLeftEar.move(0,-1);
robotRightEar.move(0,-1);
lineOne.move(0,-1);
lineTwo.move(0,-1);
lineThree.move(0,-1);
lineFour.move(0,-1);
sleep(0.1);
screen.close();
You can use robotHead.anchor.getY() and robotHead.anchor.getX() to check current position and move it only if it is not on expected position.
You can also use variables with True/False to control which element has to move (or even which element to show on screen). At start you should have moveHead = Trueand moveLineOne = False. When head is on expected position then you can change moveHead = False and moveLineOne = True.
BTW: graphics has function update(frames_per_second) to control speed of animation and you don't need sleep(). Besides update() executes some functions which graphics may need for correct work. (graphics documentation: Controlling Display Updates (Advanced))
Speed 25-30 FPS is enough for human eye to see smooth animation (and it may uses less CPU power than 60 FPS).
Simple example
from graphics import *
from random import randint
from time import sleep
screen = GraphWin("Logo", 500, 700)
# --- objects ---
robot_head = Image(Point(250, 250), "robotHead.png")
robot_head.draw(screen)
programmer = Point(250, 515)
line_one = Text(programmer, "Programmer Name")
#line_one.draw(screen) # don't show at start
# --- control objects ---
move_robot_head = True # move head at start
move_line_one = False # don't move text at start
# --- mainloop ---
while not screen.checkMouse(): # while screen.checkMouse() is None:
if move_robot_head: # if move_robot_head == True:
# check if head is on destination position
if robot_head.anchor.getY() <= 100:
# stop head
move_robot_head = False
# show text
line_one.draw(screen)
# move text
move_line_one = True
else:
# move head
robot_head.move(0, -10)
if move_line_one: # if move_line_one == True:
# check if head is on destination position
if line_one.anchor.getY() <= 150:
# stop text
move_programmer = False
else:
# move text
line_one.move(0, -10)
# control speed of animation
update(30) # 30 FPS (frames per second)
# --- end ---
screen.close()

In Python, how can I execute two Turtle commands simultaneously?

As in having two Turtles moving at once. For example, I import two turtles, then try to have both of them move forward alongside each other. How can I do this?
bob = turtle.Turtle()
john = turtle.Turtle()
def move_turtles(ammount):
for i in range(ammount // 10):
bob.forward(10)
john.forward(10)
move_turtles(100)
There's no way to move them at the same time, although you can use something like that. It moves the turtles by 10 points each, so it gives the impression that they are moving together, but they are actually moving separately by little ammounts. It repeats the operation (ammount //10) times, and moves 10 in each iteration, so if you were to give 50 as an input, it would move 5 times 10 points, resulting in 50. You can then customize the function to move by a little a turtle so they don't overlap and so on.
You can move multiple turtles independently at the same time using timer events -- you can even have them move at different rates, both in time and space:
import turtle
turtle.setworldcoordinates(0, -100, 100, 100)
bob = turtle.Turtle(shape="turtle")
bob.penup()
bob.sety(20)
john = turtle.Turtle(shape="turtle")
john.penup()
john.sety(-20)
def move_bob():
bob.forward(1)
if bob.xcor() < 90:
turtle.ontimer(move_bob, 75)
def move_john():
john.forward(2)
if john.xcor() < 90:
turtle.ontimer(move_john, 100)
move_bob()
move_john()
turtle.exitonclick()
Other folks also use threads to achieve this but timer events are built into the turtle module.
There is a way to control frames using the Turtle module - you need to change the screen attributes.
screen = turtle.Screen()
screen.tracer(0)
This method makes all turtle movement invisible until you run screen.update(), and then every turtle will be visually updated at the same time on the screen. In your case, you can write screen.update() after the movement of both turtles, and they will appear to move at the same time.

objects in a sprite.Group() not behaving as unique objects as they should

Below is the troubling code with a quick breakdown.
if player.attacked == True and delay >= 60: #if it's monster's turn plus a built in delay so everything isn't instant
for enemy in enemies_list: #iterating the all the enemies in the sprite group
if enemy.attack_rdy == True and enemy.health >0 and delay ==60: #if THAT particular monster hasn't attacked, isn't dead, and the delay has been long enough.
player.hit.play() #play the player's damaged sound
damage = random.randrange(each.attack[0],each.attack[1]+1)-player.armor #random attack roll of a tuple assigned to the enemy class
player.health -= damage
enemy.attack_rdy = False #Sets THIS particular enemy so that he may not attack until it's his turn again
player.damaged = True #Just triggers an animation on the player
each.attack_anim = 1 #triggers an animation on the enemy
break #stops the for loop so that everything doesn't happen at once and relies on the delay int.
Problem:
This iteration works properly in that the player is accurately attacked the correct number of times in accordance to the number of enemies attacking him. For some weird reason the same enemy will be attacking all those times however. When the attacking enemy dies, another one simply takes over his task of being the one who attacks. I can make no sense of it.
In true bonehead fashion, after staring at and editing my code for hours I find my blunder mere moments after posting. It's really just a stupid error.
each.attack_anim = 1
SHOULD read
enemy.attack_anim = 1
With blunder corrected, code runs as designed.

I'm trying to time how long a key is held down using vPython

I'm writing a program for my physics final. Throughout the semester we have used vPython to model situations and get exact answers, etc. Our final project is to create a game using vPython that includes some type of physics.
I chose to remake Bowman except with tanks. So you have a tank on the right hand of the screen and left hand of the screen with a wall in the middle. The object is to aim your cannon and shoot the right velocity to hit your opponent's tank. I have the a good chunk of the program complete however I am stuck on a few different things.
First, how can I time a keystroke? I have it so I shoot from the each cannon however I want to be able to hold down a key and dependent on how long it's held down for the faster the initial velocity will be.
Second, where would I incorporate gravity into the program? I have a general idea of how to but I just don't know which function to put it into.
Lastly, I have a wall height being generated randomly each time the program is run. However sometimes the wall is so small you can't see it. Is there a way I can set a range of values for this?
Here is my code:
from visual import*
from random import*
scene.autoscale=False
scene.width = 1500
scene.height = 800
scene.title='Tanks'
def moveaup(gun):
theta=arctan(gun.axis.y/gun.axis.x)
dtheta=.1
if (theta<pi/2):
theta=theta+dtheta
if not (theta>pi/2):
gun.axis=(cos(theta),sin(theta),0)
else:
gun.axis=vector(0,1,0)
def moveadown(gun):
theta=arctan(gun.axis.y/gun.axis.x)
dtheta=.1
if (theta>0):
theta=theta-dtheta
gun.axis=(cos(theta),sin(theta),0)
def movebup(gun):
theta=arctan(gun.axis.y/gun.axis.x)+pi
dtheta=.1
if (theta>pi/2):
theta=theta-dtheta
if not (theta<pi/2):
gun.axis=(cos(theta),sin(theta),0)
else:
gun.axis=vector(0,1,0)
def movebdown(gun):
theta=arctan(gun.axis.y/gun.axis.x)+pi
dtheta=.1
if (theta<pi):
theta=theta+dtheta
gun.axis=(cos(theta),sin(theta),0)
def shoota(gun):
vel = vector(1,1,0)
bullet = sphere(pos=(gun.pos.x+gun.axis.x,gun.pos.y+gun.axis.y,0),radius=(.0785),color=color.yellow)
bullet.v = vector(0,0,0)
bullet.v = bullet.v+vel
bulletlist.append(bullet)
def shootb(gun):
vel = vector(-1,1,0)
bullet = sphere(pos=(gun.pos.x+gun.axis.x,gun.pos.y+gun.axis.y,0),radius=(.0785),color=color.green)
bullet.v = vector(0,0,0)
bullet.v = bullet.v+vel
bulletlist.append(bullet)
def bulletlistupdate(bulletlist):
dt=.01
for a in bulletlist:
a.pos=a.pos+a.v*dt
def checks(agun,bgun):
if scene.kb.keys:
key=scene.kb.getkey()
if key=='a':
moveaup(agun)
if key=='s':
moveadown(agun)
if key=='l':
movebup(bgun)
if key=='k':
movebdown(bgun)
if key=='d':
shoota(agun)
if key=='j':
shootb(bgun)
#enviroment
ground = box(pos=(0,-8,0),size=(50,5,0),color=color.red)
wall = box(pos=(0,-8,0),size=(.25,20*random(),0),color=color.red)
#playerA
abody = box(pos=(-11,-5.25,0),size=(.5,.5,0),color=color.blue)
agun = cylinder(pos=(-11,-5.1,0),axis=(.8,.8,0),radius=(.08),color=color.blue)
#playerB
bbody= box(pos=(11,-5.25,0),size=(.5,.5,0),color=color.yellow)
bgun = cylinder(pos=(11,-5.1,0),axis=(-.8,.8,0),radius=(.08),color=color.yellow)
bulletlist = []
while True:
rate(1000)
checks(agun,bgun)
bulletlistupdate(bulletlist)
Any and all help is welcome!
Thanks much!
You can time things in python using the time module
import time
start = time.time()
finish = time.time()
print start # 1386269106.18
print finish # 1386269111.11
print (finish - start) # 4.9276599884
So when the player first starts pressing the button, save the time. Then save the time again when the player stops pressing the button. The difference between these two times is the number of seconds the player held the button.
[Edit] If all you can do is check if the key is pressed down, you can get the time inside the main loop and calculate dt (the amount of time that has passed):
t = time.time()
while True:
new_t = time.time()
dt = new_t - t
t = new_t
rate(1000)
checks(agun,bgun, dt)
bulletlistupdate(bulletlist)
Then pass dt to checks, and if the key is pressed down, you know the key has been held down for another dt seconds, and you can add it to your running total of time that it has been held down.
For the random you would need to enter a command similar to this:
random.randrange(5,31) #this would give you a random range between the numbers 4-30
I don't want to do your homework for you as I don't think you are asking for that. I hope this helps you.
I'm sorry this should be the correct code for you:
random.randint(7,40) # this would get you a random integer of 7-40
I apologize for the misinformation.

Categories

Resources