Algoritma Facemash (bagian 3)

Warning: Sebelum membaca post ini, anda diharapkan mengerti terlebih dahulu tentang bahasa pemrograman PHP, MYSQL, dan HTML. Serta anda diharapkan mengerti cara mengkoneksikan website anda dengan server yang anda pakai.

Sesuai janji saya di bagian kedua, di bagian ketiga ini saya akan membahas tentang pembuatan website Facemash secara keseluruhan. Jika anda belum membaca bagian satu dan bagian dua sebaiknya anda membaca terlebih dahulu, karena pada bagian ini saya akan membahas hal-hal yang menyangkut teknis saja. Segala penjelasan tentang teori dan hal-hal yang berkaitan dengan Elo Rating System telah dijelaskan di bagian pertama dan kedua.

Baiklah saya akan sedikit berbaik hati, bagi anda yang malas membaca bagian satu dan dua, saya akan mereviewnya sedikit. Apa itu Facemash? Pernah menonton film The Social Network, disana Mark (Facebook founder) dalam ceritanya membuat website untuk memilih diantara dua gambar wanita, mana dari dua gambar wanita tersebut yang dirasa paling HOT. Ke-HOT-an tersebut kemudian diurutkan berdasarkan rating. Rating tersebut didapat dari dari banyaknya dia menang, kalah dan mungkin seri yang merupakan hasil dari pemilihan gambar sebelumnya. Di post bagian satu dan dua, saya telah menjelaskan bagaimana cara me-rating yang digunakan Mark yaitu menggunakan Elo Rating System beserta algoritmanya. Pada bagian ini, akan dijelaskan secara step-by-step pembuatan website Facemash tiruannya.

Anda bisa melihat demo dari Facemash tiruan yang saya buat ini. Lihat Demo.

Pertama-tama yang anda perlukan adalah konfigurasi dengan server yang anda pakai, untuk itu anda memerlukan module yang mengkoneksikan website anda,

$dbhost="localhost";
$dbuser="DATABASE_USERNAME";
$dbpass="DATABASE_PASSWORD";
$dbname="DATABASE_PASSWORD";

$link = mysql_connect($dbhost, $dbuser, $dbpass);
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbname);

Ubah nilai $dbhost, $dbuser, $dbpass. $dbname, sesuai dengan konfigurasi server anda. Kemudian save file tersebut dengan nama module-config.php.

Setelah membuat modul konfigurasi, yang anda perlukan adalah mengikutsertakan modul tersebut ke file utama, dengan cara:

include("module-config.php");
include("elofunction.php");

dengan elofunction.php adalah modul yang telah kita buat di post bagian kedua.

Karena dalam pembuatan website Facemash memerlukan foto, anggaplah kita memiliki foto-foto yang diperlukan yang disimpan dalam folder bernama img. Di dalam folder tersebut, misalkan kita isikan dengan tes1.jpg, tes2.jpg sampai tes8.jpg yang merupakan file foto yang berformat jpg (anda bisa memilih foto siapapun teman anda, kemudian me-rename nya menjadi tes1.jpg sampai tes8.jpg). Karena asumsi disini kita memiliki delapan foto, maka kita memiliki delapan korban yang bisa di vote. Untuk memunculkan foto tersebut secara random, kita buat fungsi di php yaitu:

$a=1;
$b=1;

while($a==$b) {
	$a=rand(1,8);
	$b=rand(1,8);
}

yang berarti kita telah mendapatkan nilai $a dan $b secara acak namun nilainya tidak pernah sama.

Apalagi variabel yang kita perlukan sebelum memunculkan website? Pastinya kita membutuhkan nama korban yang akan di vote. Kita akan ambil nama korban tersebut dari database MySQL (databse MySQL tersebut akan kita buat kemudian), dengan cara:

$query="SELECT * FROM victim_members ORDER BY id";
$perintah=mysql_query($query);
while($d=mysql_fetch_array($perintah)){
	if($d['id']==$a) {
		$namaPlayerA = $d['nama'];
	}
	if($d['id']==$b) {
		$namaPlayerB = $d['nama'];
	}
}

yang berarti kita telah mendapatkan nama korban dan disimpan ke dalam variabel $namaPlayerA dan $namaPlayerB.

Dari penjelasan diatas, kita telah dapatkan 2 korban yang akan di vote. Tapi kita belum memiliki data apapun tentang dua korban tersebut. Data tentang dua korban tersebut kita ambil dari database MySQL (yang akan dijelaskan kemudian), data yang kita ambil meliputi nilai point korban A dan korban B, berapa kali A dan B ikut bertanding (di vote), berapa kali A dan B menang, seri dan kalah. Semua data tersebut kita ambl dengan cara:

