Selasa, 25 Juli 2017

Reviewing my demoscene in JS1k 2015

Untuk versi bahasa Indonesia dari entri ini, klik di sini.

It has been two years, since I know JS1k for first time. I have sent three times, until this year, 2017. This time, I'll discuss about what really happen in my demoscene and how it works.

This is the code:
for(_='er~";Z-1]Xp||W=[]V+1UA[S){QinP0<O14-p]Nstyle "+( Si] 1>h? ") 6<i%8? && ); else C(2 ":" =0; .push( function( 1>h  Sp document.createElement("t = able   for( if( >"+ +"</ === WOh  >i;i++) . .margP= >p)S8*h+7]+=S .Pn~HTML= .appendChild(  1>  j++;6<j  3, b T b Y T Y "autoZvar AV,RV,p=s=h=n=i=j=k=l=m (C= a,cQ a) 20 aQi j="ZkV; m="Z16 l="<td  =\'paddPg:9px;bord~:1px solid #000;background: i p? "cyan red #ff0 +(7>i O ?Zcursor:poPt~;\'onclick=\'C( iU)+ \' ;\' +( "rowspan=2><b b>  td> ,8>i?7>i?j+=l:m=l:k l R[0] k.rev~se().joP(" +m;R[1] j}   21 a)Os?(n=1, =(Oh 6 W 14 p?p+2:pU)%16]++,s--, 0),setTimeout( Q 1)},500)):(n=0,1< ] 7>p%8?C(pU): 2)),Y 0>h?"Reload for new game In hand: "+s+"<br/>  "Your AI\'s +" turnZ   22 aQ 1  ]Q  7> 7<p 15 N,SN   8<p 14> Op 6 pX+ U], X= U]=0} 0  7  15 W(h= 1:0  j=i 7 1 i=8; j 15 2  Oh) ;;) OSi=8+Date.now()%7]QC(iU break}}  23 a?(h=-1,al~t("You  1<c?"wP lose )):1>n (s= =aX, ]=0, 1)  { i 16 A  0:7  i 2 R T  r )  0)}})( ';g=/[^ -MRTY[-}]/.exec(_);)with(_.split(g))_=join(shift());eval(_)
Maybe you're confused with the code above. What is that?

Opening code pack

The code above is the code which has been packaged into small package that will be opened and run automatically. If you see the source code, actually, that is the code when you open the package.

Start to analyse code

// JS1K ENTRY
// Title: Dakon (Javanese Congkak)
// by Muhammad Rifqi Priyo Susanto
First, we make table for container and for information then assign them to some variables while being argument to a function.
b.appendChild(T=document.createElement("table"));
b.appendChild(Y=document.createElement("table"));
Set margin to be auto so that it is at the center of document. Only works for element with CSS display value is table, including table element.
T.style.margin=Y.style.margin="auto";
Variable initialisation, we can use global variable to store it.
var N=[], R=[],
 p=s=h=n=i=j=k=l=m=0;

Entering main function

