Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
220 changes: 220 additions & 0 deletions submissions/terminal-art/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
# Terminal Video Simulations

This project contains several Python programs that create video-like simulations and interactive games in the terminal using ASCII characters and the curses library.

## Menu

A menu program is included to easily launch any of the simulations:

```
python menu.py
```

Use the arrow keys to navigate, Enter to select a simulation, and Q to quit.

## Requirements

- Python 3.6 or higher
- curses library (included in standard library for Unix/Linux/macOS; for Windows, install windows-curses)

If you're on Windows, you'll need to install the windows-curses package:

```
pip install windows-curses
```

## Programs

### Basic Simulations

#### 1. Basic Video Simulation

A simple wave-like animation using ASCII characters.

```
python video_terminal.py
```

#### 2. Matrix Effect

A simulation of the famous "digital rain" effect from The Matrix movie.

```
python matrix_terminal.py
```

#### 3. Fire Effect

A simulation of fire using ASCII characters and colors.

```
python fire_terminal.py
```

#### 4. Dancing Man

A simulation of a dancing stick figure with disco lights.

```
python dancing_man.py
```

#### 5. Bouncing Ball

A physics-based simulation of bouncing balls with trails.

```
python bouncing_ball.py
```

#### 6. Dance and Bounce

A combined simulation featuring both the dancing man and bouncing balls.

```
python dance_and_bounce.py
```

#### 7. Starfield

A simulation of flying through space with stars moving toward you.

```
python starfield.py
```

#### 8. Rain

A simulation of rain falling with splashes when raindrops hit the ground.

```
python rain.py
```

#### 9. Conway's Game of Life

An implementation of Conway's Game of Life cellular automaton with interactive controls.

```
python game_of_life.py
```

#### 10. Fireworks Display

A colorful fireworks simulation with rising rockets and particle explosions.

```
python fireworks.py
```

#### 11. Digital Clock

A customizable digital clock with ASCII art digits and various display options.

```
python digital_clock.py
```

### Interactive Games

#### 12. Snake Game

A classic snake game where you control a snake to eat food and grow longer.

```
python snake_game.py
```

#### 13. Typing Test

A typing speed and accuracy test with WPM (words per minute) calculation.

```
python typing_test.py
```

## Controls

### Common Controls
- Press `q` to quit any simulation
- Press `Ctrl+C` to force quit

### Specific Controls

#### Bouncing Ball & Dance and Bounce
- Press `Space` to add a new ball
- Press `+`/`-` to adjust dancing speed (Dance and Bounce only)

#### Dancing Man
- Press `+`/`-` to adjust dancing speed

#### Starfield
- Press `+`/`-` to adjust flying speed

#### Rain
- Press `+`/`-` to adjust rain intensity

#### Conway's Game of Life
- Press `r` to randomize the grid
- Press `c` to clear the grid
- Press `Space` to pause/resume the simulation
- Press `+`/`-` to adjust simulation speed
- Click on cells to toggle their state (if mouse support is available)

#### Fireworks Display
- Press `Space` to manually launch a firework
- Press `+`/`-` to adjust the automatic launch rate

#### Digital Clock
- Press `c` to change the color scheme
- Press `s` to toggle seconds display
- Press `d` to toggle date display
- Press `a` to toggle AM/PM display
- Press `h` to toggle between 12h and 24h format
- Press `r` to toggle rainbow mode
- Press `m` to cycle through animation modes
- Press `*` to toggle background stars

#### Snake Game
- Use arrow keys to control the snake
- Press `r` to restart after game over

#### Typing Test
- Type the displayed text
- Press `ESC` to restart the test

## How It Works

These simulations use the curses library to control the terminal display. Each program:

1. Initializes the terminal screen for drawing
2. Creates a simulation loop that generates frames
3. Renders each frame to the terminal
4. Cleans up the terminal state when exiting

The simulations use different algorithms to create their effects:

- **video_terminal.py**: Uses wave patterns and noise to create a dynamic display
- **matrix_terminal.py**: Creates falling columns of characters that mimic the Matrix digital rain
- **fire_terminal.py**: Uses a cellular automaton approach to simulate fire rising from the bottom of the screen
- **dancing_man.py**: Uses pre-defined ASCII art frames to animate a dancing stick figure
- **bouncing_ball.py**: Uses physics calculations to simulate realistic ball bouncing with gravity
- **dance_and_bounce.py**: Combines the dancing man and bouncing ball simulations
- **starfield.py**: Creates a 3D effect of stars moving toward the viewer
- **rain.py**: Simulates raindrops falling with realistic splash effects
- **game_of_life.py**: Implements Conway's Game of Life cellular automaton with rules for cell birth, survival, and death
- **fireworks.py**: Simulates fireworks with physics for rocket launch, explosion, and particle movement with gravity
- **digital_clock.py**: Displays the current time using ASCII art digits with various display options and animations
- **snake_game.py**: Implements the classic snake game with collision detection
- **typing_test.py**: Measures typing speed and accuracy with real-time feedback

## Customization

