Tuesday, August 30, 2016

PerkunWars - a simple fantasy game based on Perkun.

I would like to introduce a small project you can download from https://sourceforge.net/projects/perkunwars/ - PerkunWars - a simple fantasy game.

In the game there is one player (Valder), three NPCs (Thragos, Dorban, Pregor) and a vampire. There are three locations (Wyzima, Shadizar and Novigrad). Click on a town to move there (you may also use a menu action).

If you meet any NPCs you may chat with them. The chat window will display something like:

Pregor >I was staying here, in Shadizar. The vampire? He is in Wyzima. I am staying here...
Thragos >I was staying here, in Shadizar. The vampire? He may be in Wyzima. He may be in Novigrad. I am staying here...


You may have noticed that Pregor and Thragos are avoiding the vampire. There is one more NPC - Dorban, who is a witcher and therefore is constantly hunting the vampire. You may attack the vampire yourself (garlic and holy water are helpful). But it makes no sense to attack him alone. You should attack him when the NPCs are around.


This simple game is based on Perkun. Open the file src/perkun_wars.cc. You will see the code creating pipes and forks. For each NPC there is a child process created (running the function main_perkun). An instance of object npc is created and it parses the Perkun specification. What is npc? See the file inc/perkun_wars.h. You will see the code:

class npc: public perkun::optimizer_with_all_data

So for each NPC (Dorban, Pregor and Thragos) there is an instance of perkun::optimizer_with_all_data with some redefined virtual functions, parsing a Perkun specification!

Now take a look at the directory perkun/final_code. It contains the Perkun specifications named after the NPCs. Take a look at the perkun/final_code/pregor_general.perkun. Note the payoff function:

payoff
{
set({where_is_Pregor=>place_Wyzima, do_I_see_vampire=>false}, 100.0);
set({where_is_Pregor=>place_Wyzima, do_I_see_vampire=>true}, 0.0);
set({where_is_Pregor=>place_Shadizar, do_I_see_vampire=>false}, 100.0);
set({where_is_Pregor=>place_Shadizar, do_I_see_vampire=>true}, 0.0);
set({where_is_Pregor=>place_Novigrad, do_I_see_vampire=>false}, 100.0);
set({where_is_Pregor=>place_Novigrad, do_I_see_vampire=>true}, 0.0);
}



Now check the payoff for Dorban (the file perkun/final_code/dorban_general.perkun):

payoff
{
set({where_is_Dorban=>place_Wyzima, do_I_see_vampire=>false}, 0.0);
set({where_is_Dorban=>place_Wyzima, do_I_see_vampire=>true}, 100.0);
set({where_is_Dorban=>place_Shadizar, do_I_see_vampire=>false}, 0.0);
set({where_is_Dorban=>place_Shadizar, do_I_see_vampire=>true}, 100.0);
set({where_is_Dorban=>place_Novigrad, do_I_see_vampire=>false}, 0.0);
set({where_is_Dorban=>place_Novigrad, do_I_see_vampire=>true}, 100.0);
}


Did you notice something? Of course the Dorban's payoff function makes him to follow the vampire, while Pregor tries to avoid him. This is how we use the payoff function.

The Dorban's variables are:
variables
{
input variable where_is_Dorban:

{place_Wyzima,place_Shadizar,place_Novigrad};
input variable do_I_see_vampire:{false,true};
output variable action:{do_nothing,goto_Wyzima,goto_Shadizar,goto_Novigrad};
hidden variable where_is_vampire:{place_Wyzima,place_Shadizar,place_Novigrad};
}


Note that we have one hidden variable here - where_is_vampire. Of course Dorban knows where is the vampire if he can see him (i.e. it is impossible for the vampire to be elsewhere when Dorban can see him). This is solved with the command "impossible" in the Dorban's model. But in general it is a hidden variable.





No comments:

Post a Comment