State Settings Dengan Bitwise Operation

Ok, a little confession.. I know minggu ini saya seharusnya melanjutkan bagian 3 dari seri  Blackberry Game Development Tutorial, hanya saja minggu ini saya masih relatif sibuk sehingga belum sempat menyelesaikan artikelnya (itu, dan karena ngejar ngabisin nonton The Big Bang Theory season 2 :P ). So instead, untuk minggu ini saya akan menulis mini-article tentang bitwise state setting sebagai gantinya. Teori ini sebenarnya bisa diaplikasikan ke berbagai macam programming language, namun karena Java adalah bahasa yang paling saya kuasai, maka sample-sample yang saya berikan akan saya tulis dengan Java juga. Okay, on to the topic..

Asumsikan kita dihadapkan pada problem berikut: Kita akan membuat sebuah game rock-paper-scissors. Pada model yang sederhana, rule-nya adalah sebagai berikut:

  • Rock beats scissors
  • Scissors beats paper
  • Paper beats rock
Untuk kasus ini, kita bisa membuat method sederhana untuk mengecek pemenang:
private static final int ROCK = 1;
private static final int PAPER = 2;
private static final int SCISSORS = 3;

public String checkWin(int myHand, int enemyHand) {
   //bila sama, maka seri
   if (enemyHand == myHand)
       return "It's a Tie!";
    switch(myHand) {
       case PAPER:
          if (enemyHand == ROCK)
              return "You Win!";
          break;
       case ROCK:
          if (enemyHand == SCISSORS)
              return "You Win!";
          break;
       case SCISSORS:
          if (enemyHand == PAPER)
              return "You Win!";
          break;
    }

    //pemain kalah
   return "You Lose!"
}

Namun bagaimana bila melakukan perhitungan yang lebih kompleks, seperti perbandingan elemen? Katakanlah kita memiliki sebuah kasus sbb: kita ingin membuat game seperti rock-paper-scissors, namun ketimbang menggunakan gunting, batu dan kertas kita ingin membuatnya lebih kompleks dengan menggunakan elemen-elemen seperti air, api dan tanah sebagai pembandingnya. Rule-nya adalah sebagai berikut:

  • Water defeats Fire
  • Fire defeats earth
  • Earth defeats Water
  • Wind defeats Earth and Fire, but loses to Water
  • Thunder defeats Earth, Wind and Water, but loses to Fire
(Note: bukan contoh yang paling realistis memang, but please bear with me :P )
Untuk kasus ini, kita bisa menyelesaikannya dengan menggunakan beberapa if-then-else statement, namun kita bisa membuatnya lebih sederhana dengan menggunakan bitwise operation. Sebelumnya, mari kita bahas beberapa bitwise operation yang bisa kita gunakan.

Joining States Using Bitwise OR

Here’s an interesting thing: kita bisa melakukan penggabungan beberapa state dengan menggunakan operator bitwise OR. Pertama, buat beberapa state; dengan cara membuat beberapa konstanta integer dengan nilai 2 pangkat n. Perhatikan sample berikut:
final int WATER = 2 << 0;
final int FIRE = 2 << 1;
final int EARTH = 2 << 3;
final int WIND = 2 << 4;
final int THUNDER = 2 << 5;
Untuk menggabung beberapa state jadi satu, gunakan operator bitwise OR (|).
int defeats= WIND|WATER|EARTH;

Checking For Value Using Bitwise AND

Untuk mengecek apakah nilai sebuah konstanta ada didalam state yg telah digabungkan dengan bitwise OR, kita bisa menggunakan operator bitwise AND (&). Bila nilai didapat tidak sama dengan 0, maka konstanta tersebut tidak terkandung dalam state. Perhatikan contoh di bawah:
int defeats= WIND|WATER|EARTH;

if ((defeats & FIRE) != 0)
   System.out.println("Fire");
if ((defeats & WIND) != 0)
   System.out.println("Wind");
Output dari code di atas adalah “Wind”, karena konstanta FIRE tidak dijoin ke dalam state parameter defeats.