if(isset($_POST['SKotak1']) or isset($_POST['SKotak2']) or isset($_POST['SKotak3'])) {
	$query="SELECT * FROM victim_members ORDER BY id";
	$perintah=mysql_query($query);
	while($d=mysql_fetch_array($perintah)){
		if($d['id']==$_POST['kotak1']) {
			$ELOplayerA = $d['EloPoint'];
			$P1 = $d['P'];
			$W1 = $d['W'];
			$D1 = $d['D'];
			$L1 = $d['L'];
		}
		if($d['id']==$_POST['kotak2']) {
			$ELOplayerB = $d['EloPoint'];
			$P2 = $d['P'];
			$W2 = $d['W'];
			$D2 = $d['D'];
			$L2 = $d['L'];
		}
	}
}

dengan isset SKotak1 or SKotak2 or SKotak3 menandakan jika vote tengah berlangsung. Nilai point korban A disimpan dalam variabel $ELOplayerA, banyaknya pertandingan disimpan di variabel $P1, menang-kalah-seri berturut turut disimpan pada variabel $W1, $D1, dan $L1. Begitu juga dengan korban B.

Data tentang kedua korban sudah kita dapatkan, kemudian baru kita proses dengan cara:

if(isset($_POST['SKotak1'])) {
	$ekspektasiA = Ekspektasi($ELOplayerA, $ELOplayerB);
	$ekspektasiB = 1-$ekspektasiA;
	$ELOplayerA = $ELOplayerA + EloRating($ELOplayerA, 1, $ekspektasiA);
	$ELOplayerB = $ELOplayerB + EloRating($ELOplayerB, 0, $ekspektasiB);
	if($ELOplayerA < 0) { $ELOplayerA = 0; }
	if($ELOplayerB < 0) { $ELOplayerB = 0; }
	$P1++;$W1++;$P2++;$L2++;
	$kueri="UPDATE victim_members SET EloPoint='".$ELOplayerA."',
	P='".$P1."', W='".$W1."' WHERE id='".$_POST['kotak1']."'";
	$kueri2="UPDATE victim_members SET EloPoint='".$ELOplayerB."',
	P='".$P2."', L='".$L2."' WHERE id='".$_POST['kotak2']."'";
	$perintah=mysql_query($kueri);
	$perintah=mysql_query($kueri2);
}else if(isset($_POST['SKotak2'])) {
	$ekspektasiA = Ekspektasi($ELOplayerA, $ELOplayerB);
	$ekspektasiB = 1-$ekspektasiA;
	$ELOplayerA = $ELOplayerA + EloRating($ELOplayerA, 0, $ekspektasiA);
	$ELOplayerB = $ELOplayerB + EloRating($ELOplayerB, 1, $ekspektasiB);
	if($ELOplayerA < 0) { $ELOplayerA = 0; }
	if($ELOplayerB < 0) { $ELOplayerB = 0; }
	$P1++;$L1++;$P2++;$W2++;
	$kueri="UPDATE victim_members SET EloPoint='".$ELOplayerA."',
	P='".$P1."', L='".$L1."' WHERE id='".$_POST['kotak1']."'";
	$kueri2="UPDATE victim_members SET EloPoint='".$ELOplayerB."',
	P='".$P2."', W='".$W2."' WHERE id='".$_POST['kotak2']."'";
	$perintah=mysql_query($kueri);
	$perintah=mysql_query($kueri2);
}else if(isset($_POST['SKotak3'])) {
	$ekspektasiA = Ekspektasi($ELOplayerA, $ELOplayerB);
	$ekspektasiB = 1-$ekspektasiA;
	$ELOplayerA = $ELOplayerA + EloRating($ELOplayerA, 0.5, $ekspektasiA);
	$ELOplayerB = $ELOplayerB + EloRating($ELOplayerB, 0.5, $ekspektasiB);
	if($ELOplayerA < 0) { $ELOplayerA = 0; }
	if($ELOplayerB < 0) { $ELOplayerB = 0; }
	$P1++;$D1++;$P2++;$D2++;
	$kueri="UPDATE victim_members SET EloPoint='".$ELOplayerA."',
	P='".$P1."', D='".$D1."' WHERE id='".$_POST['kotak1']."'";
	$kueri2="UPDATE victim_members SET EloPoint='".$ELOplayerB."',
	P='".$P2."', D='".$D2."' WHERE id='".$_POST['kotak2']."'";
	$perintah=mysql_query($kueri);
	$perintah=mysql_query($kueri2);
}

