Search⌘ K
AI Features

Creating the Game World

Explore how to create the initial game world for 2048 by initializing a 4x4 board with zeros and placing random tiles with values 2 or 4. Learn to use AI as a coding assistant to implement and validate core functions, build the initial game state, and test functionality step-by-step, preparing the foundation for a fully playable game.

This lesson builds on the existing code skeleton by initializing the board’s starting state. You’ll use the assistant to generate the initial implementation, then test and validate that generated code.

Step 0: Start with the code skeleton

We begin with the code file from the previous lesson, but with main() now doing something real.

Python 3.10.4
# =========================
# Function stubs
# =========================
def render_board(board: list[list[int]]) -> str:
"""We'll implement this in Lesson 3."""
return str(board) # temporary fallback (shows raw Python list)
def compress_row(row: list[int]) -> list[int]:
raise NotImplementedError
def merge_row(row: list[int]) -> tuple[list[int], int]:
raise NotImplementedError
def move_board(board: list[list[int]], direction: str) -> tuple[list[list[int]], int, bool]:
raise NotImplementedError
def check_game_state(board: list[list[int]], target: int = 2048) -> str:
raise NotImplementedError
# =========================
# Functions we have to implement today
# =========================
def add_random_tile(board: list[list[int]]) -> None:
"""
Add a tile (2 or 4) to a random empty cell on the 4x4 board.
Mutates board in place.
"""
# TODO: implement this in this lesson
raise NotImplementedError
def create_initial_board() -> list[list[int]]:
"""
Create a fresh 4x4 board with exactly two random tiles placed.
"""
# TODO: implement this in this lesson
raise NotImplementedError("create_initial_board not implemented")
# =========================
# main() now grows for the first time
# =========================
def main():
print("=== 2048: Creating the Game World ===")
board = create_initial_board()
print("\nYour initial board:\n")
print(render_board(board)) # Uses placeholder rendering for now
if __name__ == "__main__":
main()

Run this and see errors, like NotImplementedError. Perfect, now we know exactly what to implement.

Step 1: Implement a 4×4 empty board

When the game starts, a tile with value 2 or 4 is placed at a random position on the board. Before introducing randomness, recall how the board is represented in code.

The board is represented as a list of four lists, where each inner list corresponds to a single row. As 0 represents an empty tile, initialize the board with zeros, then place one or more tiles with value 2 or 4 at random positions.

[[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]]

We have to create this inside create_initial_board(). Scroll down to the function definition create_initial_board() and see lines 41–42. We’ve initialized the variable board with all zeros.

Python 3.10.4
import random # a library for initializing random numbers
# =========================
# Function stubs
# =========================
def render_board(board: list[list[int]]) -> str:
"""We'll implement this in Lesson 3."""
return str(board) # temporary fallback (shows raw Python list)
def compress_row(row: list[int]) -> list[int]:
raise NotImplementedError
def merge_row(row: list[int]) -> tuple[list[int], int]:
raise NotImplementedError
def move_board(board: list[list[int]], direction: str) -> tuple[list[list[int]], int, bool]:
raise NotImplementedError
def check_game_state(board: list[list[int]], target: int = 2048) -> str:
raise NotImplementedError
# =========================
# Functions we have to implement today
# =========================
def add_random_tile(board: list[list[int]]) -> None:
"""
Add a tile (2 or 4) to a random empty cell on the 4x4 board.
Mutates board in place.
"""
# TODO: implement this in this lesson
raise NotImplementedError
def create_initial_board() -> list[list[int]]:
"""
Create a fresh 4x4 board with all zeros. Return that board.
"""
board = [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]]
return board
# =========================
# main() now grows for the first time
# =========================
def main():
print("=== 2048: Creating the Game World ===")
board = create_initial_board()
print("\nYour initial board:\n")
print(render_board(board)) # Uses placeholder rendering for now
if __name__ == "__main__":
main()

When you run the code, line 52 calls the function, and line 55 prints the raw board for now. In the next lesson, we will see how to render the board for the end user more properly.

Step 2: Implement add_random_tile()

The board is initialized, but we still need to place two random tiles; each tile should be a 2 (90% chance) or a 4 (10% chance). Use the assistant to generate the first draft of add_random_tile(). Paste the prompt below along with your current code (from the editor) so it has full context.

AI prompt:

I’ve written the code for initializing a 4x4 board with all zeros. I want you to write add_random_tile() function for me, which will take this initial board and randomly add a 2 or a 4 on one location each time the function is called. Here are the specs for that: Board is always 4×4. Only place tiles in empty cells (value 0). Tile is 2 (with 90% probability) or 4 (with only 10% probability). Function must mutate the board in place and return None. My codebase is as follows:

