'Python tetris input delay gets exponentially longer
import turtle
import random
wn = turtle.Screen()
tetris = turtle.Turtle()
wn.tracer(0)
grid = []
tetriminos = ['t','l','j','i','s','z','o']
class square():
def __init__(self, falling, block, color):
self.falling = falling
self.block = block
self.color = color
for i in range(12):
grid.append([])
for i in range(12):
for j in range(25):
grid[i].append(square(False, False, 'gray'))
def gridsquare(color):
tetris.setheading(0)
tetris.color(color)
tetris.begin_fill()
for i in range(4):
tetris.forward(20)
tetris.right(90)
tetris.end_fill()
tetris.color('black')
def refreshGrid():
for i in range(12):
for j in range(25):
tetris.pu()
tetris.goto(i * 20 - 120, j * 20 - 250)
tetris.pd()
if grid[i][j].block == True:
gridsquare(grid[i][j].color)
elif grid[i][j].falling == True:
gridsquare('green')
else:
gridsquare('gray')
wn.update()
def left():
ok = True
for i in range(12):
for j in range(25):
if grid[i][j].falling == True:
if grid[i - 1][j].block == True:
ok = False
if ok == True:
for i in range(12):
for j in range(25):
if grid[i][j].falling == True:
grid[i][j].falling = False
grid[i - 1][j].falling = True
refreshGrid()
def right():
ok = True
for i in range(12):
for j in range(25):
if grid[i][j].falling == True:
if grid[i + 1][j].block == True:
ok = False
if ok == True:
for i in range(12):
for j in range(25):
if grid[11 - i][j].falling == True:
grid[11 - i][j].falling = False
grid[11 - i + 1][j].falling = True
refreshGrid()
def down():
ok = True
for i in range(12):
for j in range(25):
if grid[i][j].falling == True:
if grid[i][j - 1].block == True:
ok = False
if ok == True:
for i in range(12):
for j in range(25):
if grid[i][j].falling == True:
grid[i][j].falling = False
grid[i][j - 1].falling = True
refreshGrid()
else:
for i in range(12):
for j in range(25):
if grid[i][j].falling == True:
grid[i][j].falling = False
grid[i][j].block = True
grid[i][j].color = 'blue'
refreshGrid()
newTetrimino()
def newTetrimino():
tet = tetriminos[random.randint(0, 6)]
#'t','l','j','i','s','z','o'
#middle top - 5, 24
if tet == 'z':
grid[5][24].falling = True
grid[5][23].falling = True
grid[4][24].falling = True
grid[6][23].falling = True
elif tet == 's':
grid[5][24].falling = True
grid[5][23].falling = True
grid[4][23].falling = True
grid[6][24].falling = True
elif tet == 't':
grid[5][23].falling = True
grid[4][23].falling = True
grid[6][23].falling = True
grid[5][24].falling = True
elif tet == 'l':
grid[5][23].falling = True
grid[4][23].falling = True
grid[6][23].falling = True
grid[6][24].falling = True
elif tet == 'j':
grid[5][23].falling = True
grid[4][23].falling = True
grid[6][23].falling = True
grid[4][24].falling = True
elif tet == 'i':
grid[5][24].falling = True
grid[4][24].falling = True
grid[6][24].falling = True
grid[7][24].falling = True
elif tet == 'o':
grid[6][24].falling = True
grid[7][24].falling = True
grid[6][23].falling = True
grid[7][23].falling = True
refreshGrid()
grid[5][23].falling = True
grid[4][23].falling = True
grid[6][23].falling = True
grid[5][24].falling = True
for i in range(25):
grid[0][i].block = True
grid[0][i].color = 'black'
for i in range(25):
grid[11][i].block = True
grid[11][i].color = 'black'
for i in range(12):
grid[i][0].block = True
grid[i][0].color = 'black'
refreshGrid()
wn.listen()
wn.onkeypress(left,'a')
wn.onkeypress(right,'d')
wn.onkeypress(down,'s')
wn.mainloop()
Ok so Sorry for long code I'm trying to code tetris and i have the basics down but for some reason each tetrimino you place, it gets exponentially longer input delay I expect a little bit of input delay because of how much it has to check but i don't see why there gets more after each placement
help would be appreciated a lot
Also I am very much a beginner so please explain it as if I was an old grandma thanks
Solution 1:[1]
You've chosen an inefficient approach, graphics-wise. But let's work with it. I've optimized the code below, trying to avoid unnecessary looping and drawing. This seems to help.
Move improvement seems to have come from clearing the old drawing before drawing a new one. That is, you were stacking complete drawings atop all previous drawings whenever you did refreshGrid(). We think of the old drawings as dead ink turtle-wise, but to the underlying tkinter graphics, they are all live entities. By clearing the old drawing before making the new one, we clear out the dead elements we no longer consider valid:
from turtle import Screen, Turtle
from random import choice
tetriminos = ['t', 'l', 'j', 'i', 's', 'z', 'o']
class square():
def __init__(self, falling, block, color):
self.falling = falling
self.block = block
self.color = color
def gridsquare(color):
tetris.color(color)
tetris.pendown()
tetris.begin_fill()
for _ in range(4):
tetris.forward(20)
tetris.right(90)
tetris.end_fill()
tetris.penup()
def refreshGrid():
tetris.clear()
for j in range(25):
tetris.goto(-120, j * 20 - 250)
for i in range(12):
if grid[i][j].block:
gridsquare(grid[i][j].color)
elif grid[i][j].falling:
gridsquare('green')
else:
gridsquare('gray')
tetris.forward(20)
screen.update()
def left():
for i in range(1, 11):
for j in range(1, 25):
if grid[i][j].falling and grid[i - 1][j].block:
return
screen.onkeypress(None, 'a')
for i in range(1, 11):
for j in range(1, 25):
if grid[i][j].falling:
grid[i][j].falling = False
grid[i - 1][j].falling = True
refreshGrid()
screen.onkeypress(left, 'a')
def right():
for i in range(1, 11):
for j in range(1, 25):
if grid[i][j].falling and grid[i + 1][j].block:
return
screen.onkeypress(None, 'd')
for i in range(11, 0, -1):
for j in range(1, 25):
if grid[i][j].falling:
grid[i][j].falling = False
grid[i + 1][j].falling = True
refreshGrid()
screen.onkeypress(right, 'd')
def down():
screen.onkeypress(None, 's') # disable handler inside handler
ok = True
for i in range(1, 11):
for j in range(1, 25):
if grid[i][j].falling and grid[i][j - 1].block:
ok = False
if ok:
for i in range(1, 11):
for j in range(1, 25):
if grid[i][j].falling:
grid[i][j].falling = False
grid[i][j - 1].falling = True
refreshGrid()
else:
for i in range(1, 11):
for j in range(1, 25):
if grid[i][j].falling:
grid[i][j].falling = False
grid[i][j].block = True
grid[i][j].color = 'blue'
refreshGrid()
newTetrimino()
screen.onkeypress(down, 's') # reenable handler on exit
def newTetrimino():
tetrimino = choice(tetriminos) # 't','l','j','i','s','z','o'
# middle top - 5, 24
if tetrimino == 'z':
grid[5][24].falling = True
grid[5][23].falling = True
grid[4][24].falling = True
grid[6][23].falling = True
elif tetrimino == 's':
grid[5][24].falling = True
grid[5][23].falling = True
grid[4][23].falling = True
grid[6][24].falling = True
elif tetrimino == 't':
grid[5][23].falling = True
grid[4][23].falling = True
grid[6][23].falling = True
grid[5][24].falling = True
elif tetrimino == 'l':
grid[5][23].falling = True
grid[4][23].falling = True
grid[6][23].falling = True
grid[6][24].falling = True
elif tetrimino == 'j':
grid[5][23].falling = True
grid[4][23].falling = True
grid[6][23].falling = True
grid[4][24].falling = True
elif tetrimino == 'i':
grid[5][24].falling = True
grid[4][24].falling = True
grid[6][24].falling = True
grid[7][24].falling = True
elif tetrimino == 'o':
grid[6][24].falling = True
grid[7][24].falling = True
grid[6][23].falling = True
grid[7][23].falling = True
refreshGrid()
grid = [[square(False, False, 'gray') for j in range(25)] for i in range(12)]
for j in range(25):
grid[0][j].block = True
grid[0][j].color = 'black'
grid[11][j].block = True
grid[11][j].color = 'black'
for i in range(1, 11):
grid[i][0].block = True
grid[i][0].color = 'black'
screen = Screen()
screen.tracer(0)
tetris = Turtle()
tetris.hideturtle()
tetris.penup()
newTetrimino()
screen.onkeypress(left, 'a')
screen.onkeypress(right, 'd')
screen.onkeypress(down, 's')
screen.listen()
screen.mainloop()
See if this fixes your exponential delays.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | cdlane |
