|
|
|
"""
|
|
Modified scan handler for Tag Collector Game with Enkephalin rewards for rare tags
|
|
"""
|
|
|
|
import streamlit as st
|
|
import torch
|
|
import time
|
|
import math
|
|
from tag_categories import (
|
|
get_unlocked_categories,
|
|
get_collection_power_level
|
|
)
|
|
from game_constants import TAG_CURRENCY_NAME, ENKEPHALIN_CURRENCY_NAME, ENKEPHALIN_ICON, RARITY_LEVELS, TAG_POWER_BONUSES
|
|
from state_manager import update_game_state
|
|
|
|
def enhanced_scan_button_handler(image_path):
|
|
"""
|
|
Enhanced scan button handler with Enkephalin rewards for rare tag discoveries
|
|
"""
|
|
try:
|
|
|
|
results = st.session_state.model.predict(
|
|
image_path=image_path,
|
|
threshold=st.session_state.threshold
|
|
)
|
|
|
|
|
|
probs = results['refined_probabilities'][0]
|
|
|
|
|
|
unlocked_categories = get_unlocked_categories(st.session_state)
|
|
|
|
|
|
max_tags = float('inf')
|
|
|
|
|
|
power_info = get_collection_power_level(st.session_state)
|
|
coin_multiplier = power_info['current_level']['coin_bonus']
|
|
|
|
|
|
all_tags = {}
|
|
found_tags = []
|
|
total_currency_earned = 0
|
|
total_enkephalin_earned = 0
|
|
new_tag_count = 0
|
|
|
|
|
|
min_display_prob = 0.1
|
|
|
|
|
|
previously_unlocked = set(st.session_state.unlocked_combinations) if hasattr(st.session_state, 'unlocked_combinations') else set()
|
|
|
|
|
|
candidates = []
|
|
for idx in range(len(probs)):
|
|
prob_value = probs[idx].item()
|
|
|
|
|
|
if prob_value >= st.session_state.threshold:
|
|
tag, category = st.session_state.model.dataset.get_tag_info(idx)
|
|
candidates.append({
|
|
"idx": idx,
|
|
"tag": tag,
|
|
"probability": prob_value,
|
|
"category": category
|
|
})
|
|
|
|
|
|
candidates.sort(key=lambda x: x["probability"], reverse=True)
|
|
|
|
|
|
for idx in range(len(probs)):
|
|
prob_value = probs[idx].item()
|
|
|
|
|
|
if prob_value < min_display_prob:
|
|
continue
|
|
|
|
|
|
tag, category = st.session_state.model.dataset.get_tag_info(idx)
|
|
|
|
|
|
rarity = determine_tag_rarity(tag, prob_value, category)
|
|
|
|
|
|
if category not in all_tags:
|
|
all_tags[category] = []
|
|
|
|
|
|
is_collected = prob_value >= st.session_state.threshold
|
|
|
|
|
|
if is_collected:
|
|
all_tags[category].append((tag, prob_value, rarity, "collected"))
|
|
else:
|
|
all_tags[category].append((tag, prob_value, rarity, "displayed"))
|
|
|
|
|
|
for candidate in candidates:
|
|
tag = candidate["tag"]
|
|
prob_value = candidate["probability"]
|
|
category = candidate["category"]
|
|
|
|
|
|
rarity = determine_tag_rarity(tag, prob_value, category)
|
|
|
|
|
|
currency_earned, enkephalin_earned, is_new_tag = add_tag_to_collection(tag, prob_value, category, coin_multiplier)
|
|
|
|
|
|
if is_new_tag:
|
|
new_tag_count += 1
|
|
|
|
|
|
if currency_earned > 0:
|
|
total_currency_earned += currency_earned
|
|
|
|
|
|
if enkephalin_earned > 0:
|
|
total_enkephalin_earned += enkephalin_earned
|
|
|
|
|
|
found_tags.append({
|
|
"tag": tag,
|
|
"probability": prob_value,
|
|
"category": category,
|
|
"currency": currency_earned,
|
|
"enkephalin": enkephalin_earned,
|
|
"rarity": rarity,
|
|
"is_new": is_new_tag
|
|
})
|
|
|
|
|
|
for category in all_tags:
|
|
all_tags[category].sort(key=lambda x: x[1], reverse=True)
|
|
|
|
|
|
|
|
st.session_state.game_stats["images_processed"] += 1
|
|
st.session_state.game_stats["total_tags_found"] += len(found_tags)
|
|
|
|
|
|
if total_enkephalin_earned > 0:
|
|
if "enkephalin_generated" not in st.session_state.game_stats:
|
|
st.session_state.game_stats["enkephalin_generated"] = 0
|
|
st.session_state.game_stats["enkephalin_generated"] += total_enkephalin_earned
|
|
|
|
|
|
threshold_bonus, coin_bonus = calculate_tag_power()
|
|
st.session_state.tag_power_bonus = threshold_bonus
|
|
st.session_state.coin_multiplier = coin_bonus
|
|
|
|
|
|
if 'state_version' not in st.session_state:
|
|
st.session_state.state_version = 0
|
|
st.session_state.state_version += 1
|
|
|
|
|
|
st.session_state.current_scan = {
|
|
"all_tags": all_tags,
|
|
"found_tags": found_tags,
|
|
"threshold": st.session_state.threshold,
|
|
"total_currency_earned": total_currency_earned,
|
|
"total_enkephalin_earned": total_enkephalin_earned,
|
|
"new_tag_count": new_tag_count,
|
|
}
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
st.error(f"Error scanning image: {str(e)}")
|
|
import traceback
|
|
st.code(traceback.format_exc())
|
|
return False
|
|
|
|
def determine_tag_rarity(tag, probability, category):
|
|
"""
|
|
Determine the rarity of a tag based on the metadata if available,
|
|
otherwise use a simplified probability-based approach.
|
|
Always returns a valid rarity level.
|
|
"""
|
|
|
|
default_rarity = "Canard"
|
|
|
|
try:
|
|
|
|
if hasattr(st.session_state, 'tag_rarity_metadata') and st.session_state.tag_rarity_metadata:
|
|
|
|
if tag in st.session_state.tag_rarity_metadata:
|
|
tag_info = st.session_state.tag_rarity_metadata[tag]
|
|
|
|
|
|
if isinstance(tag_info, dict) and "rarity" in tag_info:
|
|
|
|
rarity = tag_info["rarity"]
|
|
else:
|
|
|
|
rarity = tag_info
|
|
|
|
|
|
if rarity in RARITY_LEVELS:
|
|
return rarity
|
|
|
|
|
|
if tag.startswith("rating_") or tag.startswith("year_"):
|
|
for metadata_tag in st.session_state.tag_rarity_metadata:
|
|
if metadata_tag == tag:
|
|
tag_info = st.session_state.tag_rarity_metadata[metadata_tag]
|
|
if isinstance(tag_info, dict) and "rarity" in tag_info:
|
|
rarity = tag_info["rarity"]
|
|
else:
|
|
rarity = tag_info
|
|
|
|
if rarity in RARITY_LEVELS:
|
|
return rarity
|
|
|
|
except Exception as e:
|
|
|
|
print(f"Error determining rarity for tag {tag}: {str(e)}")
|
|
|
|
|
|
return default_rarity
|
|
|
|
def get_enkephalin_reward(rarity):
|
|
"""
|
|
Determine the Enkephalin reward based on tag rarity
|
|
|
|
Args:
|
|
rarity (str): The tag rarity level
|
|
|
|
Returns:
|
|
int: Amount of Enkephalin to award
|
|
"""
|
|
|
|
if rarity in TAG_POWER_BONUSES:
|
|
return TAG_POWER_BONUSES[rarity]["enkephalin_reward"]
|
|
return 0
|
|
|
|
def add_tag_to_collection(tag, probability, category, coin_multiplier=1.0):
|
|
"""
|
|
Add a tag to the user's collection and award currency and enkephalin for new discoveries.
|
|
"""
|
|
try:
|
|
|
|
rarity = determine_tag_rarity(tag, probability, category)
|
|
|
|
|
|
is_new_tag = tag not in st.session_state.collected_tags
|
|
|
|
|
|
was_sacrificed = hasattr(st.session_state, 'sacrificed_tags') and tag in st.session_state.sacrificed_tags
|
|
|
|
|
|
base_currency_value = RARITY_LEVELS[rarity]["value"]
|
|
|
|
|
|
print(f"Processing tag: {tag}, rarity: {rarity}, is_new: {is_new_tag}, base_value: {base_currency_value}")
|
|
|
|
|
|
currency_earned = 0
|
|
enkephalin_earned = 0
|
|
|
|
|
|
timestamp = time.strftime("%H:%M:%S")
|
|
|
|
|
|
if tag in st.session_state.collected_tags:
|
|
|
|
st.session_state.collected_tags[tag]["count"] += 1
|
|
else:
|
|
|
|
st.session_state.collected_tags[tag] = {
|
|
"count": 1,
|
|
"rarity": rarity,
|
|
"category": category,
|
|
"discovery_time": timestamp
|
|
}
|
|
|
|
|
|
if not was_sacrificed and is_new_tag:
|
|
|
|
tag_power_bonus, base_coin_multiplier = calculate_tag_power()
|
|
|
|
|
|
print(f" Base multiplier: {base_coin_multiplier}, Collection multiplier: {coin_multiplier}")
|
|
|
|
|
|
total_multiplier = base_coin_multiplier * coin_multiplier
|
|
|
|
|
|
if hasattr(st.session_state, 'mastered_categories') and category in st.session_state.mastered_categories:
|
|
from tag_categories import CATEGORY_MASTERY_BONUS
|
|
total_multiplier += CATEGORY_MASTERY_BONUS.get('coin_multiplier', 0)
|
|
|
|
|
|
currency_earned = int(base_currency_value * total_multiplier)
|
|
|
|
|
|
enkephalin_earned = get_enkephalin_reward(rarity)
|
|
|
|
|
|
if hasattr(st.session_state, 'enkephalin_bonus') and st.session_state.enkephalin_bonus > 0:
|
|
enkephalin_earned = int(enkephalin_earned * (1 + st.session_state.enkephalin_bonus))
|
|
|
|
print(f" Final multiplier: {total_multiplier}, Final award: {currency_earned} {TAG_CURRENCY_NAME}, {enkephalin_earned} {ENKEPHALIN_CURRENCY_NAME}")
|
|
|
|
|
|
st.session_state.tag_currency += currency_earned
|
|
|
|
|
|
if enkephalin_earned > 0:
|
|
st.session_state.enkephalin += enkephalin_earned
|
|
|
|
|
|
st.session_state.game_stats["total_currency_earned"] += currency_earned
|
|
|
|
|
|
if not hasattr(st.session_state, 'tag_history'):
|
|
st.session_state.tag_history = []
|
|
|
|
st.session_state.tag_history.append({
|
|
"tag": tag,
|
|
"rarity": rarity,
|
|
"value": currency_earned,
|
|
"enkephalin": enkephalin_earned,
|
|
"time": timestamp,
|
|
"is_new": True
|
|
})
|
|
|
|
|
|
st.session_state.game_stats["total_tags_found"] += 1
|
|
|
|
|
|
threshold_bonus, coin_bonus = calculate_tag_power()
|
|
st.session_state.tag_power_bonus = threshold_bonus
|
|
st.session_state.coin_multiplier = coin_bonus
|
|
|
|
update_game_state(tag_currency=st.session_state.tag_currency, enkephalin=st.session_state.enkephalin)
|
|
|
|
|
|
return currency_earned, enkephalin_earned, is_new_tag
|
|
|
|
except Exception as e:
|
|
|
|
print(f"Error adding tag '{tag}' to collection: {str(e)}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
|
|
|
|
return 0, 0, False
|
|
|
|
def calculate_tag_power():
|
|
"""
|
|
Calculate tag power bonuses based on collected tags (not sacrificed ones).
|
|
Tags that are sacrificed no longer contribute to tag power until recollected.
|
|
|
|
Returns:
|
|
(threshold_reduction, coin_multiplier)
|
|
"""
|
|
if not hasattr(st.session_state, 'collected_tags'):
|
|
return 0, 1.0
|
|
|
|
total_threshold_reduction = 0
|
|
total_coin_multiplier = 1.0
|
|
|
|
|
|
for tag, info in st.session_state.collected_tags.items():
|
|
rarity = info["rarity"]
|
|
if rarity in TAG_POWER_BONUSES:
|
|
|
|
count = info["count"]
|
|
|
|
scaling_factor = 1 + (math.log(count) / 2) if count > 1 else 1
|
|
|
|
|
|
total_coin_multiplier += TAG_POWER_BONUSES[rarity]["coin_multiplier"] * scaling_factor
|
|
|
|
|
|
if hasattr(st.session_state, 'collection_power_coin_bonus'):
|
|
total_coin_multiplier *= st.session_state.collection_power_coin_bonus
|
|
|
|
return total_threshold_reduction, total_coin_multiplier |