importkandinskyaskdimportionimportrandomimporttime# Screen dimensions for the NumWorks calculator
SCREEN_WIDTH=320SCREEN_HEIGHT=240CELL_SIZE=10GRID_WIDTH=SCREEN_WIDTH//CELL_SIZEGRID_HEIGHT=SCREEN_HEIGHT//CELL_SIZE# Tetromino shapes
SHAPES=[[[1,1,1,1]],# I
[[1,1],[1,1]],# O
[[0,1,0],[1,1,1]],# T
[[1,1,0],[0,1,1]],# Z
[[0,1,1],[1,1,0]],# S
[[1,1,1],[1,0,0]],# L
[[1,1,1],[0,0,1]]# J
]# Colors for each tetromino
COLORS=[(0,255,255),# Cyan for I
(255,255,0),# Yellow for O
(128,0,128),# Purple for T
(255,0,0),# Red for Z
(0,255,0),# Green for S
(255,165,0),# Orange for L
(0,0,255)# Blue for J
]# Draw a single cell at a grid position
defdraw_cell(x,y,color):kd.fill_rect(x*CELL_SIZE,y*CELL_SIZE,CELL_SIZE,CELL_SIZE,color)# Clear the screen
defclear_screen():kd.fill_rect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,kd.white)# Draw the entire grid
defdraw_grid(grid):foryinrange(GRID_HEIGHT):forxinrange(GRID_WIDTH):ifgrid[y][x]!=0:draw_cell(x,y,COLORS[grid[y][x]-1])# Initialize a blank grid
defcreate_grid():return[[0]*GRID_WIDTHfor_inrange(GRID_HEIGHT)]# Check for collision
defcheck_collision(grid,shape,offset):off_x,off_y=offsetfory,rowinenumerate(shape):forx,cellinenumerate(row):ifcelland(x+off_x<0orx+off_x>=GRID_WIDTHory+off_y>=GRID_HEIGHTorgrid[y+off_y][x+off_x]):returnTruereturnFalse# Merge the tetromino with the grid
defmerge_shape(grid,shape,offset):off_x,off_y=offsetfory,rowinenumerate(shape):forx,cellinenumerate(row):ifcell:grid[y+off_y][x+off_x]=cell# Rotate a shape
defrotate_shape(shape):return[list(row)[::-1]forrowinzip(*shape)]# Check for full rows and remove them
defremove_full_rows(grid):new_grid=[rowforrowingridifany(cell==0forcellinrow)]whilelen(new_grid)<GRID_HEIGHT:new_grid.insert(0,[0]*GRID_WIDTH)returnnew_grid# Main game loop
deftetris():grid=create_grid()current_shape=random.choice(SHAPES)current_color=SHAPES.index(current_shape)+1shape_pos=[GRID_WIDTH//2-len(current_shape[0])//2,0]fall_time=0.5fall_speed=time.monotonic()running=Truewhilerunning:clear_screen()draw_grid(grid)# Move the shape down
iftime.monotonic()-fall_speed>fall_time:shape_pos[1]+=1ifcheck_collision(grid,current_shape,shape_pos):shape_pos[1]-=1merge_shape(grid,current_shape,shape_pos)grid=remove_full_rows(grid)current_shape=random.choice(SHAPES)current_color=SHAPES.index(current_shape)+1shape_pos=[GRID_WIDTH//2-len(current_shape[0])//2,0]ifcheck_collision(grid,current_shape,shape_pos):running=Falsefall_speed=time.monotonic()# Event handling
ifion.keypad.is_pressed(ion.keypad.Key.LEFT):shape_pos[0]-=1ifcheck_collision(grid,current_shape,shape_pos):shape_pos[0]+=1elifion.keypad.is_pressed(ion.keypad.Key.RIGHT):shape_pos[0]+=1ifcheck_collision(grid,current_shape,shape_pos):shape_pos[0]-=1elifion.keypad.is_pressed(ion.keypad.Key.UP):current_shape=rotate_shape(current_shape)ifcheck_collision(grid,current_shape,shape_pos):current_shape=rotate_shape(rotate_shape(rotate_shape(current_shape)))elifion.keypad.is_pressed(ion.keypad.Key.DOWN):shape_pos[1]+=1ifcheck_collision(grid,current_shape,shape_pos):shape_pos[1]-=1# Draw the current shape
fory,rowinenumerate(current_shape):forx,cellinenumerate(row):ifcell:draw_cell(shape_pos[0]+x,shape_pos[1]+y,COLORS[current_color-1])# Delay for the game loop
time.sleep(0.1)kd.fill_rect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,kd.white)kd.draw_string("Game Over!",100,100,kd.red)# Start the game
tetris()
During your visit to our site, NumWorks needs to install "cookies" or use other technologies to collect data about you in order to:
Ensure the proper functioning of the site (essential cookies); and
Track your browsing to send you personalized communications if you have created a professional account on the site and can be contacted (audience measurement cookies).
With the exception of Cookies essential to the operation of the site, NumWorks leaves you the choice: you can accept Cookies for audience measurement by clicking on the "Accept and continue" button, or refuse these Cookies by clicking on the "Continue without accepting" button or by continuing your browsing. You can update your choice at any time by clicking on the link "Manage my cookies" at the bottom of the page. For more information, please consult our cookies policy.