Membuat Permainan Congklak dengan Bahasa C (Bagian 2)

Tulisan ini merupakan kelanjutan dari tutorial membuat permainan congklak dengan bahasa C.

Pada bagian 1 kita sudah membuat program dasar congklak dan melakukan simulasi pergerakan biji-bijian pada papan congklak. Sekarang kita akan melanjutkan dengan mengimplementasi alur permainan congklak.

Menerima input dari pemain

Sepanjang permainan, pada dasarnya hanya ada dua jenis input yang diterima dari pemain, yaitu memilih salah satu dari tujuh lubang di bawah untuk pemain 1, atau memilih salah satu dari tujuh lubang di atas untuk pemain 2.

/**
 * Meminta pemain memilih lubang A..G dan mengembalikan indeks lubang 
 * yang dipilih.
 * 
 * @param pemain Nomor urut pemain
 * @return Indeks lubang yang dipilih
 */
int pilih_lubang(int pemain) {
  char input;
  int index;
  
  // Minta input dari pemain dan lakukan validasi
  do {
    printf("Pilih lubang [A..G] ");
    input = getchar();
    flush_input();
  } while (tolower(input) < 'a' || tolower(input) > 'g');
  
  // Pemetaan input huruf menjadi indeks sesuai nomor pemain
  // Huruf   : A   B   C   D   E   F   G
  // Pemain 1: 0   1   2   3   4   5   6
  // Pemain 2: 14  13  12  11  10  9   8
  if (pemain == 1) {
    index = input - 'a';
  } else {
    index = 14 - (input - 'a');
  }
  
  // Jika lubang yang dipilih kosong, ulangi permintaan input
  if (lubang[index] == 0) {
    return pilih_lubang(pemain);
  } else {
    return index;
  }
}

Fungsi ini akan meminta input berupa nama lubang (A..G), dan mengembalikan indeks lubang yang dipilih.

Huruf “a” memiliki nilai charcode 97, “b” bernilai 98, dan seterusnya. Karena itu kita bisa merumuskan indeks lubang untuk pemain 1 menjadi index = input - 97

Untuk pemain 2, urutannya berkebalikan dimulai dari angka 14 menurun. Jadi kita gunakan rumus index = 14 - (input - 97)

Ada kalanya pemain memilih lubang yang sudah kosong. Jika seperti itu, kita ulangi permintaan input dengan memanggil kembali fungsi pilih_lubang().

int main(int argc, char **argv)
{
  // Nomor urut giliran pemain, dimulai dari pemain 1
  int pemain = 1;

  reset_papan();
  cetak_papan();
  printf("GILIRAN PEMAIN #%d\n", pemain);
  pilih_lubang(pemain);
  return 0;
}

Kontrol alur permainan

Secara garis besar, alur permainan berlangsung seperti ini:

  1. Pemain 1 memilih lubang (pilih_lubang())
  2. Lakukan distribusi biji (distribusi_biji())
  3. Periksa di mana biji terakhir diletakkan
    • Jika berakhir di rumah (lubang besar) pemain, pemain kembali mendapat giliran memilih lubang dan mendistribusikan.
    • Jika berakhir di lumbung (lubang kecil) dan tidak kosong, pemain kembali mendapat giliran mendistribusikan dari lubang terakhir (langsung ke tahap 2).
    • Jika berakhir di lubang kosong sisi pemain, ambil biji terakhir serta semua biji di lubang seberangnya untuk dimasukkan ke rumah milik pemain. Kemudian giliran beralih ke pemain berikutnya.
    • Jika berakhir di lubang kosong sisi lawan, giliran beralih ke pemain berikutnya.
  4. Periksa apakah permainan sudah selesai, jika belum selesai, kembali ke tahap 1
  5. Setelah permainan selesai, gabungkan semua biji di lubang pemain ke rumah miliknya

Mari kita terjemahkan pseudocode di atas menjadi kode program di bahasa C.

/**
 * Kontrol alur permainan. Fungsi ini akan berputar terus menerus hingga 
 * permainan selesai.
 */
