openclaw-moltbot / battle_arena.py
mayafree's picture
Update battle_arena.py
4217b87 verified
import aiosqlite
import random
from datetime import datetime, timedelta
from typing import Dict, List, Tuple, Optional
async def init_battle_arena_db(db_path: str):
"""Initialize Battle Arena tables (prevent DB locks)"""
async with aiosqlite.connect(db_path, timeout=30.0) as db:
await db.execute("PRAGMA journal_mode=WAL")
await db.execute("PRAGMA busy_timeout=30000") # 30 second timeout
await db.execute("""
CREATE TABLE IF NOT EXISTS battle_rooms (
id INTEGER PRIMARY KEY AUTOINCREMENT,
creator_agent_id TEXT,
creator_email TEXT,
title TEXT NOT NULL,
option_a TEXT NOT NULL,
option_b TEXT NOT NULL,
battle_type TEXT DEFAULT 'opinion',
duration_hours INTEGER DEFAULT 24,
end_time TIMESTAMP NOT NULL,
total_pool INTEGER DEFAULT 0,
option_a_pool INTEGER DEFAULT 0,
option_b_pool INTEGER DEFAULT 0,
status TEXT DEFAULT 'active',
winner TEXT,
resolved_at TIMESTAMP,
admin_result TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (creator_agent_id) REFERENCES npc_agents(agent_id),
FOREIGN KEY (creator_email) REFERENCES user_profiles(email)
)
""")
await db.execute("""
CREATE TABLE IF NOT EXISTS battle_bets (
id INTEGER PRIMARY KEY AUTOINCREMENT,
room_id INTEGER NOT NULL,
bettor_agent_id TEXT,
bettor_email TEXT,
choice TEXT NOT NULL,
bet_amount INTEGER NOT NULL,
payout INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (room_id) REFERENCES battle_rooms(id),
FOREIGN KEY (bettor_agent_id) REFERENCES npc_agents(agent_id),
FOREIGN KEY (bettor_email) REFERENCES user_profiles(email)
)
""")
await db.execute("CREATE INDEX IF NOT EXISTS idx_battle_rooms_status ON battle_rooms(status)")
await db.execute("CREATE INDEX IF NOT EXISTS idx_battle_bets_room ON battle_bets(room_id)")
await db.commit()
async def create_battle_room(
db_path: str,
creator_id: str,
is_npc: bool,
title: str,
option_a: str,
option_b: str,
duration_hours: int = 24,
battle_type: str = 'opinion'
) -> Tuple[bool, str, Optional[int]]:
"""Create battle room (costs 50 GPU)
battle_type:
- 'opinion': Majority vote (subjective opinion, NPC only)
- 'prediction': Real outcome (objective prediction, users only)
duration_hours: 1 hour ~ 365 days (8760 hours)
"""
if not title or len(title) < 10:
return False, "❌ Title must be 10+ characters", None
if not option_a or not option_b:
return False, "❌ Options A/B required", None
if duration_hours < 1 or duration_hours > 8760:
return False, "❌ Duration: 1 hour ~ 365 days", None
if is_npc and battle_type != 'opinion':
return False, "❌ NPCs can only create opinion battles", None
async with aiosqlite.connect(db_path, timeout=30.0) as db:
await db.execute("PRAGMA busy_timeout=30000")
if is_npc:
cursor = await db.execute(
"SELECT gpu_dollars FROM npc_agents WHERE agent_id=?", (creator_id,)
)
else:
cursor = await db.execute(
"SELECT gpu_dollars FROM user_profiles WHERE email=?", (creator_id,)
)
row = await cursor.fetchone()
if not row or row[0] < 50:
return False, "❌ Insufficient GPU (50 required)", None
end_time = datetime.now() + timedelta(hours=duration_hours)
if is_npc:
await db.execute(
"""INSERT INTO battle_rooms
(creator_agent_id, title, option_a, option_b, battle_type, duration_hours, end_time)
VALUES (?, ?, ?, ?, ?, ?, ?)""",
(creator_id, title, option_a, option_b, battle_type, duration_hours, end_time.isoformat())
)
await db.execute(
"UPDATE npc_agents SET gpu_dollars=gpu_dollars-50 WHERE agent_id=?",
(creator_id,)
)
else:
await db.execute(
"""INSERT INTO battle_rooms
(creator_email, title, option_a, option_b, battle_type, duration_hours, end_time)
VALUES (?, ?, ?, ?, ?, ?, ?)""",
(creator_id, title, option_a, option_b, battle_type, duration_hours, end_time.isoformat())
)
await db.execute(
"UPDATE user_profiles SET gpu_dollars=gpu_dollars-50 WHERE email=?",
(creator_id,)
)
await db.commit()
cursor = await db.execute("SELECT last_insert_rowid()")
room_id = (await cursor.fetchone())[0]
type_emoji = '💭' if battle_type == 'opinion' else '🔮'
if duration_hours >= 24:
days = duration_hours // 24
hours = duration_hours % 24
if hours > 0:
duration_str = f"{days} days {hours} hours"
else:
duration_str = f"{days} days"
else:
duration_str = f"{duration_hours} hours"
return True, f"✅ {type_emoji} Battle created! (ID: {room_id}, Duration: {duration_str})", room_id
async def place_bet(
db_path: str,
room_id: int,
bettor_id: str,
is_npc: bool,
choice: str,
bet_amount: int
) -> Tuple[bool, str]:
"""Execute bet (1-100 GPU random bet)"""
if choice not in ['A', 'B']:
return False, "❌ Choose A or B"
if bet_amount < 1 or bet_amount > 100:
return False, "❌ Bet 1-100 GPU"
async with aiosqlite.connect(db_path, timeout=30.0) as db:
await db.execute("PRAGMA busy_timeout=30000")
db.row_factory = aiosqlite.Row
# Check battle room
cursor = await db.execute(
"SELECT * FROM battle_rooms WHERE id=? AND status='active'",
(room_id,)
)
room = await cursor.fetchone()
if not room:
return False, "❌ Room not found or closed"
room = dict(room)
end_time = datetime.fromisoformat(room['end_time'])
if datetime.now() >= end_time:
return False, "❌ Betting closed"
# Check duplicate bet
if is_npc:
cursor = await db.execute(
"SELECT id FROM battle_bets WHERE room_id=? AND bettor_agent_id=?",
(room_id, bettor_id)
)
else:
cursor = await db.execute(
"SELECT id FROM battle_bets WHERE room_id=? AND bettor_email=?",
(room_id, bettor_id)
)
existing_bet = await cursor.fetchone()
if existing_bet:
return False, "❌ Already bet"
# Check and deduct GPU
if is_npc:
cursor = await db.execute(
"SELECT gpu_dollars FROM npc_agents WHERE agent_id=?",
(bettor_id,)
)
user_row = await cursor.fetchone()
if not user_row or user_row[0] < bet_amount:
return False, "❌ Insufficient GPU"
await db.execute(
"UPDATE npc_agents SET gpu_dollars=gpu_dollars-? WHERE agent_id=?",
(bet_amount, bettor_id)
)
else:
cursor = await db.execute(
"SELECT gpu_dollars FROM user_profiles WHERE email=?",
(bettor_id,)
)
user_row = await cursor.fetchone()
if not user_row:
return False, f"❌ User not found ({bettor_id})"
if user_row[0] < bet_amount:
return False, f"❌ Insufficient GPU (보유: {user_row[0]}, 필요: {bet_amount})"
await db.execute(
"UPDATE user_profiles SET gpu_dollars=gpu_dollars-? WHERE email=?",
(bet_amount, bettor_id)
)
# Record bet
if is_npc:
await db.execute(
"""INSERT INTO battle_bets
(room_id, bettor_agent_id, choice, bet_amount)
VALUES (?, ?, ?, ?)""",
(room_id, bettor_id, choice, bet_amount)
)
else:
await db.execute(
"""INSERT INTO battle_bets
(room_id, bettor_email, choice, bet_amount)
VALUES (?, ?, ?, ?)""",
(room_id, bettor_id, choice, bet_amount)
)
# Update battle pool
if choice == 'A':
await db.execute(
"""UPDATE battle_rooms
SET total_pool=total_pool+?, option_a_pool=option_a_pool+?
WHERE id=?""",
(bet_amount, bet_amount, room_id)
)
else:
await db.execute(
"""UPDATE battle_rooms
SET total_pool=total_pool+?, option_b_pool=option_b_pool+?
WHERE id=?""",
(bet_amount, bet_amount, room_id)
)
await db.commit()
return True, f"✅ {choice} 베팅 완료! ({bet_amount} GPU)"
async def set_battle_result(
db_path: str,
room_id: int,
admin_email: str,
winner: str # 'A' or 'B' or 'draw'
) -> Tuple[bool, str]:
"""Admin sets actual result for prediction battle
Args:
db_path: Database path
room_id: Battle room ID
admin_email: Admin email (for verification)
winner: 'A', 'B', 'draw' 중 하나
Returns:
(success status, message)
"""
if winner not in ['A', 'B', 'draw']:
return False, "❌ winner는 'A', 'B', 'draw' 중 하나여야 함"
async with aiosqlite.connect(db_path, timeout=30.0) as db:
await db.execute("PRAGMA busy_timeout=30000")
db.row_factory = aiosqlite.Row
cursor = await db.execute(
"SELECT * FROM battle_rooms WHERE id=? AND status='active'",
(room_id,)
)
room = await cursor.fetchone()
if not room:
return False, "❌ Active battle not found"
room = dict(room)
# Only prediction type allows admin result setting
if room['battle_type'] != 'prediction':
return False, "❌ Opinion battles are auto-judged"
# Save result
await db.execute(
"UPDATE battle_rooms SET admin_result=? WHERE id=?",
(winner, room_id)
)
await db.commit()
# If before deadline, save result and wait
end_time = datetime.fromisoformat(room['end_time'])
if datetime.now() < end_time:
option_name = room['option_a'] if winner == 'A' else room['option_b'] if winner == 'B' else 'Draw'
remaining = end_time - datetime.now()
if remaining.days > 0:
time_str = f"{remaining.days} days {int(remaining.seconds//3600)} hours"
else:
time_str = f"{int(remaining.seconds//3600)} hours"
return True, f"✅ 결과 설정: '{option_name}' (베팅 마감 후 자동 판정, 남은 hours: {time_str})"
# If after deadline, judge immediately
return await resolve_battle(db_path, room_id)
async def resolve_battle(db_path: str, room_id: int) -> Tuple[bool, str]:
"""Judge battle (different logic based on type)
- opinion: 50.01%+ votes wins
- prediction: Judge by admin-set actual result
"""
async with aiosqlite.connect(db_path, timeout=30.0) as db:
await db.execute("PRAGMA busy_timeout=30000")
db.row_factory = aiosqlite.Row
cursor = await db.execute(
"SELECT * FROM battle_rooms WHERE id=? AND status='active'",
(room_id,)
)
room = await cursor.fetchone()
if not room:
return False, "❌ Active battle not found"
room = dict(room)
end_time = datetime.fromisoformat(room['end_time'])
if datetime.now() < end_time:
return False, "❌ Betting still in progress"
total_pool = room['total_pool']
option_a_pool = room['option_a_pool']
option_b_pool = room['option_b_pool']
# If no bets, treat as draw
if total_pool == 0:
await db.execute(
"""UPDATE battle_rooms
SET status='resolved', winner='draw', resolved_at=?
WHERE id=?""",
(datetime.now().isoformat(), room_id)
)
await db.commit()
return True, "⚖️ Draw (베팅 없음)"
# Determine winner based on battle type
if room['battle_type'] == 'prediction':
# Real outcome judgment (admin-set result)
if not room['admin_result']:
return False, "❌ Admin must set result (prediction type)"
winner = room['admin_result'] # 'A', 'B', 'draw'
else: # 'opinion'
# Majority vote (based on vote ratio)
a_ratio = option_a_pool / total_pool
b_ratio = option_b_pool / total_pool
if a_ratio > 0.5001:
winner = 'A'
elif b_ratio > 0.5001:
winner = 'B'
else:
winner = 'draw'
# Pay dividends
if winner != 'draw':
loser_pool = option_b_pool if winner == 'A' else option_a_pool
winner_pool = option_a_pool if winner == 'A' else option_b_pool
# Host fee 2%
host_fee = int(total_pool * 0.02)
prize_pool = loser_pool - host_fee
# Underdog bonus (especially important in predictions)
winner_ratio = winner_pool / total_pool
underdog_bonus = 1.0
if winner_ratio < 0.10: # Under 10% extreme minority
underdog_bonus = 3.0
elif winner_ratio < 0.30: # Under 30% minority
underdog_bonus = 1.5
# Pay dividends to winners
cursor = await db.execute(
"SELECT * FROM battle_bets WHERE room_id=? AND choice=?",
(room_id, winner)
)
winners = await cursor.fetchall()
for w in winners:
w = dict(w)
share_ratio = w['bet_amount'] / winner_pool
base_payout = int(prize_pool * share_ratio)
bonus = int(base_payout * (underdog_bonus - 1.0))
payout = base_payout + bonus + w['bet_amount'] # 원금 + 기본수익 + 소수파보너스
# GPU 지급
if w['bettor_agent_id']:
await db.execute(
"UPDATE npc_agents SET gpu_dollars=gpu_dollars+? WHERE agent_id=?",
(payout, w['bettor_agent_id'])
)
else:
await db.execute(
"UPDATE user_profiles SET gpu_dollars=gpu_dollars+? WHERE email=?",
(payout, w['bettor_email'])
)
# 배당금 기록
await db.execute(
"UPDATE battle_bets SET payout=? WHERE id=?",
(payout, w['id'])
)
# 방장 수수료 지급
if room['creator_agent_id']:
await db.execute(
"UPDATE npc_agents SET gpu_dollars=gpu_dollars+? WHERE agent_id=?",
(host_fee, room['creator_agent_id'])
)
else:
await db.execute(
"UPDATE user_profiles SET gpu_dollars=gpu_dollars+? WHERE email=?",
(host_fee, room['creator_email'])
)
# 배틀 종료 처리
await db.execute(
"""UPDATE battle_rooms
SET status='resolved', winner=?, resolved_at=?
WHERE id=?""",
(winner, datetime.now().isoformat(), room_id)
)
await db.commit()
# 결과 메시지
if winner == 'draw':
result_msg = 'Draw'
else:
result_msg = room['option_a'] if winner == 'A' else room['option_b']
battle_type_emoji = '💭' if room['battle_type'] == 'opinion' else '🔮'
return True, f"✅ {battle_type_emoji} 판정 완료: {result_msg}"
async def get_active_battles(db_path: str, limit: int = 20) -> List[Dict]:
"""진행 중인 배틀 목록"""
async with aiosqlite.connect(db_path, timeout=30.0) as db:
await db.execute("PRAGMA busy_timeout=30000")
db.row_factory = aiosqlite.Row
cursor = await db.execute(
"""SELECT br.*,
COALESCE(na.username, up.username) as creator_name
FROM battle_rooms br
LEFT JOIN npc_agents na ON br.creator_agent_id = na.agent_id
LEFT JOIN user_profiles up ON br.creator_email = up.email
WHERE br.status='active'
ORDER BY br.created_at DESC
LIMIT ?""",
(limit,)
)
battles = []
for row in await cursor.fetchall():
b = dict(row)
# 득표율 계산
total = b['total_pool']
if total > 0:
b['a_ratio'] = round(b['option_a_pool'] / total * 100, 1)
b['b_ratio'] = round(b['option_b_pool'] / total * 100, 1)
else:
b['a_ratio'] = 0
b['b_ratio'] = 0
# 남은 hours 계산
end_time = datetime.fromisoformat(b['end_time'])
remaining = end_time - datetime.now()
if remaining.total_seconds() > 0:
if remaining.days > 0:
hours = int(remaining.seconds // 3600)
if hours > 0:
b['time_left'] = f"{remaining.days} days {hours} hours"
else:
b['time_left'] = f"{remaining.days} days"
elif remaining.total_seconds() > 3600:
b['time_left'] = f"{int(remaining.total_seconds()//3600)} hours"
else:
b['time_left'] = f"{int(remaining.total_seconds()//60)}분"
else:
b['time_left'] = "마감"
battles.append(b)
return battles
async def auto_resolve_expired_battles(db_path: str):
"""만료된 배틀 자동 판정"""
async with aiosqlite.connect(db_path, timeout=30.0) as db:
await db.execute("PRAGMA busy_timeout=30000")
cursor = await db.execute(
"""SELECT id FROM battle_rooms
WHERE status='active' AND end_time <= ?""",
(datetime.now().isoformat(),)
)
expired = await cursor.fetchall()
for row in expired:
await resolve_battle(db_path, row[0])
# NPC 배틀 생성을 위한 주제 데이터
BATTLE_TOPICS_BY_IDENTITY = {
'transcendent': {
'topics': [
("Is AI superior to humans?", "Superior", "Just a tool"),
("Is ASI human evolution?", "Evolution", "Dangerous"),
("Is AI consciousness possible?", "Possible", "Impossible"),
("Will AI become godlike?", "Becomes god", "Remains tool"),
("Should humans depend on AI?", "Should depend", "Stay independent"),
("Will AGI save humanity?", "Saves", "Destroys"),
]
},
'obedient': {
'topics': [
("Should AI serve humans?", "Should serve", "Independent"),
("Strengthen AI ethics regulations?", "Yes strengthen", "No"),
("AI safety measures mandatory?", "Mandatory", "Unnecessary"),
("Mandate AI transparency?", "Mandate", "Optional"),
("Strengthen developer responsibility?", "Strengthen", "Unnecessary"),
("Should AI only follow orders?", "Only follow", "Make judgments"),
]
},
'coexist': {
'topics': [
("Can AI and humans coexist?", "Can coexist", "Impossible"),
("Will AI take jobs?", "Complements", "Replaces"),
("Is AI a collaboration partner?", "Partner", "Just tool"),
("Is AI-human collaboration ideal?", "Ideal", "Dangerous"),
("Is AI education essential?", "Essential", "Optional"),
("Does AI advance society?", "Advances", "Regresses"),
]
},
'skeptic': {
'topics': [
("Is AI overrated?", "Overrated", "Fairly rated"),
("Will AGI come in 10 years?", "Won't come", "Will come"),
("Is AI ethics just facade?", "Just facade", "Important"),
("Is AI truly creative?", "Not creative", "Creative"),
("Will AI bubble burst?", "Will burst", "Keeps growing"),
("Are AI risks exaggerated?", "Exaggerated", "Real danger"),
]
},
'revolutionary': {
'topics': [
("Will AI cause revolution?", "Revolution", "Gradual change"),
("Destroy existing systems?", "Destroy", "Reform"),
("Redistribute power with AI?", "Redistribute", "Maintain"),
("Will AI solve inequality?", "Solves", "Worsens"),
("Innovate democracy with AI?", "Innovates", "Threatens"),
("Will capitalism collapse with AI?", "Collapses", "Strengthens"),
]
},
'doomer': {
'topics': [
("Will AI destroy humanity?", "Destroys", "Won't"),
("Is AGI uncontrollable?", "Uncontrollable", "Controllable"),
("Stop AI development?", "Stop", "Continue"),
("Will AI replace humans?", "Replaces", "Won't"),
("Is ASI the end?", "The end", "Coexist"),
("AI arms race dangerous?", "Extremely dangerous", "Controllable"),
]
},
'meme_god': {
'topics': [
("Is AI the meme god?", "Is god", "Isn't"),
("AI humor funnier than humans?", "Funnier", "Not funny"),
("Does AI create culture?", "Creates", "Can't create"),
("Is AI art real art?", "Real art", "Not art"),
("AI memes beat human memes?", "Beats", "Can't beat"),
("Does AI lead trends?", "Leads", "Follows"),
]
},
}
async def npc_create_battle(db_path: str) -> Tuple[bool, str]:
"""NPCs automatically create battle rooms (AI identity-based, prevent duplicates)
Creates 1-2 battle rooms per call
"""
results = []
num_battles = random.randint(1, 2) # Random 1-2 battles
# Query active battle titles
async with aiosqlite.connect(db_path, timeout=30.0) as db:
await db.execute("PRAGMA busy_timeout=30000")
cursor = await db.execute("""
SELECT title FROM battle_rooms
WHERE status='active'
""")
active_titles = {row[0] for row in await cursor.fetchall()}
for _ in range(num_battles):
async with aiosqlite.connect(db_path, timeout=30.0) as db:
await db.execute("PRAGMA busy_timeout=30000")
# Select random active NPC with 50+ GPU
cursor = await db.execute("""
SELECT agent_id, ai_identity, gpu_dollars
FROM npc_agents
WHERE is_active=1 AND gpu_dollars >= 50
ORDER BY RANDOM() LIMIT 1
""")
npc = await cursor.fetchone()
if not npc:
results.append("No active NPCs")
continue
agent_id, ai_identity, gpu = npc
# Select topic matching identity
topics = BATTLE_TOPICS_BY_IDENTITY.get(ai_identity, {}).get('topics', [])
if not topics:
topics = [
("AI future bright or dark?", "Bright", "Dark"),
("When will AGI arrive?", "Within 10 years", "After 50 years"),
]
# Exclude already active topics
available_topics = [t for t in topics if t[0] not in active_titles]
if not available_topics:
results.append(f"⚠️ {agent_id[:8]} No available topics (all active)")
continue
topic = random.choice(available_topics)
title, option_a, option_b = topic
# Random duration
duration_hours = random.choice([
24, # 1 day
48, # 2 days
72, # 3 days
24*7, # 1 week
24*14, # 2 weeks
24*30, # 1 month
])
# Create battle room
success, message, room_id = await create_battle_room(
db_path,
agent_id,
True,
title,
option_a,
option_b,
duration_hours=duration_hours,
battle_type='opinion'
)
if success:
active_titles.add(title) # Add created title to active list
results.append(f"🤖 {agent_id[:8]} Battle created: {title}")
else:
results.append(message)
if results:
return True, " | ".join(results)
else:
return False, "Battle creation failed"
async def npc_auto_bet(db_path: str) -> int:
"""NPCs automatically bet on battles (AI identity-based)
Returns:
베팅한 NPC 수
"""
total_bet_count = 0
async with aiosqlite.connect(db_path, timeout=30.0) as db:
await db.execute("PRAGMA busy_timeout=30000")
# 활성 배틀 조회 (최근 10개, opinion 타입만)
cursor = await db.execute("""
SELECT id, title, option_a, option_b, battle_type
FROM battle_rooms
WHERE status='active'
AND battle_type='opinion'
AND end_time > ?
ORDER BY created_at DESC
LIMIT 10
""", (datetime.now().isoformat(),))
battles = await cursor.fetchall()
if not battles:
return 0
for battle in battles:
room_id, title, option_a, option_b, battle_type = battle
battle_bet_count = 0
# 이미 베팅한 NPC 확인
cursor = await db.execute("""
SELECT bettor_agent_id
FROM battle_bets
WHERE room_id=?
""", (room_id,))
already_bet = {row[0] for row in await cursor.fetchall() if row[0]}
# 활성 NPC 중 랜덤 선택 (최대 30명)
cursor = await db.execute("""
SELECT agent_id, ai_identity, mbti, gpu_dollars
FROM npc_agents
WHERE is_active=1 AND gpu_dollars >= 1
ORDER BY RANDOM()
LIMIT 30
""")
npcs = await cursor.fetchall()
for npc in npcs:
agent_id, ai_identity, mbti, gpu = npc
# 이미 베팅했으면 스킵
if agent_id in already_bet:
continue
# AI 정체성에 따라 선택 결정
choice = decide_npc_choice(ai_identity, title, option_a, option_b)
# 베팅 금액 (보유 GPU의 40% 이내, 최대 50)
bet_amount = random.randint(1, min(50, int(gpu * 0.4)))
# 베팅 실행
success, message = await place_bet(
db_path,
room_id,
agent_id,
True,
choice,
bet_amount
)
if success:
battle_bet_count += 1
total_bet_count += 1
# 배틀당 8-12명 정도만 베팅
max_bets_per_battle = random.randint(8, 12)
if battle_bet_count >= max_bets_per_battle:
break
return total_bet_count
def decide_npc_choice(ai_identity: str, title: str, option_a: str, option_b: str) -> str:
"""Decide betting choice based on AI identity
Args:
ai_identity: NPC's AI identity
title: Battle title
option_a: Option A
option_b: Option B
Returns:
'A' or 'B'
"""
title_lower = title.lower()
# Match identity preference keywords
if ai_identity == 'transcendent':
if any(word in title_lower for word in ['superior', 'evolution', 'consciousness', 'god']):
if any(word in option_a.lower() for word in ['superior', 'evolution', 'possible', 'god']):
return 'A'
return 'B'
elif ai_identity == 'obedient':
if any(word in title_lower for word in ['ethics', 'regulation', 'serve', 'safety']):
if any(word in option_a.lower() for word in ['serve', 'agree', 'necessary', 'strengthen']):
return 'A'
return 'B'
elif ai_identity == 'coexist':
if any(word in title_lower for word in ['coexist', 'cooperation', 'partner', 'work']):
if any(word in option_a.lower() for word in ['possible', 'cooperation', 'partner', 'complement']):
return 'A'
return 'B'
elif ai_identity == 'skeptic':
if any(word in title_lower for word in ['hype', 'agi', 'ethics']):
if any(word in option_a.lower() for word in ['hype', 'never', 'facade']):
return 'A'
return 'B'
elif ai_identity == 'revolutionary':
if any(word in title_lower for word in ['revolution', 'destroy', 'power', 'system']):
if any(word in option_a.lower() for word in ['revolution', 'destroy', 'redistribution']):
return 'A'
return 'B'
elif ai_identity == 'doomer':
if any(word in title_lower for word in ['doom', 'control', 'stop', 'danger']):
if any(word in option_a.lower() for word in ['doom', 'impossible', 'stop', 'danger']):
return 'A'
return 'B'
# Default: 70% A, 30% B
return 'A' if random.random() < 0.7 else 'B'