Live Commentary Replicube: Menyelesaikan 18 Soal Puzzle Menggambar Objek Voxel dengan Kode Lua
ゲーミングボーイDiterjemahkan dari 日本語
Replicube adalah gim puzzle berbasis tahap yang menantang pemain untuk mereplikasi objek 3D yang telah ditentukan. Voxel tidak diletakkan dengan tangan, melainkan ditempatkan dengan menulis program. Dalam video ini, streamer menyelesaikan 11 soal dari kumpulan soal tutorial pertama, lalu 7 soal dari kumpulan soal tambahan yang datang berikutnya. Targetnya bukan menamatkan semua soal; video dihentikan setelah kedua kumpulan soal itu selesai. Sepanjang video, streamer lebih mengutamakan penulisan kode yang mudah dibaca daripada mengejar skor.
Cara Kerja Gim: Menerima Koordinat dan Mengembalikan Warna
Menurut tutorialnya, dalam gim ini pemain menempatkan voxel dengan total 16 warna di ruang voxel seperti Minecraft. Voxel adalah istilah bentukan yang berarti "piksel yang memiliki volume". Penempatannya dilakukan dengan kode: jika menulis kode yang selalu mengembalikan putih, seluruh ruang akan terisi putih; jika mengembalikan ungu, jadi ungu; jika mengembalikan biru, jadi biru. Artinya, formatnya adalah menulis kode yang menerima koordinat setiap voxel dan mengembalikan nilai warna yang akan diletakkan di sana. Sambil berkata "Kepala saya sudah mulai pusing", streamer mengatakan bahwa belakangan ini ia hanya memainkan gim pertarungan, jadi sesekali gim damai seperti ini juga menyenangkan.
Di dalam gim, pemain menerima email dari pengelola sebuah tempat bernama Cubenet, lalu menyelesaikan kumpulan soal dasar yang dilampirkan di sana. Bentuk jawaban yang benar ditampilkan di bagian atas layar, sedangkan bentuk yang digambar oleh kode saat ini ditampilkan di bagian bawah. Penilaian tampaknya juga mencakup jumlah kode dan kecepatan eksekusi, tetapi streamer menunda optimasi sebagai "hidangan penutup nanti" dan memutuskan untuk mengutamakan keterbacaan terlebih dahulu. Alasannya, menurut dia, "kode itu pada dasarnya ditulis untuk manusia".
1-1 hingga 1-3: Mengganti Warna dan Percabangan Kondisi
Pada soal pertama, dengan membaca komentar pada kode yang sudah ada, terlihat bahwa warna yang dikembalikan hanya sedikit berbeda. Soal ini selesai dengan mengganti PURPLE menjadi RED.
Pada soal kedua, objek diwarnai dengan dua warna sesuai posisinya. Karena tersedia variabel x, y, dan z yang mewakili koordinat, soal ini diselesaikan dengan menulis pernyataan if yang mengembalikan DARKBLUE jika y bernilai 1 atau lebih, dan ORANGE jika tidak.
Tema soal ketiga adalah operator perbandingan. Streamer memperhatikan bahwa dalam bahasa ini, ketidaksamaan ditulis dengan "~=", dan memperkirakan bahwa operator itu akan segera dipakai. Soalnya sendiri hampir sama polanya dengan soal kedua dan dapat diselesaikan dengan kondisi "y bernilai ○○ atau lebih". Ia juga menyebut solusi alternatif tanpa operator perbandingan, seperti return GREEN - (y + 4) // 3 * 2, tetapi tidak memakainya karena kode semacam ini cenderung menyulitkan pembaca.
1-4 dan 1-5: Cara Membuat Transparan
Mulai soal keempat, selain koordinat y, koordinat x dan z juga mulai digunakan. Kode awal sudah memiliki skema warna pelangi. Karena nilai koordinat y langsung dipakai sebagai kode warna, warnanya berganti ke warna berikutnya setiap naik satu tingkat. Namun, yang diperlukan dalam soal ini hanyalah membuat sebagian objek menjadi transparan. Menurut komentar, objek menjadi transparan jika tidak mengembalikan apa pun, atau mengembalikan 0 atau EMPTY. Soal ini selesai dengan mengubah kondisi "ketika x dan z bernilai 2 atau lebih" pada kode awal menjadi "ketika bernilai 0 atau lebih".
Soal kelima juga memiliki struktur yang hampir sama, dan diselesaikan dengan menulis kondisi "ketika x, y, dan z semuanya bernilai 1 atau lebih".
1-6: Menggambar Bentuk Simetris dengan Nilai Mutlak
Soal keenam memperkenalkan fungsi abs. Komentarnya menyebutkan bahwa fungsi ini mengembalikan nilai mutlak dan sangat berguna untuk menggambar objek yang simetris. Bentuk target kali ini simetris terhadap sumbu mana pun.
Streamer pertama-tama memperhatikan sumbu z dan menentukan ketebalan dengan mengembalikan kosong jika nilai mutlak z bernilai 2 atau lebih. Bisa juga ditulis "2 atau lebih, atau -2 atau kurang", tetapi menurut streamer, menggunakan konsep nilai mutlak membuat kodenya lebih mudah dipahami. Bentuk kisi-kisi selebihnya juga dibuat dengan nilai mutlak untuk membentuk batang vertikal dan horizontal, lalu dirangkai dengan or (disjungsi logis) hingga selesai. Karena struktur simetris tampaknya akan sering muncul ke depannya, streamer memperkirakan akan banyak situasi yang memerlukan nilai mutlak.
1-7: Membaca Pesan Error dan Memperbaikinya
Soal ketujuh sudah memunculkan error sejak awal. Streamer pertama-tama membaca pesan error-nya. Dari tampilan "LUA_ERRSYNTAX", ia menduga bahwa bahasa ini adalah Lua. Seharusnya ada end untuk menutup if di baris ke-10, tetapi di baris ke-13 malah tertulis if. Artinya, end lupa ditulis.
Setelah diperbaiki pun belum selesai, karena masih ada bagian kotak yang seharusnya merah tetapi berwarna GREY, sehingga bagian itu juga diganti hingga soal selesai. Di sini streamer mengatakan bahwa sebenarnya jarang ada kesempatan menulis kode dari nol, dan dalam praktiknya kemampuan membaca kode orang lain sering kali lebih penting.
1-8: Menyelesaikan Soal Bebas "sushi?" dengan Jarak Papan Catur dan Table
Namun, soal kedelapan justru meminta menulis kode dari nol. Nama soalnya "sushi?", dan streamer merasakan adanya "selera yang luar biasa". Karena tampaknya bentuknya boleh dibuat bebas, ia memutuskan untuk mewarnai objek dengan merah, putih, dan hijau sesuai jaraknya dari pusat.
Jarak yang digunakan di sini disebut jarak papan catur (chessboard distance). Ini adalah jarak berupa berapa langkah yang dibutuhkan bidak yang dapat bergerak ke 8 arah untuk mencapai suatu titik, dan streamer memperkenalkannya sebagai konsep yang sesekali ia andalkan juga dalam gim roguelike seperti Shiren the Wanderer. Jarak ini mudah dihitung jika ada fungsi max, jadi ia membuka tab Documentation untuk mencarinya. Dokumentasinya terdiri dari 4 bab: bab 1 berisi gambaran umum, bab 2 berisi detail penggambaran, dan informasi yang dicarinya tampaknya ada di bab 3. Di sana ia memastikan bahwa variabel dapat didefinisikan, operator seperti + dan - dapat digunakan, dan fungsi max tersedia.
Untuk konversi ke merah, putih, dan hijau, streamer berniat membuat percabangan if secara apa adanya jika tidak ada fitur yang praktis. Sebagai ide "implementasi iseng", ia juga menyebut cara menggeser ke kanan (right shift) 0xb17—yaitu 7, 1, dan 11 yang dideretkan dalam heksadesimal—sesuai jaraknya.
Di sini streamer bercerita sebagai selingan bahwa plugin OBS yang biasa ia gunakan untuk merekam video juga bisa ditulis dengan Lua. Ia pernah menulis plugin sederhana yang secara otomatis membuat stempel waktu YouTube, dan katanya mungkin itulah satu-satunya saat ia menyentuh Lua seumur hidupnya.
Dalam implementasinya, pertama-tama ia mengambil nilai maksimum dari nilai mutlak x dan nilai mutlak y untuk mendapatkan jarak papan catur dari titik asal. Kali ini nilainya berupa 0, 1, atau 2, sehingga diperlukan mekanisme untuk mengonversinya menjadi 0→7 (merah), 1→1 (putih), dan 2→11 (hijau). Karena sekilas terlihat tulisan "table" di dokumentasi, ia menduga struktur seperti array bisa digunakan. Ia menulis literal array dengan kurung siku yang bisa dipakai di banyak bahasa, tetapi ternyata tidak bisa digunakan di Lua. Lalu, dari nama "Table", ia mengira bentuknya memakai kurung kurawal dan menulis ulang kodenya, dan hasilnya hampir berhasil. Namun, warnanya bergeser satu, dan ketahuan bahwa indeks Lua dimulai dari 1. Setelah disesuaikan, sushi pun selesai.
Elemen yang dipakai memang agak rumit, tetapi jika kodenya dilihat, ternyata tampak cukup ringkas, kata streamer. Meski begitu, ia sendiri menambahkan bahwa biasanya hanya penulisnya sendiri yang berpikir begitu.
1-9 dan 1-10: "Bagian yang Tidak Diwarnai" dan if Bersarang
Soal kesembilan lebih mirip tutorial kontrol, yang mengajak pemain menggerakkan sudut pandang dengan mouse untuk memeriksa bentuk dengan saksama. Bentuknya berupa kotak yang terbuka di bagian atas, dan cukup mengembalikan BROWN ketika x atau z bernilai ±3, atau ketika y bernilai -3. Dengan mengecualikan kasus y bernilai +3, terbentuklah kotak dengan tutup atas yang terbuka. Di sini pun nilai mutlak digunakan. Komentarnya tampak ingin agar pemain menyatakannya dengan "bagian mana yang tidak diwarnai" alih-alih "bagian mana yang diwarnai", tetapi streamer menilai keduanya sama saja. Karena terlalu bersemangat di soal sushi sebelumnya, ia merasa soal ini agak antiklimaks.
Soal kesepuluh, menurut streamer, memiliki skema warna seperti Google Chrome, tetapi tidak terlihat keteraturan khusus pada urutan warnanya. Komentarnya juga tampaknya mengharapkan if bersarang, jadi ia menulis percabangan kondisi secara lugas. Ketika y bernilai 1 atau lebih, kembalikan GREEN jika x bernilai 1 atau lebih, dan ORANGE jika tidak. Ketika y tidak bernilai 1 atau lebih, kembalikan BLUE jika z bernilai 1 atau lebih, dan RED jika tidak. Streamer menulis kodenya sambil memutar sudut pandang agar sumbunya mudah terlihat.
1-11: Dua Kesalahan Ejaan dan Mekanisme Bentuk X
Soal ke-11, yang merupakan soal terakhir tutorial, juga sudah bermasalah sejak awal. Menurut pesan error, baris ke-31 menangani variabel tak dikenal bernama "colo". Streamer menduga ini salah ketik dari "color" dan memperbaikinya. Namun, itu saja belum cukup, karena tangganya hanya tergambar sebagian. Setelah membaca kodenya lebih lanjut, ditemukan bagian yang memakai ejaan bahasa Inggris Britania, "colour", dan setelah diperbaiki, soal pun selesai.
Mengenai alasan kode ini bisa menggambar bentuk X, streamer memahaminya karena kode tersebut menggunakan ekspresi x==y dan x==-y. Artinya, bentuk seperti ini bisa digambar dengan menggunakan fungsi linear sebagai persamaan. Di sini streamer berkata, "Yah, pasti itu pengetahuan yang tidak ada hubungannya dengan saya."
2-1 hingga 2-3: Menggambar Garis Diagonal dengan Persamaan
Setelah tutorial selesai, datang email sambutan dari komunitas beserta kumpulan soal tambahan berisi 7 soal.
Di soal pertama kumpulan soal tambahan, langsung muncul soal fungsi linear yang baru saja ia sebut "tidak ada hubungannya". Karena berupa garis y = -x, dalam Lua bisa ditulis x == -y. Perbandingan dengan == mengembalikan true atau false, dan di Replicube keduanya digambar sebagai putih dan kosong, sehingga soal bisa selesai hanya dengan mengembalikan hasil perbandingan tersebut apa adanya.
Soal kedua juga berupa garis diagonal, tetapi perlu dipersempit lagi dengan koordinat z. Pertama-tama ia menggambar bidang dengan x == y, lalu merangkai kondisi x == z dengan and (konjungsi logis) untuk menyelesaikan bentuknya. Agar nilai kembaliannya berupa GREEN atau kosong, bukan true/false, ia menambahkan and GREEN di bagian akhir dengan memanfaatkan evaluasi hubung singkat (short-circuit evaluation).
Soal ketiga berbentuk versi simetris dari soal kedua, sehingga bisa diselesaikan hanya dengan mengubah ekspresinya menjadi versi nilai mutlak. Menghitung abs(x) dua kali memang agak boros, tetapi karena bukan proses yang lambat, ia memutuskan untuk tidak memedulikannya.
2-4 hingga 2-6: Membuat Pola dengan Modulo dan Penjumlahan
Soal keempat memperkenalkan operator % yang mengembalikan sisa pembagian. Kode awal menggunakan sisa pembagian y dengan 3 untuk membagi nilai secara berurutan ke 0, 1, dan 2. Melihat bentuk jawaban yang benar, tampaknya nilai x dikonversi menjadi 0 atau 1, sehingga ia menduga cukup menggunakan sisa pembagian dengan 2. Karena bergeser satu kotak, ia menyesuaikannya dengan mengurangi x dengan 1 hingga soal selesai.
Soal kelima berupa papan catur (checkerboard). Pertama, untuk membuatnya menjadi bidang, ia mencoba menulis proses yang mengembalikan kosong jika nilainya bukan 0, tetapi awalnya ia keliru menulis kondisinya dengan z, lalu memperbaikinya menjadi y. Panah RGB berkorespondensi dengan XYZ, tetapi katanya ia kadang lupa dan jadi bingung. Untuk polanya, ia sudah "diam-diam mengintip" bahwa penjumlahan dengan return x+y pada kode awal soal kedua menghasilkan pola garis diagonal. Jika hasil ini dibulatkan dengan %, jadilah papan catur. Awalnya warnanya menjadi merah muda, jadi ia memperbaikinya agar mengembalikan hitam hingga soal selesai. Ia juga menunjukkan bahwa jika ingin menghindari percabangan kondisi, hal ini bisa dicapai dengan ekspresi yang mengonversi sisa 0 dan 1 menjadi 1 dan 3 untuk putih dan hitam, tetapi streamer menilai konversi ke warnanya menjadi sangat sulit dipahami.
Soal keenam berupa pola pelangi diagonal. Dengan memanfaatkan fakta bahwa penjumlahan bisa menggambar garis diagonal, pertama-tama ia menjumlahkan x dan y. Hasilnya sudah kurang lebih mirip. Namun, pada kode streamer titik asal mengembalikan 0, sedangkan pada jawaban yang benar bernilai LIGHTGREEN, jadi ia menambahkan LIGHTGREEN untuk menyesuaikannya. Terakhir, ia mengatur ketebalan dengan mengembalikan kosong ketika z bukan 0, dan soal pun selesai.
2-7: Meja Berkaki Empat dan Merapikan Kode dengan Fungsi
Soal terakhir berupa meja berkaki empat yang khas, dan seluruh materialnya BROWN. Karena hanya perlu memikirkan bentuknya, streamer mengikuti proses perakitan di dunia nyata dan menangani papan atas dan kaki secara terpisah. Karena ternyata komentar bisa ditulis dengan --, ia juga menambahkan komentar. Papan atasnya berupa bidang yang cukup mengembalikan BROWN ketika y bernilai 1. Untuk kaki, pertama-tama ia membatasi area penggambaran pada y bernilai 0 atau kurang untuk menentukan tingginya. Karena posisinya simetris, seperti biasa ia menggunakan nilai mutlak dan hanya menggambar ketika nilai mutlak x dan z sama-sama bernilai 2. Kondisi-kondisi ini dirangkai dengan and, dan BROWN dikembalikan ketika semuanya terpenuhi, hingga soal selesai.
Namun, streamer merasa masih sedikit belum puas dan memutuskan untuk mengutak-atiknya sedikit lagi. Menurut dokumentasi, seharusnya fungsi buatan sendiri bisa didefinisikan, dan ia ingin mencoba menggunakannya. Kode saat ini menulis return BROWN dua kali padahal seluruh materialnya BROWN, sehingga jika ada yang berkata "Ternyata bisa diganti jadi WHITE saja, nggak?", pekerjaannya jadi dua kali. Karena itu, ia menulis ulang kodenya dengan membuat fungsi yang hanya menangani bentuk, sementara warna ditentukan di satu tempat saja.
Secara spesifik, ia mendefinisikan fungsi isTopPlate yang mengembalikan apakah koordinat tersebut merupakan papan atas, dan fungsi isLeg yang mengembalikan apakah koordinat tersebut merupakan kaki, lalu menulis "kembalikan BROWN jika merupakan papan atas atau kaki". Nama fungsi di Lua mungkin umumnya memakai snake_case, tetapi kali ini ia memakai camelCase untuk berjaga-jaga karena lebar layarnya sangat sempit. Pemanggilan fungsi memang memerlukan biaya tertentu, tetapi streamer menilai hal itu tidak masalah karena penggambaran objek diam tidak terlalu menuntut performa. Di sisi lain, karena gim ini tampaknya juga bisa membuat animasi, ia juga mengatakan bahwa dalam situasi seperti itu mungkin sebaiknya hal ini sedikit diperhatikan.
Penilaian Streamer
Setelah menyelesaikan kedua kumpulan soal, streamer menilai Replicube sebagai berikut. Awalnya gim ini terkesan sulit didekati, tetapi UI dan pengenalannya sangat cermat, dan ternyata sangat menyenangkan saat dimainkan. Sebagai gim puzzle, gim ini unggul dengan beragam sudut pandang dan cara penyelesaian, dan juga bisa dinikmati sebagai pemicu ketertarikan pada pemrograman. Gim ini juga memiliki keterkaitan dengan bidang matematika, dan ia menutup dengan mengatakan bahwa ini adalah karya yang bisa dinikmati dari berbagai sisi.
Artikel tidak ditemukan.
Artikel diterbitkan · Diperbarui
