ThorkildFregi commited on
Commit
b25e82e
1 Parent(s): 163d596

Upload 7 files

Browse files
Files changed (7) hide show
  1. main.py +109 -0
  2. model.py +34 -0
  3. static/gif jett.gif +0 -0
  4. templates/home.html +62 -0
  5. templates/loading.html +28 -0
  6. templates/result.html +26 -0
  7. vct_data.py +165 -0
main.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, redirect, url_for, request
2
+ from vct_data import create_data
3
+ from model import create_model
4
+ import pandas as pd
5
+ import pickle
6
+ import os
7
+
8
+ app = Flask(__name__)
9
+
10
+ @app.route('/')
11
+ def home():
12
+ if "data.csv" not in os.listdir():
13
+ return redirect(url_for("loading_update_data"))
14
+ elif "model.sav" not in os.listdir():
15
+ return redirect(url_for("loading_train_model"))
16
+ else:
17
+ df = pd.read_csv("data.csv")
18
+
19
+ tournaments_df = df["Tournament"]
20
+ tournaments = list(pd.unique(tournaments_df))
21
+
22
+ maps_df = df["Map"]
23
+ maps = list(pd.unique(maps_df))
24
+
25
+ team_A_df = df["Team A"]
26
+ team_A = list(pd.unique(team_A_df))
27
+
28
+ team_B_df = df["Team B"]
29
+ team_B = list(pd.unique(team_B_df))
30
+
31
+ agents = ["Astra", "Breach", "Brimstone", "Chamber", "Clove", "Cypher", "Deadlock", "Fade", "Gekko", "Harbor", "Iso", "Jett", "Kayo", "Killjoy", "Neon", "Omen", "Phoenix", "Raze", "Reyna", "Sage", "Skye", "Sova", "Viper", "Yoru"]
32
+
33
+ return render_template("home.html", tournaments=tournaments, maps=maps, team_A=team_A, team_B=team_B, agents=agents)
34
+
35
+ @app.route('/update-data')
36
+ def update_data():
37
+ create_data()
38
+ return redirect(url_for("loading_train_model"))
39
+
40
+ @app.route('/loading-update-data')
41
+ def loading_update_data():
42
+ return render_template("loading.html", next_page="update_data", loading_mission="Updating data...")
43
+
44
+ @app.route('/train-model')
45
+ def train_model():
46
+ create_model()
47
+ return redirect(url_for("home"))
48
+
49
+ @app.route('/loading-train-model')
50
+ def loading_train_model():
51
+ return render_template("loading.html", next_page="train_model", loading_mission="Training model...")
52
+
53
+ @app.route('/prediction', methods=["post", "get"])
54
+ def prediction():
55
+ if request.method == "POST":
56
+ tournament = request.form["tournament"]
57
+ map = request.form["map"]
58
+ team_a = request.form["team_a"]
59
+ team_b = request.form["team_b"]
60
+ ta_agents_list = sorted(request.form["ta_agents"].split())
61
+ tb_agents_list = sorted(request.form["tb_agents"].split())
62
+
63
+ i = 0
64
+ ta_agents = "["
65
+ for agents in ta_agents_list:
66
+ if i == 4:
67
+ ta_agents += agents + "]"
68
+ else:
69
+ ta_agents += agents + ", "
70
+
71
+ i = 0
72
+ tb_agents = "["
73
+ for agents in tb_agents_list:
74
+ if i == 4:
75
+ tb_agents += agents + "]"
76
+ else:
77
+ tb_agents += agents + ", "
78
+
79
+ train_data = pd.read_csv("data.csv")
80
+ model = pickle.load(open("model.sav", 'rb'))
81
+
82
+ features = ["Tournament", "Map", "Team A", "Team B", "TA Agents", "TB Agents"]
83
+
84
+ x = pd.get_dummies(train_data[features])
85
+
86
+ data_test = {"Tournament": [tournament], "Map": [map], "Team A": [team_a], "Team B": [team_b], "TA Agents": [ta_agents], "TB Agents": [tb_agents]}
87
+ test_data = pd.DataFrame(data=data_test)
88
+ x_test = pd.get_dummies(test_data[features])
89
+
90
+ col_x_test = []
91
+ for column in x_test:
92
+ col_x_test.append(column)
93
+
94
+ for column in x:
95
+ if column in col_x_test:
96
+ pass
97
+ else:
98
+ x_test.insert(0, column, [False])
99
+
100
+ x_test = x_test.reindex(x.columns, axis=1)
101
+
102
+ prediction = model.predict(x_test)[0]
103
+
104
+ return render_template("result.html", prediction=prediction)
105
+ else:
106
+ return redirect(url_for("home"))
107
+
108
+ if __name__ == "__main__":
109
+ app.run(debug=True)
model.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sklearn.model_selection import RandomizedSearchCV
2
+ from sklearn.ensemble import RandomForestClassifier
3
+ import pandas as pd
4
+ import pickle
5
+
6
+ def create_model():
7
+ train_data = pd.read_csv("data.csv")
8
+
9
+ features = ["Tournament", "Team A", "Team B", "Map", "TA Agents", "TB Agents"]
10
+
11
+ x = pd.get_dummies(train_data[features])
12
+ y = train_data["Result"]
13
+
14
+ print("Train data created...")
15
+
16
+ param_dist = {
17
+ 'n_estimators': [i for i in range(1, 501)],
18
+ 'max_depth': [i for i in range(1, 21)]
19
+ }
20
+
21
+ rf = RandomForestClassifier()
22
+
23
+ rand_search = RandomizedSearchCV(rf, param_distributions=param_dist, n_iter=5, cv=5)
24
+
25
+ rand_search.fit(x, y)
26
+
27
+ best_rf = rand_search.best_estimator_
28
+
29
+ print("Optimizations and training of the model finished...")
30
+
31
+ filename = "model.sav"
32
+ pickle.dump(best_rf, open(filename, "wb"))
33
+
34
+ print("Model saved !")
static/gif jett.gif ADDED
templates/home.html ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Home</title>
6
+
7
+ <link href="https://seeklogo.com/images/V/valorant-logo-3D72D9117F-seeklogo.com.png" rel="icon"/>
8
+
9
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.20.8/dist/css/uikit.min.css" />
10
+
11
+ <script src="https://cdn.jsdelivr.net/npm/uikit@3.20.8/dist/js/uikit.min.js"></script>
12
+ <script src="https://cdn.jsdelivr.net/npm/uikit@3.20.8/dist/js/uikit-icons.min.js"></script>
13
+ </head>
14
+ <body>
15
+ <div class="uk-container uk-align-center uk-flex uk-flex-center uk-flex-middle" uk-height-viewport="expand: true">
16
+ <div>
17
+ <h1 class="uk-text-center">VCT Map Predictor</h1>
18
+ <form action="{{url_for('prediction')}}" method="POST">
19
+ <label>Tournament</label>
20
+ <select id="tournament" name="tournament" class="uk-select uk-margin-bottom" aria-label="Select">
21
+ <option value="">Please select tournament...</option>
22
+ {% for tournament in tournaments %}
23
+ <option>{{tournament}}</option>
24
+ {% endfor %}
25
+ </select>
26
+ <br>
27
+ <label>Map</label>
28
+ <select id="map" name="map" class="uk-select uk-margin-bottom" aria-label="Select">
29
+ <option value="">Please select map...</option>
30
+ {% for map in maps %}
31
+ <option>{{map}}</option>
32
+ {% endfor %}
33
+ </select>
34
+ <br>
35
+ <label>Team A</label>
36
+ <select id="team_a" name="team_a" class="uk-select uk-margin-bottom" aria-label="Select">
37
+ <option value="">Please select team A...</option>
38
+ {% for team_a in team_A %}
39
+ <option>{{team_a}}</option>
40
+ {% endfor %}
41
+ </select>
42
+ <br>
43
+ <label>Team B</label>
44
+ <select id="team_b" name="team_b" class="uk-select uk-margin-bottom" aria-label="Select">
45
+ <option value="">Please select team B...</option>
46
+ {% for team_b in team_B %}
47
+ <option>{{team_b}}</option>
48
+ {% endfor %}
49
+ </select>
50
+ <label>Team A agents</label>
51
+ <input class="uk-input" type="text" id="ta_agents" name="ta_agents" placeholder="Agents1 Agents2 Agents3 Agents4 Agents5" aria-label="Input">
52
+ <label>Team B agents</label>
53
+ <input class="uk-input" type="text" id="tb_agents" name="tb_agents" placeholder="Agents1 Agents2 Agents3 Agents4 Agents5" aria-label="Input">
54
+ <button class="uk-button uk-button-default uk-margin-top uk-align-center" type="submit">Predict map</button>
55
+ </form>
56
+ <div class="uk-flex uk-flex-center">
57
+ <a class="uk-margin-right" href="{{url_for('loading_train_model')}}">Train model</a> | <a class="uk-margin-left" href="{{url_for('loading_update_data')}}">Update data</a>
58
+ </div>
59
+ </div>
60
+ </div>
61
+ </body>
62
+ </html>
templates/loading.html ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Loading...</title>
6
+
7
+ <link href="https://seeklogo.com/images/V/valorant-logo-3D72D9117F-seeklogo.com.png" rel="icon"/>
8
+
9
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.20.8/dist/css/uikit.min.css" />
10
+
11
+ <script src="https://cdn.jsdelivr.net/npm/uikit@3.20.8/dist/js/uikit.min.js"></script>
12
+ <script src="https://cdn.jsdelivr.net/npm/uikit@3.20.8/dist/js/uikit-icons.min.js"></script>
13
+ </head>
14
+ <body>
15
+ <div class="uk-container uk-align-center uk-flex uk-flex-center uk-flex-middle" uk-height-viewport="expand: true">
16
+ <div>
17
+ <img src="/static/gif jett.gif">
18
+ <p>by u/quelm_nossfe</p>
19
+ <h1 class="uk-text-center">{{loading_mission}}</h1>
20
+ </div>
21
+ </div>
22
+ </body>
23
+ {% if next_page == "train_model" %}
24
+ <script> window.location.replace('{{url_for("train_model")}}'); </script>
25
+ {% elif next_page == "update_data" %}
26
+ <script> window.location.replace('{{url_for("update_data")}}'); </script>
27
+ {% endif %}
28
+ </html>
templates/result.html ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Result</title>
6
+
7
+ <link href="https://seeklogo.com/images/V/valorant-logo-3D72D9117F-seeklogo.com.png" rel="icon"/>
8
+
9
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.20.8/dist/css/uikit.min.css" />
10
+
11
+ <script src="https://cdn.jsdelivr.net/npm/uikit@3.20.8/dist/js/uikit.min.js"></script>
12
+ <script src="https://cdn.jsdelivr.net/npm/uikit@3.20.8/dist/js/uikit-icons.min.js"></script>
13
+ </head>
14
+ <body>
15
+ <div class="uk-container uk-align-center uk-flex uk-flex-center uk-flex-middle" uk-height-viewport="expand: true">
16
+ <div>
17
+ <h1 class="uk-text-center">Result</h1>
18
+ <h2 class="uk-text-center uk-text-medium">{{prediction}}</h2>
19
+ <div class="uk-flex uk-flex-center">
20
+ <a class="uk-margin-right" href="{{url_for('home')}}">Home</a>
21
+ </div>
22
+ </div>
23
+ </div>
24
+ </body>
25
+ </html>
26
+ </html>
vct_data.py ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from bs4 import BeautifulSoup
2
+ import pandas as pd
3
+ import requests
4
+
5
+ headers = {
6
+ 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:35.0) Gecko/20100101 Firefox/35.0',
7
+ }
8
+
9
+ def get_html_document(url):
10
+ response = requests.get(url, headers=headers)
11
+
12
+ return response.text
13
+
14
+ def create_data():
15
+ url = "https://www.vlr.gg/"
16
+
17
+ html_document_events = get_html_document(url + "events")
18
+
19
+ soup_events = BeautifulSoup(html_document_events, 'html.parser')
20
+
21
+ events_html = soup_events.find_all("a", {"class": "wf-card mod-flex event-item"})
22
+
23
+ data = {"Tournament": [], "Match ID": [], "Team A": [], "Team B": [], "Map ID": [], "Map": [], "TA Agents": [], "TB Agents": [], "Result": []}
24
+
25
+ events_id = []
26
+ events_name = []
27
+ for event_html in events_html:
28
+ event_id = ""
29
+
30
+ i = 0
31
+ for character in event_html["href"]:
32
+ if i > 6 and i < 11:
33
+ event_id += character
34
+ i += 1
35
+ else:
36
+ i += 1
37
+
38
+ event_name = event_html.find_all("div", {"class": "event-item-title"})[0].text.strip()
39
+
40
+ print("Tournament : " + event_name)
41
+
42
+ if "Champions Tour 2024" not in event_name:
43
+ continue
44
+
45
+ events_id.append(event_id)
46
+ events_name.append(event_name)
47
+
48
+ html_document_matches = get_html_document(url + f"event/matches/{event_id}")
49
+
50
+ soup_matches = BeautifulSoup(html_document_matches, 'html.parser')
51
+
52
+ matches_html = soup_matches.find_all("a", {"class": "wf-module-item match-item mod-color mod-left mod-bg-after-striped_purple mod-first"}) + soup_matches.find_all("a", {"class": "wf-module-item match-item mod-color mod-left mod-bg-after-striped_purple"})
53
+
54
+ matches_id = []
55
+ for match_html in matches_html:
56
+ match_id = ""
57
+
58
+ i = 0
59
+ for character in match_html["href"]:
60
+ if i > 0 and i < 7:
61
+ match_id += character
62
+ i += 1
63
+ else:
64
+ i += 1
65
+
66
+ matches_id.append(match_id)
67
+
68
+ print("Match ID : " + match_id)
69
+
70
+ html_document_match = get_html_document(url + match_id)
71
+
72
+ soup_match = BeautifulSoup(html_document_match, 'html.parser')
73
+
74
+ match_header_vs = soup_match.find_all("div", {"class": "match-header-vs"})
75
+
76
+ team_a_split = match_header_vs[0].find_all("div", {"class": "match-header-link-name mod-1"})[0].find_all("div", {"class": "wf-title-med"})[0].text.split()
77
+ team_a = ""
78
+ for a in team_a_split:
79
+ team_a = team_a + a + " "
80
+
81
+ print("Team A : " + team_a)
82
+
83
+ team_b_split = match_header_vs[0].find_all("div", {"class": "match-header-link-name mod-2"})[0].find_all("div", {"class": "wf-title-med"})[0].text.split()
84
+ team_b = ""
85
+ for b in team_b_split:
86
+ team_b = team_b + b + " "
87
+
88
+ print("Team B : " + team_b)
89
+
90
+ if team_a == "TBD" or team_b == "TBD":
91
+ print("not finished")
92
+ else:
93
+ maps_html = soup_match.find_all("div", {"class": "vm-stats-gamesnav-item js-map-switch"})
94
+
95
+ maps_id = []
96
+ for map_html in maps_html:
97
+ map_id = map_html["data-game-id"]
98
+
99
+ print("Map ID : " + map_id)
100
+
101
+ maps_id.append(map_id)
102
+
103
+ html_document_map = get_html_document(url + match_id + "/?game=" + map_id)
104
+
105
+ soup_map = BeautifulSoup(html_document_map, 'html.parser')
106
+
107
+ vm_stats_game = soup_map.find_all("div", {"class": "vm-stats-game mod-active"})
108
+
109
+ map_html = vm_stats_game[0].find_all("div", {"class": "map"})
110
+
111
+ map_text = map_html[0].find_all("span", {"style": "position: relative;"})[0].text.split()
112
+
113
+ map = map_text[0]
114
+
115
+ print("Map : " + map)
116
+
117
+ agents_html = vm_stats_game[0].find_all("span", {"class": "stats-sq mod-agent small"})
118
+
119
+ i = 0
120
+ ta_agents = []
121
+ tb_agents = []
122
+ for agent_html in agents_html:
123
+ if i <= 4:
124
+ agent = agent_html.find_all("img")[0]["title"]
125
+ ta_agents.append(agent)
126
+ i += 1
127
+ else:
128
+ agent = agent_html.find_all("img")[0]["title"]
129
+ tb_agents.append(agent)
130
+ i += 1
131
+
132
+ ta_agents = sorted(ta_agents)
133
+ tb_agents = sorted(tb_agents)
134
+
135
+ print("TA Agents : ", ta_agents)
136
+ print("TB Agents : ", tb_agents)
137
+
138
+ if ta_agents == [] or tb_agents == []:
139
+ print("not finished")
140
+ pass
141
+ else:
142
+ is_winner = vm_stats_game[0].find_all("div", {"class": "team"})[0].find_all("div", {"class": "score mod-win"})
143
+
144
+ if is_winner == []:
145
+ result = "Team B win"
146
+ else:
147
+ result = "Team A win"
148
+
149
+ data["Tournament"].append(event_name)
150
+ data["Match ID"].append(match_id)
151
+ data["Team A"].append(team_a)
152
+ data["Team B"].append(team_b)
153
+ data["Map ID"].append(map_id)
154
+ data["Map"].append(map)
155
+ data["TA Agents"].append(ta_agents)
156
+ data["TB Agents"].append(tb_agents)
157
+ data["Result"].append(result)
158
+
159
+ print("All data of the map : ", data)
160
+
161
+ df = pd.DataFrame(data=data)
162
+
163
+ df.to_csv("data.csv", sep=",", index=False, encoding="utf-8")
164
+
165
+ print(".csv file downloaded...")