Do you ever dodge queue or pick Vayne mid because because you don't know who else to play? PickMyChamp is a solution to all your problems: a utility to generate the best choice of champion in a game of League of Legends (LoL).
Clone the repository to your computer
git clone git://github.com/vsb321/PickMyChamp
In the directory, execute
python PickMyChamp.py
This project can be broken down into 3 components:
-
Collecting and manipulating user input
- To keep things simple, I only ask for a summoner username and opponent the user is facing, in order to develop a profile of the user and their possible picks for the game.
- Although we request information from the user at various points, we have to actually interpret it to come to a conclusion. I have basic information about the user, but how do I actually transcribe it?
- Throughout the whole runtime of the application, I only webscrape two distinct sources:
- LoL database for user statistics: op.gg
- Portal of good/bad picks for any and every champion that exists in LoL: lolcounter
- Throughout the whole runtime of the application, I only webscrape two distinct sources:
def get_true_url(text_to_add, url_to_add, symbol): final_url = url_to_add if len(text_to_add.split()) == 1: final_url = url_to_add + text_to_add else: words = text_to_add.split() i = 0 for word in words: if i < len(words) - 1: final_url = final_url + (word + symbol) else: final_url = final_url + word i = i + 1 return final_url
To create a final URL to parse and webscrape from, I had to generate it from the user input. Let's examine the makeup of URLs for both sources using the sample output above, as well as for another set of inputs.
The input username (Imaqtpie) and the input enemy champion (Akali) are simply appended to a generic url displaying data and statistics. In the case that either inputs exceed one word, a symbol such as '+' is concatenated between each additional word. This is all accomplished through the
get_true_url()
function. -
Gathering and organizing user-specific data
After opening the connection to our sources and using Beautiful Soup to parse the HTML to an applicable format for operating upon, I had to scrape the HTML for the variables to use in my calculations.
When deciding a player's rating on a champion in comparison to the rest of their champion pool, I had to take a few factors into consideration: Kill/Death/Assist Ratio, Games Played, Win Ratio. Once this data was identified, I had to search for and extract it within the HTML. Here is a portion of an HTML sample for a champion I worked with:
<td class="RatioGraph Cell" data-value="65.957446808511"> <div class="WinRatioGraph"> <div class="Graph"> <div class="Fill Left" style="width: 65%"></div> <div class="Text Left">62W</div> <div class="Fill Right"></div> <div class="Text Right">32L</div> <div class="Bar" style="left: 65%;"></div> </div> <span class="WinRatio red">66%</span> </div> </td>
To scrape the static winrate from the HTML, I had to search for
<td>
tags, going layer by layer until I got to the magic number I was looking for. Repeating this step for KDA ratio and Games played, the simplest way to work with this data was withChampion()
objects in an array storing a user's champion pool. I had to repeat this process to generate the opponent counter list array as well. -
Coming to a conclusion of champions
- In order to generate a list of top champions for the user to play, I needed some sort of relation between games played, KDA and win rate.
X = frame[['Games','KDA']] Y = frame['Win Rate'] regr = linear_model.LinearRegression() regr.fit(X, Y)
- Using pandas and sklearn, I implemented a multiple linear regression with a data frame, utilizing games played, KDA and win rate. In other words, I was testing the effects that the number games played and the KDA ratio had on a champion's win rate.
- When I had generated a prediction of weights for each champion using user-specific stats, I also had to take counter picks into account. If the opponent was strong against a champion in the user's pool, that champion's corresponding weight was multipled by
0.75
. As you can guess, If the opponent was weak against a champion, the weight was multiplied by1.25
. - Sorting the array of weights in descending order, the champions with the top three highest weights were returned and printed!
- How do I generate a champion for a specific lane?
- As of yet, this feature is not supported. Check back for future updates!
- Will this utility be supported on a mobile platform or website?
- I am currently in the process of making http://pickmychampion.com! Expect it in the near future.
- How can I support PickMyChamp?
- Spreading the word or generating test cases is more than enough! I'm always looking for feedback, so please reach out to me with advice or ideas for future capabilities.
- MIT license
- Copyright 2022 © Vijay Baliga.