isset SKotak1 menandakan bahwa si korban A dipilih / menang dalam vote tersebut kemudian diproses sebagaimana mestinya korban A menang, begitu pula dengan isset SKotak2 yang menandakan si korban B lah yang memenangkan vote tersebut. isset SKotak3 menyatakan bahwa kedua-duanya tidak dipilih dan mereka dinyatakan seri.

Fungsi PHP sudah selesai, sekarang yang belum terbuat adalah form HTML untuk menampilkannya dalam browser, secara sederhana saya membuatnya seperti ini:

FACEMASH tiruan
Which one from this two pics suit you (almost your type)! Choose by clicking the photo or click "They are not my type!" if not any of them.

Untuk menampilkan hasil vote tersebut, anda hanya perlu membuat satu file php baru dan menuliskan codenya seperti berikut:

include("module-config.php");

$i=1;
$query="SELECT * FROM victim_members ORDER BY EloPoint DESC";
$perintah=mysql_query($query);
while($d=mysql_fetch_array($perintah)){

echo '
'; echo $i++.'. '.$d['nama'].''; echo $d['nama']; echo ', Point: '.$d['EloPoint'].''; echo '
'; }

Untuk database MySQL yang saya gunakan, memiliki struktur seperti dibawah ini:

CREATE TABLE `victim_members` (
	`id` int(11) auto_increment,
	`nama` varchar(100) NOT NULL,
	`URLfoto` longtext NOT NULL,
	`EloPoint` float NOT NULL,
	`P` int(11) NOT NULL,
	`W` int(11) NOT NULL,
	`D` int(11) NOT NULL,
	`L` int(11) NOT NULL,
	PRIMARY KEY (`id`)
) TYPE=MyISAM;

Mungkin segitu aja penjelasan saya tentang bagaimana membuat website Facemash tiruan ini. Jika ada pertanyaan, tuliskan di kolom komentar di bawah. Anda bisa melihat demo dari website Facemash tiruan ini DISINI, dengan source program DISINI (pass: hotswaps.blogspot.com). Sekian dari saya, terima kasih telah membaca tulisan ini hingga bagian 3.

PS: diperbolehkan mengcopy-paste tulisan ini, namun hargai penulis dengan menyertakan sumbernya: http://hotswaps.blogspot.com.

Wass.

Referensi:
http://en.wikipedia.org/wiki/Elo_rating_system
http://www.glicko.net/
Paper “Elo-rating as a tool in the sequential estimation of dominance strengths” oleh PAUL C. H. ALBERS & HAN DE VRIES, Utrecht University
Paper “Rating The Chess Rating System” oleh Mark E. Glickman & Albyn C. Jones, Boston University

Algoritma Facemash (bag. 2)

Oke kawan-kawan pembaca, melanjutkan dari bagian pertama, sekarang udah pada tau kan gimana Elo Rating System itu? Kalo yang masih belum tau, baca di postingan sebelumnya di bagian 1. Nah sekarang gimana cara menggunakan Elo Rating itu? Ini sedikit ilustrasinya,

Misal si pemain A yang punya poin 1900 tanding lawan pemain B yang poinnya baru 1700. Tentunya dugaan awal kita adalah si A lebih jago karena punya poin lebih tinggi. Nah, dugaan awal itulah yang nantinya menjadi harapan/ekspektasi dari si A terhadap si B. Nilai ekspektasi itu dihitung berdasarkan rumus sebelumnya dengan Ra = 1900 dan Rb = 1700, didapat:

Qa = 56234.132
Qb = 17782.794
maka,
Ea = Qa/(Qa + Qb) = 0.76
Eb = 1-Ea = 0.24

Untuk nilai faktor-K, asumsikan kita menggunakan aturan USCF. Karena poin si A maunpun B di bawah 2100, faktor K yang digunakan adalah K = 32, sehingga:

Ra’ = 1900 + K(Sa – Ea)
Ra’ = 1900 + 32(Sa – 0.76)

Nilai Ra’ adalah nilai poin yang baru setelah melakukan permainan. Nilai Sa bergantung dari pemain A, apakah menang, kalah atau seri. Sekarang kita tinjau kedalam tiga kasus, kasus pertama seandainya si A menang dan si B kalah, kasus kedua seandainya si A kalah dan si B menang, kasus ketiga seandainya si A dan si B seri.

Kasus pertama: Si A menang dan Si B kalah (Sa = 1 dan Sb = 0)

Ra’ = 1900 + 32(1-0.76)
Ra’ = 1907.68

Rb’ = 1700 + 32(0-0.24)
Rb’ = 1692.32

yang kemudian nilai Ra’ menjadi nilai poin Ra dan Rb’ menjadi nilai poin Rb. Terlihat pemain A mencuri poin milik pemain B sebesar 7.68 karena pemain A telah memenangkan permainan.

Kasus kedua: Si A kalah dan Si B menang (Sa = 0 dan Sb = 1)

Ra’ = 1900 + 32(0-0.76)
Ra’ = 1875.68

Rb’ = 1700 + 32(1-0.24)
Rb’ = 1724.32

Terlihat pemain B mencuri poin yang lebih besar jika memenangkan pertandingan melawan pemain A yaitu 24.32 karena faktor dugaan awal atau ekpektasi A lebih dijagokan untuk menang dan ternyata pemain A kalah.

Kasus ketiga: Si A dan Si B seri (Sa = Sb = 0.5)

Ra’ = 1900 + 32(0.5-0.76)
Ra’ = 1891.68

Rb’ = 1700 + 32(0.5-0.24)
Rb’ = 1708.32

Terlihat pemain B tetap berhasil mencuri poin dari Pemain A walaupun hasil permainan berakhir seri. Hal ini dikarenakan perbandingan poin yang relatif jauh antara pemain A dan pemain B.

Algoritma sudah, lalu gimana cara nulisnya ke bahasa pemrograman? Ok saya akan kasih contoh penulisannya dalam bahasa pemrograman PHP. Penulisannya akan saya jadikan sebagai fungsi, jadi akan lebih mudah digunakan di program. Saya menggunakan versi USCF seperti contoh ilustrasi diatas. Here we are:

// Elo rating system engine based on USCF K-Factor
// Created by Ganjar Santoso

function Ekspektasi($Ra, $Rb) {
 $Qa = exp(($Ra/400)*log(10));
 $Qb = exp(($Rb/400)*log(10));
 $Eksp = $Qa/($Qa+$Qb);
 return $Eksp;
}

function EloRating($Ra, $Sa, $Ea) {
 if($Ra > 2400) {
  $elorate = $Ra + 16*($Sa - $Ea);
 }else if(($Ra = 2100)) {
  $elorate = $Ra + 24*($Sa - $Ea);
 }else{
  $elorate = $Ra + 32*($Sa - $Ea);
 }
 return $elorate;
}

Gimana cara menampilkannya di PHP, gampang aja. Kita ambil contoh kasus yang pertama dari ilustrasi yang udah dijelasin, yaitu pemain A menang dan pemain B kalah. Misal fungsi-fungsi diatas disave dengan nama file “elofunction.php”.

include("elofunction.php");

// Menghitung ekspektasi Ea dan Eb
$Ea = Ekspektasi(1900, 1700);
$Eb = 1-$Ea;

// Menghitung Elo Poin
$EloPoinA = EloRating(1900, 1, $Ea);
$EloPoinB = EloRating(1700, 0, $Eb);

// Menampilkan Elo Poin
echo "Poin pemain A : ".$EloPoinA."</br>";
echo "Poin pemain B : ".$EloPoinB;

Hasilnya kira-kira akan seperti ini:

Poin pemain A : 1907.68
Poin pemain B : 1692.32

Oke, algoritma dan code udah, yang belum apa? yang belum adalah silahkan dicoba! Apalagi ditambah database MySQL, jadilah Facemash beneran (bukan tiruan lagi! haha). Mungkin ini untuk yang hobi aja kali ya.

Overall, segitu dulu aja. Selamat mencoba kawan-kawan! Kalo ada waktu, rencananya mau buat bagian 3 untuk membahas codenya menggunakan MySQL, jadi fokus ngebahas websitenya secara keseluruhan, bukan teori-teori lagi yang cuma bikin pusing, haha.

PS: diperbolehkan mengcopy-paste tulisan ini, namun hargai penulis dengan menyertakan sumbernya: http://hotswaps.blogspot.com, http://hotswaps.wordpress.com.

Wass.

Referensi:

http://en.wikipedia.org/wiki/Elo_rating_system

http://www.glicko.net/

Paper “Elo-rating as a tool in the sequential estimation of dominance strengths” oleh PAUL C. H. ALBERS & HAN DE VRIES, Utrecht University
Paper “Rating The Chess Rating System” oleh Mark E. Glickman & Albyn C. Jones, Boston University

Follow

Get every new post delivered to your Inbox.