from flask import Flask, render_template, jsonify, request import json import random from transformers import AutoTokenizer, AutoModelForCausalLM import torch import os # Set the TRANSFORMERS_CACHE environment variable os.environ['TRANSFORMERS_CACHE'] = '/app/cache' app = Flask(__name__) # Load initial coins with open('coins.json', 'r') as f: coins = json.load(f) # Initialize game state game_state = { 'balance': 0, 'flips_left': 1000, 'current_coin': 0 } # Load leaderboard try: with open('leaderboard.json', 'r') as f: leaderboard = json.load(f) except FileNotFoundError: leaderboard = [] # Load AI model tokenizer = AutoTokenizer.from_pretrained("TinyLlama/TinyLlama-1.1B-Chat-v1.0") model = AutoModelForCausalLM.from_pretrained("TinyLlama/TinyLlama-1.1B-Chat-v1.0") @app.route('/') def index(): return render_template('index.html', coins=coins, game_state=game_state, leaderboard=leaderboard) @app.route('/flip', methods=['POST']) def flip_coin(): if game_state['flips_left'] > 0: coin = coins[game_state['current_coin']] is_heads = random.random() < coin['winrate'] if is_heads: game_state['balance'] += coin['value'] game_state['flips_left'] -= 1 # Apply coin ability if it exists if 'ability' in coin: ability_effect(coin['ability']) return jsonify({ 'result': 'H' if is_heads else 'T', 'balance': game_state['balance'], 'flips_left': game_state['flips_left'] }) return jsonify({'error': 'No flips left'}) @app.route('/buy', methods=['POST']) def buy_coin(): index = int(request.json['index']) if index < len(coins) and game_state['balance'] >= coins[index]['price'] and index != game_state['current_coin']: game_state['balance'] -= coins[index]['price'] game_state['current_coin'] = index return jsonify({'success': True, 'balance': game_state['balance']}) return jsonify({'success': False}) @app.route('/generate_coin', methods=['POST']) def generate_coin(): if game_state['balance'] < 4: return jsonify({'success': False, 'error': 'Not enough balance to generate a coin'}) prompt = """Generate a new coin for a game in JSON format with the following properties: name (a creative name for the coin), color (as a hex code), price (higher than 10), value (higher than 0.1), winrate (between 0.5 and 0.8), ability (a unique effect that modifies game state, e.g., 'add 5 flips', 'double next flip value', etc.) Example: { "name": "Lucky Clover", "color": "#2ecc71", "price": 15, "value": 0.2, "winrate": 0.65, "ability": "add 3 flips on every 10th flip" } """ inputs = tokenizer(prompt, return_tensors="pt") with torch.no_grad(): outputs = model.generate(**inputs, max_length=300) response = tokenizer.decode(outputs[0], skip_special_tokens=True) try: new_coin = json.loads(response) if validate_coin(new_coin): coins.append(new_coin) with open('coins.json', 'w') as f: json.dump(coins, f) game_state['balance'] -= 4 return jsonify({'success': True, 'coin': new_coin, 'balance': game_state['balance']}) else: return jsonify({'success': False, 'error': 'Invalid coin format'}) except json.JSONDecodeError: return jsonify({'success': False, 'error': 'Invalid JSON format'}) @app.route('/game_over', methods=['POST']) def game_over(): initials = request.json['initials'] score = game_state['balance'] leaderboard.append({'initials': initials, 'score': score}) leaderboard.sort(key=lambda x: x['score'], reverse=True) leaderboard = leaderboard[:10] # Keep only top 10 with open('leaderboard.json', 'w') as f: json.dump(leaderboard, f) return jsonify({'success': True}) @app.route('/reset_game', methods=['POST']) def reset_game(): game_state['balance'] = 0 game_state['flips_left'] = 1000 game_state['current_coin'] = 0 return jsonify({'success': True}) def validate_coin(coin): required_keys = ['name', 'color', 'price', 'value', 'winrate', 'ability'] return all(key in coin for key in required_keys) and \ isinstance(coin['name'], str) and \ isinstance(coin['color'], str) and coin['color'].startswith('#') and \ isinstance(coin['price'], (int, float)) and coin['price'] > 10 and \ isinstance(coin['value'], (int, float)) and coin['value'] > 0.1 and \ isinstance(coin['winrate'], (int, float)) and 0.5 <= coin['winrate'] <= 0.8 and \ isinstance(coin['ability'], str) def ability_effect(ability): # Implement ability effects here if "add" in ability and "flips" in ability: flips_to_add = int(ability.split()[1]) game_state['flips_left'] += flips_to_add elif "double next flip value" in ability: # This would need to be handled in the flip_coin function pass # Add more ability effects as needed if __name__ == '__main__': app.run(host='0.0.0.0', port=7860)