Belajar Goroutine Dengan Permainan Korek Api Bernyanyi
***

Daftar Isi

Korek Bernyanyi

Halo, kali ini kita akan coba bermain permainan korek api bernyanyi, namun menggunakan coding. Pada permainan kali ini, kita akan menggunakan goroutine dan channel untuk penerapannya.

Mekanisme Permainan

Keterangan :

  • Warna hijau untuk player yang menang
  • Warna merah untuk player yang kalah

Adapun mekanisme untuk permainan kali ini adalah, setiap player akan melakukan buka tutup korek api secara bergantian dan diiringi dengan lantunan musik.

Permainan akan terus berlangsung hingga musik berhenti. Dan saat musik berhenti, player yang memegang korek api akan kalah. Bisa kita lihat seperti gambar diatas.

Aturan

Pada aturan kali ini, kita akan menggunakan goroutine dan channel. Lalu ada break point sebagai pengganti musiknya. Kali ini, kita akan menggunakan 11 sebagai break point. Yang mana nantinya akan dilakukan operasi menggunakan angka random di modulus dengan break point.

Jika randomNumber % breakPoint == 0, maka permainan berhenti.

Code Program

Setelah mengetahui cara bermain dan aturannya, sekarang kita akan langsung membuat kode programnya.

1package main
2
3/*
4    struct untuk korek
5    hits        => untuk proses buka tutup korek api
6    lastPlayer  => player yang sedang memegang korek
7*/
8type Korek struct {
9	hits       int
10	lastPlayer string
11}
12
13// break point
14const BreakPoint = 11
15
16func main() {
17    // membuat channel 
18	korek := make(chan *Korek)
19
20    players := []string{"player 1", "player 2", "player 3", "player 4"}
21
22    for _, p := range players {
23		go play(p, korek)
24	}
25
26    // initialize channel kosong
27	korek <- new(Korek)
28
29    // proses pengeluaran nilai
30	<-korek
31}
32

Setelah itu, kita akan membuat sebuah function untuk memulai permainan.

1func play(name string, korek chan *Korek){
2    // code here ...
3}
4

function ini akan memulai permainan dengan mendefinisikan nama player dan channel korek. Adapun implementasi kodenya adalah sebagai berikut :

1func play(name string, korek chan *Korek){
2    // lakukan perulangan terus menerus
3    for {
4        select {
5        // akan di eksekusi jika ada data yg dikirim ke channel korek
6		case k := <-korek:
7            // melakukan proses buka tutup korek
8			k.hits++
9			k.lastPlayer = name
10			fmt.Println("korek ada di", k.lastPlayer, "pada hit ke", k.hits)
11
12            // proses pengiriman korek antar player
13			korek <- k
14		}
15    }
16}
17

Disini kita akan menggunakan unlimited for agar permainan bisa terus menerus berlangsung. Jika kita jalankan, maka output yang dihasilkan adalah sebagai berikut :

Output :

1korek ada di player 4 pada hit ke 1
2korek ada di player 2 pada hit ke 2
3korek ada di player 4 pada hit ke 3
4korek ada di player 2 pada hit ke 4
5korek ada di player 4 pada hit ke 5
6korek ada di player 2 pada hit ke 6
7korek ada di player 4 pada hit ke 7
8korek ada di player 3 pada hit ke 8
9korek ada di player 4 pada hit ke 9
10korek ada di player 3 pada hit ke 10
11...
12

Kode diatas akan berjalan dan akan menampilkan hasil yang berbeda beda. Untuk memberhentikan kode tersebut, kita perlu melakukan break point.

1// disini, kita akan menambahkan 1 channel lagi yaitu `done`
2func play(name string, korek, done chan *Korek) {
3    // membuat angka random
4	rand.Seed(time.Now().UnixNano())
5	min := 1
6	max := 100
7	for {
8		select {
9		case k := <-korek:
10            // mengambil angka random
11			v := rand.Intn(max-min) + min
12			time.Sleep(500 * time.Millisecond)
13			k.hits++
14			k.lastPlayer = name
15			fmt.Println("korek ada di", k.lastPlayer, "pada hit ke", k.hits, "dan mempunyai nilai", v)
16
17            // tambahan
18			if v%BreakPoint == 0 {
19                // jika oke, maka akan mengirim value ke channel `done`
20				done <- k
21
22                // return akan memberhentikan perulangan
23				return
24			}
25
26			korek <- k
27		}
28	}
29}
30

Lalu pada function main, kita lakukan adjustment :

1func main() {
2	korek := make(chan *Korek)
3
4    // channel untuk menangkap data jika sudah selesai
5	done := make(chan *Korek)
6
7	players := []string{"player 1", "player 2", "player 3", "player 4"}
8	for _, p := range players {
9        // tambahin kedalam parameter
10		go play(p, korek, done)
11	}
12	korek <- new(Korek)
13
14    // tambahin function finish
15	finish(done)
16}
17
18

Lalu pada function finish :

1func finish(done chan *Korek){
2    for {
3		select {
4        // jika ada data yang masuk pada channel done,
5        // maka game selesai
6		case d := <-done:
7			fmt.Println(d.lastPlayer, "kalah pada hit ke", d.hits)
8			return
9		}
10	}
11}
12

Output :

1korek ada di player 1 pada hit ke 1 dan mempunyai nilai 29
2korek ada di player 2 pada hit ke 2 dan mempunyai nilai 53
3korek ada di player 4 pada hit ke 3 dan mempunyai nilai 58
4korek ada di player 3 pada hit ke 4 dan mempunyai nilai 81
5korek ada di player 1 pada hit ke 5 dan mempunyai nilai 27
6korek ada di player 2 pada hit ke 6 dan mempunyai nilai 98
7korek ada di player 4 pada hit ke 7 dan mempunyai nilai 28
8korek ada di player 3 pada hit ke 8 dan mempunyai nilai 18
9korek ada di player 1 pada hit ke 9 dan mempunyai nilai 15
10korek ada di player 2 pada hit ke 10 dan mempunyai nilai 1
11korek ada di player 4 pada hit ke 11 dan mempunyai nilai 46
12korek ada di player 3 pada hit ke 12 dan mempunyai nilai 14
13korek ada di player 1 pada hit ke 13 dan mempunyai nilai 62
14korek ada di player 2 pada hit ke 14 dan mempunyai nilai 81
15korek ada di player 4 pada hit ke 15 dan mempunyai nilai 15
16korek ada di player 3 pada hit ke 16 dan mempunyai nilai 27
17korek ada di player 1 pada hit ke 17 dan mempunyai nilai 68
18korek ada di player 2 pada hit ke 18 dan mempunyai nilai 44
19player 2 kalah pada hit ke 18
20

Pada output tersebut, maka bisa dilihat player 2 mempunyai nilai 44 pada hit ke 18. karena 44 % 11 = 0, maka player 2 kalah.

Dan begitulah caranya kita membuat permainan korek api bernyanyi menggunakan goroutine dan channel. Jika ada yg ingin ditanyakan, bisa melalui DM IG kami yaa @noobeeid.

Terimakasih

***