A little fun with Tkinter

Python is truly a versatile language. While I mostly use it as a study platform to learn machine learning, analytics and artificial intelligence, that doesn’t mean that Python isn’t a fully fledged developer language on its own and from time to time I like to build small things with it while I have a longer-term analytics projects in the works.

The product I brought you today is one such project, as an enthusiast of Role Playing Games (RPG’s), I often find myself wanting to have a way to simulate or test a character I may be building and maybe test him out on his combat skills.

Like so many other things, this is one that can be done on paper but if you need to do a couple of dozen iterations it starts to get old pretty fast, thus it makes sense to try and automate it with a little program. As it turns out , is not that difficult to create an RPG with the help of some python classes and the Tkinter module

Shapes and buttons

The main screen of my game looks like this:

Game Screen

It can´t certainly hold up against the Witcher 3 , but for our purposes it will do the job. This layout is clearly inspired in old school Japanese RPG’s battlescreens and is meant to function in a similar manner. To the left , we have the Player menus and stats

Player Action

Notice the HP and Stamina stats, these depend on the type of player selected (more on that later), the player can perform an Action , can guard itself or Flee the combat altogether , if the flee attempt is successful the program will terminate.

On the right, we found the Enemy stats

Enemy stats

Again , its HP an stamina are different to that of the player and we have two more tags ‘Enemy Console’ and ‘Player Actions’ , these tags will let us know how the battle is progressing as we choose moves.

Back to the player, if I hit the action button my menu changes to the selection of Actions I can perform

Player actions

This is a fairly typical RPG action selection, however, the Use Item and Habilities button are non functional, this is because I haven´t actually sat down and thought about all the rules for items and special abilities in order to code them , so right now , our character can only attack and defend itself.

If we use the attack button, we observe than actions occur at the other side of the screen,indicating that our game is already underway

Action console

So as you can see, the player and enemy consoles tell us what consequences our attack had , notice that while the player dealt 5 damage the enemy only absorbed 1 , meaning the net damage done to the Enemy is only 4 . These calculations have to do with the respective stats of both the player and the enemy and how the program decides how much damage is taken.

Logic trumps all

Under the hood , the program is really not that complicated, there are simple python scripts, one that handles the interface behavior using the tkinter module and a second “backend” script that creates the enemy a player classes to be used by the program , let´s take a look at the backend script first.

The program is run by a simple Character() class, this class deals with the main attributes of any given character , such as their features (strength, agility, inteligence etc.) and the basic methods of attack and defense as outlined below

The character class is , in fact, a mother class that allows to create enemy and player classes objects with ease. In this way , we can have 3 different player classes (Combat Operative, Tech Operative and Covert Operative) just by adjusting the base parameters of our Character class. Note that Enemy is just another instance of character with different stats.

The methods attack() and defend() are a simple based on the stats for each class. The attack method will favor the player classes with higher agility and and strength (the base damage is a function of the player strength),while the defense favors the constitution stat . The idea behind these rules is to create a balance between the different player classes and the enemy so is not too easy or to hard for them to beat each other.

The second script controls all the interface aspects by making use of tkinter. Here , we will find mirror images of the attack()(attack_press() and defend() (defend() press) functions but this time dealing with the events that occur after a button press.

The whole screen is handled through the use of label frames, neatly allowing the arrangement of the different consoles , the canvas to show the player and enemy graphics and the action buttons

Now let´s take a closer look at attack_press()

def attack_press():
enemy_init_health=enemy.health
damage = player.attack()
enemy_health=enemy.defend(damage)
absorbed_damage=(damage-(enemy_init_health-enemy_health))
Action_button=ttk.Button(player_control,text="Action",command=command_action)
Action_button.grid(column=0,row=0)
Action_button.configure(state="disabled")
Flee_button=ttk.Button(player_control,text="Flee")
Flee_button.grid(column=0,row=1)
Flee_button.configure(state="disabled")
Guard_button=ttk.Button(player_control,text="Guard")
Guard_button.grid(column=1,row=0)
Guard_button.configure(state="disabled")
Pass_button=ttk.Button(player_control,text="Pass",command=enemy_attack)
Pass_button.grid(column=1,row=1,sticky=tk.W)
player_message=ttk.Label(action_console,text="Player Attacks! deals %s damage"%damage)
player_message.grid(row=0,column=0)
enemy_hp=ttk.Label(enemy_stats,text="Hp: %s"%enemy_health)
enemy_hp.grid(row=0,column=0)
enemy_message=ttk.Label(enemy_console,text="Enemy absorbs %s damage"%absorbed_damage)
enemy_message.grid(column=0,row=1)
if enemy.health==0:
mBox.showinfo("Python Message Info Box","You´ve won, restart the simulator!!!")

In the first few lines, the Character attack() method is invoked and with it we will calculate the base damage dealt by the player to the enemy. The enemy will , in turn , invoke the defend() method to calculate how much damage , if any, is absorbed.

When the player is done attacking , it must hit the ‘Pass’ button , giving the enemy a change to attack (this occurs with the enemy_attack() method), while the enemy_attack() method also invokes the Character attack() and defend() methods, it must also reset the state of the buttons used by the player so that a new run can be performed. The player will constantly hit attack and pass until either the enemy or the player runs out of HP, at which point , the program throws a little alert

And that’s it . What´s fun about this program is that its concept can be developed for bigger simulations and with a polished UI it could make a fairly decent RPG. I find that, most of the time, the difficulty lies in balancing the game’s rules so maybe one could pick up some tabletop RPG’s rulebook and bring them to life in the computer. By using the python´s libraries , the development possibilities are varied and quite extensive indeed. I have more ideas for game development but , as usual, this takes some time as I mostly focus in Analytics and Artificial Intelligence, which are quite extensive topics in and of themeselves, however sometimes I take a break from the more academic stuff and wind up by writing up some development ideas in my notebook, and eventually I try to find the time to put them together.

Until the next one

Engineer , Data and AI enthusiast . Amateur programmer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store