PETROOM大改造
【萌え萌えキャラクターズと遊ぼー。】

ランキング表示をソート(並び替え)しよう

PETROOMのランキング表示は、

なついている人
嫌いな人
それ以外の人

の3つに別れていまして、さらに、そのそれぞれの中の表示は、
先に登録した人順に上から表示されます。

つまり、オリジナルのままですと、
ただ単に登録した順番で上から並びますので、
遊ぶ人数が増えれば増えるほど、自分が一体どの辺りの順位なのか、
さっぱり分からなくなってしまいます。

それを解決する手段として、ラブポイントを表示する方法があります。
「遊ぼー。」では、初めて遊びに来てくれた人が、
上位の人のあまりにも高いラブポイントを見て、
絶望に打ちひしがれ、その後やらなくなる事がないように(笑)、
この方法は、選びませんでした。

苦肉の策として、ランキングを細分化したり、中間線を引いたりしましたが、
所詮は登録順、同じランクにたくさん人が集まれば、
結局分からなくなってしまうのです・・・うぅ(T_T)

そこで、R.C.T-eがついに立ち上がりましたっ!(爆)
「こりゃもう、ソート(並び替え)するしかないズラ」(なぜ方言?)
何回かのバグを乗り越え、ようやく完成しました(^^;
・・・前置きが長くなりましたが、そんなわけで、ランキング表示をソートしましょう。

・・・ですが、この改造、ちょっとした問題がありまして・・・(^^;
どんな問題かというと、「一番なついている人が必ずしも一番上とは限らない(場合がある)」という、
なんとも、とんでもない仕様なのです(^^;;;

どんな場合かと言いますと、それは「一番」が複数いるとき、つまりラブポイントが同点の時ですね。
ここの改造の場合、ラブポイントが同点の場合は、お名前でソートされるのですが、
オリジナルのPETROOMでは、登録が早かった人が一番になるためです。
「遊ぼー。」では、この問題を回避するため、また別の改造を施していますが、
今回それは掲載いたしません、改造の手間の方が遙かに掛かるからです。
というか、かなりいじりますので、上手く掲載する自信がないのです(^^;
もしかしたら、そのうちアップするかもしれませんが、現状はこの仕様でお願い致します。
実際、トップが同点になる場合はあまりありませんし、
そのような注記をしていただければ、それほど問題でもありませんので。

※これから説明するソート(並び替え)について。
ラブポイントの高い順に並び替えは行われるのですが、
もしラブポイントが同点の場合、
順番はお名前順(英数字→ひらがなカタカナ→漢字)になります。ご注意下さい。

それでは、まず、ソートを行うサブルーチンを追加しましょう。
サブルーチンを呼び出す所の近くにあった方が分かりやすいので、
ユーザーデータの書き込み(sub openoutuserdata)の手前辺りに追加しましょう。

            } else {
                @otherlist[$othernum] = "$name";
                $othernum++;
            }
        }
    }
}

# → ここ!

# ------------------------- #
# Sub Open Out User Data
# ユーザーデータの書きこみ
# ------------------------- #
sub openoutuserdata {
    if ($lockkey == 1) { &lock; }
    open(OUT,">$userdata") || &error("Can't write $userdata");
    print OUT @new;
    close(OUT);
    &unlock;
}

# → ここ!の部分に入るのは、これです。

# ------------------------- #
# Sub User Sort
# ユーザーソート
# ------------------------- #
sub user_sort_r {
    local(@txt) = @_;
    @newtxt = sort by_reverse_number @txt;
}

sub by_reverse_number {
    if ($a == $b) {
        $a cmp $b;
    }
    else {
        $b <=> $a;
    }
}

ここで一体何をやっているのか、詳しい説明は省きますが、
要は、このサブルーチンを呼ぶときに今までのランキングリストを突っ込んでやると、
並び替えられた新しいランキングリストが@newtxtに入って、返ってくるのです。

・・・くるのですが、今までのランキングリストも少しいじる必要があります。
そうです、このサブルーチンでソートするために、
今までのランキングリストにラブポイントを含ませないといけないのです。

というわけで、ユーザーデータの読み込み(sub openinuserdata)の下の方を、
下記のように変更(追記だけです)してください。

        if ($_[0] eq 'ownerlist') {
            if ($love >= $loved) {
                @lovelist[$lovenum] = "$love<>$name";
                $lovenum++;
                if ($bestlove < $love)
                    { $bestowner = "$name"; $bestlove = $love; }
            } elsif ($love <= $disliked) {
                @hatelist[$hatenum] = "$love<>$name";
                $hatenum++;
            } else {
                @otherlist[$othernum] = "$love<>$name";
                $othernum++;
            }
        }