Z is a main function to do a lot of things in this demo. Z function can do many things, which will explained one by one.
(Z=function(task,param){
  1. Preparing the game.
    Prepare value for each house. Also, prepare tr element for container described above.
    if(!task){
     for(i=0;i<16;i++)N.push(i%8>6?0:7);
     for(i=0;i<2;i++)R.push(T.appendChild(document.createElement("tr")));
     Z(20);
  2. Tell user about now's status, from this on, called "drawing".
    By using created tr element, fill with td elements which already filled with amount of seeds for each houses. If that house is being passed by player, choose another color.
    }else if(task===20){
     for(i=0,j="",k=[],m="";i<16;i++){
      // draw house
      l="<td style='padding:9px;border:1px solid #000;background:"+
       (i===p?(h<1?"cyan":"red"):"#ff0")+
       (i<7&&N[i]>0
        ?";cursor:pointer;'onclick='Z("+(i+1)+")'"
         :";'"
       )+
       (i%8>6?"rowspan=2><b>"+N[i]+"</b>":">"+N[i]+"</td>");
      i<8?i<7?j+=l:m=l:k.push(l);
     }
     R[0].innerHTML=k.reverse().join("")+m;
     R[1].innerHTML=j;
  3. Moves each step.
    }else if(task===21){
     // if there is a seed on hand, go
     if(s>0){
      // declare step activity
      n=1;
      // add 1 to next house
      // move pointer
      N[p=(
       h>0&&p===6 || h<1&&p===14 ?
        p+2:
         p+1
      )%16]++;
      // subtract seed amount on hand
      s--;
      // draw game
      Z(20);
      // set next step
      setTimeout(function(){Z(21)},500)
     // if there is no seed on hand
     }else{
      // stop step activity
      n=0;
      // if seed in pointed house
      // is more than one and
      // not a storehouse
      N[p]>1&&p%8<7?
       // next step
       Z(p+1):
      // else
       // run analyser
       Z(22)
     }
     // tell player
     // if game's over, add notification
     // to refresh for new game
     // if not, tell amount of seed on hand and whose turn is it
     Y.innerHTML=h<0?
      "Reload for new game":
       "In hand: "+s+"<br/>"+(h<1?"Your":"AI's")+" turn"
     ;
  4. Analysing game's condition and computer movement.
    Also will check for special condition, including another rules in game.
    }else if(task===22){
     if(N[p]===1){
      // shooting ("nembak")
      //  if seed amount in pointed house is 1 and the house across is
      //  one of enemy's house then add seed from was house shot to
      //  storehouse and set seed amount in house shot to zero
       if(h<1&&p<7 || h>0&&p>7&&p<15){
        N[h*8+7]+=N[14-p],
        N[14-p]=0
       }
      // bring ("mikul")
      //  if amount of seed in pointed house is 1 and that house is enemy's
      //  and there is seed in left and right houses (not storehouse) then
      //  add seed from those houses to storehouse and set amount of seed
      //  in those houses to zero
       if(h<1&&p>8&&p<14 || h>0&&p>0&&p<6){
        N[h*8+7]+=N[p-1]+N[p+1],
        N[p-1]=N[p+1]=0
       }
     }
     
     // draw game
     Z(20);
     // if pointer is not at storehouse,
     // change player
     !(h<1&&p===7 || h>0&&p===15) && (h=h<1?1:0);
     
     // check player's houses (except storehouse)
     for(i=0,j=0;i<7;i++)N[i]<1&&j++;
     // if all player's houses don't have seed,
     // computer wins!
     j>6&&Z(23,1);
    
     // check computer's houses (except storehouse)
     for(i=8,j=0;i<15;i++)N[i]<1&&j++;
     // if all computer's houses don't have seed,
     // player wins!
     j>6&&Z(23,2);
    
     // if this is computer's turn now
     if(h>0)
      // run
      // Artificial Intelligence
      // by using loop and random select
      for(;;){
       // if sample house is more than zero
       if(N[i=8+Date.now()%7]>0){
        // choose that house
        Z(i+1);
        break;
       }
      }
  5. When game's over.
    }else if(task===23){
     // not anyone's turn
     h=-1;
     // announce who's the winner
     alert("You "+(param>1?"win":"lose"));
  6. Choose house to move next.
    }else{
     // if activity step is NOT running,
     if(n<1)
     // set:
     // - seed amount on hand
     // - pointer
     // - seed amount on hand in pointed house to zero
     s=N[p=task-1],
     N[p]=0,
     // run step activity
     Z(21);
    }

Run this function automatically so that immediately prepare the game.
})();

Last words

Maybe that's what I can tell about how my code works. I remember how happy I was if I could save one byte.

Meninjau ulang demosceneku di JS1k 2015

For English version from this entry, click here.

Sudah dua tahun berlalu, sejak aku pertama kali mengenal JS1k. Aku sudah mengirim sebanyak tiga kali, hingga tahun ini, 2017. Kali ini, aku akan membahas tentang apa yang sebenarnya terjadi pada demosceneku ini dan bagaimana cara kerjanya.