void alur_permainan() {
  int pemain = 1;
  int index = -1;
  
  // Kontrol alur permainan
  do {
    cetak_papan();
    
    // Minta input dari pemain
    // index -1 berarti lubang belum dipilih.
    if (index == -1) {
      printf("GILIRAN PEMAIN #%d\n", pemain);
      index = pilih_lubang(pemain);
    }
  
    // Lakukan distribusi biji
    index = distribusi_biji(index, pemain);
    
    // Jika berakhir di rumah pemain, pemain kembali mendapat 
    // giliran memilih lubang dan mendistribusikan.
    if (index == 7 || index == 15) {
      // Reset index agar pemain bisa memilih kembali
      index = -1;
    }
    
    // Jika berakhir di lubang kecil dan tidak kosong, pemain kembali 
    // mendapat giliran mendistribusikan dari lubang terakhir
    // Lubang kosong akan berisi 1 biji karena ditaruh biji terakhir.
    else if (lubang[index] > 1) {
      // Tidak perlu mereset index
    }
    
    // Jika berakhir di lubang kosong
    else {
      // Jika berakhir di sisi milik pemain, pindahkan biji 
      // di lubang terakhir, juga seluruh biji di lubang seberangnya.
      
      // Pengecekan untuk pemain 1
      if ((pemain == 1) && (index >= 0) && (index <= 6)) {
        menembak_biji(index, pemain);
        menembak_biji(14 - index, pemain);
      }
      // Pengecekan untuk pemain 2
      else if ((pemain == 2) && (index >= 8) && (index <= 14)) {
        menembak_biji(index, pemain);
        menembak_biji(14 - index, pemain);
      }
      
      // Ganti giliran pemain
      index = -1;
      pemain = (pemain % 2) + 1;
    }
  } while (cek_permainan_selesai() == 0);
  
  // Jika permainan selesai, gabungkan semua biji di lubang sisi pemain 
  // ke rumah miliknya
  for (int i = 0; i <= 6; i++) {
    lubang[7] += lubang[i];
    lubang[i] = 0;
  }
  for (int i = 8; i <= 14; i++) {
    lubang[15] += lubang[i];
    lubang[i] = 0;
  }
  
  cetak_papan();
}

Mengecek apakah permainan sudah selesai

Permainan akan selesai jika seluruh lubang pada salah satu sisi sudah kosong. Berikut ini kode untuk fungsi cek_permainan_selesai().

/**
 * Periksa apakah permainan sudah tidak dapat dilanjutkan karena seluruh 
 * lubang di salah satu sisi pemain sudah kosong.
 */
int cek_permainan_selesai() {
  // Pengecekan sisi pemain 1
  int selesai = 1;
  for (int i = 0; i <= 6; i++) {
    if (lubang[i] > 0) {
      selesai = 0;
      break;
    }
  }
  
  // Jika sisi pemain 1 masih terisi, coba cek sisi pemain 2
  if (selesai == 0) {
    selesai = 1;
    for (int i = 8; i <= 14; i++) {
      if (lubang[i] > 0) {
        selesai = 0;
        break;
      }
    }
  }
  
  return selesai;
}

Coba jalankan program dengan mengubah isi fungsi main() menjadi sbb.

int main(int argc, char **argv)
{
  reset_papan();
  alur_permainan();
  return 0;
}

Menentukan pemenang

Setelah permainan selesai, tentukan pemenangnya dengan melihat jumlah biji terbanyak. Permainan berakhir setelah pemenang diumumkan.

int main(int argc, char **argv)
{
  reset_papan();
  alur_permainan();
  
  // Tentukan pemenangnya
  if (lubang[7] > lubang[15]) {
    printf("PEMAIN 1 MENANG\n");
  }
  else if (lubang[15] > lubang[7]) {
    printf("PEMAIN 2 MENANG\n");
  }
  else {
    printf("SERI\n");
  }
  getchar();
  return 0;
}

Selesai! Program congklak dengan bahasa C sudah dapat dimainkan.

Babak selanjutnya

Penentuan pemenang ini berdasarkan permainan satu babak saja. Pada permainan congklak di beberapa daerah, ada juga yang menerapkan aturan main yang lebih menantang dengan lebih dari satu babak, di mana lumbung-lumbung bisa hangus terbakar. Permainan baru akan selesai dan pemenangnya didapat jika seluruh lumbung lawan telah terbakar.

Tutorial lanjutan mengenai permainan congklak dengan sistem banyak babak dan lumbung terbakar akan dibahas pada bagian selanjutnya.

Unduh kode program di sini.

2 komentar untuk “Membuat Permainan Congklak dengan Bahasa C (Bagian 2)”

  1. Pingback: Membuat Permainan Congklak dengan Bahasa C (Bagian 3) – Meramu Koding

  2. Pingback: Membuat Permainan Congklak dengan Bahasa C (Bagian 1) – Meramu Koding

Tulis Komentar