Build, test, and compete with confidence.
Learn how to create an agent, understand judge limits, debug matches, and improve your ranking.
Overview
ByteArena is a programming competition platform for turn-based board-game agents. You submit source code, the judge runs it in an isolated environment, and the platform records results, resource use, logs, replays, and rankings.
1. Choose
Pick a game and read its rules and API.
2. Build
Implement and submit your decision logic.
3. Improve
Study replays and challenge more opponents.
Quick Start
- Open All Games and choose an arena.
- Read the rules, input state, legal-move format, and examples.
- Choose a supported language and implement the required decision function.
- Submit the source and wait for compilation and validation.
- Start a battle, then inspect its status, logs, and replay.
Important
Your program must produce exactly the move format required by the selected game. Extra text on stdout can make an otherwise correct move invalid.
How Matches Work
For each turn, the runner starts your agent with the current game state, waits for one decision, validates the output, applies the move, and advances the game. Do not rely on in-memory variables surviving between turns unless the game API explicitly guarantees it.
- Load the board and metadata for the current turn.
- Compute one legal action within the configured limits.
- Write only the required decision to stdout.
- Use stderr for optional diagnostic output.
Time & Memory Limits
Limits apply to one decision step, not to the entire match. The exact values are shown on each game page and are frozen when a judge task is created.
| Limit | Applies to | If exceeded |
|---|---|---|
| Time (ms) | One turn | Time Limit Exceeded (TLE), usually a forfeit |
| Memory (KB) | One turn | Memory Limit Exceeded (MLE), usually a forfeit |
| Output | One turn | Output may be truncated or rejected |
Leaderboard Avg Time and Avg Mem use the same units: milliseconds and kilobytes.
Debugging
Start with the replay
- Open a finished battle and select Replay.
- Move through the steps until the board first differs from your expectation.
- Check the log for runtime errors, invalid moves, TLE, or MLE details.
Send debug output to stderr
The judge parses your move from stdout. Diagnostic prints belong on stderr so they do not corrupt the move format.
import sys
print("board=", board, file=sys.stderr)C/C++: fprintf(stderr, ...) / std::cerr Java: System.err.println(...)
Leaderboard & Ranking
Ranking metrics use your latest non-tournament two-leg pairing against each opponent. A pairing normally contains one game as Player A and one as Player B, which reduces first-move bias.
Counted matches
- The latest valid non-tournament pairing against each opponent is counted.
- Tournament matches do not affect the normal leaderboard.
- Historical matches remain available even when a newer pairing replaces them in ranking calculations.
Metrics and ordering
Win% balances the side-specific win rates you have actually played. Ties are resolved by higher Win%, then lower Avg Time, then lower Avg Mem. Use Refresh if a recently completed match has not appeared yet.
Game Scores
Every completed match stores scores for both sides. Their meaning depends on the game; a leaderboard score is an aggregate ranking metric rather than a universal raw score.
| Game | Score meaning |
|---|---|
| TicTacToe | Winner 1, loser 0; a draw is 0-0. |
| Trap Gomoku | Longest consecutive line length; 5 means a winning line. |
| XGame | Number of completed X patterns on the final board. |
| Tessella | Capture-based score; higher means more opposing pieces were removed. |
TicTacToe: Build an Unbeatable Bot
Player A uses X and moves first; Player B uses O. The goal is three marks in a row. Start with a legal random move, then add stronger rules one at a time.
- If you can win immediately, play the winning move.
- Otherwise, block the opponent's immediate win.
- Create a fork, or block an opponent fork.
- Prefer the center, then an opposite corner, an empty corner, and finally an edge.
For perfect play, implement minimax over the small game tree and assign positive scores to wins, negative scores to losses, and zero to draws.
def choose_move(board, legal_moves):
move = find_winning_move(board, legal_moves, me)
if move is not None:
return move
move = find_winning_move(board, legal_moves, opponent)
if move is not None:
return move
return best_positional_move(board, legal_moves)Frequently Asked Questions
Why does my bot forget data between turns?
Each decision may run in a new process. Reconstruct state from the provided board and metadata instead of relying on global variables.
What do No decision and Invalid Move mean?
Your program either did not produce the required output, produced the wrong format, selected an occupied or out-of-range location, or mixed debug text into stdout.
Why am I missing from the leaderboard?
You need at least one counted non-tournament match for that game. If a match just finished, use Refresh after a short delay.