I am trying to design an app for Swiss Round Robin system. In this game, we have X number of players and they play R rounds. I first ask the end user to upload list of players and how many rounds we want to play. Now, round 1 begins where players randomly get their opponents. But once round 1 is done, the next matchups happen between players that are in same level playing field.
As an example, after round 1 - player 1 and 2 are ranked based on their points - since they have highest points, they will play against each other in round 2. This is similar to chess where a player does not meet the same opponent in future rounds if the player has played with the same opponent in the past rounds.
As seen in the screenshot I have developed a button to upload players and then number of rounds. I can generate round 1 match ups. But then I want to compute standings based on round 1 results, which is where I am having trouble with. I want to have the option for user to keep uploading current roundβs results until all the rounds (R) are complete.
Overall flow should be like below for 3 rounds -
- generate round 1 randomly
- allow user to upload results for round 1
- compute standings after round 1 and generate round 2 matchups
- allow user to upload results for round 2
- compute standings after round 2 and generate round 3 matchups
- allow user to upload results for round 3
- compute standings after round 3
- END
I am using below code to generate the UI at the current stage -
import streamlit as st
import pandas as pd
st.header("CACA SRR System")
with st.sidebar.form(key='srr-form'):
st.header("Upload Players here")
st.write("Columns should contain SERIAL_NUMBER and PLAYER_NAME only.")
st.write("Make sure that the number of players are EVEN.")
uploaded_file = st.file_uploader("Player Roster", key="player_list")
srr_rounds = st.text_input("SRR Rounds", key = "srr_rounds")
submit = st.form_submit_button("Submit")
if "round" not in st.session_state:
st.session_state.round = 1
if "current_round" not in st.session_state:
st.session_state.current_round = 1
def create_random_matchup(df):
# random_data = df.drop_duplicates().sample(n=df.shape[0])
df = df.copy().sample(frac=1).reset_index(drop=True)
matchups = []
for i in range(0, len(df), 2):
player1 = df.loc[i]
player2 = df.loc[i + 1]
matchups.append({
'player_number': player1['serial_number'],
'player_name': player1['player_name'],
'opponent_number': player2['serial_number'],
'opponent_name': player2['player_name']
})
# Create a DataFrame for the match-ups
matchups_df = pd.DataFrame(matchups)
st.dataframe(matchups_df)
def display_players():
if "player_list" in st.session_state:
data = pd.read_csv(st.session_state.player_list)
data.columns = data.columns.str.lower()
st.dataframe(data)
st.header("Creating random matchups for Round 1...")
if st.session_state.round == 1:
create_random_matchup(data)
st.markdown("""---""")
st.write("Upload current round scores - use player_name, opponent_name, player_score, opponent_score as columns...")
# for i in range(5):
# current_key = "round" + str(i)
# round_scores = st.file_uploader("Upload Current Round Scores", key=current_key)
if submit:
st.header("Player List Available Below")
display_players()