Berikut kodenya:
for(_='er~&quot;;Z-1]Xp||W=[]V+1UA[S){QinP0&lt;O14-p]Nstyle &quot;+( Si] 1&gt;h? &quot;) 6&lt;i%8? &amp;&amp; ); else C(2 &quot;:&quot; =0; .push( function( 1&gt;h  Sp document.createElement(&quot;t = able   for( if( &gt;&quot;+ +&quot;&lt;/ === WOh  &gt;i;i++) . .margP= &gt;p)S8*h+7]+=S .Pn~HTML= .appendChild(  1&gt;  j++;6&lt;j  3, b T b Y T Y &quot;autoZvar AV,RV,p=s=h=n=i=j=k=l=m (C= a,cQ a) 20 aQi j=&quot;ZkV; m=&quot;Z16 l=&quot;&lt;td  =\'paddPg:9px;bord~:1px solid #000;background: i p? &quot;cyan red #ff0 +(7&gt;i O ?Zcursor:poPt~;\'onclick=\'C( iU)+ \' ;\' +( &quot;rowspan=2&gt;&lt;b b&gt;  td&gt; ,8&gt;i?7&gt;i?j+=l:m=l:k l R[0] k.rev~se().joP(&quot; +m;R[1] j}   21 a)Os?(n=1, =(Oh 6 W 14 p?p+2:pU)%16]++,s--, 0),setTimeout( Q 1)},500)):(n=0,1&lt; ] 7&gt;p%8?C(pU): 2)),Y 0&gt;h?&quot;Reload for new game In hand: &quot;+s+&quot;&lt;br/&gt;  &quot;Your AI\'s +&quot; turnZ   22 aQ 1  ]Q  7&gt; 7&lt;p 15 N,SN   8&lt;p 14&gt; Op 6 pX+ U], X= U]=0} 0  7  15 W(h= 1:0  j=i 7 1 i=8; j 15 2  Oh) ;;) OSi=8+Date.now()%7]QC(iU break}}  23 a?(h=-1,al~t(&quot;You  1&lt;c?&quot;wP lose )):1&gt;n (s= =aX, ]=0, 1)  { i 16 A  0:7  i 2 R T  r )  0)}})( ';g=/[^ -MRTY[-}]/.exec(_);)with(_.split(g))_=join(shift());eval(_)
Mungkin kalian bingung dengan kode di atas. Apa itu?

Membuka paket kode

Kode di atas adalah kode yang sudah dijadikan paket berukuran kecil yang nantinya akan dibuka dan berjalan otomatis. Jika kalian melihat sumber kodenya, sebenarnya kira-kira itu yang akan muncul saat dibuka paketnya.

Mulai menganalisis kode

// JS1K ENTRY
// Title: Dakon (Javanese Congkak)
// by Muhammad Rifqi Priyo Susanto
Pertama, kita buat tabel untuk wadah dan untuk informasi lalu menyimpannya ke suatu variabel sambil sebagai argumen ke suatu fungsi.
b.appendChild(T=document.createElement("table"));
b.appendChild(Y=document.createElement("table"));
Atur nilai margin menjadi auto sehingga tabel berada di tengah dokumen. Hanya berlaku untuk elemen dengan nilai CSS display adalah table, termasuk elemen table.
T.style.margin=Y.style.margin="auto";
Inisialisasi variabel, kita bisa gunakan variabel global untuk menyimpan variabelnya.
var N=[], R=[],
 p=s=h=n=i=j=k=l=m=0;

Masuk ke fungsi utama

