Python code not working: does not print winner - python

I was wondering why my code keeps printing 'tan', I can't seem to get it to print the actual winner.
import turtle
import random
turtles = []
def setup():
global turtles
startline = -610
screen = turtle.Screen()
screen.bgpic('pavement.gif')
screen.setup(1290, 720)
turtle_ycor = [-40, -20, 0, 20, 40]
turtle_color = ['pink', 'skyblue', 'indigo', 'turquoise', 'tan']
for i in range(0, len(turtle_ycor)):
new_turtle = turtle.Turtle()
new_turtle.shape('turtle')
new_turtle.penup()
new_turtle.setpos(startline, turtle_ycor[i])
new_turtle.color(turtle_color[i])
new_turtle.pendown()
turtles.append(new_turtle)
def race():
global turtles
winner = False
finishline = 550
while not winner:
for current_turtle in turtles:
move = random.randint(0, 10)
current_turtle.forward(move)
xcor = current_turtle.xcor()
if (xcor >= finishline):
winner = True
current_turtle.forward(0)
turtle.forward(0)
winner_color = current_turtle.color()
print('The winner is', winner_color[1])
setup()
race()
turtle.mainloop()
I tried winner_color[0].

I think I may have found the error in this code.
I found out that with your code the last string value in the list turtle_color always wins.
This is because of this part of your code:
while not winner:
for current_turtle in turtles:
move = random.randint(0, 10)
current_turtle.forward(move)
xcor = current_turtle.xcor() #this should be indented, or itll only run this code
#for the last color in the list, in this case, tan
if (xcor >= finishline): #and all of this code should be indented too
winner = True #so it checks all colors, not just tan
current_turtle.forward(0)
turtle.forward(0)
winner_color = current_turtle.color()
print('The winner is', winner_color[1])
So, the correct code (in full) is:
import turtle
import random
turtles = []
def setup():
global turtles
startline = -610
screen = turtle.Screen()
screen.bgpic('pavement.gif')
screen.setup(1290, 720)
turtle_ycor = [-40, -20, 0, 20, 40]
turtle_color = ['pink', 'skyblue', 'indigo', 'turquoise', 'tan']
for i in range(0, len(turtle_ycor)):
new_turtle = turtle.Turtle()
new_turtle.shape('turtle')
new_turtle.penup()
new_turtle.setpos(startline, turtle_ycor[i])
new_turtle.color(turtle_color[i])
new_turtle.pendown()
turtles.append(new_turtle)
def race():
global turtles
winner = False
finishline = 550
while not winner:
for current_turtle in turtles:
move = random.randint(0, 10)
current_turtle.forward(move)
xcor = current_turtle.xcor()
if (xcor >= finishline):
winner = True
current_turtle.forward(0)
turtle.forward(0)
winner_color = current_turtle.color()
print('The winner is', winner_color[1])
setup()
race()
Tell me if there are still any errors (etc)!

It is possible the winner is in fact 'tan' at the end of every race.
The cause of this can be that random.seed is not called yet. Therefore, the code will initialize with the same seed every time it is run, causing the same sequence of random numbers generated every time having the same winner as result. You can increase randomization by for instance initializing the seed before every call, or only at the top of your code.
Adding this line:
random.seed() # initializes seed using current system time
anywhere in your code should randomize the outcomes.
On the note of reading out the winner_color: I'm assuming
winner_color = current_turtle.color() # gets the color of the current turtle
is now a string containing the color 'tan'. In this case, the index [0] will work on a string, and not a list. See for example
>>> a = 'tan'
>>> a[0]
't'
>>> a[1]
'a'
>>> a[2]
'n'
>>> a[:]
'tan'
>>> a[::-1]
'nat'
Also, have a look at how to present your question in a nice way (the stackoverflow text editor also shows tooltips on styling). This will increase the chances of your question being answered and studied.
Welcome to stackoverflow, I hoped this helps you get your code to work!

Related

Python Turtle Issue

