Kali ini saya akan berbagi soal membuat game sederhana dengan menggunakan bahasa pemrograman C++.
Semester ganjil 2019 ini, saya diberi kepercayaan untuk mengasuh mata kuliah Pemrograman Dasar dimana bahasa yang digunakan adalah bahasa C++ dan Service Oriented Architecture yang mana salah satu sub materinya adalah tentang modeling.
Pada materi modeling tersebut, saya memberikan contoh sebuah skenario dimana seekor monyet masuk ke dalam suatu ruangan, di dalam ruangan tersebut terdapat sebuah kotak di dekat jendela dan sesisir pisang tergantung di langit langit di dekat dinding. Untuk mencapai pisang monyet harus memindahkan kotak ke dinding dan memanjatnya.
Berdasarkan skenario tersebut bisa kita simpulkan beberapa hal:
Dari skenario tersebut bisa kita buat model komputasinya dimulai dari class, properti dan method/functionnya.
Tutorial Model Monkey Banana.
Setelah bagian modeling selesai, berikutnya kita harus menentukan aksi apa saja yang bisa dilakukan dan state atau kondisi-kondisi yang mungkin terjadi dari skenario tersebut supaya dapat kita ilustrasikan ke pemain.
Aksi yang bisa dilakukan meliputi:
Asumsi bahwa posisi dinding berada di kiri (posisi 0), jendela berada di tengah (posisi 1) dan pintu di kanan (posisi 2).
Namun harus menjadi perhatian ada beberapa aksi yang memerlukan kondisi tertentu untuk dapat dieksekusi, yaitu:
Selanjut kondisi/state yang mungkin terjadi akibat aksi di atas:
Selanjutnya setelah kita memahami semua state/kondisi yang mungkin terjadi kita bisa melanjutkan ke implementasi-nya.
Perhatikan bahwa kondisi selesai (yang ingin dicapai) adalah ketika Monyet mendapatkan Pisang, atau kondisi gotBanana.
Sesuai yang sudah saya sebut diawal post ini, saya akan menggunakan bahasa C++. Untuk mempermudah pemain memahami setiap kondisi / state yang mungkin, disini kita menggunakan ilustrasi berupa text art, untuk menggambarkan kondisi / state tersebut.
#include <iostream>
#include <stdlib.h>
using namespace std;
class Position {
private:
string desc;
public:
void setDesc(string d){
desc = d;
}
string getDesc(){
return desc;
}
};
class Figure {
private:
int at;
string desc;
public:
void setAt(int p){
at = p;
}
int getAt(){
return at;
}
void setDesc(string d){
desc = d;
}
string getDesc(){
return desc;
}
};
class Banana : public Figure {
public:
Banana(int a){
setDesc("Banana");
setAt(a);
}
};
class Box : public Figure {
public:
Box(int a){
setDesc("Box");
setAt(a);
}
};
class Monkey : public Figure {
private:
bool onBox;
bool gotBanana;
public:
Monkey (int a, bool onB, bool gotB){
setDesc("Monkey");
setAt(a);
onBox = onB;
gotB = gotB;
}
bool getOnBox(){
return onBox;
}
bool getGotBanana(){
return gotBanana;
}
void climbBox(){
onBox = true;
}
void offBox(){
onBox = false;
}
void pickBanana(){
gotBanana = true;
}
void moveLeft(){
setAt(getAt()-1);
}
void moveRight(){
setAt(getAt()+1);
}
Box moveBoxLeft(Box bo){
bo.setAt(bo.getAt()-1);
setAt(getAt()-1);
return bo;
}
Box moveBoxRight(Box bo){
bo.setAt(bo.getAt()+1);
setAt(getAt()+1);
return bo;
}
};
int menu();
void cetakWelcome();
void cetak(int i);
int cekKondisi(Monkey m, Banana b, Box bo);
int main(){
// menu
int pilih;
// Membuat Position dulu
Position pos\[3\];
pos\[0\].setDesc("Dinding");
pos\[1\].setDesc("Jendela");
pos\[2\].setDesc("Pintu");
// Membuat Banana posisi 0
Banana b(0);
// Membuat Box posisi 1
Box bo(1);
// Membuat Monkey posisi 2, onBox false, gotBanana false
Monkey m(2,false,false);
cetakWelcome();
do {
system("cls");
cetak(cekKondisi(m, b, bo));
pilih = menu();
// Menu 1, moveLeft
// Menu 2, moveRight
// Menu 3, moveBoxLeft
// Menu 4, moveBoxRight
// Menu 5, climbBox
// Menu 6, offBox
// Menu 7, pickBanana
// cek jika monyet di atas box maka 1-5 tidak bisa dilakukan
if (m.getOnBox()&&(pilih==1||pilih==2||pilih==3||pilih==4||pilih==5)){
cout<<"Entar jatuh Nyet!!!"<<endl;
cout<<endl;
cout<<"Tekan sembarang tombol untuk melanjutkan!"<<endl;
cin.get();
}else{
switch (pilih) {
case 1:
// Jika posisi di dinding
if (m.getAt()==0){
cout<<"Tidak bisa ke kiri lagi Nyet! Mentok di dinding."<<endl;
cout<<endl;
cout<<"Tekan sembarang tombol untuk melanjutkan!"<<endl;
cin.get();
}else{
m.moveLeft();
}
break;
case 2:
// Jika posisi di pintu
if (m.getAt()==2){
cout<<"Tidak bisa ke kanan lagi Nyet! Mentok di pintu."<<endl;
cout<<endl;
cout<<"Tekan sembarang tombol untuk melanjutkan!"<<endl;
cin.get();
}else{
m.moveRight();
}
break;
case 3:
// apakah posisi monyet sama dengan posisi kotak?
if (m.getAt()!=bo.getAt()){
cout<<"Tidak ada kotak yang bisa didorong Nyet!"<<endl;
cout<<endl;
cout<<"Tekan sembarang tombol untuk melanjutkan!"<<endl;
cin.get();
}else{
// Jika posisi di dinding
if (m.getAt()==0){
cout<<"Tidak bisa ke kiri lagi Nyet! Mentok di dinding."<<endl;
cout<<endl;
cout<<"Tekan sembarang tombol untuk melanjutkan!"<<endl;
cin.get();
}else{
bo = m.moveBoxLeft(bo);
}
}
break;
case 4:
// apakah posisi monyet sama dengan posisi kotak?
if (m.getAt()!=bo.getAt()){
cout<<"Tidak ada kotak yang bisa didorong Nyet!"<<endl;
cout<<endl;
cout<<"Tekan sembarang tombol untuk melanjutkan!"<<endl;
cin.get();
}else{
// Jika posisi di pintu
if (m.getAt()==2){
cout<<"Tidak bisa ke kanan lagi Nyet! Mentok di pintu."<<endl;
cout<<endl;
cout<<"Tekan sembarang tombol untuk melanjutkan!"<<endl;
cin.get();
}else{
bo = m.moveBoxRight(bo);
}
}
break;
case 5:
if (m.getAt()!=bo.getAt()){
cout<<"Tidak ada kotak yang bisa dipanjat Nyet!"<<endl;
cout<<endl;
cout<<"Tekan sembarang tombol untuk melanjutkan!"<<endl;
cin.get();
}else{
m.climbBox();
}
break;
case 6:
if (m.getOnBox()){
m.offBox();
}else{
cout<<"Manjat aja belum, kok mau turun Nyet!"<<endl;
cout<<endl;
cout<<"Tekan sembarang tombol untuk melanjutkan!"<<endl;
cin.get();
}
break;
case 7:
// cek di atas kotak
if (m.getOnBox()){
if (m.getAt()==0){
cout<<"Hebat memang kamu Monyet!"<<endl;
cout<<"Selamat menikmati Pisang!"<<endl;
m.pickBanana();
cout<<endl;
cout<<"Tekan sembarang tombol untuk melanjutkan!"<<endl;
cin.get();
// udah di atas kotak tapi bukan di dekat dinding (tempat pisang)
}else{
cout<<"Tidak ada yg bisa dipetik disini selain hikmah kehidupan Nyet!"<< endl;
cout<<endl;
cout<<"Tekan sembarang tombol untuk melanjutkan!"<<endl;
cin.get();
}
}else{
cout<<"Sadar diri, pendek kayak Monyet!"<<endl;
cout<<endl;
cout<<"Tekan sembarang tombol untuk melanjutkan!"<<endl;
cin.get();
}
break;
}
}
// ulang sampai user pilih diluar 1-7 dan selama monyet belum dapat pisang
// atau berhenti ketika user pilih diluar 1-7 atau monyet ketemu pisang
}while ((pilih>0&&pilih<8)&&!m.getGotBanana());
if (m.getGotBanana()){
system("cls");
cetak(13);
cout<<endl;
cout<<"Tekan sembarang tombol untuk melanjutkan!"<<endl;
cin.get();
system("cls");
cout<<"TTTTT AAA M M AAA TTTTT"<<endl;
cout<<" T A A MM MM A A T "<<endl;
cout<<" T AAAAA M M M AAAAA T "<<endl;
cout<<" T A A M M A A T "<<endl;
cout<<" T A A M M A A T "<<endl;
cout<<endl;
cout<<"Tekan sembarang tombol untuk melanjutkan!"<<endl;
cin.get();
}
return 0;
}
// cetak menu
int menu(){
int p;
cout<<"1. Jalan ke kiri"<<endl;
cout<<"2. Jalan ke kanan"<<endl;
cout<<"3. Dorong kotak ke kiri"<<endl;
cout<<"4. Dorong kotak ke kanan"<<endl;
cout<<"5. Manjat kotak"<<endl;
cout<<"6. Turun kotak"<<endl;
cout<<"7. Petik pisang"<<endl;
cout<<"Apa yang dilakukan monyet \[1-7\]?: ";
cin>>p;
return p;
}
void cetakWelcome(){
cout<<" \_\_,\_\_"<<endl;
cout<<" .--. .-/ \\\\-. .--."<<endl;
cout<<" / .. \\\\/ .-. .-. \\\\/ .. \\\\ "<<endl;
cout<<" | | | / Y \\\\ | | |"<<endl;
cout<<" | \\\\ \\\\ \\\\ 0 | 0 / / / |"<<endl;
cout<<" \\\\ - ,\\\\.- -./, - /"<<endl;
cout<<" \` - /\_ ^ ^ \_\\\\ - \`"<<endl;
cout<<" | \\\\.\_ \_./ |"<<endl;
cout<<" \\\\ \\\\ ~ / /"<<endl;
cout<<" .\_ -=- \_. "<<endl;
cout<<" ~---~ "<<endl;
cout<<endl;
cout<<"MONYET DAN PISANG!"<<endl;
cout<<"created by: Wendy"<<endl;
cout<<"art by : jgs @asciiart.eu"<<endl;
cin.get();
}
void cetak(int kondisi){
switch (kondisi){
// Kondisi 1 monyet di pintu, kotak di dinding dan pisang di dinding
case 1:
cout<<" |"<<endl;
cout<<"\*Posisi | DINDING . JENDELA . PINTU ."<<endl;
cout<<" |"<<endl;
cout<<" | \*Pisang "<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" | \_\_\_\_ O Monyet "<<endl;
cout<<" | | |Box -|\\\\"<<endl;
cout<<" | |\_\_| /\\\\"<<endl;
break;
// Kondisi 2 monyet di pintu, kotak di jendela dan pisang di dinding
case 2:
cout<<" |"<<endl;
cout<<"\*Posisi | DINDING . JENDELA . PINTU ."<<endl;
cout<<" |"<<endl;
cout<<" | \*Pisang "<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" | \_\_\_\_ O Monyet "<<endl;
cout<<" | | |Box -|\\\\"<<endl;
cout<<" | |\_\_| /\\\\"<<endl;
break;
// Kondisi 3 monyet di pintu, kotak di pintu dan pisang di dinding
case 3:
cout<<" |"<<endl;
cout<<"\*Posisi | DINDING . JENDELA . PINTU ."<<endl;
cout<<" |"<<endl;
cout<<" | \*Pisang "<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" | \_\_\_\_ O Monyet "<<endl;
cout<<" | | | -|\\\\"<<endl;
cout<<" | |\_\_| /\\\\"<<endl;
break;
// Kondisi 4 monyet di jendela, kotak di dinding dan pisang di dinding
case 4:
cout<<" |"<<endl;
cout<<"\*Posisi | DINDING . JENDELA . PINTU ."<<endl;
cout<<" |"<<endl;
cout<<" | \*Pisang "<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" | \_\_\_\_ O Monyet "<<endl;
cout<<" | | |Box -|\\\\"<<endl;
cout<<" | |\_\_| /\\\\"<<endl;
break;
// Kondisi 5 monyet di jendela, kotak di jendela dan pisang di dinding
case 5:
cout<<" |"<<endl;
cout<<"\*Posisi | DINDING . JENDELA . PINTU ."<<endl;
cout<<" |"<<endl;
cout<<" | \*Pisang "<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" | \_\_\_\_ O Monyet "<<endl;
cout<<" | | | -|\\\\"<<endl;
cout<<" | |\_\_| /\\\\"<<endl;
break;
// kondisi 6 monyet di jendela, kotak di pintu dan pisang di dinding
case 6:
cout<<" |"<<endl;
cout<<"\*Posisi | DINDING . JENDELA . PINTU ."<<endl;
cout<<" |"<<endl;
cout<<" | \*Pisang "<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" | O \_\_\_\_ ."<<endl;
cout<<" | -|\\\\ | |Box ."<<endl;
cout<<" | /\\\\ |\_\_| ."<<endl;
break;
// kondisi 7 monyet di dinding, kotak di dinding dan pisang di dinding
case 7:
cout<<" |"<<endl;
cout<<"\*Posisi | DINDING . JENDELA . PINTU ."<<endl;
cout<<" |"<<endl;
cout<<" | \*Pisang "<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" | \_\_\_\_ O Monyet "<<endl;
cout<<" | | | -|\\\\"<<endl;
cout<<" | |\_\_| /\\\\"<<endl;
break;
// kondisi 8 monyet di dinding, kotak di jendela dan pisang di dinding
case 8:
cout<<" |"<<endl;
cout<<"\*Posisi | DINDING . JENDELA . PINTU ."<<endl;
cout<<" |"<<endl;
cout<<" | \*Pisang "<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" | O \_\_\_\_ "<<endl;
cout<<" | -|\\\\ | |Box "<<endl;
cout<<" | /\\\\ |\_\_| "<<endl;
break;
// Kondisi 9 monyet di dinding, kotak di pintu dan pisang di dinding
case 9:
cout<<" |"<<endl;
cout<<"\*Posisi | DINDING . JENDELA . PINTU ."<<endl;
cout<<" |"<<endl;
cout<<" | \*Pisang "<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" |"<<endl;
cout<<" | O \_\_\_\_ ."<<endl;
cout<<" | -|\\\\ | |Box ."<<endl;
cout<<" | /\\\\ |\_\_| ."<<endl;
break;
// Kondisi 10 monyet di dinding di atas kotak, kotak di dinding dan pisang di dinding
case 10:
cout<<" |"<<endl;
cout<<"\*Posisi | DINDING . JENDELA . PINTU ."<<endl;
cout<<" |"<<endl;
cout<<" | \*Pisang "<<endl;
cout<<" |"<<endl;
cout<<" | O"<<endl;
cout<<" | -|\\\\"<<endl;
cout<<" | /\_\\\\\_ "<<endl;
cout<<" | | |"<<endl;
cout<<" | |\_\_|"<<endl;
break;
// Kondisi 11 monyet di jendela di atas kotak, kotak di jendela dan pisang di dinding
case 11:
cout<<" |"<<endl;
cout<<"\*Posisi | DINDING . JENDELA . PINTU ."<<endl;
cout<<" |"<<endl;
cout<<" | \*Pisang "<<endl;
cout<<" |"<<endl;
cout<<" | O"<<endl;
cout<<" | -|\\\\"<<endl;
cout<<" | /\_\\\\\_ "<<endl;
cout<<" | | |"<<endl;
cout<<" | |\_\_|"<<endl;
break;
// Kondisi 12 monyet di pintu di atas kotak, kotak di pintu dan pisang di dinding
case 12:
cout<<" |"<<endl;
cout<<"\*Posisi | DINDING . JENDELA . PINTU ."<<endl;
cout<<" |"<<endl;
cout<<" | \*Pisang "<<endl;
cout<<" |"<<endl;
cout<<" | O"<<endl;
cout<<" | -|\\\\"<<endl;
cout<<" | /\_\\\\\_ "<<endl;
cout<<" | | |"<<endl;
cout<<" | |\_\_|"<<endl;
break;
// Kondisi 13 makan pisang
case 13:
cout<<"Monyet dan pisang "<<endl;
cout<<" \_\_,\_\_ "<<endl;
cout<<" .--. .- -. .--. "<<endl;
cout<<" / .. \\\\/ .-. .-. \\\\/ .. \\\\ "<<endl;
cout<<" | | | / Y \\\\ | | |"<<endl;
cout<<" | \\\\ \\\\ \\\\ 0 | 0 / / / |"<<endl;
cout<<" \\\\ - ,\\\\.- -./, - /"<<endl;
cout<<" \\\\ - /\_ ^ ^ \_\\\\ - "<<endl;
cout<<" .-- | \\\\.\_ \_ \_./ | --. "<<endl;
cout<<" / \\\\ \\\\.-. / / \\\\"<<endl;
cout<<" / .\_/ |- \_. \\\\"<<endl;
cout<<" / ; /--~ | \\\\"<<endl;
cout<<" / . \\\\|.-\\\\--. \\\\ \\\\"<<endl;
cout<<" / . -. /.-.;\\\\ |\\\\|'~'-.|\\\\ \\\\"<<endl;
cout<<" \\\\ -./ |\_\\\\\_/ \\\\ . \\\\"<<endl;
cout<<" . ; \_\_\_) . ; /"<<endl;
cout<<" -.,\_ ; \_\_\_) \\\\/ /"<<endl;
cout<<" \\\\ ------ \\\\ \\\\ /"<<endl;
cout<<" . \\\\ . | ;/\_"<<endl;
cout<<"jgs \_\_\_> . \\\\\_ \_ \_/ , --."<<endl;
cout<<" . . .-~~~~~-. / |-- ~~-. \\\\"<<endl;
cout<<" // / .--- / .-~~-.\_/ / / /---..\_\_. /"<<endl;
cout<<" ((\_(\_/ / / (\_(\_(\_(---.\_\_ . "<<endl;
cout<<" | | \_ ~~ "<<endl;
cout<<" | | \\\\ ."<<endl;
cout<<" \\\\ .... |"<<endl;
cout<<" .,\_\_\_. "<<endl;
break;
}
}
int cekKondisi(Monkey m, Banana b, Box bo){
// cek kondisi
// Kondisi 1 monyet di pintu, kotak di dinding dan pisang di dinding
// Kondisi 2 monyet di pintu, kotak di jendela dan pisang di dinding
// Kondisi 3 monyet di pintu, kotak di pintu dan pisang di dinding
// Kondisi 4 monyet di jendela, kotak di dinding dan pisang di dinding
// Kondisi 5 monyet di jendela, kotak di jendela dan pisang di dinding
// kondisi 6 monyet di jendela, kotak di pintu dan pisang di dinding
// kondisi 7 monyet di dinding, kotak di dinding dan pisang di dinding
// kondisi 8 monyet di dinding, kotak di jendela dan pisang di dinding
// Kondisi 9 monyet di dinding, kotak di pintu dan pisang di dinding
// Kondisi 10 monyet di dinding di atas kotak, kotak di dinding dan pisang di dinding
// Kondisi 11 monyet di jendela di atas kotak, kotak di jendela dan pisang di dinding
// Kondisi 12 monyet di pintu di atas kotak, kotak di pintu dan pisang di dinding
// Kondisi 13 makan pisang
if (m.getAt()==2 && bo.getAt()==0 && m.getGotBanana()==false && m.getOnBox()==false){
return 1;
}else if (m.getAt()==2 && bo.getAt()==1 && m.getGotBanana()==false && m.getOnBox()==false){
return 2;
}else if (m.getAt()==2 && bo.getAt()==2 && m.getGotBanana()==false && m.getOnBox()==false){
return 3;
}else if (m.getAt()==1 && bo.getAt()==0 && m.getGotBanana()==false && m.getOnBox()==false){
return 4;
}else if (m.getAt()==1 && bo.getAt()==1 && m.getGotBanana()==false && m.getOnBox()==false){
return 5;
}else if (m.getAt()==1 && bo.getAt()==2 && m.getGotBanana()==false && m.getOnBox()==false){
return 6;
}else if (m.getAt()==0 && bo.getAt()==0 && m.getGotBanana()==false && m.getOnBox()==false){
return 7;
}else if (m.getAt()==0 && bo.getAt()==1 && m.getGotBanana()==false && m.getOnBox()==false){
return 8;
}else if (m.getAt()==0 && bo.getAt()==2 && m.getGotBanana()==false && m.getOnBox()==false){
return 9;
}else if (m.getAt()==0 && bo.getAt()==0 && m.getGotBanana()==false && m.getOnBox()==true){
return 10;
}else if (m.getAt()==1 && bo.getAt()==1 && m.getGotBanana()==false && m.getOnBox()==true){
return 11;
}else if (m.getAt()==2 && bo.getAt()==2 && m.getGotBanana()==false && m.getOnBox()==true){
return 12;
}else{
return 13;
}
}
Jika ingin mencoba aplikasinya bisa download file .exe melalui link MonkeyBanana.exe.
Post yang cukup panjang hehehehe (panjang di coding). Semoga dapat membantu, jika ada kesalahan mari kita diskusi melalui fitur komentar. Cheers.
Text Art Credits: asciiart.eu by jgs