Z adalah sebuah fungsi utama yang berperan banyak pada demo ini. Fungsi Z dapat melakukan berbagai hal, yang akan dibahas satu per satu.
(Z=function(task,param){
  1. Menyiapkan permainan.
    Siapkan nilai untuk masing-masing rumah. Siapkan juga elemen tr pada elemen table untuk wadah di atas.
    if(!task){
     for(i=0;i<16;i++)N.push(i%8>6?0:7);
     for(i=0;i<2;i++)R.push(T.appendChild(document.createElement("tr")));
     Z(20);
  2. Informasikan kepada pengguna tentang keadaan saat ini, selanjutnya disebut "menggambar".
    Dengan menggunakan elemen tr yang sudah dibuat, isi dengan elemen td yang sudah memiliki isi jumlah benih pada rumah-rumah yang ada. Jika rumah tersebut sedang dilewati pemain, gunakan warna yang berbeda.
    }else if(task===20){
     for(i=0,j="",k=[],m="";i<16;i++){
      // gambar lubang alias "rumah"
      l="<td style='padding:9px;border:1px solid #000;background:"+
       (i===p?(h<1?"cyan":"red"):"#ff0")+
       (i<7&&N[i]>0
        ?";cursor:pointer;'onclick='Z("+(i+1)+")'"
         :";'"
       )+
       (i%8>6?"rowspan=2><b>"+N[i]+"</b>":">"+N[i]+"</td>");
      i<8?i<7?j+=l:m=l:k.push(l);
     }
     R[0].innerHTML=k.reverse().join("")+m;
     R[1].innerHTML=j;
  3. Gerakan tiap langkah.
    }else if(task===21){
     // jika masih ada benih di tangan, jalan
     if(s>0){
      // deklarasikan aktivitas langkah
      n=1;
      // tambah 1 ke rumah selanjutnya
      // gerakkan penunjuk
      N[p=(
       h>0&&p===6 || h<1&&p===14 ?
        p+2:
         p+1
      )%16]++;
      // kurangi jumlah benih di tangan
      s--;
      // gambar permainan
      Z(20);
      // atur langkah selanjutnya
      setTimeout(function(){Z(21)},500)
     // jika tidak ada benih di tangan
     }else{
      // berhentikan aktivitas langkah
      n=0;
      // jika benih di rumah yang
      // ditunjuk lebih dari 1 dan
      // bukan lumbung
      N[p]>1&&p%8<7?
       // langkah selanjutnya
       Z(p+1):
      // else
       // jalankan penganalisis
       Z(22)
     }
     // beritahukan pemain
     // jika permainan sudah selesai, tambahkan pemberitahuan
     // untuk muat ulang untuk permainan baru
     // jika tidak, katakan jumlah benih di tangan dan giliran siapa sekarang
     Y.innerHTML=h<0?
      "Reload for new game":
       "In hand: "+s+"<br/>"+(h<1?"Your":"AI's")+" turn"
     ;
  4. Menganalisis keadaan permainan dan gerakan komputer.
    Juga akan dicek untuk keadaan spesial, termasuk aturan-aturan lain dalam bermain.
    }else if(task===22){
     if(N[p]===1){
      // "nembak"
      //  jika jumlah benih di rumah yang ditunjuk adalah 1 dan
      //  rumah yang di seberangnya adalah salah satu rumah musuh maka
      //  tambah benih dari rumah yang ditembak ke lumbung
      //  dan atur jumlah benih yang ada di rumah yang ditembak menjadi nol
       if(h<1&&p<7 || h>0&&p>7&&p<15){
        N[h*8+7]+=N[14-p],
        N[14-p]=0
       }
      // "mikul"
      //  jika jumlah benih dalam rumah yang ditunjuk adalah 1 dan
      //  rumah itu adalah milik musuh dan ada benih di rumah sebelahnya
      //  (bukan lumbung) maka tambahkan benih dari rumah sebelahnya ke lumbung
      //  dan atur jumlah benih di rumah sebelahnya menjadi nol
       if(h<1&&p>8&&p<14 || h>0&&p>0&&p<6){
        N[h*8+7]+=N[p-1]+N[p+1],
        N[p-1]=N[p+1]=0
       }
     }
     
     // gambar permainan
     Z(20);
     // jika penunjuk tidak berada di lumbung,
     // ganti pemain
     !(h<1&&p===7 || h>0&&p===15) && (h=h<1?1:0);
     
     // cek rumah-rumah pemain (kecuali lumbung)
     for(i=0,j=0;i<7;i++)N[i]<1&&j++;
     // jika semua rumah pemain tidak punya benih,
     // komputer menang!
     j>6&&Z(23,1);
    
     // cek rumah-rumah komputer (kecuali lumbung)
     for(i=8,j=0;i<15;i++)N[i]<1&&j++;
     // jika semua rumah komputer tidak punya benih,
     // pemain menang!
     j>6&&Z(23,2);
    
     // jika sekarang giliran komputer
     if(h>0)
      // jalankan
      // Kecerdasan Buatan
      // dengan menggunakan looping dan pemilihan acak
      for(;;){
       // jika rumah sampel lebih dari nol
       if(N[i=8+Date.now()%7]>0){
        // pilih rumah itu
        Z(i+1);
        break;
       }
      }
  5. Saat permainan selesai.
    }else if(task===23){
     // bukan giliran siapa-siapa
     h=-1;
     // beritahu siapa pemenangnya
     alert("You "+(param>1?"win":"lose"));
  6. Memilih rumah untuk bergerak selanjutnya.
    }else{
     // jika aktivitas langkah TIDAK berjalan,
     if(n<1)
     // atur:
     // - jumlah benih di tangan
     // - penunjuk
     // - jumlah benih di rumah yang dipilih ke nol
     s=N[p=task-1],
     N[p]=0,
     // jalankan aktivitas langkah
     Z(21);
    }

Jalankan otomatis fungsi ini sehingga langsung menyiapkan permainan.
})();

Kata Penutup

Mungkin hanya itu yang bisa kuceritakan tentang bagaimana kodeku bekerja. Aku teringat betapa senangnya jika berhasil menghemat satu bita.