SORU
16 Kasım 2010, Salı


En iyi kod Başarıları için bir yol sistemi

En iyi şekilde sitemde kullanmak için başarıları bir sistem tasarımı için düşünüyorum. Veritabanı yapısı MySQL: Best way to tell 3 or more consecutive records missing bulunabilir ve bu konuyu gerçekten geliştiricilerin fikirlerini almak için bir uzantısıdır.

Bu web sitesinde rozetleri/başarı sistemi hakkında konuşmak bir sürü var bu sorun, tüm konuşma ve hiçbir kod -- sadece. Asıl kod örnekleri implemention?

Ben bir tasarım insanlar katkıda bulunur ve umarım genişletilebilir başarı sistemleri kodlama için iyi bir tasarım yaratabilir umarım burada öneriyorum. En iyisi bu o kadar demiyorum, ama olası bir başlangıç bloğu.

Lütfen fikirlerinizi katkıda bulunmak için çekinmeyin.


sistem tasarımı benim fikrim

Genel bir fikir birliği, bir "olay tabanlı sistem bilinen bir olay sonrası oluşturulan, silinmiş, vb . bunun gibi olay sınıfı çağırır olduğunda" -- oluşturmak için gibi görünüyor

$event->trigger('POST_CREATED', array('id' => 8));

Olay sınıfı sonra rozetleri "" bu olay için, o zaman 8 ** Bu dosya, bu sınıfın bir örneğini oluşturur: . ne dinlediğini öğrenirse

require '/badges/' . $file;
$badge = new $class;

O zaman varsayılan olay verileri trigger denilen zaman aldı çağırır;

$badge->default_event($data);

rozetleri

Bu gerçek sihir burada. her rozet eğer bir rozet verilir belirlemek için kendi sorgu/mantığı vardır. Her rozet örneğin bu biçimde yola çıktı

class Badge_Name extends Badge
{
 const _BADGE_500 = 'POST_500';
 const _BADGE_300 = 'POST_300';
 const _BADGE_100 = 'POST_100';

 function get_user_post_count()
 {
  $escaped_user_id = mysql_real_escape_string($this->user_id);

  $r = mysql_query("SELECT COUNT(*) FROM posts
                    WHERE userid='$escaped_user_id'");
  if ($row = mysql_fetch_row($r))
  {
   return $row[0];
  }
  return 0;
 }

 function default_event($data)
 {
  $post_count = $this->get_user_post_count();
  $this->try_award($post_count);
 }

 function try_award($post_count)
 {
  if ($post_count > 500)
  {
   $this->award(self::_BADGE_500);
  }
  else if ($post_count > 300)
  {
   $this->award(self::_BADGE_300);
  }
  else if ($post_count > 100)
  {
   $this->award(self::_BADGE_100);
  }

 }
}

13* *işlevi temelde kontrol eden 14* *uzun bir sınıftan eğer kullanıcı zaten o rozeti layık değilse, rozet db tablosunu güncelleştirmek olacak olup olmadığını görmek için geliyor. Rozet sınıfı ayrıca bir kullanıcı için tüm rozetleri almak ve dizi, vb rozetleri örneğin, kullanıcı profilinde görünür) iade ilgilenir

ne sistem önce zaten canlı bir site üzerinde uygulanan son durumu hakkında?

Ayrıca "" her karta eklenebilir bu işi sorgu. cron var Bunun nedeni rozet sistemi ilk uygulanan ve initilaised çok zaman, zaten kazanılmış olması gereken rozetleri henüz bu olay sistemidir çünkü layık değil çünkü. Yani bir CRON ödül için her rozet için talep edilmesi gereken bir şey. Örneğin yukarıdaki CRON işi gibi görünecektir:

class Badge_Name_Cron extends Badge_Name
{

 function cron_job()
 {
  $r = mysql_query('SELECT COUNT(*) as post_count, user_id FROM posts');

  while ($obj = mysql_fetch_object($r))
  {
   $this->user_id = $obj->user_id; //make sure we're operating on the right user

   $this->try_award($obj->post_count);
  }
 }

}

Yukarıdaki cron sınıfı ana rozeti sınıfını genişletir, yeniden kullanım mantığı try_award çalışabilir

Ben sebebini oluşturmak için özel bir sorgu bu olsa da yapabiliriz "taklit" önceki olaylar, yani gidip her kullanım sonrası ve tetikleyici olay sınıfı gibi $event->trigger() olurdu çok yavaş, özellikle için birçok nişanlar. Biz yerine getirilmiş bir sorgu oluşturun.

kullanıcı Ödülü ne olur? ödül hakkındadiğerkullanıcılar olaya dayalı

award fonksiyon Badge sınıfı her zaman ödül verilecektir user_id -- üzerinde hareket eder. Varsayılan rozeti layık kişi kim NEDEN olay oldu yani oturum kullanıcı kimliği (bu gerçek için default_event işlev, ancak CRON işi belli döngüler üzerinden tüm kullanıcıları ve ödülleri ayrı kullanıcılar)