Removing States Using Bitwise XOR

Untuk melepaskan sebuah konstanta dari state yg telah digabungkan, kita bisa menggunakan operator bitwise XOR(^). Perhatikan sample berikut:
int defeats= WIND|WATER|EARTH;

defeats = defeats ^ WIND; //remove konstanta WIND

if ((defeats & WIND) == 0)
   System.out.println("No Wind");

Hasil dari code snipped di atas adalah text “No Wind” akan dicetak, karena konstanta WIND telah diremove dari state parameter defeats.

Completing The Code

Berdasar pengetahuan kita tentang bitwise operation di atas, code untuk kasus di atas dapat kita sederhanakan seperti berikut:
final int WATER = 2 << 0;
final int FIRE = 2 << 1;
final int EARTH = 2 << 3;
final int WIND = 2 << 4;
final int THUNDER = << 5;

private int getDefeats(int hand) {
   int defeats = 0;
   switch (hand) {
        case WATER:
            defeats = FIRE|WIND;
        case FIRE:
            defeats = EARTH|THUNDER;
        case EARTH:
            defeats = WATER;
        case WIND:
            defeats = EARTH|FIRE;
        case THUNDER:
            defeats = EARTH|WIND|WATER;
   }
   return defeats;
}
private String checkWin(int myHand, int enemyHand) {
   if (enemyHand == myHand)
     return "It's a Tie!";
   int defeats = getDefeats(myHand);
   if ((defeats & enemyHand) != 0)
     return "You Win!"
   else
     return "You Lose!"
}

Bitwise operation dapat menjadi tools yang sangat berguna, khususnya untuk membuat code kita lebih compact dan sederhana.  Ada banyak implementasi dan teknik lain dalam penggunaan bitwise operation untuk app/game kita, namun secara pribadi, saya lebih sering menggunakannya untuk state settings karena cukup ringkas dan flexible. Feel free to look for more bitwise operation implementation out there, as this is just the simplest ones. Hope this has been helpful, minggu depan kita akan kembali ke tutorial Blackberry Game Development kita ;)

bhimz

BhimZ adalah seorang Mobile Development Manager di salah satu perusahaan swasta di Jakarta, membantu mengembangkan berbagai macam aplikasi mobile khususnya untuk platform smartphone. Bersama rekan-rekannya sesama hobbyist, BhimZ juga membentuk Pokkon Studio sebagai project after office dan memulai mengembangkan beberapa game baik web-based maupun mobile, beberapa di antaranya sedang dirilis untuk Blackberry AppWorld dan Android Market.

Notice: This work is licensed under a BY-NC-SA. Permalink: State Settings Dengan Bitwise Operation
  • Dennis Adriansyah Ganda

    agak masih kurang paham dengan operator bit buat ngecek kondisi ,,

    (defeats & FIRE) != 0

    ini maksudnya gmana? -_-a

    • bart

      (defeat & FIRE) != 0 maksudnya defeat di AND kan oleh FIRE(ane biasa nyebut di defeat difilter pake FIRE)
      *posted by bart yang asli*

      • aaulia

        Bitwise AND, bukan Logical AND

    • Anonymous

      Misal

      Water = 2 < 00010 = 2
      Fire = 2 < 00100 = 4
      Earth = 2 < 10000 = 16

      Wind defeats earth | fire > 00100 OR 10000 = 10100

      Nah jadi defeats untuk wind nilainya 10100 = 20 ( angka desimal ga bgt penting di sini)

  • http://twitter.com/AryadiPS Aryadi Subagio

    baru nyadar, nama penulis ga tampil ya? ato cuma di wa doang?

    • Artlogicgames

      iya di sini juga ga nongol authornya om

  • Fandrey

    Uwoo… Baru nyadar bisa diginiin… Manteb oom o_o

  • Anonymous

    Bitwise juga lebih cepat dan hardware friendly daripada if then else

  • Anonymous

    wogh mantab om artikelnya,
    btw jadi kepikiran pake array untuk “defeats” yang dynamic
    (bisa ditambah pas runtime)

Stop SOPA