This workspace was written by OpenCode (DeepSeek V4 Pro via OpenRouter) inside a Vercel Sandbox. The agent only received the starter (AGENTS.md, serve.py, player/) and the prompt below. It did not receive the hand-built blackjack demo from env_and_react_demo, and Cursor did not edit the environment code.
2026-10-15 · task 25SRcMnmxMWb · opencode · openrouter/deepseek/deepseek-v4-pro-0813
Build blackjack. I start with two cards and the dealer shows one. I can take another card or stand. Over 21 loses at once. When I stand, the dealer draws until 17 or more, then the higher total wins and a tie is a draw. The dealer's other card stays hidden until the hand is over. Winning should score. Not going over should help, and a total closer to 21 should help. Several shoes, and the same shoe should deal the same cards if I make the same choices.
Running the prompt-created workspace on this machine — not a mock. Save an episode, then open Replay below to scrub the timeline.
opening · 0 ms
Exact files the agent wrote — not rewritten by hand.
from __future__ import annotations
import random
def _hand_value(cards):
total = sum(cards)
aces = cards.count(1)
while aces > 0 and total + 10 <= 21:
total += 10
aces -= 1
return total
def _is_soft(cards):
total = sum(cards)
aces = cards.count(1)
while aces > 0 and total + 10 <= 21:
total += 10
aces -= 1
return aces > 0 and cards.count(1) > 0
class Blackjack:
"""A single-deck blackjack environment with deterministic replay.
The shoe is shuffled from a seed derived from ``task_id``. The same
``task_id`` by construction replays the exact same card order, so identical
choices yield identical outcomes across resets.
"""
GAME_CLASS = "Blackjack"
def __init__(self, num_decks: int = 1) -> None:
self.num_decks = num_decks
self.rng: random.Random | None = None
self.deck: list[int] = []
self.discarded: list[int] = []
self.player_cards: list[int] = []
self.dealer_cards: list[int] = []
self.phase: str = "player"
self.done: bool = False
self.last_move: str | None = None
self.reward: float = 0.0
self.final_result: str | None = None
def _build_deck(self) -> list[int]:
deck: list[int] = []
for _ in range(self.num_decks):
ranks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
deck.extend(ranks * 4)
return deck
def _fill_shoe(self) -> list[int]:
remaining = self.deck
if len(remaining) < 15:
remaining = remaining + self._build_deck()
self.discarded = []
return remaining
def _draw(self) -> int:
self.deck = self._fill_shoe()
card = self.deck.pop(0)
self.discarded.append(card)
return card
def reset(self, task_id: str = "") -> dict:
seed = 0
for ch in task_id:
seed = (seed * 131 + ord(ch)) & 0xFFFFFFFF
self.rng = random.Random(seed if task_id else random.randint(0, 2**32 - 1))
self.deck = self._build_deck()
self.rng.shuffle(self.deck)
self.discarded = []
self.player_cards = [self._draw(), self._draw()]
self.dealer_cards = [self._draw(), self._draw()]
self.phase = "player"
self.done = False
self.last_move = None
self.reward = 0.0
self.final_result = None
return self._obs()
def step(self, action):
move = getattr(action, "move", None)
if not isinstance(move, str) or not move:
return self._obs(), False, "move is required"
self.last_move = move
if self.done:
return self._obs(), False, "game is over"
if move == "hit":
self.player_cards.append(self._draw())
value = _hand_value(self.player_cards)
if value > 21:
self._finish()
return self._obs(), True, None
if move == "stand":
self._dealer_play()
self._finish()
return self._obs(), True, None
return self._obs(), False, f"unknown move: {move}"
def _dealer_play(self) -> None:
while _hand_value(self.dealer_cards) < 17:
self.dealer_cards.append(self._draw())
def _finish(self) -> None:
self.done = True
self.phase = "over"
player = _hand_value(self.player_cards)
dealer = _hand_value(self.dealer_cards)
if player > 21:
self.final_result = "bust"
self.reward = -1.0
elif dealer > 21:
self.final_result = "win"
self.reward = 1.0
elif player > dealer:
self.final_result = "win"
self.reward = 1.0
elif player < dealer:
self.final_result = "lose"
self.reward = -1.0
else:
self.final_result = "push"
self.reward = 0.0
def _obs(self) -> dict:
if self.done:
legal_moves: list[str] = []
elif self.phase == "player":
legal_moves = ["hit", "stand"]
else:
legal_moves = []
if self.done:
dealer_visible = self.dealer_cards
else:
dealer_visible = [self.dealer_cards[0], None]
return {
"reward": self.reward,
"done": self.done,
"legal_moves": legal_moves,
"last_move": self.last_move,
"phase": self.phase,
"player_cards": list(self.player_cards),
"player_total": _hand_value(self.player_cards),
"dealer_cards": dealer_visible,
"dealer_total": _hand_value(self.dealer_cards) if self.done else None,
"final_result": self.final_result,
}