Sergidev commited on
Commit
933256c
1 Parent(s): fceddfd

Upload 7 files

Browse files
Files changed (7) hide show
  1. Dockerfile +10 -0
  2. app.py +74 -0
  3. coins.json +26 -0
  4. requirements.txt +4 -0
  5. static/script.js +83 -0
  6. static/styles.css +54 -0
  7. templates/index.html +42 -0
Dockerfile ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY requirements.txt .
6
+ RUN pip install --no-cache-dir -r requirements.txt
7
+
8
+ COPY . .
9
+
10
+ CMD ["python", "app.py"]
app.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, jsonify, request
2
+ import json
3
+ import random
4
+ from transformers import AutoTokenizer, AutoModelForCausalLM
5
+ import torch
6
+
7
+ app = Flask(__name__)
8
+
9
+ # Load initial coins
10
+ with open('coins.json', 'r') as f:
11
+ coins = json.load(f)
12
+
13
+ # Initialize game state
14
+ game_state = {
15
+ 'balance': 0,
16
+ 'flips_left': 1000,
17
+ 'current_coin': 0
18
+ }
19
+
20
+ # Load AI model
21
+ tokenizer = AutoTokenizer.from_pretrained("TinyLlama/TinyLlama-1.1B-Chat-v1.0")
22
+ model = AutoModelForCausalLM.from_pretrained("TinyLlama/TinyLlama-1.1B-Chat-v1.0")
23
+
24
+ @app.route('/')
25
+ def index():
26
+ return render_template('index.html', coins=coins, game_state=game_state)
27
+
28
+ @app.route('/flip', methods=['POST'])
29
+ def flip_coin():
30
+ if game_state['flips_left'] > 0:
31
+ coin = coins[game_state['current_coin']]
32
+ is_heads = random.random() < coin['winrate']
33
+ if is_heads:
34
+ game_state['balance'] += coin['value']
35
+ game_state['flips_left'] -= 1
36
+ return jsonify({
37
+ 'result': 'H' if is_heads else 'T',
38
+ 'balance': game_state['balance'],
39
+ 'flips_left': game_state['flips_left']
40
+ })
41
+ return jsonify({'error': 'No flips left'})
42
+
43
+ @app.route('/buy', methods=['POST'])
44
+ def buy_coin():
45
+ index = int(request.json['index'])
46
+ if index < len(coins) and game_state['balance'] >= coins[index]['price']:
47
+ game_state['balance'] -= coins[index]['price']
48
+ game_state['current_coin'] = index
49
+ return jsonify({'success': True, 'balance': game_state['balance']})
50
+ return jsonify({'success': False})
51
+
52
+ @app.route('/generate_coin', methods=['POST'])
53
+ def generate_coin():
54
+ prompt = "Generate a new coin for a game in JSON format with the following properties: color (as a hex code), price, value, and winrate. The price should be higher than 10, the value should be higher than 0.1, and the winrate should be between 0.5 and 0.8."
55
+
56
+ inputs = tokenizer(prompt, return_tensors="pt")
57
+ with torch.no_grad():
58
+ outputs = model.generate(**inputs, max_length=200)
59
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
60
+
61
+ try:
62
+ new_coin = json.loads(response)
63
+ if all(key in new_coin for key in ['color', 'price', 'value', 'winrate']):
64
+ coins.append(new_coin)
65
+ return jsonify({'success': True, 'coin': new_coin})
66
+ else:
67
+ print("Error: Generated coin does not have all required properties")
68
+ return jsonify({'success': False, 'error': 'Invalid coin format'})
69
+ except json.JSONDecodeError:
70
+ print("Error: Could not parse generated coin as JSON")
71
+ return jsonify({'success': False, 'error': 'Invalid JSON format'})
72
+
73
+ if __name__ == '__main__':
74
+ app.run(host='0.0.0.0', port=7860)
coins.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "color": "#CD7F32",
4
+ "price": 0.0,
5
+ "value": 0.01,
6
+ "winrate": 0.5
7
+ },
8
+ {
9
+ "color": "#C0C0C0",
10
+ "price": 1.0,
11
+ "value": 0.02,
12
+ "winrate": 0.55
13
+ },
14
+ {
15
+ "color": "#FFD700",
16
+ "price": 5.0,
17
+ "value": 0.05,
18
+ "winrate": 0.6
19
+ },
20
+ {
21
+ "color": "#E5E4E2",
22
+ "price": 10.0,
23
+ "value": 0.1,
24
+ "winrate": 0.65
25
+ }
26
+ ]
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ flask
2
+ transformers
3
+ torch
4
+ uvicorn
static/script.js ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ let balance = 0;
2
+ let flipsLeft = 1000;
3
+ let currentCoin = 0;
4
+
5
+ function updateInfo() {
6
+ document.getElementById("balance").textContent = balance.toFixed(2);
7
+ document.getElementById("flips-left").textContent = flipsLeft;
8
+ }
9
+
10
+ function flipCoin() {
11
+ if (flipsLeft > 0) {
12
+ fetch("/flip", {
13
+ method: "POST",
14
+ headers: {
15
+ "Content-Type": "application/json",
16
+ },
17
+ body: JSON.stringify({ coin_index: currentCoin }),
18
+ })
19
+ .then((response) => response.json())
20
+ .then((data) => {
21
+ const coin = document.getElementById("coin");
22
+ coin.textContent = data.is_heads ? "H" : "T";
23
+ if (data.is_heads) {
24
+ balance += data.value;
25
+ }
26
+ flipsLeft--;
27
+ updateInfo();
28
+ });
29
+ }
30
+ }
31
+
32
+ function buyCoin(index) {
33
+ fetch("/buy", {
34
+ method: "POST",
35
+ headers: {
36
+ "Content-Type": "application/json",
37
+ },
38
+ body: JSON.stringify({ coin_index: index, balance: balance }),
39
+ })
40
+ .then((response) => response.json())
41
+ .then((data) => {
42
+ if (data.success) {
43
+ balance -= coins[index].price;
44
+ currentCoin = index;
45
+ document.getElementById("coin").style.backgroundColor =
46
+ coins[index].color;
47
+ updateInfo();
48
+ } else {
49
+ alert("Not enough money to buy this coin!");
50
+ }
51
+ });
52
+ }
53
+
54
+ function generateCoin() {
55
+ fetch("/generate_coin", {
56
+ method: "POST",
57
+ })
58
+ .then((response) => response.json())
59
+ .then((data) => {
60
+ if (data.success) {
61
+ coins.push(data.coin);
62
+ const shop = document.getElementById("shop");
63
+ const newCoin = document.createElement("div");
64
+ newCoin.className = "shop-coin";
65
+ newCoin.style.backgroundColor = data.coin.color;
66
+ newCoin.innerHTML = `
67
+ <div>P: ${data.coin.winrate.toFixed(2)}</div>
68
+ <div>V: $${data.coin.value.toFixed(2)}</div>
69
+ <div>C: $${data.coin.price.toFixed(2)}</div>
70
+ `;
71
+ newCoin.onclick = () => buyCoin(coins.length - 1);
72
+ shop.appendChild(newCoin);
73
+ } else {
74
+ console.error("Failed to generate new coin:", data.error);
75
+ }
76
+ });
77
+ }
78
+
79
+ document.addEventListener("DOMContentLoaded", () => {
80
+ updateInfo();
81
+ document.getElementById("coin").onclick = flipCoin;
82
+ document.getElementById("generate-coin").onclick = generateCoin;
83
+ });
static/styles.css ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ font-family: Arial, sans-serif;
3
+ display: flex;
4
+ flex-direction: column;
5
+ align-items: center;
6
+ background-color: #f0f0f0;
7
+ }
8
+
9
+ #game-info {
10
+ margin-bottom: 20px;
11
+ font-size: 18px;
12
+ }
13
+
14
+ #coin {
15
+ width: 200px;
16
+ height: 200px;
17
+ border-radius: 50%;
18
+ display: flex;
19
+ justify-content: center;
20
+ align-items: center;
21
+ font-size: 72px;
22
+ cursor: pointer;
23
+ margin-bottom: 20px;
24
+ }
25
+
26
+ #shop {
27
+ display: flex;
28
+ justify-content: space-around;
29
+ width: 100%;
30
+ max-width: 800px;
31
+ margin-top: 20px;
32
+ }
33
+
34
+ .shop-item {
35
+ text-align: center;
36
+ padding: 10px;
37
+ border: 1px solid #ccc;
38
+ border-radius: 5px;
39
+ cursor: pointer;
40
+ }
41
+
42
+ .shop-coin {
43
+ width: 50px;
44
+ height: 50px;
45
+ border-radius: 50%;
46
+ margin: 0 auto;
47
+ }
48
+
49
+ #generate-coin {
50
+ margin-top: 20px;
51
+ padding: 10px 20px;
52
+ font-size: 16px;
53
+ cursor: pointer;
54
+ }
templates/index.html ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Pennyflip</title>
7
+ <link
8
+ rel="stylesheet"
9
+ href="{{ url_for('static', filename='styles.css') }}"
10
+ />
11
+ </head>
12
+ <body>
13
+ <div id="game-container">
14
+ <div id="info">
15
+ <h2>Pennyflip</h2>
16
+ <p>
17
+ Balance: $<span id="balance">0.00</span> | Flips left:
18
+ <span id="flips-left">1000</span>
19
+ </p>
20
+ </div>
21
+ <div id="coin" style="background-color: {{ coins[0].color }}"></div>
22
+ <div id="shop">
23
+ {% for coin in coins %}
24
+ <div
25
+ class="shop-coin"
26
+ style="background-color: {{ coin.color }}"
27
+ onclick="buyCoin({{ loop.index0 }})"
28
+ >
29
+ <div>P: {{ "%.2f"|format(coin.winrate) }}</div>
30
+ <div>V: ${{ "%.2f"|format(coin.value) }}</div>
31
+ <div>C: ${{ "%.2f"|format(coin.price) }}</div>
32
+ </div>
33
+ {% endfor %}
34
+ </div>
35
+ <button id="generate-coin">Generate New Coin</button>
36
+ </div>
37
+ <script>
38
+ const coins = {{ coins|tojson|safe }};
39
+ </script>
40
+ <script src="{{ url_for('static', filename='script.js') }}"></script>
41
+ </body>
42
+ </html>