mirror of
https://git.astronand.dev/minecartchris/Stock-Game.git
synced 2026-06-06 05:54:18 -04:00
230 lines
7.7 KiB
Python
230 lines
7.7 KiB
Python
from flask import Flask, render_template, request, jsonify, session
|
|
import random
|
|
from datetime import datetime
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = 'your_secret_key_here'
|
|
|
|
# Game state management
|
|
game_state = {}
|
|
|
|
def init_game(days):
|
|
"""Initialize a new game session"""
|
|
return {
|
|
'balance': 1000,
|
|
'kwiktripStockPrice': 100 + random.randint(-100, 100),
|
|
'appleStockPrice': 100 + random.randint(-100, 100),
|
|
'microsoftStockPrice': 100 + random.randint(-100, 100),
|
|
'walmartStockPrice': 100 + random.randint(-100, 100),
|
|
'carStockPrice': 100 + random.randint(-100, 100),
|
|
'kwiktrip': 0,
|
|
'apple': 0,
|
|
'microsoft': 0,
|
|
'walmart': 0,
|
|
'car': 0,
|
|
'day': 1,
|
|
'daysleft': days,
|
|
'message': ''
|
|
}
|
|
|
|
def calculate_index(state):
|
|
"""Calculate market index"""
|
|
prices = [state['kwiktripStockPrice'], state['appleStockPrice'],
|
|
state['microsoftStockPrice'], state['walmartStockPrice'],
|
|
state['carStockPrice']]
|
|
return sum(prices) / 5
|
|
|
|
def get_stock_list(state):
|
|
"""Return list of stocks with prices"""
|
|
return [
|
|
{'id': 1, 'name': 'Kwik trip', 'price': state['kwiktripStockPrice']},
|
|
{'id': 2, 'name': 'Apple computers', 'price': state['appleStockPrice']},
|
|
{'id': 3, 'name': 'Microsoft', 'price': state['microsoftStockPrice']},
|
|
{'id': 4, 'name': 'Walmart Super Store', 'price': state['walmartStockPrice']},
|
|
{'id': 5, 'name': 'Car company', 'price': state['carStockPrice']}
|
|
]
|
|
|
|
def get_holdings(state):
|
|
"""Return user's stock holdings"""
|
|
return [
|
|
{'id': 1, 'name': 'Kwik trip', 'amount': state['kwiktrip']},
|
|
{'id': 2, 'name': 'Apple computers', 'amount': state['apple']},
|
|
{'id': 3, 'name': 'Microsoft', 'amount': state['microsoft']},
|
|
{'id': 4, 'name': 'Walmart Super Store', 'amount': state['walmart']},
|
|
{'id': 5, 'name': 'Car company', 'amount': state['car']}
|
|
]
|
|
|
|
def get_game_state_data():
|
|
"""Get current game state data as dictionary"""
|
|
if 'current' not in game_state:
|
|
return None
|
|
|
|
state = game_state['current']
|
|
stocks = get_stock_list(state)
|
|
holdings = get_holdings(state)
|
|
|
|
return {
|
|
'balance': state['balance'],
|
|
'day': state['day'],
|
|
'daysleft': state['daysleft'],
|
|
'index': round(calculate_index(state), 2),
|
|
'stocks': stocks,
|
|
'holdings': holdings,
|
|
'message': state.get('message', '')
|
|
}
|
|
|
|
@app.route('/')
|
|
def home():
|
|
"""Home page - ask for number of days"""
|
|
return render_template('index.html')
|
|
|
|
@app.route('/api/start', methods=['POST'])
|
|
def start_game():
|
|
"""Initialize a new game"""
|
|
data = request.json
|
|
days = int(data.get('days', 5))
|
|
|
|
state = init_game(days)
|
|
game_state['current'] = state
|
|
|
|
return jsonify(get_game_state_data())
|
|
|
|
@app.route('/api/game-state', methods=['GET'])
|
|
def get_game_state():
|
|
"""Get current game state"""
|
|
state_data = get_game_state_data()
|
|
if state_data is None:
|
|
return jsonify({'error': 'Game not started'}), 400
|
|
|
|
return jsonify(state_data)
|
|
|
|
@app.route('/api/buy', methods=['POST'])
|
|
def buy_stock():
|
|
"""Buy stocks"""
|
|
if 'current' not in game_state:
|
|
return jsonify({'error': 'Game not started'}), 400
|
|
|
|
state = game_state['current']
|
|
data = request.json
|
|
|
|
try:
|
|
stock_id = int(data['stock_id'])
|
|
amount = int(data['amount'])
|
|
|
|
stocks = get_stock_list(state)
|
|
stock_price = stocks[stock_id - 1]['price']
|
|
total_cost = amount * stock_price
|
|
|
|
if state['balance'] < total_cost:
|
|
state['message'] = f"Insufficient funds. Cost: ${total_cost}, Balance: ${state['balance']}"
|
|
return jsonify({'error': state['message']}), 400
|
|
|
|
state['balance'] -= total_cost
|
|
|
|
stock_keys = ['kwiktrip', 'apple', 'microsoft', 'walmart', 'car']
|
|
state[stock_keys[stock_id - 1]] += amount
|
|
|
|
state['message'] = f"Successfully bought {amount} shares of {stocks[stock_id - 1]['name']} for ${total_cost}"
|
|
|
|
return jsonify(get_game_state_data())
|
|
except (ValueError, IndexError, KeyError) as e:
|
|
return jsonify({'error': str(e)}), 400
|
|
|
|
@app.route('/api/sell', methods=['POST'])
|
|
def sell_stock():
|
|
"""Sell stocks"""
|
|
if 'current' not in game_state:
|
|
return jsonify({'error': 'Game not started'}), 400
|
|
|
|
state = game_state['current']
|
|
data = request.json
|
|
|
|
try:
|
|
stock_id = int(data['stock_id'])
|
|
amount = int(data['amount'])
|
|
|
|
stocks = get_stock_list(state)
|
|
holdings = get_holdings(state)
|
|
|
|
user_holdings = holdings[stock_id - 1]['amount']
|
|
|
|
if user_holdings < amount:
|
|
state['message'] = f"You don't own enough shares. You own: {user_holdings}"
|
|
return jsonify({'error': state['message']}), 400
|
|
|
|
stock_price = stocks[stock_id - 1]['price']
|
|
total_payout = amount * stock_price
|
|
|
|
state['balance'] += total_payout
|
|
|
|
stock_keys = ['kwiktrip', 'apple', 'microsoft', 'walmart', 'car']
|
|
state[stock_keys[stock_id - 1]] -= amount
|
|
|
|
state['message'] = f"Successfully sold {amount} shares of {stocks[stock_id - 1]['name']} for ${total_payout}"
|
|
|
|
return jsonify(get_game_state_data())
|
|
except (ValueError, IndexError, KeyError) as e:
|
|
return jsonify({'error': str(e)}), 400
|
|
|
|
@app.route('/api/next-day', methods=['POST'])
|
|
def next_day():
|
|
"""Progress to next day"""
|
|
if 'current' not in game_state:
|
|
return jsonify({'error': 'Game not started'}), 400
|
|
|
|
state = game_state['current']
|
|
|
|
if state['daysleft'] <= 0:
|
|
return jsonify({'error': 'Game over!', 'game_over': True}), 400
|
|
|
|
state['day'] += 1
|
|
state['daysleft'] -= 1
|
|
|
|
# Update stock prices
|
|
state['kwiktripStockPrice'] = abs(state['kwiktripStockPrice'] + random.randint(-100, 100))
|
|
state['appleStockPrice'] = abs(state['appleStockPrice'] + random.randint(-100, 100))
|
|
state['microsoftStockPrice'] = abs(state['microsoftStockPrice'] + random.randint(-100, 100))
|
|
state['walmartStockPrice'] = abs(state['walmartStockPrice'] + random.randint(-100, 100))
|
|
state['carStockPrice'] = abs(state['carStockPrice'] + random.randint(-100, 100))
|
|
|
|
# Market crash chance
|
|
if random.randint(0, 1000) == 555:
|
|
state['kwiktripStockPrice'] = 10
|
|
state['appleStockPrice'] = 10
|
|
state['microsoftStockPrice'] = 10
|
|
state['walmartStockPrice'] = 10
|
|
state['carStockPrice'] = 10
|
|
state['message'] = "Market crash! All stocks dropped to $10"
|
|
else:
|
|
state['message'] = f"Moved to day {state['day']}"
|
|
|
|
return jsonify(get_game_state_data())
|
|
|
|
@app.route('/api/end-game', methods=['GET'])
|
|
def end_game():
|
|
"""Get end game statistics"""
|
|
if 'current' not in game_state:
|
|
return jsonify({'error': 'Game not started'}), 400
|
|
|
|
state = game_state['current']
|
|
stocks = get_stock_list(state)
|
|
|
|
total_net_worth = state['balance']
|
|
holdings = get_holdings(state)
|
|
|
|
for i, holding in enumerate(holdings):
|
|
total_net_worth += holding['amount'] * stocks[i]['price']
|
|
|
|
profit = state['balance'] - 1000
|
|
|
|
return jsonify({
|
|
'starting_balance': 1000,
|
|
'ending_balance': state['balance'],
|
|
'total_net_worth': round(total_net_worth, 2),
|
|
'profit': profit,
|
|
'holdings': holdings,
|
|
'stocks': stocks
|
|
})
|
|
|
|
if __name__ == '__main__':
|
|
app.run(debug=True) |