Copy the above prompt and paste it in the AI widget below. Then append the prompt with the entire code copied from the code widget from Step 1.

Powered by AI
3 Prompts Remaining
Prompt AI WidgetOur tool is designed to help you to understand concepts and ask any follow up questions. Ask a question to get started.

Take the code for the add_random_tile function, which was generated by AI, and paste it in the code widget below, at line 28. If anything goes wrong when you run the code, you can copy the solution from the “Solution” tab as well.

Python 3.10.4
import random
# =========================
# Function stubs
# =========================
def render_board(board: list[list[int]]) -> str:
"""We'll implement this in Lesson 3."""
return str(board) # temporary fallback (shows raw Python list)
def compress_row(row: list[int]) -> list[int]:
raise NotImplementedError
def merge_row(row: list[int]) -> tuple[list[int], int]:
raise NotImplementedError
def move_board(board: list[list[int]], direction: str) -> tuple[list[list[int]], int, bool]:
raise NotImplementedError
def check_game_state(board: list[list[int]], target: int = 2048) -> str:
raise NotImplementedError
# =========================
# Functions we have to implement today
# =========================
def add_random_tile(board: list[list[int]]) -> None:
def create_initial_board() -> list[list[int]]:
"""
Create a fresh 4x4 board with all zeros. Return that board.
"""
board = [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]]
return board
# =========================
# main() now grows for the first time
# =========================
def main():
print("=== 2048: Creating the Game World ===")
board = create_initial_board()
print("\nYour initial board:\n")
print(render_board(board)) # Uses placeholder rendering for now
if __name__ == "__main__":
main()

When you run the program, the output is unchanged; you still see an all-zero board. That’s because add_random_tile() is defined but never called yet.

Step 3: Complete create_initial_board()

You have the function that creates an empty board, initialized by all zeros. You have also got the functionality for changing a tile randomly from 0 to a 2 or a 4, but you have to use that add_random_tile inside the create_initial_board now to complete the requirement of this lesson. For that, we have to make two calls to the function right after we have created the board inside the function create_initial_board, and before the function returns the board.

Lines 48–49 are ready for your contribution. In case of any confusion, you can also look up the solution.

Python 3.10.4
import random
# =========================
# Function stubs
# =========================
def render_board(board: list[list[int]]) -> str:
"""We'll implement this in Lesson 3."""
return str(board) # temporary fallback (shows raw Python list)
def compress_row(row: list[int]) -> list[int]:
raise NotImplementedError
def merge_row(row: list[int]) -> tuple[list[int], int]:
raise NotImplementedError
def move_board(board: list[list[int]], direction: str) -> tuple[list[list[int]], int, bool]:
raise NotImplementedError
def check_game_state(board: list[list[int]], target: int = 2048) -> str:
raise NotImplementedError
# =========================
# Functions we have to implement today
# =========================
def add_random_tile(board: list[list[int]]) -> None:
"""
Add a tile (2 or 4) to a random empty cell on the 4x4 board.
Mutates board in place.
"""
empty_cells = [(i, j) for i in range(4) for j in range(4) if board[i][j] == 0]
if not empty_cells:
return # No empty cells, can't add a tile
i, j = random.choice(empty_cells)
# 90% chance to add a 2, 10% chance to add a 4
board[i][j] = 2 if random.random() < 0.9 else 4
def create_initial_board() -> list[list[int]]:
"""
Create a fresh 4x4 board with all zeros.
Add two random tiles to the board. Return that board.
"""
board = [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]]
return board
# =========================
# main() now grows for the first time
# =========================
def main():
print("=== 2048: Creating the Game World ===")
board = create_initial_board()
print("\nYour initial board:\n")
print(render_board(board)) # Uses placeholder rendering for now
if __name__ == "__main__":
main()

If you have completed the implementation as per the requirements of the game, each time you press the Run button, you will see a new initial board in the output, with two non-zero tiles placed at random locations.

It’s a start

We have a start to the game.

You can now:

  • Create and reason about a fixed 4×4 grid.

  • Use AI to generate the implementation of the function by giving it complete specifications.

  • Implement add_random_tile() safely.

  • Build create_initial_board() correctly.

  • Test early functions in isolation.

  • Extend main() with real functionality.

This sets the stage for the next lesson, where the board becomes beautifully rendered and the “game” starts feeling alive.