Tower Defense — Milestone 1

The Grid & The Map

# TOWER DEFENSE — MILESTONE 1: The Grid & The Map
# =============================================================================
# TARGET (show me when this works):
#   A 20 x 15 grid fills the window. The START cell on the left is GREEN.
#   The END cell on the right is RED and says "END".
#
# NEW IN THIS FILE:
#   - The grid (this is what we built in class)
#   - draw_grid() now actually USES the grid list to pick each cell's color
#
# THE ONE IDEA TO UNDERSTAND:
#   The screen is measured in PIXELS, but we think in CELLS.
#   Cell (col, row) is drawn at pixel (col * CELL, row * CELL).
#   That one line of math is the whole trick behind every grid game.
#
# NEXT (Milestone 2): enemies that walk from START to END.
# =============================================================================

import pygame

pygame.init()

COLS, ROWS = 20, 15
CELL = 40
WIDTH = COLS * CELL
HEIGHT = ROWS * CELL

screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Tower Defense — Milestone 1")
clock = pygame.time.Clock()
font = pygame.font.SysFont("Courier", 18, bold=True)

# Colors
BG_COLOR = (20, 28, 40)
GRID_COLOR = (30, 40, 55)
OPEN_COLOR = (35, 50, 70)
START_COLOR = (50, 180, 80)
END_COLOR = (200, 60, 60)

# Grid Setup
START = (0, ROWS // 2)
END = (COLS - 1, ROWS // 2)

grid = [['open'] * ROWS for _ in range(COLS)]
grid[START[0]][START[1]] = 'start'
grid[END[0]][END[1]] = 'end'


def draw_grid():
    for row in range(ROWS):
        for col in range(COLS):
            x = col * CELL
            y = row * CELL

            # TEACH: look up what KIND of cell this is, then pick a color.
            # This is why we stored 'start' and 'end' in the grid list above.
            cell_type = grid[col][row]
            if cell_type == 'start':
                color = START_COLOR
            elif cell_type == 'end':
                color = END_COLOR
            else:
                color = OPEN_COLOR

            pygame.draw.rect(screen, color, (x, y, CELL, CELL))
            pygame.draw.rect(screen, GRID_COLOR, (x, y, CELL, CELL), 1)

    # Label the end cell so it is obvious what we are defending
    end_x = END[0] * CELL + CELL // 2
    end_y = END[1] * CELL + CELL // 2
    label = font.render("END", True, (255, 210, 210))
    screen.blit(label, label.get_rect(center=(end_x, end_y)))


running = True

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

    screen.fill(BG_COLOR)
    draw_grid()
    pygame.display.flip()
    clock.tick(60)

pygame.quit()