Örneğin izin almak, zorluk kodlama kodlama kullanıcıların kendi giriş gönderin web sitesinde. Admin o zaman girişleri Hakimler ve tamamlandığında, mesajları görmek için meydan sayfası için sonuçlar. Bu durumda, POSTED_RESULTS bir olay denir.

İsterseniz ödül rozetleri için kullanıcılar için tüm girişleri gönderildi, diyelim ki, eğer onlar içinde sıralamada ilk 5, kullanmanız cron işi (her ne kadar çıplak aklında bu güncelleme tüm kullanıcılar için değil sadece itiraz sonuçları yayınlanmıştır

İsterseniz bir hedef daha özel bir alan güncelleme ile cron işi, bakalım varsa bir şekilde eklemek için filtreleme parametrelerini içine cron işi nesne, ve elde cron_job işlevi için kullanılır. Örneğin:

class Badge_Top5 extends Badge
{
   const _BADGE_NAME = 'top5';

   function try_award($position)
   {
     if ($position <= 5)
     {
       $this->award(self::_BADGE_NAME);
     }
   }
}

class Badge_Top5_Cron extends Badge_Top5
{
   function cron_job($challenge_id = 0)
   {
     $where = '';
     if ($challenge_id)
     {
       $escaped_challenge_id = mysql_real_escape_string($challenge_id);
       $where = "WHERE challenge_id = '$escaped_challenge_id'";
     }

     $r = mysql_query("SELECT position, user_id
                       FROM challenge_entries
                       $where");

    while ($obj = mysql_fetch_object($r))
   {
      $this->user_id = $obj->user_id; //award the correct user!
      $this->try_award($obj->position);
   }
}

Cron işlevi hala eğer parametre verilirse bile çalışır.

CEVAP
18 Kasım 2010, PERŞEMBE


Bir ödül sistemi bir kez belge odaklı veritabanı dediğiniz (bu oyuncular için bir çamur oldu) uygulanan ettik. Bazıları benim uygulama, PHP ve MySQL tercüme vurgulamaktadır:

  • Rozet ilgili her ayrıntıyı kullanıcı verileri saklanır. Eğer MySQL kullanıyorsanız, bu veri performans için veritabanı kullanıcı için bir kayıt olduğundan emin olurdum.

  • Soru her zaman kişinin kod verilen bir bayrak rozeti kodu tetikleyen bir şey yapar, örneğin ('') POST_MESSAGE. bayrak

  • Bir olay da bir sayaç, örneğin mesaj sayımını tetikleyebilir. ('') POST_MESSAGE. increase_count Burada bir kontrol edin (ya da bir kanca ile, ya da sadece bu yöntemde bir test olması) POST_MESSAGE sayısı ^ ise, onu alabilirsin . Bir rozet, örneğin ödül olmalıdır 300 sonra: ("300_POST"). bayrak

  • Bayrak yöntemi, kod rozetleri ödül koyarım. Eğer Bayrağı 300_POST gönderdi ise, örneğin, sonra rozet reward_badge("300_POST") çağrılmalıdır.

  • Bayrak yöntemi, aynı zamanda kullanıcıların önceki bayrakları mevcut olmalıdır. darısı başına derken kullanıcı var FİRST_COMMENT, FİRST_POST, FİRST_READ verin rozet("YENİ KULLANICI"), ve ne zaman sen almak 100_COMMENT, 100_POST, 300_READ edebilirsiniz grant rozet("EXPERİENCED_USER")

  • Bu bayraklar ve rozetler her bir şekilde saklanması gerekir. Bit bayrakları, olduğunu sandığın yerde bir şekilde kullanın. Eğer istediğiniz bu saklanabilir gerçekten verimli, sence onlara bit ve kullandığınız kod aşağıda: (Veya sadece kullanımı yalın dize "000000001111000" eğer istemiyorsan bu karmaşıklık.

$achievments = 0;
$bits = sprintf("2b", $achievements);

/* Set bit 10 */
$bits[10] = 1;

$achievements = bindec($bits);

print "Bits: $bits\n";
print "Achievements: $achievements\n";

/* Reload */

$bits = sprintf("2b", $achievments);

/* Set bit 5 */
$bits[5] = 1;

$achievements = bindec($bits);

print "Bits: $bits\n";
print "Achievements: $achievements\n";
  • Kullanıcı için bir belge saklamak güzel bir şekilde json kullanmak ve tek bir metin sütununda kullanıcıların veri depolamak için. Json_encode ve json_decode/veri depolamak ve almak için kullanın.

  • Bazı kullanıcılar izleme etkinliği için veri başka bir kullanıcı tarafından manipüle, madde üzerinde veri yapısı ekleyin ve sayaçlar orada da kullanın. Örneğin okuma sayısı. Ödül rozetleri için yukarıda açıklandığı gibi aynı tekniği kullanın, ancak güncelleştirme elbette sahip kullanıcılar yazıya gitmek gerekir. (Örneğin makale 1000 kere rozet okuyun).

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • H3Ctic (old channel)

    H3Ctic (old

    23 Mart 2011
  • Neil Cicierega

    Neil Ciciere

    22 Mart 2006
  • SVB International

    SVB Internat

    29 EKİM 2011