Upload 103 files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- app.py +144 -0
- requirements.txt +4 -0
- static/10_of_clubs.png +0 -0
- static/10_of_clubs.pngZone.Identifier +3 -0
- static/10_of_diamonds.png +0 -0
- static/10_of_diamonds.pngZone.Identifier +3 -0
- static/10_of_spades.png +0 -0
- static/10_of_spades.pngZone.Identifier +3 -0
- static/11_of_clubs.png +0 -0
- static/11_of_diamonds.png +0 -0
- static/11_of_hearts.png +0 -0
- static/11_of_spades.png +0 -0
- static/12_of_clubs.png +0 -0
- static/12_of_spades.png +0 -0
- static/13_of_clubs.png +0 -0
- static/13_of_hearts.png +0 -0
- static/13_of_spades.png +0 -0
- static/1_of_clubs.png +0 -0
- static/1_of_diamonds.png +0 -0
- static/2_of_clubs.png +0 -0
- static/2_of_clubs.pngZone.Identifier +3 -0
- static/2_of_diamonds.png +0 -0
- static/2_of_hearts.png +0 -0
- static/2_of_hearts.pngZone.Identifier +3 -0
- static/2_of_spades.png +0 -0
- static/2_of_spades.pngZone.Identifier +3 -0
- static/3_of_diamonds.png +0 -0
- static/3_of_hearts.png +0 -0
- static/3_of_hearts.pngZone.Identifier +3 -0
- static/3_of_spades.png +0 -0
- static/3_of_spades.pngZone.Identifier +3 -0
- static/4_of_clubs.png +0 -0
- static/4_of_clubs.pngZone.Identifier +3 -0
- static/4_of_diamonds.png +0 -0
- static/4_of_hearts.png +0 -0
- static/4_of_hearts.pngZone.Identifier +3 -0
- static/4_of_spades.pngZone.Identifier +3 -0
- static/5_of_clubs.png +0 -0
- static/5_of_clubs.pngZone.Identifier +3 -0
- static/5_of_diamonds.png +0 -0
- static/5_of_diamonds.pngZone.Identifier +3 -0
- static/5_of_hearts.png +0 -0
- static/5_of_hearts.pngZone.Identifier +3 -0
- static/5_of_spades.png +0 -0
- static/5_of_spades.pngZone.Identifier +3 -0
- static/6_of_clubs.png +0 -0
- static/6_of_clubs.pngZone.Identifier +3 -0
- static/6_of_diamonds.png +0 -0
- static/6_of_diamonds.pngZone.Identifier +3 -0
- static/6_of_hearts.png +0 -0
app.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
from PIL import Image
|
| 3 |
+
import random, operator, ast, sqlite3, datetime, json, math
|
| 4 |
+
from itertools import product, permutations
|
| 5 |
+
from utils import *
|
| 6 |
+
from sqlite3 import Connection
|
| 7 |
+
import pandas as pd
|
| 8 |
+
|
| 9 |
+
@st.cache_data()
|
| 10 |
+
def static_variables():
|
| 11 |
+
suits = ["hearts","spades","diamonds","clubs"]; jo = "_of_"; path = "static/"
|
| 12 |
+
return suits, jo, path
|
| 13 |
+
|
| 14 |
+
@st.cache_data(ttl=3600*4)
|
| 15 |
+
def static_layout_top():
|
| 16 |
+
st.header("24 Game!")
|
| 17 |
+
st.markdown(f"""Welcome! Today is {st.session_state.date}""")
|
| 18 |
+
|
| 19 |
+
st.markdown("""
|
| 20 |
+
#### How to play:
|
| 21 |
+
|
| 22 |
+
- Using +, -, *, / , and () on 4 cards to get 24;
|
| 23 |
+
- Each card represent a number as shown, where J=11, Q=12, K=13, and A=1
|
| 24 |
+
- You will have 3 operations, and you have to express the first and second
|
| 25 |
+
operation explicitly, e.g. even though you have 6, 6, 6, 6 and you know that
|
| 26 |
+
6 + 6 + 6 + 6 = 24, you need to type your expression clearly as ((6+6)+6)+6 or
|
| 27 |
+
(6+6)+(6+6) to specify your first two operations.
|
| 28 |
+
- The algorithm encourage thinking of associativity, so, (12/6)*(11+1) and
|
| 29 |
+
(12/6)*(1+11) would be counted as two different and correct answers.
|
| 30 |
+
|
| 31 |
+
""")
|
| 32 |
+
c0, c1, c2, c3 = st.columns([0.25,0.25,0.25,0.25]); cs = [c0,c1,c2,c3]
|
| 33 |
+
for idx, x in enumerate(cs):
|
| 34 |
+
with x:
|
| 35 |
+
im = Image.open(path+str(st.session_state.nums[idx])+jo+st.session_state.su[idx]+".png")
|
| 36 |
+
st.image(im)
|
| 37 |
+
|
| 38 |
+
@st.cache_resource(ttl=3600*4)
|
| 39 |
+
def get_cards():
|
| 40 |
+
i = True
|
| 41 |
+
while i:
|
| 42 |
+
nums = random.sample(range(1,14),4)
|
| 43 |
+
suit = random.sample(suits,4)
|
| 44 |
+
sols = solve24(nums)
|
| 45 |
+
i = (len(sols) == 0)
|
| 46 |
+
conn = get_connection("data24.db"); date = str(datetime.date.today())
|
| 47 |
+
value = (date, str(nums), str(suit), str(sols), len(sols))
|
| 48 |
+
insert_value_games(conn, value)
|
| 49 |
+
return nums, suit, sols, date, conn
|
| 50 |
+
|
| 51 |
+
def check_ans_default(inp): # for non-id player
|
| 52 |
+
if inp in st.session_state.sols:
|
| 53 |
+
if st.session_state.get('ans') == None:
|
| 54 |
+
st.session_state['ans'] = {inp}
|
| 55 |
+
|
| 56 |
+
else:
|
| 57 |
+
s1 = st.session_state['ans']
|
| 58 |
+
s1.add(inp)
|
| 59 |
+
st.session_state['ans'] = s1
|
| 60 |
+
a1, a2 = st.columns([0.5,0.5])
|
| 61 |
+
with a1:
|
| 62 |
+
st.markdown(f"Got one! :green[${inp}=24$]")
|
| 63 |
+
with a2:
|
| 64 |
+
st.markdown(f"There are {len(st.session_state.sols)} expressions in total. :chart_with_upwards_trend:")
|
| 65 |
+
else:
|
| 66 |
+
st.write("Oop! Incorrect.....")
|
| 67 |
+
return
|
| 68 |
+
|
| 69 |
+
def check_ans_user(inp): # On session, but data on cache_resource
|
| 70 |
+
id = int(st.session_state.u_id); date = st.session_state.date;
|
| 71 |
+
nums = str(st.session_state.nums); suit = str(st.session_state.su)
|
| 72 |
+
df = get_plays_answer(st.session_state.conn, id, date, nums)
|
| 73 |
+
if len(df) > 0:
|
| 74 |
+
st.session_state['ans'] = set(ast.literal_eval(df.values[0][0]))
|
| 75 |
+
else:
|
| 76 |
+
st.session_state['ans'] = set()
|
| 77 |
+
if inp in st.session_state.sols:
|
| 78 |
+
s1 = st.session_state['ans']
|
| 79 |
+
if len(s1) > 0:
|
| 80 |
+
s1.add(inp)
|
| 81 |
+
else:
|
| 82 |
+
s1 = {inp}
|
| 83 |
+
st.session_state['ans'] = s1
|
| 84 |
+
if st.session_state.u_id is not None:
|
| 85 |
+
if not check_plays_user(st.session_state.conn, id, date, nums):
|
| 86 |
+
value = (id, date, nums, suit, json.dumps(s1,default=tuple))
|
| 87 |
+
insert_value_plays(st.session_state.conn, value)
|
| 88 |
+
else:
|
| 89 |
+
update_value_plays(st.session_state.conn, id, date, nums, json.dumps(s1,default=tuple))
|
| 90 |
+
else:
|
| 91 |
+
st.write("Oop! Incorrect.....")
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
# Call statics and session variables
|
| 95 |
+
suits, jo, path = static_variables()
|
| 96 |
+
st.session_state['nums'], st.session_state['su'], st.session_state['sols'], st.session_state['date'], st.session_state['conn'] = get_cards()
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
# Call page layout
|
| 100 |
+
#with st.sidebar:
|
| 101 |
+
# df = get_top_board(st.session_state.conn)
|
| 102 |
+
# df = top_board_df(df)
|
| 103 |
+
# st.write(df)
|
| 104 |
+
|
| 105 |
+
static_layout_top()
|
| 106 |
+
|
| 107 |
+
# User data collecting
|
| 108 |
+
#with st.expander("If you want to join the competition"):
|
| 109 |
+
# u1, u2 = st.columns([0.5,0.5])
|
| 110 |
+
# with u1:
|
| 111 |
+
# st.text_input("Enter your TGS id for prize:", key="u_id")
|
| 112 |
+
# with u2:
|
| 113 |
+
# st.text_input("The user name, one per TGS id", key="u_name")
|
| 114 |
+
# if st.button("Join Weekly Competition"):
|
| 115 |
+
# conn = st.session_state.conn; u_id = int(st.session_state.u_id); u_name = st.session_state.u_name
|
| 116 |
+
# if check_value_user(conn, u_id):
|
| 117 |
+
# st.write("You already joined the competition, good luck! :smile:")
|
| 118 |
+
# else:
|
| 119 |
+
# insert_value_user(conn, (u_id, u_name))
|
| 120 |
+
# st.write(f"Welcome {u_name}! You just signed up for this week's competition! Good Luck!")
|
| 121 |
+
|
| 122 |
+
# User plays collecting
|
| 123 |
+
inp = st.text_input("Enter your expression here: ").replace(" ", "")
|
| 124 |
+
if st.button("Try your luck!"):
|
| 125 |
+
if st.session_state.u_id:
|
| 126 |
+
check_ans_user(inp)
|
| 127 |
+
else:
|
| 128 |
+
check_ans_default(inp)
|
| 129 |
+
|
| 130 |
+
#st.write(st.session_state.ans) #-- local testing only
|
| 131 |
+
# Display session answers
|
| 132 |
+
if st.session_state.get('ans') == None:
|
| 133 |
+
pass
|
| 134 |
+
else:
|
| 135 |
+
st.markdown("### Your correct answers: ")
|
| 136 |
+
col = 4; n = len(st.session_state.ans)
|
| 137 |
+
row = math.ceil(n / col)
|
| 138 |
+
for i in range(row):
|
| 139 |
+
cols = st.columns(col)
|
| 140 |
+
for m in range(min(4, n-4*i)):
|
| 141 |
+
cols[m].latex(list(st.session_state.ans)[m+i*4].replace("/","\div"))
|
| 142 |
+
st.markdown("##")
|
| 143 |
+
|
| 144 |
+
#st.write(st.session_state.sols)
|
requirements.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
SQLAlchemy==2.0.19
|
| 2 |
+
pandas==1.5.3
|
| 3 |
+
streamlit==1.24.0
|
| 4 |
+
Pillow==9.5.0
|
static/10_of_clubs.png
ADDED
|
static/10_of_clubs.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/10_of_diamonds.png
ADDED
|
static/10_of_diamonds.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/10_of_spades.png
ADDED
|
static/10_of_spades.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/11_of_clubs.png
ADDED
|
static/11_of_diamonds.png
ADDED
|
static/11_of_hearts.png
ADDED
|
static/11_of_spades.png
ADDED
|
static/12_of_clubs.png
ADDED
|
static/12_of_spades.png
ADDED
|
static/13_of_clubs.png
ADDED
|
static/13_of_hearts.png
ADDED
|
static/13_of_spades.png
ADDED
|
static/1_of_clubs.png
ADDED
|
static/1_of_diamonds.png
ADDED
|
static/2_of_clubs.png
ADDED
|
static/2_of_clubs.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/2_of_diamonds.png
ADDED
|
static/2_of_hearts.png
ADDED
|
static/2_of_hearts.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/2_of_spades.png
ADDED
|
static/2_of_spades.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/3_of_diamonds.png
ADDED
|
static/3_of_hearts.png
ADDED
|
static/3_of_hearts.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/3_of_spades.png
ADDED
|
static/3_of_spades.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/4_of_clubs.png
ADDED
|
static/4_of_clubs.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/4_of_diamonds.png
ADDED
|
static/4_of_hearts.png
ADDED
|
static/4_of_hearts.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/4_of_spades.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/5_of_clubs.png
ADDED
|
static/5_of_clubs.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/5_of_diamonds.png
ADDED
|
static/5_of_diamonds.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/5_of_hearts.png
ADDED
|
static/5_of_hearts.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/5_of_spades.png
ADDED
|
static/5_of_spades.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/6_of_clubs.png
ADDED
|
static/6_of_clubs.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/6_of_diamonds.png
ADDED
|
static/6_of_diamonds.pngZone.Identifier
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[ZoneTransfer]
|
| 2 |
+
ZoneId=3
|
| 3 |
+
ReferrerUrl=C:\tgs\aiclub\PNG-cards-1.3.zip
|
static/6_of_hearts.png
ADDED
|