Write a Python agent that plays Lineup 4, run it against the game's bots and see the results — free in your browser, with no sign-up and nothing saved.

Lineup 4 Game Instructions

Welcome to Lineup 4! Your task is to implement the make_decision method in the CustomPlayer class and return the position you want to play.

Board Layout

  • The board is 7 columns wide (numbered 1-7) and 6 rows high (lettered A-F)
  • Positions are referenced by column then row (e.g., '1A' is bottom-left, '7F' is top-right)
  • Pieces stack from the bottom up, so each column has at most one playable position: its lowest empty square

Game Rules

  • Players alternate placing pieces; X always moves first
  • First player to line up 4 pieces horizontally, vertically, or diagonally wins
  • If the board fills up with no winner, the game is a draw

Available Information

The game_state parameter provides you with the following information:

  • board: Dictionary mapping every position ('1A' to '7F') to 'X', 'O' or None
  • possible_moves: List of positions you can play right now (one per column that isn't full)
  • last_move: Your opponent's last move, or None if you move first
  • move_history: List of all moves made so far
  • self.symbol tells you whether you are 'X' or 'O'

Your move must be one of game_state["possible_moves"]; random.choice(game_state["possible_moves"]) always gives a valid move.

Scoring

Each submission plays a round-robin against the five bots below, repeated 30 times: you meet every bot 60 times, 30 going first and 30 going second (300 games in total). The bots also play each other, and everyone is ranked on the same table.

  • Win: 2 points
  • Draw: 1 point
  • Loss: 0 points

Meet the Bots

  • RandomPlayer: Drops its piece into a random valid position every turn.
  • LeftStackPlayer: Always plays in the leftmost column that still has space.
  • MrCenter: Prefers the centre column and works outwards (4, 3, 5, 2, 6, 1, 7).
  • RandomUntilWin: Plays randomly, but always takes a winning move the moment one is available.
  • BlockUntilWin: Takes a winning move if one exists, otherwise blocks your winning move, otherwise plays randomly.

Strategy Tips

  • Always take a winning move when one is available.
  • Otherwise, block your opponent's winning move.
  • Centre columns touch the most winning lines.
  • Use self.add_feedback() to debug your strategy.

Want lessons first? Start the free Python course or browse the Python lessons.