Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
33 changes: 13 additions & 20 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,21 @@
{
"name": "Python 3",

// This is the default
// "image": "mcr.microsoft.com/devcontainers/universal:2",
"image": "mcr.microsoft.com/devcontainers/python:1-3.12-bookworm",

// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
//"image": "mcr.microsoft.com/devcontainers/python:1-${templateOption:imageVariant}",
//"image": "mcr.microsoft.com/devcontainers/python:1-3.12-bookworm",

"build": {
"dockerfile": "Dockerfile",
"context": ".."
},
//"build": {
// "dockerfile": "Dockerfile",
// "context": ".."
//},

"containerEnv": {
"SDL_VIDEO_WINDOW_POS": "0,0", // GUI Windows all the way in the upper left.
"SDL_AUDIODRIVER": "dummy" // Disable audio
},

// Features to add to the dev container. More info: https://containers.dev/features.
"features": {
"ghcr.io/devcontainers/features/desktop-lite:1": {
"password" : "code4life"
}
},

"features": {},


// Use 'forwardPorts' to make a list of ports inside the container available locally.
Expand All @@ -43,24 +34,26 @@


// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "./.devcontainer/cs-setup.sh",
"postCreateCommand": "bash ./.devcontainer/setup.sh ${containerWorkspaceFolder}",


"customizations": {
"codespaces": {
"openFiles": [
//"lessons/00_Turtles/01_Get_Started.ipynb"
"README.md"
"lessons/10_Turtles/10_Welcome/10_Welcome.ipynb"
]
},
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.debugpy",
"ms-python.isort",
"ms-toolsai.jupyter"
"ms-toolsai.jupyter",
"jointheleague.jtl-syllabus"
],
"settings": {

"python.defaultInterpreterPath": "/usr/local/bin/python",
"python.terminal.activateEnvironment": true
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
{
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/.DS_Store": true,
"**/Thumbs.db": true,
"**/*.crswap": true,
".git": true,
".github": true,
"**/.gitignore": true,
".gitattributes": true,
".pylintrc": true,
".vscode": true,
".yarn": true,
".devcontainer": true,
"**/node_modules": true,
"**/.ipynb_checkpoints": true,
".venv": true,
".lib": true,
"**/.jtl": true,
"requirements.txt": true,
".lessons": true
}

}
82 changes: 82 additions & 0 deletions catchball.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import pygame
import random

# Initialize Pygame
pygame.init()

# Screen size
WIDTH, HEIGHT = 500, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Catch the Ball")

# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)

# Basket settings
basket_width = 100
basket_height = 20
basket_x = WIDTH // 2 - basket_width // 2
basket_y = HEIGHT - basket_height - 10
basket_speed = 7

# Ball settings
ball_radius = 15
ball_x = random.randint(ball_radius, WIDTH - ball_radius)
ball_y = 0
ball_speed = 5

# Score
score = 0
font = pygame.font.SysFont(None, 36)

# Game loop flag
running = True
clock = pygame.time.Clock()

while running:
clock.tick(60) # 60 frames per second
screen.fill(WHITE)

for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False

# Get keys pressed
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and basket_x > 0:
basket_x -= basket_speed
if keys[pygame.K_RIGHT] and basket_x < WIDTH - basket_width:
basket_x += basket_speed

# Move the ball down
ball_y += ball_speed

# Check if ball caught by basket
if (basket_y < ball_y + ball_radius < basket_y + basket_height) and (basket_x < ball_x < basket_x + basket_width):
score += 1
ball_x = random.randint(ball_radius, WIDTH - ball_radius)
ball_y = 0

# If ball hits the bottom, reset ball and lose a point
if ball_y > HEIGHT:
score -= 1
ball_x = random.randint(ball_radius, WIDTH - ball_radius)
ball_y = 0

# Draw basket
pygame.draw.rect(screen, BLACK, (basket_x, basket_y, basket_width, basket_height))

# Draw ball
pygame.draw.circle(screen, RED, (ball_x, ball_y), ball_radius)

# Draw score
score_text = font.render(f"Score: {score}", True, BLACK)
screen.blit(score_text, (10, 10))

pygame.display.flip()

pygame.quit()


139 changes: 139 additions & 0 deletions flappybird.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import pygame
import sys
import random

# Initialize pygame
pygame.init()

# Screen dimensions
WIDTH, HEIGHT = 400, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Flappy Bird")

# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLUE = (0, 150, 255)
GREEN = (0, 255, 0)

# Clock for controlling FPS
clock = pygame.time.Clock()
FPS = 60

# Bird properties
bird_x = 50
bird_y = HEIGHT // 2
bird_radius = 20
bird_velocity = 0
gravity = 0.25 # slower fall
jump_strength = -8 # gentler jump

# Pipe properties
pipe_width = 70
pipe_gap = 200 # bigger gap
pipe_velocity = 4

# Pipes: list of dictionaries with x position and height of the top pipe
pipes = []
pipe_spawn_time = 0 # Timer to spawn pipes

score = 0
font = pygame.font.SysFont(None, 40)

def draw_bird(y):
pygame.draw.circle(screen, BLUE, (bird_x, int(y)), bird_radius)

def draw_pipe(x, height):
# Top pipe
pygame.draw.rect(screen, GREEN, (x, 0, pipe_width, height))
# Bottom pipe
bottom_pipe_y = height + pipe_gap
bottom_pipe_height = HEIGHT - bottom_pipe_y
pygame.draw.rect(screen, GREEN, (x, bottom_pipe_y, pipe_width, bottom_pipe_height))

def check_collision(bird_y, pipes):
# Check if bird hits ground or ceiling
if bird_y - bird_radius < 0 or bird_y + bird_radius > HEIGHT:
return True
# Check collision with pipes
for pipe in pipes:
pipe_x = pipe['x']
pipe_height = pipe['height']
if bird_x + bird_radius > pipe_x and bird_x - bird_radius < pipe_x + pipe_width:
if bird_y - bird_radius < pipe_height or bird_y + bird_radius > pipe_height + pipe_gap:
return True
return False

def display_score(score):
score_text = font.render(f"Score: {score}", True, BLACK)
screen.blit(score_text, (10, 10))

def game_over_screen(score):
screen.fill(WHITE)
game_over_text = font.render("Game Over!", True, BLACK)
score_text = font.render(f"Final Score: {score}", True, BLACK)
screen.blit(game_over_text, (WIDTH // 2 - game_over_text.get_width() // 2, HEIGHT // 2 - 50))
screen.blit(score_text, (WIDTH // 2 - score_text.get_width() // 2, HEIGHT // 2))
pygame.display.flip()
pygame.time.wait(3000)

def main():
global bird_y, bird_velocity, pipes, pipe_spawn_time, score

running = True
while running:
clock.tick(FPS)
screen.fill(WHITE)

# Event handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
bird_velocity = jump_strength

# Bird physics
bird_velocity += gravity
bird_y += bird_velocity

# Pipe spawning
pipe_spawn_time += 1
if pipe_spawn_time > 90: # Every 1.5 seconds (at 60 FPS)
pipe_height = random.randint(50, HEIGHT - pipe_gap - 50)
pipes.append({'x': WIDTH, 'height': pipe_height})
pipe_spawn_time = 0

# Move pipes and remove off-screen ones
for pipe in pipes:
pipe['x'] -= pipe_velocity
pipes = [pipe for pipe in pipes if pipe['x'] + pipe_width > 0]

# Check score (when bird passes pipe)
for pipe in pipes:
if pipe['x'] + pipe_width < bird_x and not pipe.get('passed', False):
score += 1
pipe['passed'] = True

# Draw everything
draw_bird(bird_y)
for pipe in pipes:
draw_pipe(pipe['x'], pipe['height'])
display_score(score)

# Check collisions
if check_collision(bird_y, pipes):
game_over_screen(score)
# Reset game state
bird_y = HEIGHT // 2
bird_velocity = 0
pipes = []
pipe_spawn_time = 0
score = 0

pygame.display.flip()

if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions lessons/.jtl/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
syllabus-completion.json
1 change: 1 addition & 0 deletions lessons/.jtl/syllabus-completion.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Loading