Python Turtle Window freezes when I execute the code - python

I made a simple text-based tic-tac-toe game and now I am trying to step it up creating a GUI using the Turtle module. The problem is that when I run my program, the Turtle window draws the board correctly, but then freezes and stops responding. I tried searching this problem everywhere and some people said that it could have to do with the line screen.mainloop(), but I can't figure out what is wrong.
Here is my code:
import warnings
import numpy as np
from turtle import Turtle, Screen
warnings.simplefilter(action='ignore', category=FutureWarning)
def create_board():
# turtle.hideturtle()
turtle.speed(0)
turtle.pensize(5)
turtle.left(90)
turtle.penup()
turtle.setpos(-150, -450)
turtle.pendown()
turtle.forward(900)
turtle.penup()
turtle.setpos(150, -450)
turtle.pendown()
turtle.forward(900)
turtle.right(90)
turtle.penup()
turtle.setpos(-450, -150)
turtle.pendown()
turtle.forward(900)
turtle.penup()
turtle.setpos(-450, 150)
turtle.pendown()
turtle.forward(900)
def enter_data(matrix, user, number):
if user == 1:
matrix = np.where(matrix == number, 'X', matrix)
if is_winner(matrix):
user = 1
else:
user = 2
elif user == 2:
matrix = np.where(matrix == number, 'O', matrix)
if is_winner(matrix):
user = 2
else:
user = 1
return matrix, user
def show_board(matrix):
print('-----|-----|-----')
for i in range(3):
print(f' {matrix[i][0]} | {matrix[i][1]} | {matrix[i][2]} ')
print('-----|-----|-----')
return
def is_winner(matrix):
for i in range(3):
if matrix[0][i] == matrix[1][i] == matrix[2][i]:
return True
elif matrix[:, 0][i] == matrix[:, 1][i] == matrix[:, 2][i]:
return True
if matrix[0][0] == matrix[1][1] == matrix[2][2]:
return True
elif matrix[0][2] == matrix[1][1] == matrix[2][0]:
return True
else:
return False
def draw_circle(x, y):
turtle.penup()
turtle.goto(x, y + 60)
turtle.pendown()
turtle.circle(-60)
def draw_cross(x, y):
turtle.penup()
turtle.goto(x - 60, y - 60)
turtle.pendown()
turtle.goto(x + 60, y + 60)
turtle.penup()
turtle.goto(x - 60, y + 60)
turtle.pendown()
turtle.goto(x + 60, y - 60)
screen = Screen()
screen.setup(width=0.65, height=0.95, starty=0)
turtle = Turtle()
create_board()
array = np.array(np.mat('1 2 3; 4 5 6; 7 8 9'), dtype=object)
count = 0
player = 1
show_board(array)
while count < 9 and is_winner(array) is not True:
choice = int(input(f'\nPlayer {player}, enter the number you want:\n'))
if choice not in range(1, 10) or choice not in array:
print('\nThat is invalid. Try again.\n')
show_board(array)
else:
count += 1
array, player = enter_data(array, player, choice)
screen.update()
show_board(array)
if count == 9:
print("\nThat's a draw.")
else:
print(f'\nPlayer {player} won! Congratulations!!')
print('Game Over!')
screen.mainloop()
Any help would be very much appreciated.

Related

I have problem with my game, when the ball goes over the block, it is not deleting from my screen