I am tryig to create a turtle game where two players can chase around a "goal" shape. I am struggling to get the program to recognize that two shapes are close to each other and therefore that one player should receive a point and then the goal should move. I have pasted my code below, any help would be greatly appreciated.
import turtle as trtl
import random as rand
#initialization / game setup
wn = trtl.Screen()
player1 = trtl.Turtle()
player1.shape('turtle')
player1.fillcolor('red')
player1.penup()
player1.goto(rand.randint(-100,100),rand.randint(-100,100))
player2 = trtl.Turtle()
player2.shape('triangle')
player2.fillcolor('blue')
player2.penup()
player2.goto(rand.randint(-100,100),rand.randint(-100,100))
goal = trtl.Turtle()
goal.shape('circle')
goal.fillcolor('yellow')
goal.penup()
goal.goto(rand.randint(-200,200),rand.randint(-150,-150))
player1_score = 0
player2_score = 0
def player1_up():
player1.setheading(90)
player1.forward(10)
def player2_up():
player2.setheading(90)
player2.forward(10)
def player1_down():
player1.setheading(270)
player1.forward(10)
def player2_down():
player2.setheading(270)
player2.forward(10)
def player1_right():
player1.setheading(0)
player1.forward(10)
def player2_right():
player2.setheading(0)
player2.forward(10)
def player1_left():
player1.setheading(180)
player1.forward(10)
def player2_left():
player2.setheading(180)
player2.forward(10)
if (abs(player1.xcor() - goal.xcor())<5):
if (abs(player1.ycor() - goal.ycor())<5):
player1_score+=1
goal.goto(rand.randint(-200,200),rand.randint(-150,150))
print(player1_score)
#events
wn.onkeypress(player1_up, "w")
wn.onkeypress(player2_up, "i")
wn.onkeypress(player1_down, "s")
wn.onkeypress(player2_down, "k")
wn.onkeypress(player1_right, "d")
wn.onkeypress(player2_right, "l")
wn.onkeypress(player1_left, "a")
wn.onkeypress(player2_left, "j")
wn.listen()
wn.mainloop()
I tried to simplify the code and I have seen this work in other programs. However, I cannot get it to work here!

NameError: name 'height' is not defined on line 10

