Trophäensystem, wie realisieren?

String

Erfahrenes Mitglied
Hallo zusammen,

wie würdet ihr / wie ist es am besten, eine Art Trophäensystem zu realisieren.

Also nehmen wir an ich habe eine kleine Community, bei der die User sich beteiligen können. Beiträge, Umfragen, Pages erstellen usw.

Wenn ich jetzt dem User eine Belohnung dafür geben wollen würde, dass er 100.000 Seitenaufrufe getätigt hat, kann ich das dann wirklich nur indem ich jedes mal prüfe, ob er jetzt über 100.000 Seitenaufrufe liegt und dann prüfen, ob er diese "Trophäe" schoneinmal erhalten hat.

Ich meine, unterhalb der 100.000 ist das jedes mal nur eine einfach abfage ala "if($aufrufe>100000)" aber wenn der dann größer ist, wird das immer mehr, if($aufrufe>100000) { if($schonerhalten==true) {} }

Oder geht das evt. ein bisschen einfacher und ich komm einfach nicht drauf?

string
 
Grüße zum Abend,

als Stichwort würde ich hier mal eben Modulo-Operator in den Raum werfen...
Du checkst einfach, ob seine momentanen Aufrufe modulo 100.000 (Ergebnis abgerundet) 1, 2, 3, 4...
ergibt. Das geht natürlich nur, sofern du das immer in 100.000er Schritten machen möchtest.
Wenn du dann beispielsweise 3 rausbekommst, kannst du sicher sein, dass der Nutzer schon 1 und 2 erhalten hat....

Hoffe der kleine Denkanstoss hat dir was gebracht...
und noch einen schönen Abend.
 
Schau dir mal das Chain of Responsibility Pattern an. Du könntest z.B. ein Objekt übergeben, was die relevanten Daten für die Trophäen enthält, z.B. Seitenaufrufe und Beiträge. Dann übergibst du dieses an die Chain und diese durchläuft sich dann automatisch und gibt dir die entsprechenden Trophäen zurück.
 
Okay, aber am prinzip (egal, ob Objekte in Form von CoR Pattern) bei JEDEM seitenaufruf zu prüfen ob er die 100.000 Seitenaufrufe hat und ob er dann schon die trophäe bekommen hat, ändert sich nichts, sehe ich das richtig?

Mir gehts halt jedesmal darum, dass es mindestens ein Datenbank-Aufruf mehr ist, um zu prüfen ob er die Trophäe schon erhalten hat..

paD
 
Hab mal ein Beispiel mit Objekt und Session gemacht.
Das beinhaltet die folgenden DB-Aufrufe:
- Laden der User-Infos(beim ersten Zugriff unter der Session)
- Speichern der Klicks und ggf der Trophäe (bei jedem Seitenaufruf)

PHP:
<?php 
//Die Klasse muss vor dem session_start() definiert werden!

/**
 * User-Klasse
 * @sql     Zugrundeliegende Tabelle
 * CREATE TABLE `user` (
 *   `user_id` INT(10) NULL DEFAULT NULL,
 *   `username` VARCHAR(50) NULL DEFAULT NULL,
 *   `clicks` INT(10) NULL,
 *   `click_trophy` INT(10) NULL,
 * INDEX `idx_user_user_id` (`user_id`));
 * INSERT INTO `user` (`user_id`, `username`, `clicks`, `click_trophy`) VALUES (1, 'testuser', 0, 0);
 * INSERT INTO `user` (`user_id`, `username`, `clicks`, `click_trophy`) VALUES (2, 'usertest', 0, 0);
 */
class User{
    /**
     * Liste der Trophäen-Werte für die Clicks
     * @var Array<int> $click_trophies
     */
    private static $click_trophies = array(2,5,10,20,50);
    /**
     * Flag ob ein Log mittels Echo asugegeben wird
     * @var Boolean $log
     */
    private $log = false;
    
    /**
     * Konstrukteur: Lädt die user-Daten aus der Datenbank
     * @param Int $id       Id des Users
     * @param Boolean $log  Angabe ob ein Log fürs SQL mitausgegeben werden soll
     */
    public function __construct($id, $log = false){
        $this->log = $log;
        $sql = 'SELECT * FROM user WHERE user_id = '.mysql_escape_string($id);       
        if($this->log) echo "Laden der User-Daten zu User {$id}: {$sql}<br/>";
        $result = mysql_query($sql);
        //TODO: Prüfung ob der User gefunden wurde
        $row = mysql_fetch_object($result);
        $this->id = $id;
        $this->username = $row->username;
        $this->clicks = $row->clicks;
        $this->click_trophy = $row->click_trophy;
    }
    
    /**
     * ein Klick dazuzähen
     * @return int  Aktuelle Klick-Zahl
     */
    public function click(){
        $this->clicks++;
        $sets[] = "clicks={$this->clicks}";
        $click_trophy = self::getTrophy(self::$click_trophies, $this->clicks); 
        if($click_trophy != $this->click_trophy){
            $this->click_trophy = $click_trophy;
            $sets[] = "click_trophy={$click_trophy}";
        }
        $setsS = implode(',', $sets); 
        $sql = "UPDATE user SET {$setsS} WHERE user_id={$this->id}";
        if($this->log) echo "Speichern der Klicks: {$sql}<br/>";        
        mysql_query($sql);
        return $this->clicks;
    }
    
    /**
     * Ermitteln der aktuellen Trophäe
     * @param Array<int> $trophies  Liste der Trophäen-Werte
     * @param int $value            Aktueller Wert
     * @static
     */
    protected static function getTrophy($trophies, $value){
        foreach($trophies as $trophy){
            if      ($trophy<=$value)   $act_trophy = $trophy;
            else    break;
        }       
        return $act_trophy;
    }
    
}

/**
 * Ausführender Code
 */

//normaler mysql-DB-Connect
include_once('connect.php');


//Testwert für die User-ID
$user_id = 2;

//Starten der Session
session_start();
//Falls das Objekt myUser noch nicht in der Session besteht oder die User-ID unterschiedlich sind
//eine neue Instanz der Klasse User erstellen
if(!isset($_SESSION['myUser']) || $_SESSION['myUser']->id != $user_id){
    $_SESSION['myUser'] = new User($user_id, true); 
}

//Ein Klick hinzufügen
echo 'Klicks:'.$_SESSION['myUser']->click().'<br />';
//Die aktuelle Klick-Trophy abrufen
echo "Trophäe:{$_SESSION['myUser']->click_trophy}<br />";
?>
 
Na dafür bedank ich mich doch mal gleich.
Ist ne nette Idee, dass so zu machen.

Allerdings wird das bei einigen Trophäen auch ne menge arbeit. Vielleicht wäre es dann sinvoll auch eine Trophäen klasse für jeden User an zu legen.

Hälst du / ihr eine Cronjob-Lösung für angebracht? Also dass einfach mal jede Stunde danach geschaut wird, welcher User was verdient haben könnte?

paD
 
Zurück