Compare commits

..

2 Commits

Author SHA1 Message Date
f77dda2946 fix score oopsi 2024-05-09 23:22:13 -04:00
8aa0621395 score for tetris 2024-05-09 20:03:27 -04:00
3 changed files with 58 additions and 62 deletions

View File

@ -1,6 +1,6 @@
# np-tetris # np-tetris
`main.py`: tetris in pure python + `numpy` `main.py`: tetris in `numpy`
`tetris.py`: tetris with `curses` `tetris.py`: tetris with `curses`
`snake.py`: snake with `curses` and `numpy` `snake.py`: snake with `curses` and `numpy`

21
main.py
View File

@ -32,13 +32,14 @@ def attempt_rotate(piece, board, i, j):
return piece return piece
def clear_rows(board): def clear_rows(board, score):
clear_indices = np.where(np.all(board == 1, axis=1))[0] clear_indices = np.where(np.all(board == 1, axis=1))[0]
if clear_indices.size > 0: if clear_indices.size > 0:
board = np.delete(board, clear_indices, axis=0) board = np.delete(board, clear_indices, axis=0)
new_rows = np.zeros((len(clear_indices), board.shape[1])) new_rows = np.zeros((len(clear_indices), board.shape[1]))
board = np.vstack([new_rows, board]) board = np.vstack([new_rows, board])
return board score = update_score(score)
return board, score
def calculate_shadow(piece, board, i, j): def calculate_shadow(piece, board, i, j):
@ -48,7 +49,7 @@ def calculate_shadow(piece, board, i, j):
return i return i
def display_board(board, piece, i, j): def display_board(board, piece, i, j, score):
display = board.copy() display = board.copy()
shadow_i = calculate_shadow(piece, board, i, j) shadow_i = calculate_shadow(piece, board, i, j)
n, m = piece.shape n, m = piece.shape
@ -69,7 +70,7 @@ def display_board(board, piece, i, j):
for row in display for row in display
) )
) )
print() print(f"Score: {score}\n")
def game_over(board): def game_over(board):
@ -78,9 +79,13 @@ def game_over(board):
return np.zeros_like( return np.zeros_like(
board board
) # Clear the board and continue or call sys.exit() to end ) # Clear the board and continue or call sys.exit() to end
def update_score(score):
return score + 1
def main(): def main():
score = 0
board = np.zeros((20, 10), dtype=int) board = np.zeros((20, 10), dtype=int)
piece_types = list(PIECES.keys()) piece_types = list(PIECES.keys())
current_piece = PIECES[np.random.choice(piece_types)] current_piece = PIECES[np.random.choice(piece_types)]
@ -89,7 +94,7 @@ def main():
auto_gravity = True # Auto-gravity enabled by default auto_gravity = True # Auto-gravity enabled by default
while True: while True:
display_board(board, current_piece, i, j) display_board(board, current_piece, i, j, score)
if not check_placement(current_piece, board, *START_POS): if not check_placement(current_piece, board, *START_POS):
board = game_over(board) board = game_over(board)
continue continue
@ -117,13 +122,13 @@ def main():
i += 1 i += 1
else: else:
board = place_piece(current_piece, board, i, j) board = place_piece(current_piece, board, i, j)
board = clear_rows(board) board, score = clear_rows(board, score)
current_piece = PIECES[np.random.choice(piece_types)] current_piece = PIECES[np.random.choice(piece_types)]
i, j = 0, 4 i, j = 0, 4
elif command == "S": elif command == "S":
i = calculate_shadow(current_piece, board, i, j) i = calculate_shadow(current_piece, board, i, j)
board = place_piece(current_piece, board, i, j) board = place_piece(current_piece, board, i, j)
board = clear_rows(board) board, score = clear_rows(board, score)
current_piece = PIECES[np.random.choice(piece_types)] current_piece = PIECES[np.random.choice(piece_types)]
i, j = START_POS i, j = START_POS
elif command == "G": elif command == "G":
@ -134,7 +139,7 @@ def main():
i += 1 i += 1
else: else:
board = place_piece(current_piece, board, i, j) board = place_piece(current_piece, board, i, j)
board = clear_rows(board) board, score = clear_rows(board, score)
current_piece = PIECES[np.random.choice(piece_types)] current_piece = PIECES[np.random.choice(piece_types)]
i, j = START_POS i, j = START_POS

View File

@ -1,76 +1,67 @@
import numpy as np
import curses import curses
import time
import random import random
import numpy as np
def main(stdscr): def main(stdscr):
curses.curs_set(0) # Hide the cursor for a cleaner look curses.curs_set(0) # Hide cursor
stdscr.nodelay(True) # Non-blocking input to keep the game flowing stdscr.nodelay(True) # Don't block I/O calls
h, w = 20, 40 # Dimensions of the game board stdscr.timeout(100) # Refresh rate
board = np.zeros((h, w), dtype=int) # Game board initialization
snake = [(h // 2, w // 2)] # Starting position of the snake # Initialize the board
board[h // 2, w // 2] = 1 # Mark the snake's start on the board h, w = 40, 80 # Board dimensions
board = np.zeros((h, w), dtype=int)
snake = [(h // 2, w // 2)]
board[h // 2, w // 2] = 1
food = (random.randint(0, h - 1), random.randint(0, w - 1)) food = (random.randint(0, h - 1), random.randint(0, w - 1))
board[food] = 2 # Place initial food board[food] = 2 # Food position
direction = (0, 1) # Initial movement direction direction = (0, 1) # Initial direction (right)
last_update_time = time.time()
move_interval = 0.1 # Base move interval in seconds
vertical_adjustment = 2 # Vertical moves occur every this number of base intervals
while True: while True:
# Input handling
key = stdscr.getch() key = stdscr.getch()
if key in [ord("Q"), ord("q")]: if key in [ord("q"), ord("Q")]:
break break
if key in [ord("a"), ord("A")] and direction != (0, 1): elif key in [ord("a"), ord("A")] and direction != (0, 1):
direction = (0, -1) direction = (0, -1)
if key in [ord("d"), ord("D")] and direction != (0, -1): elif key in [ord("d"), ord("D")] and direction != (0, -1):
direction = (0, 1) direction = (0, 1)
if key in [ord("w"), ord("W")] and direction != (1, 0): elif key in [ord("w"), ord("W")] and direction != (1, 0):
direction = (-1, 0) direction = (-1, 0)
if key in [ord("s"), ord("S")] and direction != (-1, 0): elif key in [ord("s"), ord("S")] and direction != (-1, 0):
direction = (1, 0) direction = (1, 0)
elif key == ord(" "): # Pause
stdscr.nodelay(False)
stdscr.getch()
stdscr.nodelay(True)
current_time = time.time() # Update snake position
time_elapsed = current_time - last_update_time head = (snake[0][0] + direction[0], snake[0][1] + direction[1])
head = (head[0] % h, head[1] % w) # Torus wrapping
# Adjust move interval based on direction if head in snake: # Check self-collision
current_interval = move_interval * ( break
vertical_adjustment if direction in [(-1, 0), (1, 0)] else 1
)
if time_elapsed >= current_interval: snake.insert(0, head) # Move head
new_head = (snake[0][0] + direction[0], snake[0][1] + direction[1]) if head == food: # Check food collision
new_head = (new_head[0] % h, new_head[1] % w) # Toroidal field logic food = (random.randint(0, h - 1), random.randint(0, w - 1))
while food in snake:
if new_head in snake:
break # Collision detection
snake.insert(0, new_head)
if new_head == food:
food = (random.randint(0, h - 1), random.randint(0, w - 1)) food = (random.randint(0, h - 1), random.randint(0, w - 1))
while food in snake: else:
food = (random.randint(0, h - 1), random.randint(0, w - 1)) tail = snake.pop()
else: board[tail] = 0
tail = snake.pop()
board[tail] = 0
board[new_head] = 1 board[head] = 1
board[food] = 2 board[food] = 2
last_update_time = current_time # Reset the timer
# Clear and redraw the board # Draw the board
stdscr.clear() stdscr.clear()
for i in range(h): for i in range(h):
for j in range(w): for j in range(w):
if board[i, j] == 1: char = " " if board[i, j] == 0 else "*" if board[i, j] == 1 else "O"
stdscr.addch(i, j, "X") stdscr.addch(i, j, char)
elif board[i, j] == 2: stdscr.refresh()
stdscr.addch(i, j, "O")
else:
stdscr.addch(i, j, " ")
stdscr.refresh()
curses.wrapper(main) curses.wrapper(main)