I'm currently creating a game for a school project on Python. This is what I have so far and Python's telling me NameError: name 'height' is not defined on line 10. What does this mean? I've done lots of research, but I still can't figure it out. Can someone help me?
import turtle
enter code here`import random
def main():
wn=turtle.Screen();
Gameturtle=turtle.Turtle()
Setupuser(Gameturtle,wn)
Setupcontrols(Gameturtle,wn)
Randomanglegenerator(turtle,len,height)
li = []
InsertEnemyturtleintolist(li)
while (True):
Hitchecker(Gameturtle, li)
def Setupuser(myTurtle,window):
window.bgcolor("white")
#width=x height=y
window.setup (width=400, height=400, startx=100, starty=100)
myTurtle.speed(2)
myTurtle.shape('turtle')
myTurtle.penup()
myTurtle.delay(0)
myTurtle.left(90)
myTurtle.mainloop()
window.exitonclick ()
def Hitchecker(myTurtle, enemyTurtles):
for eturtle in enemyTurtles:
distance=myTurtle.distance(eturtle)
if distance <= 1:
print("You lost a life >:^D")
def InsertEnemyturtleintolist(list):
Enemy=turtle.Turtle()
Enemy.shape=("triangle")
Enemy.speed(5)
Enemy.penup()
Enemy.left(90)
Enemy.showturtle()
list.append(Enemy)
def Setupcontrols(turtle, window):
window.onkey(lambda: turtle.goto(turtle.xcor(), turtle.ycor()+15), 'w')
window.onkey(lambda: turtle.goto(turtle.xcor()-15, turtle.ycor()), 'a')
window.onkey(lambda: turtle.goto(turtle.xcor()+15, turtle.ycor()), 'd')
window.onkey(lambda: turtle.goto(turtle.xcor(), turtle.ycor()-15), 's')
window.listen()
def Randomanglegenerator(turtle,len,height):
XYcord = random.randrange(1,5)
print(XYcord)
if XYcord==2 or 4:
Enemy.setheading(90)
main()
There are several problems with your program. First, invalid or questionable Python syntax:
if XYcord==2 or 4:
wn=turtle.Screen();
Should be something like:
if XYcord == 2 or XYcord == 4:
wn = turtle.Screen()
These are equivalent methods and you should use one or the other, not both. And mainloop() is a method of the screen or a function in the package 'turtle', not a method of a turtle instance:
myTurtle.mainloop()
window.exitonclick()
Instead do:
window.mainloop()
or:
window.exitonclick()
Redefining Python built-ins like list is a bad idea:
def InsertEnemyturtleintolist(list):
...
list.append(Enemy)
instead do:
def InsertEnemyturtleintolist(myEnemiesList):
...
myEnemiesList.append(Enemy)
Finally, an infinite loop like this has no place in an event-driven world like turtle:
while (True):
we need to replace it with a timer event. Below is my rewrite of your code to address the above issues and get it to basically function:
from turtle import Screen, Turtle
from random import randrange
def main():
screen = Screen()
turtle = Turtle()
SetupUser(turtle, screen)
SetupControls(turtle, screen)
RandomAngleGenerator(turtle)
enemies = []
for _ in range(5):
InsertEnemyTurtleIntoList(enemies, turtle)
HitChecker(turtle, screen, enemies)
screen.mainloop()
def SetupUser(myTurtle, myScreen):
myScreen.bgcolor('white')
myScreen.setup(width=400, height=400, startx=100, starty=100)
myTurtle.speed('slow')
myTurtle.shape('turtle')
myTurtle.penup()
def SetupControls(myTurtle, myScreen):
myScreen.onkey(lambda: myTurtle.sety(myTurtle.ycor() + 15), 'w')
myScreen.onkey(lambda: myTurtle.setx(myTurtle.xcor() - 15), 'a')
myScreen.onkey(lambda: myTurtle.setx(myTurtle.xcor() + 15), 'd')
myScreen.onkey(lambda: myTurtle.sety(myTurtle.ycor() - 15), 's')
myScreen.listen()
def HitChecker(myTurtle, myScreen, enemyTurtles):
dead = False
for myEnemy in enemyTurtles:
if myTurtle.distance(myEnemy) <= 10:
print("You lost a life >:^D")
dead = True
break
if dead:
myScreen.onkey(None, 'w')
myScreen.onkey(None, 'a')
myScreen.onkey(None, 'd')
myScreen.onkey(None, 's')
else:
myScreen.ontimer(lambda: HitChecker(myTurtle, myScreen, enemyTurtles), 100)
def InsertEnemyTurtleIntoList(array, myTurtle):
enemy = Turtle()
enemy.hideturtle()
enemy.shape('triangle')
enemy.speed('normal')
enemy.penup()
enemy.left(90)
enemy.showturtle()
while enemy.distance(myTurtle) < 30:
enemy.setposition(randrange(-190, 190), randrange(-190, 190))
array.append(enemy)
def RandomAngleGenerator(myTurtle):
turns = randrange(1, 3)
for _ in range(turns):
myTurtle.left(90)
main()
I'm sure it doesn't do everything you want it to do yet, but this should give you a workable starting point to finish your program.

How to know who is winner in Tic Tac Toe in python using guizero

I have created a game called Tic Tac Toe. There are 2 players one of them are Xs one of them are Os all you have to do is get your symbol 3 in a row without the other person blocking you.
The Gui for the game looks like this:
Code:
from guizero import App, TextBox, PushButton, Text, info
empty = ' '
player = "X"
def clicked(z):
button = buttonlist[int(z)] # Finds out which button was pressed
global empty, player
if button.text != empty:
pass # If button already pushed do nothing
else:
# Marks button with user's go
button.text = player
# Switches players
if player == "X":
player = "O"
else:
player = "X"
return
def instructions():
info("Instructions","There are 2 players one of them are Xs one of them are Os. All you have to do is you have to try getting your symbol 3 times in a row without the other player blocking you")
def quit_game():
app.destroy()
app = App(title="Tic Tac Toe", layout="grid", width=200, height=250)
buttonlist = [] # Empty list to contain a list of Buttons
Player1_label = Text(app, text="Player 1", align="top", grid=[0, 0, 2 , 1])
Player1 = TextBox(app, text=empty, align="top", grid=[2, 0, 3, 1])# Player 1 enters the username
Player2_label = Text(app, text="Player 2", align="top", grid=[0, 1, 2 , 1])
Player2 = TextBox(app, text=empty, align="top", grid=[2, 1, 3, 1])# Player 2 enters the username
Instructions = PushButton(app, command=instructions, text="Instructions", grid=[0, 5, 3, 1])# Display the instructions
Quit = PushButton(app, command=quit_game ,text="Quit",grid=[10, 0, 3, 2])
# Create Buttons for game, in 3 rows of 3
z=0
for x in range(3):
for y in range(2, 5):
buttonlist.append(PushButton(app, text=empty, args=str(z), grid=[x, y], command=clicked))
z+=1
app.display()
The problem I have is in displaying who is the winner. I know how to make a window appear to show the winner and the line that does this is:
app.info("Tic Tac Toe Winner","The winner is" + Player1.value)
But the problem that i am having is knowing who is the winner at the end of the game so and displaying that they are the winner also I have a feeling that to find out the winner its got something to do with buttonlist list that i made but i just cannot figure out how to do it so I would appriciate if some one could help me.
Thanks
Nice game. To work with the game board, I would suggest to create an internal data representation rather than working with the gui elements all the time according to common practice.
The reason is, that if you work with the gui elements everywhere, it might be slower, as it is not the ideal data representation. You could not save the data with pickle etc and you also add a strong dependency to the gui framework you use.
E.g. if you later plan to convert it to a web application etc. you will have a very hard time.
So I just created a simple data representation in which I store the field in a two dimensional array.
# check_win checks if there are three markings
# in one row/column or diagonally
def check_win():
# the checks array is just a trick to
# reduce the amount of code,
# you could avoid it by just adding
# one nested loop where the outer iterates
# over y and the inner over x
# one with the outer on x and the inner on y
# and then two others with just one loop
# for the diagonals
# the body of the inner loops would
# esentially look the same as for the while
# loop below
checks= [(0, 0, 1, 1), (0, 2, 1, -1)]
for i in range(3):
checks.append((i, 0, 0, 1))
checks.append((0, i, 1, 0))
won= None
for y, x, incr_y, incr_x in checks:
player= field[y][x]
found= player is not None
while found and x < 3 and y < 3:
found= (player == field[y][x])
y+= incr_y
x+= incr_x
if found:
won= player
break
return won
# I also changed your clicked method a bit, so
# it calles the check_win method
# and also changed the signature, so
# it gets the y and x coordinate of the
# button which makes maintaining the
# field array inside the clicked method
# a bit simpler and also seems more natural
# to me
def clicked(y, x):
button = buttonlist[y][x] # Finds out which button was pressed
global empty, player
if button.text != empty:
pass # If button already pushed do nothing
else:
# Marks button with user's go
button.text = player
field[y][x] = player
# Switches players
if player == "X":
player = "O"
else:
player = "X"
won= check_win()
if won is not None:
print(f'Player {won} has won the game')
return
# now I initialize the field array
# it will contain None for an untouched
# cell and X/O if taken by the corresponding
# user
field= [[None] * 3 for i in range(3)]
buttonlist= list()
# to get the buttons to call the
# clicked function with the new
# signature and also maintain the
# buttons in a two dimensional array
# I changed the order of your loops
# and the args argument
for y in range(0, 3):
rowlist= list()
buttonlist.append(rowlist)
for x in range(3):
rowlist.append(PushButton(app, text=empty, args=(y, x), grid=[x, y+2], command=clicked))
z+=1
app.display()
# a plain vanilla version of check_win would look something like:
def check_win():
for start in range(3):
x= start
mark= field[0][x]
for y in range(1, 3):
if field[y][x] != mark:
# the sequence is not complete
mark= None
if mark is not None:
# player who set the mark won
return mark
y= start
mark= field[y][0]
for x in range(1, 3):
if field[y][x] != mark:
# the sequence is not complete
mark= None
if mark is not None:
# player who set the mark won
return mark
mark= field[0][0]
for x in range(1, 3):
if field[y][x] != mark:
# the sequence is not complete
mark= None
if mark is not None:
# player who set the mark won
return mark
mark= field[0][3]
for x in range(1, 3):
if field[y][2-x] != mark:
# the sequence is not complete
mark= None
if mark is not None:
# player who set the mark won
return mark
return None

Python Coding Need Assistance

I am having trouble with my code, I don't know what I can do. My code has a variable "bheight" and it splits into parts automatically(which I have coded and is good) but I want it so whenever it goes through the "def Building():" code it adds 1 onto bheight[0] so when it loops through next time it'll be bheight[1].
import turtle
turtle.bgcolor("orange")
blist = input('Please enter builidng heights e.g. "50 30 60"')
leo = turtle.Turtle()
bsplit = blist.split()
bheight = list(map(int, bsplit))
size = len(bsplit)
def Water():
leo.penup()
leo.goto(-200,0)
leo.fillcolor('midnightblue')
leo.begin_fill()
for a in range (1,3):
leo.forward(400)
leo.right(90)
leo.forward(150)
leo.right(90)
leo.end_fill()
leo.pendown()
def Building():
for x in range (0,int(size)):
leo.fillcolor('darkslategrey')
leo.begin_fill()
leo.left(90)
leo.forward(bheight[-1+1])
leo.right(90)
leo.forward(20)
leo.right(90)
leo.forward(bheight[-1+1])
leo.left(90)
leo.end_fill()
def Reset():
leo.towards(leo)
Water()
Building()
I agree with #maverick's index fix but don't see any need for the index in the first place. Instead of:
for x in range (0,int(size)):
...
leo.forward(bheight[x])
which really should be:
for x in range(size):
...
leo.forward(bheight[x])
why not simply do:
for height in bheight:
...
leo.forward(height)
The reworked code with this and various other style fixes:
from turtle import Turtle, Screen
def Water():
leo.penup()
leo.setx(-200)
leo.fillcolor('midnightblue')
leo.begin_fill()
for _ in range(2):
leo.forward(400)
leo.right(90)
leo.forward(150)
leo.right(90)
leo.end_fill()
leo.pendown()
def Building():
leo.fillcolor('darkslategrey')
for height in bheight:
leo.begin_fill()
leo.left(90)
leo.forward(height)
leo.right(90)
leo.forward(20)
leo.right(90)
leo.forward(height)
leo.left(90)
leo.end_fill()
blist = input('Please enter building heights e.g. "50 30 60": ')
bsplit = blist.split()
bheight = list(map(int, bsplit))
screen = Screen()
screen.bgcolor("orange")
leo = Turtle()
Water()
Building()
screen.mainloop()
Change the def building code:-
def Building():
for x in range (0,int(size)):
leo.fillcolor('darkslategrey')
leo.begin_fill()
leo.left(90)
leo.forward(bheight[x])
leo.right(90)
leo.forward(20)
leo.right(90)
leo.forward(bheight[x])
leo.left(90)
leo.end_fill()
What was happening in your code was that everytime your where doing -1+1 which will get value at 0th index.Instead just add 'x'.

Individual keypress bug in python

The following code is a python sprinting game. It was posted as an answer to my previous post, by #mango You have to tap 'a' and 'd' as fast as you can to run 100 meters. However, there are a few bugs...
1) If you hold down 'a' and 'd' at the same time, the game is completed as fast as possible and defeats the point of the game.
2) Like in my previous post, I would like to incorporate a scoring system into this code, however, due to my level of skill and experience with python, unfortunately, I am unable to do so, and would appreciate and suggestions.
Many Thanks
Previous code:
import msvcrt
import time
high_score = 50
name = "no-one"
while True:
distance = int(0)
print("\n--------------------------------------------------------------")
print('\n\nWelcome to the 100m sprint, tap a and d rapidly to move!')
print('* = 10m')
print("\n**Current record: " + str(high_score) + "s, by: " + name)
print('\nPress enter to start')
input()
print('Ready...')
time.sleep(1)
print('GO!')
start_time = time.time()
while distance < 100:
k1 = msvcrt.getch().decode('ASCII')
if k1 == 'a':
k2 = msvcrt.getch().decode('ASCII')
if k2 == 'd':
distance += 1
if distance == 50:
print("* You're halfway there!")
elif distance % 10 == 0:
print('*')
fin_time = time.time() - start_time
fin_time = round(fin_time,2)
print('Well done you did it in...'+str(fin_time))
if fin_time < high_score:
print("Well done you've got a new high score ")
name = input("Please enter your name : ")
This is the code that I recieved as feedback, I have made a few changes, but I am struggling witht the bugs that I listed before.
1) If you hold down 'a' and 'd' at the same time, the game is completed as fast as possible and defeats the point of the game.
2) Like in my previous post, I would like to incorporate a scoring system into this code, however, due to my level of skill and experience with python, unfortunately, I am unable to do so, and would appreciate and suggestions.
Many Thanks
# these are the modules we'll need
import sys
import tkinter as tk
class SprintGame(object):
# this represents the distance we'll allow our player to run
# NOTE: the distance is in meters
distance = 100
# this represents the stride length of the players legs
# NOTE: basically how far the player can travel in one footstep
stride = 1.5
# this represents the last key the user has pressed
lastKey = ""
# this represents wether or not the race has been completed
completed = False
# this function initiates as soon as the "sprint" variable is defined
def __init__(self):
# create the tk window
self.root = tk.Tk()
# set the tk window size
self.root.geometry('600x400')
# set the tk window title
self.root.title("Sprinting Game")
# bind the keypress event to the self.keypress handler
self.root.bind('<KeyPress>', self.keypress)
# center the window
self.centerWindow(self.root)
# insert the components
self.insertComponents()
# initial distance notice
self.output("{0}m left to go!".format(self.distance))
# start out wonderful game
self.start()
# this function centers the window
def centerWindow(self, window):
window.update_idletasks()
# get the screen width
width = window.winfo_screenwidth()
# get the screen height
height = window.winfo_screenheight()
# get the screen size
size = tuple(int(_) for _ in window.geometry().split('+') [0].split('x'))
# get the screen's dimensions
x = (width / 2) - (size[0] / 2)
y = (height / 2) - (size[1] / 2)
# set the geometry
window.geometry("%dx%d+%d+%d" % (size + (x, y)))
# this function replaces the old text in the textbox with new text
def output(self, text = ""):
self.text.delete('1.0', tk.END)
self.text.insert("end", text)
# this function handles key presses inside the tkinter window
def keypress(self, event):
# get the key and pass it over to self.logic
self.logic(event.char)
# this function handles game logic
def logic(self, key):
# convert key to a lower case string
key = str(key).lower()
# let us know how far we've got left
if key == "l":
self.output("{0}m left to go!".format(self.distance))
# restart the race
if key == "r":
# clear the output box
self.text.delete('1.0', tk.END)
# reset the distance
self.distance = 100
# reset the stride
self.stride = 1.5
# reset the last key
self.lastKey = ""
# set race completed to false
self.completed = False
# output restart notice
self.output("The Race Has Been Restarted.")
# don't bother with logic if race is completed
if self.completed == True:
return False
# check if distance is less than or equal to zero (meaning the race is over)
if self.distance <= 0:
# set the "self.completed" variable to True
self.completed = True
# let us know we've completed the race
self.output("Well done, you've completed the race!")
# return true to stop the rest of the logic
return True
# convert the key to lower case
key = key.lower()
# this is the quit function
if key == "q":
# lights out...
sys.exit(0)
# check if the key is a
if key == "a":
# set the last key to a so that we can decrement the "distance"
# variable if it is pressed next
self.lastKey = "a"
# only bother with "d" keypresses if the last key was "a"
if self.lastKey == "a":
# capture the "d" keypress
if key == "d":
# decrement the "distance" variable
self.distance -= self.stride
# let us know how far into the game we are
self.output("{0}m left to go!".format(self.distance))
# this function inserts the components into the window
def insertComponents(self):
# this component contains all of our output
self.text = tk.Text(self.root, background='#d6d167', foreground='#222222', font=('Comic Sans MS', 12))
# lets insert out text component
self.text.pack()
# this function opens the window and starts the game
def start(self):
self.root.mainloop()
# create a new instance of the game
Game = SprintGame()

Categories