そして、サブルーチンを呼び出すのですが、
これらを挿入する場所に注意してくださいね。
括弧が入り組んでいるので、分かりづらいかもしれませんが、
場所を間違えると、正常に動きませんので(^^;

ユーザーデータの読み込み(sub openinuserdata)の下の方に、
下記のように追加してください。

        if ($_[0] eq 'ownerlist') {
            if ($love >= $loved) {
                @lovelist[$lovenum] = "$love<>$name";
                $lovenum++;
                if ($bestlove < $love)
                    { $bestowner = "$name"; $bestlove = $love; }
            } elsif ($love <= $disliked) {
                @hatelist[$hatenum] = "$love<>$name";
                $hatenum++;
            } else {
                @otherlist[$othernum] = "$love<>$name";
                $othernum++;
            }
        }
    }
    if ($_[0] eq 'ownerlist') {
        &user_sort_r(@lovelist);
        @lovelist = @newtxt;

        &user_sort_r(@hatelist);
        @hatelist = @newtxt;

        &user_sort_r(@otherlist);
        @otherlist = @newtxt;
    }
}

# ------------------------- #
# Sub Open Out User Data
# ユーザーデータの書きこみ

&user_sort_r(@lovelist);で、先ほど作ったサブルーチンへ、
@lovelistを突っ込んで呼び出します。
並び替えられた新しいランキングリストが@newtxtに入ってくるので、
それを@lovelistにコピーします。
これを、各ランキングリスト分だけやればOK!
ラブポイントの高い順に並び替わっているはずです。

では次に、新しくソートされたランキングリストを、
ランキング表示で表示できるようにしましょう。
飼い主ランキング(sub ownerlist)を下記のように変更してください。
そして、ランキング表示にラブポイントを表示したい場合は、
緑色の部分も含めてください。
ラブポイントの表示がいらない方は、緑の部分は書かないで下さい。

プレイヤーの明示の改造を行っている人は、
何人中第何位なのかを表示しようの【4】を合わせて参照してみてください。

# ------------------------- #
# Sub Owner List
# 飼い主ランキング
# ------------------------- #
sub ownerlist {
    &header;
    &title;
    $bestlove = $lovenum = $hatenum = $othernum = 0;
    &openinuserdata('ownerlist');

    &bodytop('飼い主ランキング');
    &tabletop;

    print "$font2$petnameが一番なついている人は</font><br>";
    if ($bestlove < $loved) { print "いません<br>\n";}
    else { print "$bestownerさんです<br>\n"; }
    print "<br>\n";

    print "$font2$petnameがなついている人は</font><br>";
    if ($lovenum == 0) { print "いません<br>"; }
#   else { foreach $owner (@lovelist)  { print "$ownerさん<br>\n"; } }
    else {
        foreach $owner (@lovelist) {
            ($love,$name) = split(/<>/,$owner);    # ←プレイヤーの明示をしている人はここ注意!
            print "$nameさん($loveポイント)<br>\n";
        }
    }
    print "<br>\n";

    print "$font2$petnameが嫌いな人は</font><br>";
    if ($hatenum == 0) { print "いません<br>";}
#   else { foreach $owner (@hatelist)  { print "$ownerさん<br>\n"; } }
    else {
        foreach $owner (@hatelist) {
            ($love,$name) = split(/<>/,$owner);    # ←プレイヤーの明示をしている人はここ注意!
            print "$nameさん($loveポイント)<br>\n";
        }
    }
    print "<br>\n";
    
    print "$font2それ以外の人</font><br>";
    if ($othernum == 0) { print "いません<br>"; }
#   else { foreach $owner (@otherlist) { print "$ownerさん<br>\n"; } }
    else {
        foreach $owner (@otherlist) {
            ($love,$name) = split(/<>/,$owner);    # ←プレイヤーの明示をしている人はここ注意!
            print "$nameさん($loveポイント)<br>\n";
        }
    }

    &tablebottom;
    &bodybottom;
    &footer;
}

これで完成です。
表示を凝りたい方は、オレンジの所のprint "〜";をいじって下さい。
$nameにお名前、$loveにラブポイントが入っています。