You can modify these programs to create your own terminal animations by changing:

- The characters used for display
- The colors (if supported by your terminal)
- The algorithms that generate the patterns
- The speed of the animation

Enjoy the terminal video simulations and games!
151 changes: 151 additions & 0 deletions submissions/terminal-art/bouncing_ball.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#!/usr/bin/env python3
import os
import time
import curses
import math
import random
BALL_CHARS = {
'small': 'o',
'medium': 'O',
'large': '@'
}
TRAIL_CHARS = '.·'
class Ball:
"""A class representing a bouncing ball."""
def __init__(self, x, y, x_vel, y_vel, size='medium', color=1):
self.x = x
self.y = y
self.x_vel = x_vel
self.y_vel = y_vel
self.size = size
self.color = color
self.gravity = 0.2
self.elasticity = 0.8
self.trail = []
self.max_trail_length = 10
def update(self, width, height):
"""Update the ball's position and velocity."""
self.trail.append((self.x, self.y))
if len(self.trail) > self.max_trail_length:
self.trail.pop(0)
self.x += self.x_vel
self.y += self.y_vel
self.y_vel += self.gravity
if self.x < 0:
self.x = 0
self.x_vel = -self.x_vel * self.elasticity
elif self.x >= width:
self.x = width - 1
self.x_vel = -self.x_vel * self.elasticity
if self.y < 0:
self.y = 0
self.y_vel = -self.y_vel * self.elasticity
elif self.y >= height - 1:
self.y = height - 2
self.y_vel = -self.y_vel * self.elasticity
if abs(self.y_vel) > 0.5:
self.x_vel += (random.random() - 0.5) * 0.5
self.x_vel *= 0.99
if abs(self.y_vel) < 0.3 and self.y >= height - 2:
self.y_vel = -1.5
def draw(self, screen):
"""Draw the ball and its trail."""
for i, (trail_x, trail_y) in enumerate(self.trail):
if i < len(self.trail) - 2:
try:
char_index = i % len(TRAIL_CHARS)
screen.addch(int(trail_y), int(trail_x), TRAIL_CHARS[char_index],
curses.color_pair(self.color) | curses.A_DIM)
except curses.error:
pass
try:
screen.addch(int(self.y), int(self.x), BALL_CHARS[self.size],
curses.color_pair(self.color) | curses.A_BOLD)
except curses.error:
pass
def initialize_screen():
"""Initialize the curses screen."""
screen = curses.initscr()
curses.start_color()
curses.use_default_colors()
colors = [curses.COLOR_RED, curses.COLOR_GREEN, curses.COLOR_YELLOW,
curses.COLOR_BLUE, curses.COLOR_MAGENTA, curses.COLOR_CYAN,
curses.COLOR_WHITE]
for i, color in enumerate(colors, start=1):
curses.init_pair(i, color, curses.COLOR_BLACK)
curses.curs_set(0)
curses.noecho()
curses.cbreak()
screen.keypad(True)
screen.timeout(100)
return screen
def cleanup_screen(screen):
"""Clean up the curses screen."""
screen.keypad(False)
curses.nocbreak()
curses.echo()
curses.endwin()
def get_terminal_size():
"""Get the terminal size."""
return os.get_terminal_size()
def draw_floor(screen, width, height):
"""Draw a floor for the ball to bounce on."""
floor_y = height - 1
try:
screen.addstr(floor_y, 0, "=" * width)
except curses.error:
pass
def draw_walls(screen, width, height):
"""Draw walls on the sides."""
for y in range(height - 1):
try:
screen.addch(y, 0, '|')
screen.addch(y, width - 1, '|')
except curses.error:
pass
def main(screen):
"""Main function."""
try:
width, height = get_terminal_size()
width = min(width, 80)
height = min(height, 24)
balls = [
Ball(width // 4, height // 4, 1.0, 0.0, 'large', 1),
Ball(width // 2, height // 3, -0.8, 0.5, 'medium', 2),
Ball(3 * width // 4, height // 2, 0.5, -1.0, 'small', 3)
]
frame_num = 0
while True:
key = screen.getch()
if key == ord('q'):
break
elif key == ord(' '):
x = random.randint(5, width - 5)
y = random.randint(5, height // 2)
x_vel = random.uniform(-1.5, 1.5)
y_vel = random.uniform(-1.0, 0.0)
size = random.choice(['small', 'medium', 'large'])
color = random.randint(1, 7)
balls.append(Ball(x, y, x_vel, y_vel, size, color))
screen.clear()
draw_floor(screen, width, height)
draw_walls(screen, width, height)
for ball in balls:
ball.update(width, height)
ball.draw(screen)
try:
screen.addstr(0, 2, "Press 'q' to quit, SPACE to add ball")
except curses.error:
pass
screen.refresh()
frame_num += 1
time.sleep(0.03)
except KeyboardInterrupt:
pass
if __name__ == "__main__":
try:
screen = initialize_screen()
main(screen)
finally:
cleanup_screen(screen)
print("Bouncing ball simulation ended.")
Loading