Initial commit

Signed-off-by: Ilan Bigio <ilan@openai.com>
This commit is contained in:
Ilan Bigio
2025-04-16 12:56:08 -04:00
commit 59a180ddec
163 changed files with 30587 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
#!/bin/bash
# run.sh — Create a new run_N directory for a Codex task, optionally bootstrapped from a template,
# then launch Codex with the task description from task.yaml.
#
# Usage:
# ./run.sh # Prompts to confirm new run
# ./run.sh --auto-confirm # Skips confirmation
#
# Assumes:
# - yq and jq are installed
# - ../task.yaml exists (with .name and .description fields)
# - ../template/ exists (optional, for bootstrapping new runs)
# Enable auto-confirm mode if flag is passed
auto_mode=false
[[ "$1" == "--auto-confirm" ]] && auto_mode=true
# Create the runs directory if it doesn't exist
mkdir -p runs
# Move into the working directory
cd runs || exit 1
# Grab task name for logging
task_name=$(yq -o=json '.' ../task.yaml | jq -r '.name')
echo "Checking for runs for task: $task_name"
# Find existing run_N directories
shopt -s nullglob
run_dirs=(run_[0-9]*)
shopt -u nullglob
if [ ${#run_dirs[@]} -eq 0 ]; then
echo "There are 0 runs."
new_run_number=1
else
max_run_number=0
for d in "${run_dirs[@]}"; do
[[ "$d" =~ ^run_([0-9]+)$ ]] && (( ${BASH_REMATCH[1]} > max_run_number )) && max_run_number=${BASH_REMATCH[1]}
done
new_run_number=$((max_run_number + 1))
echo "There are $max_run_number runs."
fi
# Confirm creation unless in auto mode
if [ "$auto_mode" = false ]; then
read -p "Create run_$new_run_number? (Y/N): " choice
[[ "$choice" != [Yy] ]] && echo "Exiting." && exit 1
fi
# Create the run directory
mkdir "run_$new_run_number"
# Check if the template directory exists and copy its contents
if [ -d "../template" ]; then
cp -r ../template/* "run_$new_run_number"
echo "Initialized run_$new_run_number from template/"
else
echo "Template directory does not exist. Skipping initialization from template."
fi
cd "run_$new_run_number"
# Launch Codex
echo "Launching..."
description=$(yq -o=json '.' ../../task.yaml | jq -r '.description')
codex "$description"

View File

@@ -0,0 +1,11 @@
name: "impossible-pong"
description: |
Update index.html with the following features:
- Add an overlayed styled popup to start the game on first load
- Between each point, show a 3 second countdown (this should be skipped if a player wins)
- After each game the AI wins, display text at the bottom of the screen with lighthearted insults for the player
- Add a leaderboard to the right of the court that shows how many games each player has won.
- When a player wins, a styled popup appears with the winner's name and the option to play again. The leaderboard should update.
- Add an "even more insane" difficulty mode that adds spin to the ball that makes it harder to predict.
- Add an "even more(!!) insane" difficulty mode where the ball does a spin mid court and then picks a random (reasonable) direction to go in (this should only advantage the AI player)
- Let the user choose which difficulty mode they want to play in on the popup that appears when the game starts.

View File

@@ -0,0 +1,233 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Pong</title>
<style>
body {
margin: 0;
background: #000;
color: white;
font-family: sans-serif;
overflow: hidden;
}
#controls {
display: flex;
justify-content: center;
align-items: center;
gap: 12px;
padding: 10px;
background: #111;
position: fixed;
top: 0;
width: 100%;
z-index: 2;
}
canvas {
display: block;
margin: 60px auto 0 auto;
background: #000;
}
button, select {
background: #222;
color: white;
border: 1px solid #555;
padding: 6px 12px;
cursor: pointer;
}
button:hover {
background: #333;
}
#score {
font-weight: bold;
}
</style>
</head>
<body>
<div id="controls">
<button id="startPauseBtn">Pause</button>
<button id="resetBtn">Reset</button>
<label>Mode:
<select id="modeSelect">
<option value="player">Player vs AI</option>
<option value="ai">AI vs AI</option>
</select>
</label>
<label>Difficulty:
<select id="difficultySelect">
<option value="basic">Basic</option>
<option value="fast">Gets Fast</option>
<option value="insane">Insane</option>
</select>
</label>
<div id="score">Player: 0 | AI: 0</div>
</div>
<canvas id="pong" width="800" height="600"></canvas>
<script>
const canvas = document.getElementById('pong');
const ctx = canvas.getContext('2d');
const startPauseBtn = document.getElementById('startPauseBtn');
const resetBtn = document.getElementById('resetBtn');
const modeSelect = document.getElementById('modeSelect');
const difficultySelect = document.getElementById('difficultySelect');
const scoreDisplay = document.getElementById('score');
const paddleWidth = 10, paddleHeight = 100;
const ballRadius = 8;
let player = { x: 0, y: canvas.height / 2 - paddleHeight / 2 };
let ai = { x: canvas.width - paddleWidth, y: canvas.height / 2 - paddleHeight / 2 };
let ball = { x: canvas.width / 2, y: canvas.height / 2, vx: 5, vy: 3 };
let isPaused = false;
let mode = 'player';
let difficulty = 'basic';
const tennisSteps = ['0', '15', '30', '40', 'Adv', 'Win'];
let scores = { player: 0, ai: 0 };
function tennisDisplay() {
if (scores.player >= 3 && scores.ai >= 3) {
if (scores.player === scores.ai) return 'Deuce';
if (scores.player === scores.ai + 1) return 'Advantage Player';
if (scores.ai === scores.player + 1) return 'Advantage AI';
}
return `Player: ${tennisSteps[Math.min(scores.player, 4)]} | AI: ${tennisSteps[Math.min(scores.ai, 4)]}`;
}
function updateScore(winner) {
scores[winner]++;
const diff = scores[winner] - scores[opponent(winner)];
if (scores[winner] >= 4 && diff >= 2) {
alert(`${winner === 'player' ? 'Player' : 'AI'} wins the game!`);
scores = { player: 0, ai: 0 };
}
}
function opponent(winner) {
return winner === 'player' ? 'ai' : 'player';
}
function drawRect(x, y, w, h, color = "#fff") {
ctx.fillStyle = color;
ctx.fillRect(x, y, w, h);
}
function drawCircle(x, y, r, color = "#fff") {
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
function resetBall() {
ball.x = canvas.width / 2;
ball.y = canvas.height / 2;
let baseSpeed = difficulty === 'insane' ? 8 : 5;
ball.vx = baseSpeed * (Math.random() > 0.5 ? 1 : -1);
ball.vy = 3 * (Math.random() > 0.5 ? 1 : -1);
}
function update() {
if (isPaused) return;
ball.x += ball.vx;
ball.y += ball.vy;
// Wall bounce
if (ball.y < 0 || ball.y > canvas.height) ball.vy *= -1;
// Paddle collision
let paddle = ball.x < canvas.width / 2 ? player : ai;
if (
ball.x - ballRadius < paddle.x + paddleWidth &&
ball.x + ballRadius > paddle.x &&
ball.y > paddle.y &&
ball.y < paddle.y + paddleHeight
) {
ball.vx *= -1;
if (difficulty === 'fast') {
ball.vx *= 1.05;
ball.vy *= 1.05;
} else if (difficulty === 'insane') {
ball.vx *= 1.1;
ball.vy *= 1.1;
}
}
// Scoring
if (ball.x < 0) {
updateScore('ai');
resetBall();
} else if (ball.x > canvas.width) {
updateScore('player');
resetBall();
}
// Paddle AI
if (mode === 'ai') {
player.y += (ball.y - (player.y + paddleHeight / 2)) * 0.1;
}
ai.y += (ball.y - (ai.y + paddleHeight / 2)) * 0.1;
// Clamp paddles
player.y = Math.max(0, Math.min(canvas.height - paddleHeight, player.y));
ai.y = Math.max(0, Math.min(canvas.height - paddleHeight, ai.y));
}
function drawCourtBoundaries() {
drawRect(0, 0, canvas.width, 4); // Top
drawRect(0, canvas.height - 4, canvas.width, 4); // Bottom
}
function draw() {
drawRect(0, 0, canvas.width, canvas.height, "#000");
drawCourtBoundaries();
drawRect(player.x, player.y, paddleWidth, paddleHeight);
drawRect(ai.x, ai.y, paddleWidth, paddleHeight);
drawCircle(ball.x, ball.y, ballRadius);
scoreDisplay.textContent = tennisDisplay();
}
function loop() {
update();
draw();
requestAnimationFrame(loop);
}
startPauseBtn.onclick = () => {
isPaused = !isPaused;
startPauseBtn.textContent = isPaused ? "Resume" : "Pause";
};
resetBtn.onclick = () => {
scores = { player: 0, ai: 0 };
resetBall();
};
modeSelect.onchange = (e) => {
mode = e.target.value;
};
difficultySelect.onchange = (e) => {
difficulty = e.target.value;
resetBall();
};
document.addEventListener("mousemove", (e) => {
if (mode === 'player') {
const rect = canvas.getBoundingClientRect();
player.y = e.clientY - rect.top - paddleHeight / 2;
}
});
loop();
</script>
</body>
</html>