Crystal Legends — Penjelasan Kode

Presentasi per-blok kode & penjelasan (Ziren - Terminal RPG)
Author: Resta Nugroho
Bahasa: Python · Mode: Terminal
Slide 1 — Pengenalan & Struktur Data (The Database)
Bagian ini mendefinisikan "database" game. Menggunakan Dictionary (dict) untuk menyimpan atribut dengan pasangan key-value (seperti status pemain atau monster), dan List untuk koleksi dinamis (seperti inventori dan daftar misi). Data ini adalah sumber tunggal kebenaran (Source of Truth) yang akan diakses dan dimodifikasi oleh semua fungsi game.
player = {
  'nama': 'Ziren', 'hp': 150, 'atk': 20, 'lvl': 1,
  'exp': 0, 'gold': 150, 'inv': []
}

monster_data = {
  'Goblin Iblis': {'hp': 80, 'atk':10, 'exp':15},
  'Iblis Reland': {'hp':250, 'atk':40, 'exp':100}
}

item_shop = {'Pedang Cahaya':{'kat':'Senjata','harga':80}, ...}

misi = [{'nama':'Mengalahkan Goblin', 'status':'Belum','progress':0, 'target':1}]
              
Poin penting: Konsistensi penggunaan struktur data sangat penting. **Dictionary** diakses dengan key (misalnya player['hp']) dan **List** diakses dengan index.
Slide 2 — Utility & UI Terminal (The View)
Fungsi-fungsi sederhana ini bertanggung jawab untuk tampilan dan keterbacaan output di terminal. garis() berfungsi sebagai pembatas visual, sementara status() melakukan operasi **Read** terhadap dictionary player untuk menampilkan informasi penting. Memisahkan fungsi tampilan dari logika game adalah praktik yang baik (**prinsip MVC** sederhana).
def garis():
  print('='*40)

def status():
  garis()
  print('Nama:', player['nama'])
  print('HP:', player['hp'])
  garis()
              
Rekomendasi: Tampilan (**View**) harus minim logika. Semua yang ditampilkan harus sudah dihitung di bagian logika (**Model**) game.
Slide 3 — Toko & CRUD (The Logic)
Fungsi beli() mengimplementasikan operasi CRUD (Create, Read, Update) sederhana.
  • Read: Mengulang (iterate) dan menampilkan item yang tersedia dari item_shop.
  • Update: Mengurangi nilai player['gold'].
  • Create: Menambahkan item baru ke player['inv'] (List).
Perluasan di masa depan harus menyertakan validasi: apakah pemain memiliki cukup gold dan apakah input yang dipilih valid.
def beli():
  for i,(n,d) in enumerate(item_shop.items()):
    print(i+1, n, '-', d['harga'])
  pilih = input('Pilih item:')
  player['gold'] -= harga # Asumsi 'harga' terdefinisi dari item yang dipilih
  player['inv'].append(nama) # Asumsi 'nama' terdefinisi dari item yang dipilih
              
Pendekatan ini menyederhanakan interaksi database game dengan fungsi dasar. Logika **CRUD** adalah dasar dari hampir semua sistem game.
Slide 4 — Pertarungan (Turn-Based Loop)
Ini adalah inti gameplay. Fungsi bertarung() menggunakan perulangan while untuk menjalankan pertarungan sampai salah satu HP (**Pemain** atau **Musuh**) mencapai nol.
  • Shallow Copy: Penggunaan .copy() memastikan kita hanya mengubah HP monster yang sedang bertarung, bukan data templat di monster_data.
  • Damage Calculation: Kerusakan dihitung dengan variasi random untuk membuat pertarungan tidak monoton.
  • Turn Order: Setelah pemain menyerang, giliran monster menyerang (jika monster masih hidup).
def bertarung():
  mon = random.choice(list(monster_data.keys()))
  musuh = monster_data[mon].copy()
  while musuh['hp']>0 and player['hp']>0:
    aksi = input('1 serang / 2 ramuan')
    if aksi=='1':
      dmg = rand(player['atk']-5, player['atk']+5)
      musuh['hp'] -= dmg
    if musuh['hp']>0: player['hp'] -= rand(musuh['atk']-5, musuh['atk']+5)
              
Konsep .copy() penting untuk menghindari modifikasi data templat, memastikan monster lain yang muncul nanti memiliki HP penuh lagi.
Slide 5 — EXP & Level-Up (Progress System)
Sistem kemajuan pemain. Setelah pertarungan, EXP yang didapat ditambahkan. Blok kode ini adalah logic gate yang menentukan apakah pemain memenuhi syarat untuk naik level.
  • Threshold: Syarat EXP untuk naik level adalah player['lvl'] * 40 (skala linear sederhana).
  • Level Up: Jika syarat terpenuhi, level bertambah, sisa EXP dipertahankan (EXP -= threshold), dan atribut dasar seperti HP dan ATK ditingkatkan.
if player['exp'] >= player['lvl']*40:
  player['exp'] -= player['lvl']*40
  player['lvl'] += 1
  player['hp'] += 30
  player['atk'] += 5
              
Penting: Penentuan **threshold** adalah kunci seberapa cepat pemain akan naik level. Untuk game jangka panjang, gunakan rumus eksponensial.
Slide 6 — Sistem Misi (Quest Tracker)
Fungsi ini dipanggil setelah setiap kemenangan pertarungan. Ini mengulang (iterate) setiap misi yang belum selesai dan mengecek apakah nama monster yang dikalahkan ada dalam string nama misi.
  • Tracking: Jika match, progress misi ditingkatkan.
  • Completion: Jika progress mencapai target, status diubah menjadi 'Selesai' dan pemain menerima reward gold.
Ini adalah contoh penggunaan pencocokan string untuk logika sederhana.
def update_misi(nama_monster):
  for m in misi:
    if m['status']!='Selesai' and nama_monster.lower() in m['nama'].lower():
      m['progress'] += 1
      if m['progress']>=m['target']:
        m['status']='Selesai'
        player['gold'] += m['reward'] # Asumsi 'reward' ada di dict misi
              
Pendekatan yang lebih kuat (untuk game besar) adalah menggunakan **ID numerik** atau string unik alih-alih mencocokkan nama dalam string.
Slide 7 — Game Loop & State Machine (The Controller)
Fungsi main() adalah **Controller** yang mengendalikan alur permainan. Ini adalah Game Loop utama, yang berjalan selamanya (while True) hingga pemain memilih opsi keluar (break).
  • State Display: Selalu menampilkan status pemain terbaru sebelum menu.
  • Input Handling: Membaca input pemain dan memanggil fungsi subsistem yang sesuai (bertarung, beli).
Ini adalah implementasi dari **State Machine** sederhana.
def main():
  while True:
    status(); print(menu) # Tampilkan status dan menu
    pilih = input()
    if pilih=='1': bertarung()
    elif pilih=='2': beli()
    elif pilih=='3': break
              
Prinsip dasar game loop: **Ambil Input -> Perbarui State -> Render Output**. Di sini, Render Output (status) ada di awal loop.