Someone can help me please?
I spent many hours to understand the problem.. (Without success 🤣)
I tried to built a 80s hit game.
The problem is that when the ball goes on one of the stones, I catch the event (shows me in the console) and update the list of blocks but the block is not deleted from the screen as if nothing happened and I did not update any list
this is my code:
import time
from turtle import Screen, Turtle
import random
screen = Screen()
screen.bgcolor("black")
screen.setup(width=800, height=600)
screen.tracer(0)
player = Turtle("square")
player.shapesize(1.0, 4.0, 0)
player.color("blue")
player.penup()
player.goto(0, -250)
screen.tracer(0)
blue_turtle = []
blue_positions = []
for i in range(7):
turtle = Turtle("square")
turtle.shapesize(2.0 ,4.0, 0)
turtle.color("blue")
turtle.penup()
blue_positions.append((-300 + i * 100, 200))
blue_turtle.append(turtle)
def renderBlocks(b):
for i in range(len(b) - 1):
if b[i] == None:
print("Skipped")
continue
else:
x, y= blue_positions[i]
b[i].goto(x=x, y=y)
# total += 100
ball = Turtle("circle")
ball.color("white")
game_on = True
def move():
x = ball.xcor() + 10
y = ball.ycor()+ 10
ball.goto(x=x, y=y)
while game_on:
move()
renderBlocks(blue_turtle)
for i in range(len(blue_turtle) - 1):
if (blue_turtle[i] != None) and ball.distance(blue_turtle[i]) < 20:
blue_turtle[i] = (None)
time.sleep(0.1)
screen.update()
screen.exitonclick()
I believe the problem is here:
blue_turtle[i] = (None)
You tell your code that the turtle has been eliminated but you don't tell turtle graphics that it should be removed. Instead consider:
blue_turtle[i].hideturtle()
blue_turtle[i] = None
My rework of your code addressing this issue and some others:
from turtle import Screen, Turtle
def renderBlocks(b):
for i in range(len(b) - 1):
if b[i]:
x, y = blue_positions[i]
b[i].goto(x, y)
def move():
if game_on:
x = ball.xcor() + 10
y = ball.ycor() + 10
ball.goto(x, y)
renderBlocks(blue_turtles)
for i in range(len(blue_turtles) - 1):
if blue_turtles[i] and ball.distance(blue_turtles[i]) < 20:
blue_turtles[i].hideturtle()
blue_turtles[i] = None
screen.update()
screen.ontimer(move, 100) # milliseconds
screen = Screen()
screen.setup(width=800, height=600)
screen.bgcolor('black')
screen.tracer(0)
player = Turtle('square')
player.shapesize(1, 4, 0)
player.color('blue')
player.penup()
player.sety(-250)
blue_turtles = []
blue_positions = []
for i in range(7):
turtle = Turtle('square')
turtle.shapesize(2, 4, 0)
turtle.color('blue')
turtle.penup()
blue_positions.append((-300 + i * 100, 200))
blue_turtles.append(turtle)
ball = Turtle('circle')
ball.color('white')
game_on = True
move()
screen.exitonclick()

How can I start drawing from a specific place in Python turtle?

