From c7262892e947416f711c0df14184a83e0488c111 Mon Sep 17 00:00:00 2001
From: ElTata <eltata@firemail.cc>
Date: Wed, 4 Dec 2019 14:01:11 +0100
Subject: [PATCH] exponential distribution to choose player for events

---
 CHANGELOG.md  |  4 ++++
 Irpg/Event.pm | 39 ++++++++++++++++++++++++++++++++-------
 2 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 784101e..6a3c3db 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,9 @@ before it.
 Thanks for your interest in the Idle RPG! Feel free to contact me with ideas and
 comments, or post them in the issues of the project for public view.
 
+---
+## v5.3.0:
+- players are chosen based on exponential distribution (of their levels) for the random events
 
 ---
 ## v5.2.2: released 12/02/19
@@ -20,6 +23,7 @@ comments, or post them in the issues of the project for public view.
 - new command ACTIONS, do all available actions
 - actions messages now colorize the status of the action, and the changed TTL
 - fixed chclass for classes with ' ' in their name
+- no more warnings "argument isn't numeric" in steal_result subroutine
 
 ---
 ## v5.2.1: released 10/28/19
diff --git a/Irpg/Event.pm b/Irpg/Event.pm
index ae6412e..5e964ca 100644
--- a/Irpg/Event.pm
+++ b/Irpg/Event.pm
@@ -139,8 +139,9 @@ sub find_item { # find item for argument player
 
 
 sub hog { # summon the hand of god
-    my @players = grep { $rps->{$_}{online} } keys(%$rps);
-    my $player = $players[rand(@players)];
+	#my @players = grep { $rps->{$_}{online} } keys(%$rps);
+	#my $player = $players[rand(@players)];
+	my $player = choose_player() || return;
     my $win = int(rand(5));
     my $time = int(((5 + int(rand(71)))/100) * $rps->{$player}{next});
     if ($win) {
@@ -162,10 +163,33 @@ sub hog { # summon the hand of god
     Irpg::Irc::chanmsg("$player reaches next level in ".duration($rps->{$player}{next}).".");
 }
 
-sub calamity { # suffer a little one
+sub choose_player {
     my @players = grep { $rps->{$_}{online} } keys(%$rps);
     return unless @players;
-    my $player = $players[rand(@players)];
+
+	#sort players by group of same levels
+    my %levels = ();
+    foreach (@players) {
+        if (exists $levels{$rps->{$_}{level}}) {
+            push $levels{$rps->{$_}{level}}, $_;
+        }
+        else {
+            $levels{$rps->{$_}{level}} = [$_,];
+        }
+    }
+	@players = @levels{sort keys %levels};
+
+    #exponential distribution on levels (lambda = 0.5)
+	@players = @{$players[-log(rand) / 0.5]};
+	#then uniform distribution for players of the same level
+	return $players[rand(@players)];
+}
+
+sub calamity { # suffer a little one
+	#my @players = grep { $rps->{$_}{online} } keys(%$rps);
+    #return unless @players;
+    #my $player = $players[rand(@players)];
+	my $player = choose_player() || return;
     if (rand(10) < 1) {
         my @items = ("amulet","charm","weapon","tunic","set of leggings",
                      "shield");
@@ -234,9 +258,10 @@ sub calamity { # suffer a little one
 }
 
 sub godsend { # bless the unworthy
-    my @players = grep { $rps->{$_}{online} } keys(%$rps);
-    return unless @players;
-    my $player = $players[rand(@players)];
+	#my @players = grep { $rps->{$_}{online} } keys(%$rps);
+	#return unless @players;
+	#my $player = $players[rand(@players)];
+	my $player = choose_player() || return;
     if (rand(10) < 1) {
         my @items = ("amulet","charm","weapon","tunic","set of leggings",
                      "shield");
-- 
GitLab