Menu
Coddy logo textTech

Oyun Karakteri Geliştirme

Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 90 / 91.

challenge icon

Görev

Kolay

Farklı karakter sınıflarının benzersiz yetenekler kullanarak savaştığı bir Oyun Karakteri Geliştirme sistemi kuralım. Kalıtım, arayüzler (interfaces), trait'ler ve kapsüllemenin (encapsulation) bir oyun bağlamında nasıl birlikte çalıştığını gösteren, deneyim ve seviye atlama sistemine sahip bir karakter hiyerarşisi oluşturacaksınız.

Kodunuzu altı dosya halinde düzenleyeceksiniz:

  • Ability.php — İki yöntemi olan bir Ability arayüzü tanımlayın: getName(): string ve use(Character $target): string. Bu sözleşme, tüm yeteneklerin özel etkilerinden bağımsız olarak tutarlı bir şekilde kullanılabilmesini sağlar.
  • CombatLogger.php — Bir logAction(string $action): string yöntemi sağlayan bir CombatLogger trait'i oluşturun. Bu yöntem, eylem dizesini başına "[COMBAT] " ekleyerek döndürmelidir. Karakterler, savaş mesajlarını tutarlı bir şekilde formatlamak için bu trait'i kullanacaktır.
  • Character.php — Ability ve CombatLogger dosyalarını dahil edin. CombatLogger trait'ini kullanan soyut (abstract) bir Character sınıfı oluşturun. name (string, public readonly) için constructor promotion kullanın. health (int, 100'den başlayan), level (int, 1'den başlayan) ve experience (int, 0'dan başlayan) için private özellikler ekleyin. Şunları uygulayın:
    • getHealth(): int ve getLevel(): int — private özellikler için getter yöntemleri
    • takeDamage(int $amount): void — sağlığı azaltır ancak asla 0'ın altına düşürmez
    • heal(int $amount): void — sağlığı artırır ancak asla 100'ün üzerine çıkarmaz
    • gainExperience(int $xp): string — XP ekler; deneyim 100 veya daha fazlasına ulaşırsa seviye atlatır (XP'yi 0'a sıfırlayın, seviyeyi artırın, 20 HP iyileştirin), "[name] leveled up to [level]!" döndürün; aksi takdirde "[name] gained [xp] XP" döndürün
    • isAlive(): bool — sağlık 0'dan büyükse true döndürür
    • abstract getSpecialAbility(): Ability — her karakter türü kendi benzersiz yeteneğini sağlar
    • attack(Character $target): string — hedefe 10 hasar verir, "[COMBAT] [name] attacks [target name] for 10 damage" döndürmek için logAction() kullanır
  • Warrior.php — Character dosyasını dahil edin. Character sınıfını genişleten bir Warrior sınıfı oluşturun. Ability arayüzünü uygulayan anonim bir sınıf döndürmek için getSpecialAbility() yöntemini uygulayın:
    • getName() yöntemi "Shield Bash" döndürür
    • use() yöntemi 25 hasar verir ve "[COMBAT] Shield Bash hits [target name] for 25 damage!" döndürür (trait içindeki logAction() yöntemini kullanın)
  • Mage.php — Character dosyasını dahil edin. Character sınıfını genişleten bir Mage sınıfı oluşturun. Ability arayüzünü uygulayan anonim bir sınıf döndürmek için getSpecialAbility() yöntemini uygulayın:
    • getName() yöntemi "Fireball" döndürür
    • use() yöntemi 35 hasar verir ve "[COMBAT] Fireball engulfs [target name] for 35 damage!" döndürür
  • main.php — Warrior ve Mage dosyalarını dahil edin. İki girdi alacaksınız: karakter verileri (JSON) ve bir dizi savaş eylemi (JSON).

    Karakterler JSON formatı:

    [{"type": "warrior", "name": "Thorin"}, {"type": "mage", "name": "Gandalf"}]

    Eylemler JSON formatı:

    [{"action": "attack", "attacker": 0, "target": 1}, {"action": "special", "attacker": 1, "target": 0}, {"action": "xp", "character": 0, "amount": 100}, {"action": "status", "character": 0}]

    Tüm karakterleri oluşturun ve bir dizide saklayın (indeks 0, 1, vb.). Her eylemi işleyin:

    • "attack" — Saldırgan indeksindeki karakter hedefe saldırır; sonucu yazdırın
    • "special" — Karakter hedef üzerinde özel yeteneğini kullanır; sonucu yazdırın
    • "xp" — Karakter deneyim kazanır; sonucu yazdırın
    • "heal" — Karakter verilen miktar kadar iyileşir; "[name] healed to [health] HP" yazdırın
    • "status""[name] - Level [level], HP: [health], Alive: [Yes/No]" yazdırın

    Her sonucu yeni bir satıra yazdırın.

Bu sistem; soyut sınıfların paylaşılan karakter davranışlarını nasıl tanımladığını, arayüzlerin yeteneklerin tutarlı bir sözleşmeye uymasını nasıl sağladığını, trait'lerin yeniden kullanılabilir günlükleme (logging) işlevselliği sağladığını ve anonim sınıfların tek kullanımlık sınıflarla kod tabanınızı karmaşıklaştırmadan nasıl benzersiz yetenek uygulamaları oluşturduğunu göstermektedir.

Kendin dene

<?php
require_once 'Warrior.php';
require_once 'Mage.php';

// Girdiyi oku
$charactersJson = trim(fgets(STDIN));
$actionsJson = trim(fgets(STDIN));

// JSON girdilerini ayrıştır
$charactersData = (array)json_decode($charactersJson, true);
$actionsData = (array)json_decode($actionsJson, true);

// TODO: Karakter nesnelerini saklamak için bir dizi oluşturun
$characters = [];

// TODO: $charactersData üzerinde döngü kurun ve "type" alanına göre
// Warrior veya Mage nesneleri oluşturup bunları $characters dizisinde saklayın

// TODO: $actionsData içindeki her bir eylemi işleyin
// Şu eylem türlerini yönetin:
// - "attack": Saldırgan dizinindeki karakter hedefe saldırır; sonucu yazdırın
// - "special": Karakter hedef üzerinde getSpecialAbility()->use() kullanır; sonucu yazdırın
// - "xp": Karakter deneyim kazanır; sonucu yazdırın
// - "heal": Karakter iyileşir; "[name] healed to [health] HP" yazdırın
// - "status": "[name] - Level [level], HP: [health], Alive: [Yes/No]" yazdırın

?>

Nesne Yönelimli Programlama bölümündeki tüm dersler