I'm trying to draw grass and I'm struggling to make my drawing start from the bottom left then go all the way to the bottom right. I know there is something wrong with my code but can't figure it out.
The code I have starts from the middle and that's not what I want.
import turtle
import random
window = turtle.Screen()
bob = turtle.Turtle()
window.bgcolor("white")
window.title("TURTLE")
bob.pencolor("green")
window.colormode(255)
position = 0
height = 0
height11 = 0
height12 = 0
height13 = 0
height14 = 0
def draw_grass(bob):
green = random.randint (100, 200)
length = random.randint(10,20)
bob.fillcolor(0,green,0)
bob.begin_fill()
bob.setheading(90)
for i in range (2):
bob.forward(length)
bob.right(90)
bob.forward(3)
bob.right(90)
bob.end_fill()
bob.penup()
bob.pendown()
return length
for i in range (10):
height = draw_grass(bob)
position = position + 3
bob.goto(position, 0)
if height == 11 :
height11 = height11 + 1
elif height == 12:
height12 = height12 + 1
elif height == 13:
height13 = height13 + 1
You need to understand that the origin (0, 0) is in the center of the window and you have to work with positive and negative numbers. The screen methods window_width() and window_height() are useful for figuring out the size of a window that you didn't configure yourself. Here's a rework of your code that incorporates these ideas:
from turtle import Screen, Turtle
from random import randint
def draw_grass(turtle):
green = randint(100, 200)
length = randint(10, 20)
turtle.fillcolor(0, green, 0)
turtle.begin_fill()
for _ in range(2):
turtle.forward(3)
turtle.left(90)
turtle.forward(length)
turtle.left(90)
turtle.end_fill()
turtle.penup()
turtle.pendown()
return length
screen = Screen()
screen.bgcolor('white')
screen.title("TURTLE")
screen.colormode(255)
turtle = Turtle()
turtle.pencolor('green')
turtle.speed('fastest') # because I have no patience
turtle.penup()
turtle.setposition(6 - screen.window_width()//2, 12 - screen.window_height()//2)
turtle.pendown()
height11 = 0
height12 = 0
height13 = 0
height14 = 0
while turtle.xcor() < screen.window_width()//2 - 6:
height = draw_grass(turtle)
if height == 11:
height11 += 1
elif height == 12:
height12 += 1
elif height == 13:
height13 += 1
elif height == 14:
height14 += 1
turtle.forward(3)
screen.exitonclick()

Turtle code not working, showing py-lint no member error

i believe i have coded everything correctly but i keep getting an error message saying, for example("Module 'turtle' has no 'reset' member)
import turtle
color = input('Enter a color:')
while (color != "QUIT"):
turtle.reset()
turtle.pencolor(color)
turtle.pensize(10)
n = int(input('Enter a number:'))
if n % 3 == 0 and n % 5 == 0:
turtle.penup()
turtle.setposition(x=0, y=150)
turtle.pendown()
drawU(turtle.Turtle)
turtle.penup()
turtle.setposition(x = 0, y = -10)
turtle.pendown()
drawH(t)
elif n % 3 == 0:
turtle.penup()
turtle.setposition(x=0, y=150)
turtle.pendown()
drawU(turtle.Turtle)
elif n % 5 == 0:
turtle.penup()
turtle.setposition(x=0, y=150)
turtle.pendown()
drawH(turtle.Turtle)
else:
turtle.pencolor('black')
def drawU (t):
turtle.setheading(270)
turtle.forward(150)
turtle.left(90)
turtle.forward(75)
turtle.left(90)
turtle.forward(150)
each "turtle.____" shows as an error. i am not too sure what i am doing wrong. i included turtle.done() at the end as well, this is only half of my code.
i believe i have coded everything correctly
Far from it: termination of your loop depends on the value of color which never changes during the loop; you should be passing a turtle instance here drawU(turtle.Turtle) but are passing a turtle class; your else clause makes no sense, effectively a no-op; your indentation as shown doesn't work; your drawH() function is missing.
Below is my attempt to reconstruct your intended code, but I can't be certain:
from turtle import Screen, Turtle
def drawU(turtle):
turtle.setheading(270)
turtle.forward(150)
turtle.left(90)
turtle.forward(75)
turtle.left(90)
turtle.forward(150)
def drawH(turtle):
pass
color = input('Enter a color: ')
screen = Screen()
turtle = Turtle()
while color != "QUIT":
n = int(input('Enter a number: '))
turtle.reset()
turtle.pencolor(color)
turtle.pensize(10)
if n % 3 == 0 and n % 5 == 0:
turtle.penup()
turtle.setposition(x=0, y=150)
turtle.pendown()
drawU(turtle)
turtle.penup()
turtle.setposition(x=0, y=10)
turtle.pendown()
drawH(turtle)
elif n % 3 == 0:
turtle.penup()
turtle.setposition(x=0, y=150)
turtle.pendown()
drawU(turtle)
elif n % 5 == 0:
turtle.penup()
turtle.setposition(x=0, y=150)
turtle.pendown()
drawH(turtle)
color = input('Enter a color: ')
screen.mainloop()

Adding user checks to Python turtle tic-tac-toe game

import turtle
#1)draw board
sc= turtle.Screen()
sc.setup(300,300)
import turtle
sc= turtle.Screen()
sc.setup(300,300)
turtle.speed(0)
turtle.pensize(10)
turtle.bgcolor("black")
turtle.pencolor("white")
turtle.penup()
turtle.goto(-150,50)
turtle.pendown()
turtle.forward(300)
turtle.penup()
turtle.goto(-150,-50)
turtle.pendown()
turtle.forward(300)
turtle.penup()
turtle.goto(-50,150)
turtle.setheading(-90)
turtle.pendown()
turtle.forward(300)
turtle.penup()
turtle.goto(50,150)
turtle.pendown()
turtle.forward(300)
turtle.penup()
#2) X's and O's
turtle.pencolor("yellow")
def kreuz(x,y):
turtle.penup()
turtle.goto(x+30,y-45)
turtle.setheading(-45)
turtle.pendown()
turtle.forward(50)
turtle.penup()
turtle.goto(x+60,y-40)
turtle.setheading(-130)
turtle.pendown()
turtle.forward(50)
turtle.penup()
def kreis(x,y):
turtle.penup()
turtle.goto(x+50,y-80)
turtle.setheading(0)
turtle.pendown()
turtle.circle(20)
turtle.penup()
AlleTeile=["","","","","","","","",""]
nächsterZug="X"
def zeichneTeile (AlleTeile):
x = -150
y = 150
for einTeil in AlleTeile:
if einTeil=="X":
kreuz(x,y)
elif einTeil=="O":
kreis(x,y)
else:
print("leeres feld")
x=x+100
if x > 50:
x=-150
y=y-100
zeichneTeile(AlleTeile)
def geklickt(x,y):
global nächsterZug,AlleTeile
senkrecht= (x+150) // 100
waagrecht= (-y+150)// 100
Bereich= senkrecht+waagrecht*3
Bereich=int(Bereich)
print("Du klicktest auf Bereich-Nummer", Bereich)
AlleTeile[Bereich]=nächsterZug
if nächsterZug =="X":
nächsterZug="O"
else:
nächsterZug="X"
zeichneTeile(AlleTeile)
turtle.onscreenclick(geklickt)
turtle.mainloop()
I want to create this tic-tac-toe game using turtle in Python but I am stuck. The problem is that I keep drawing noughts and crosses on the game board after all 9 fields are full with noughts and crosses. How can I code this so that after 9 turns (9 fields) it is no longer possible to keep on drawing?
Since unused squares consist of an empty string in AlleTeile, this is trivial to fix since empty strings are False in a boolean context. At the top of geklickt(), after the global statement:
if all(AlleTeile):
print("All taken!")
return
We can reuse the same trick later in that function to prevent overwritting of existing squares. After the Bereich calculation, we can do something like:
print("Du klicktest auf Bereich-Nummer", Bereich, end="")
if AlleTeile[Bereich]:
print(" -- already taken!")
return
else:
print()
Here's my complete rework with the above changes, some turtle idoms, code cleanup and English translation courtesy of Google (and common sense):
from turtle import Screen, Turtle
# X's and O's
def cross(x, y):
turtle.penup()
turtle.goto(x + 30, y - 35)
turtle.setheading(-45)
turtle.pendown()
turtle.forward(50)
turtle.penup()
turtle.goto(x + 60, y - 30)
turtle.setheading(-130)
turtle.pendown()
turtle.forward(50)
turtle.penup()
def nought(x, y):
turtle.penup()
turtle.goto(x + 50, y - 70)
turtle.setheading(0)
turtle.pendown()
turtle.circle(20)
turtle.penup()
# Playing the game
def drawSquares():
screen.tracer(False) # because this routine is a graphics bottleneck
x, y = -150, 150
for square in AllSquares:
if square == "X":
cross(x, y)
elif square == "O":
nought(x, y)
x += 100
if x > 50:
x = -150
y -= 100
screen.tracer(True)
def clicked(x, y):
global turn
if all(AllSquares):
print("All taken!")
return
vertical = (x + 150) // 100
horizontal = (150 - y) // 100
Area = int(vertical + horizontal * 3)
print("You clicked area number", Area, end="")
if AllSquares[Area]:
print(" -- already taken!")
return
else:
print()
AllSquares[Area] = turn
if turn == "X":
turn = "O"
else:
turn = "X"
drawSquares()
# Draw the board
screen = Screen()
screen.setup(330, 330)
screen.bgcolor("black")
turtle = Turtle(visible=False)
turtle.pensize(10)
turtle.color("white")
turtle.speed('fastest')
turtle.penup()
turtle.goto(-150, 50)
turtle.pendown()
turtle.forward(300)
turtle.penup()
turtle.goto(-150, -50)
turtle.pendown()
turtle.forward(300)
turtle.setheading(-90)
turtle.penup()
turtle.goto(-50, 150)
turtle.pendown()
turtle.forward(300)
turtle.penup()
turtle.goto(50, 150)
turtle.pendown()
turtle.forward(300)
turtle.penup()
# Start the game
turtle.color("yellow")
AllSquares = ["", "", "", "", "", "", "", "", ""]
turn = "X"
drawSquares()
screen.onscreenclick(clicked)
screen.mainloop()

Drawing a chessboard with Turtle (even number dimension fail)

I have written this Python code with turtle graphics for drawing a chessboard by given dimension. The problem I'm facing is when I enter an odd number everything works just fine:
The last square is also filled, I just didn't manage to screen shot it on time
But when I enter an even number, it's like:
Here's the code:
from turtle import *
import sys
def main():
dimension = int(input('Enter dimension: '))
side = 50
x_coord = -250
y_coord = 300
turtle = Turtle()
turtle.speed('fastest')
turtle.pensize(5)
for i in range(dimension ** 2):
if not i % dimension:
y_coord -= side
turtle.penup()
turtle.setx(x_coord)
turtle.sety(y_coord)
turtle.pendown()
if not i % 2:
turtle.begin_fill()
for _ in range(4):
turtle.forward(side)
turtle.right(90)
turtle.forward(side)
turtle.end_fill()
if __name__ == '__main__':
sys.exit(main())
A similar flag-based solution with alternate approaches. I don't understand what your main() layout gets you so I reworked it to be a potential library with the test code under __main__:
import turtle
def draw_board(dimension, x_coord, y_coord, side):
parity = False
for i in range(dimension ** 2):
if i % dimension == 0:
y_coord -= side
turtle.penup()
turtle.setpos(x_coord, y_coord)
turtle.pendown()
parity = parity != (dimension % 2 == 0) # logical XOR
if parity:
turtle.begin_fill()
for _ in range(4):
turtle.forward(side)
turtle.right(90)
if turtle.filling():
turtle.end_fill()
turtle.forward(side)
parity = not parity
if __name__ == '__main__':
size = int(input('Enter dimension: '))
turtle.speed('fastest')
turtle.pensize(5)
draw_board(size, -250, 300, 50)
turtle.hideturtle()
turtle.exitonclick()
I didnt look through your code, but it seems that the problem you have is that unlike a true chessboard, you change from white to black and vice versa when making a new line of squares, this example:
black,white,black,white
black,white,black,white
etc.
or black,white,black
white,black,white
etc.
while a chessboard is:
black,white,black,white
WHITE,black,white,black
BLACK....etc.
you see the difference?
so that seems to be the problem, il try to fix your code aswell, but i think you could manage that
I suggest setting a flag for when to fill instead of doing it only when it's an odd number from the range which is what trips you up since it doesn't go black white left to right, it reaches then end an then goes right to left.
Anyway, here is my edit, just a simple boolean which toggles each time except when going to new row. I also suggest using turtle.exitonclick instead of sys.exit
from turtle import *
def main():
dimension = int(input('Enter dimension: '))
side = 50
x_coord = -250
y_coord = 300
turtle = Turtle()
turtle.speed('fastest')
turtle.pensize(5)
fill = False
for i in range(dimension ** 2):
if not i % dimension:
y_coord -= side
turtle.penup()
turtle.setx(x_coord)
turtle.sety(y_coord)
turtle.pendown()
if not dimension % 2:
fill = not fill
if fill:
turtle.begin_fill()
for _ in range(4):
turtle.forward(side)
turtle.right(90)
turtle.forward(side)
turtle.end_fill()
fill = not fill
if __name__ == '__main__':
main()
exitonclick()
For Python 3,7 I would recommend this way
import turtle
turtle.speed(0)
turtle.up()
turtle.goto(-200,200)
turtle.down()
for row in range(8):
for col in range(8):
if col % 2 == row % 2:
turtle.forward(50)
continue
turtle.begin_fill()
for _ in range(4):
turtle.forward(50)
turtle.right(90)
turtle.end_fill()
turtle.forward(50)
turtle.backward(400)
turtle.right(90)
turtle.forward(50)
turtle.left(90)
turtle.width(6)
for _ in range(4):
turtle.forward(400)
turtle.left(90)
turtle.hideturtle()
turtle.done()

Categories

Resources