Python code for identifying Splinterlands' best brawlers.

Image created with Bing image generator.

This is a companion post to the Best brawlers in Tier 3,4,5 post. Here, I go over the python code used to download and process the brawl data.

Identifying the best brawlers is a slightly complicated data sorting task. We need to ask for brawl data for each guild and each brawl. Downloading this data takes quite a while. Fortunately, I have stored the brawl data once before up to brawl #232, so there is not that much additional data to download for me.

Once we have the brawl data, we need to compute statistics for each fray.

separator.png

Python code

The script is available in entirety in spltools: best_brawler_in_fray.py

image.png

First, we import a few standard python libraries. I also use Numpy, an absolutely amazing library, in this script to do some math manipulations. From spltools, I use the Guild and Brawl classes, as well as the two functions get_guild_list and get_player_guild.

Next we define functions to download and load brawl data. To identify the best all-time brawlers, we need to download every brawl for all top 300 guilds. This is a lot of data, so we need to save it to file, otherwise we risk losing it all if we get some network/computer error. I added a manual delay in the download function to be a bit nice with the Splinterlands servers.

image.png

image.png

image.png

The main processing of the data is done within the BrawlHistory class. I set it up so that the BrawlHistory object is specific for a tier, and we instantiate one for tier 3, one for tier 4 and one for tier 5. It has a function to add brawl data: BrawlHistory.add_data(...). It takes a Brawl object as input and then inserts player results into the correct data structures.

image.png

In the BrawlHistory initializer I have hard-coded some properties for the three Brawl tiers I'm interested in analyzing. First of all, we need to know the number of frays, and also which frays have the same rules - for those we want to combine the results.

So I set up the number of frays and the duplicate_fray info from the tier parameter, and then define a list of unique frays, along with the names of the unique frays. For example, frays 3 and 4 are duplicates in tier 3, so I label the combined one '3+4'. Then I setup the fray_data dictionary where I will store all the data

image.png

The add_data function is quite simple, since the data is already nicely structured in the Brawl object. We loop over the players, look at which fray they played and insert their data. If we have seen the player before in this fray, we add the brawl results to the already existing data structure, otherwise we add a new one.

image.png

Finally, we can identify the best players in each fray. Again, since we have well structured data, the code can be quite compact and nice. I call an internal function that converts the dictionaries to lists of players, wins, losses and winrates, and then find which index in the list that corresponds to the highest number of wins. That is done with the np.argmax function call. Then, the last step is to print a markdown table line with the info for that player.

image.png

There is also a function to compute the best players in the tier. It does essentially the same as the get_best_player_in_fray, but has to combine the fray data into one big data set first.

Finally, the rest of the script just calls the functions we have defined. We loop over all guilds, get their data from each brawl, and insert it into the BrawlHistory objects.

image.png

Once all data is setup up, we call the functions to get the best players:

image.png

separator.png

Final words

Thank you for your attention. If you are interested in more posts about the spltools python package, you can find the previous ones here:

spltools update posts:

4. spltools update: Classes for Brawl data
3. spltools update: Reward chest classes
2. spltools update: Checking which set a card belongs to
1. Initial spltools commit


If you have not yet joined Splinterlands please click the referral link below to get started.



Join Splinterlands


Best wishes
@Kalkulus

separator.png



0
0
0.000
12 comments
avatar

Great post...👏

I need to start experimenting more with the brawl api.

Also the post about the top tier players is nice just missing my name 🤣.
See some regular names that also competing well in tournaments.

0
0
0.000
avatar

Another cool thing about it is that you can go back and get all your own match data too, from all brawls you ever played. (Thats the same for tournament's but I don't know how to retrieve tournament ids when they are no longer visible in the list on the site).

0
0
0.000
avatar

yeah that is where i think you need to use the hive blockchain.
For that i use the hive python package (beem)

Here is some example code:
This will only be valid with tournaments that have an entry fee i think.


from dateutil.parser import isoparse

from src.api import hive

from_date = '2024-10-14T01:00:00.000Z'
till_date = '2024-10-20T23:00:00.000Z'

account = 'beaker007'
from_date = isoparse(from_date).replace(tzinfo=None)
till_date = isoparse(till_date).replace(tzinfo=None)

transactions = hive.get_spl_transactions(account, from_date, till_date, filter_spl_transactions=['sm_token_transfer'])
for transaction in transactions:
    data = json.loads(transaction['trx_info']['data'])
    if 'type' in data and data['type'] == 'enter_tournament':
        print(data['tournament_id'])

The calls that i use are defined in this file:
https://github.com/gamerbeaker007/splinterlands-statistics/blob/main/src/api/hive.py

Not the nicest code (with retries and node selections etc)... but it works for my use case :)
I did not test to see if this works when used with years old information. My use case is just tournaments of last season

0
0
0.000
avatar

Wow, this is gold for me! As a Python beginner Classes are still completely out of my reach, so having something to explore and study like your code above (and your spstool tool in general) is awesome :)

0
0
0.000
avatar

Cool! Please don't hesitate to ask if something is confusing :)

0
0
0.000
avatar

I'm going to be confused... but due to my lack of knowledge!

Jokes aside, thanks, if I'll find something I do not understand, I'm going to let you know :)

0
0
0.000
avatar

This was so cool to read through. I haven't truly programmed in over 10 years and I have little familiarity with Python. But all the computer language talk made sense in a conceptual way, so it was fun to think back through the logic that you used to run the script. Thanks for sharing!

0
0
0.000
avatar

At least Python is pretty easy to read to understand the broad terms of the program. Glad you liked it!

0
0
0.000
avatar

This is gold! Thank you for sharing!

0
0
0.000
avatar
(Edited)

@kalkulus, I paid out 1.215 HIVE and 0.228 HBD to reward 5 comments in this discussion thread.

0
0
0.000