Orobas
The Oracle
Unit #076
| HP | PWR | CP | Speed | Range | Tier |
|---|---|---|---|---|---|
| 12 (+6) | 4 (+2) | 3 (+2) | Fast | Distant | C |
Abilities
Divination — 1 AP
Divination: 1 AP - a: Draw 2 demon cards. Then, move 2 demon cards from your hand to the bottom of the deck.
Engine Implementation
def _orobas_divination(
state: GameState, demon: DemonInstance, targets, choices, rng
) -> GameState:
"""#076 Orobas — Divination
1 AP, (exhaust): Draw 2 demon cards. Then, move 2 demon cards from your hand
to the bottom of the deck.
Draws 2 from demon_deck to hand, then puts 2 from hand to bottom of deck.
For random rollout (OpenSpiel): use rng to randomly select which 2 cards to
return from hand (simulating the player choice randomly).
If hand has < 2 cards after drawing, only return as many as available.
Targets: None
"""
new_state = copy.deepcopy(state)
player = new_state.players[demon.owner]
# Draw 2 from demon_deck to hand
draws = min(2, len(player.demon_deck))
for _ in range(draws):
card = player.demon_deck.pop(0)
player.hand.append(card)
# Put 2 from hand to bottom of deck (random selection for rollout)
to_return = min(2, len(player.hand))
if rng is not None and to_return > 0:
for _ in range(to_return):
if not player.hand:
break
# Pick random card from hand to return
idx = rng.randint(0, len(player.hand) - 1)
card = player.hand.pop(idx)
player.demon_deck.append(card)
else:
# Fallback: return the last cards added (deterministic)
for _ in range(to_return):
if not player.hand:
break
card = player.hand.pop(-1)
player.demon_deck.append(card)
return new_state
register_ability("076", 0, _orobas_divination)
Exchange — 1 AP
Exchange: 1 AP - 1x: Randomly reveal a card from your opponent's hand. You may exchange that card with a card from your hand.
Engine Implementation
def _orobas_exchange(
state: GameState, demon: DemonInstance, targets, choices, rng
) -> GameState:
"""#076 Orobas — Exchange
Action, 1 AP, 1x: Randomly reveal a card from your opponent's hand.
You may exchange that card with a card from your hand.
If choices["exchange"] is True and choices["own_card"] is the unit_id to give,
the exchange is performed (remove own_card from owner's hand, add revealed card,
remove revealed card from opponent, add own_card to opponent's hand).
Otherwise (no exchange), only the reveal happens (no state change).
"""
import random as _rng
owner = demon.owner
opponent = Side.PLAYER_2 if owner == Side.PLAYER_1 else Side.PLAYER_1
opponent_hand = state.players[opponent].hand
if not opponent_hand:
return state # Opponent has no cards — nothing to reveal
# Randomly select a card from opponent's hand
if choices and "revealed_card" in choices:
revealed = choices["revealed_card"]
elif rng is not None:
revealed = rng.choice(list(opponent_hand))
else:
revealed = _rng.choice(list(opponent_hand))
# If player chooses to exchange
if choices and choices.get("exchange", False):
own_card = choices.get("own_card", None)
if own_card and own_card in state.players[owner].hand and revealed in state.players[opponent].hand:
new_state = copy.deepcopy(state)
new_state.players[owner].hand.remove(own_card)
new_state.players[owner].hand.append(revealed)
new_state.players[opponent].hand.remove(revealed)
new_state.players[opponent].hand.append(own_card)
return new_state
return state # No exchange — just the reveal (state unchanged mechanically)
register_ability("076", 1, _orobas_exchange)