Menu
Coddy logo textTech

Oyun Karakter Sistemi

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

challenge icon

Görev

Kolay

Esnek dövüş mekanikleri oluşturmak için struct gömme (embedding), arayüzler (interfaces) ve Strateji (Strategy) desenini bir araya getiren bir Oyun Karakter Sistemi inşa edelim! Çalışma zamanında değiştirilebilen yeteneklerle, benzersiz şekillerde saldırabilen ve savunma yapabilen farklı karakter türleri tasarlayacaksınız.

Kodunuzu beş dosya halinde düzenleyeceksiniz:

  • character.go: Ortak alanlara sahip bir temel Character struct'ı tanımlayın: Name (string), Health (int) ve MaxHealth (int). Bir NewCharacter yapıcı fonksiyonu (constructor) ve şu metotları ekleyin:
    • IsAlive() bool — sağlık 0'dan büyükse true döner
    • Status() string — şu formatı döner: [Name]: [Health]/[MaxHealth] HP
  • interfaces.go: Polimorfizmi (çok biçimlilik) sağlayan dövüş arayüzlerini tanımlayın:
    • Attack() int metoduna sahip Attacker arayüzü — verilen hasarı döner
    • TakeDamage(damage int) int metoduna sahip Defender arayüzü — hasar azaltmayı uygular ve alınan gerçek hasarı döner
    • Use() string metoduna sahip Ability arayüzü — yetenek etkisinin bir açıklamasını döner
  • characters.go: Character struct'ını gömen ve hem Attacker hem de Defender arayüzlerini uygulayan üç karakter türü oluşturun:

    WarriorStrength (int) ve Armor (int) alanlarına sahiptir. Attack, Strength değerini hasar olarak döner. TakeDamage, gelen hasarı Armor kadar azaltır (en az 1 hasar alınır).

    MageIntelligence (int) ve MagicResist (int) alanlarına sahiptir. Attack, Intelligence * 2 değerini hasar olarak döner. TakeDamage, gelen hasarı MagicResist / 2 kadar azaltır (en az 1 hasar alınır).

    ArcherAgility (int) ve Evasion (int) alanlarına sahiptir. Attack, Agility + 5 değerini hasar olarak döner. TakeDamage: Eğer Evasion > 10 ise, hasarı %25 oranında azaltır (tamsayı bölmesi), aksi takdirde tam hasar alır (en az 1 hasar alınır).

    Her biri için isim, sağlık ve özel istatistik değerlerini alan yapıcılar ekleyin: NewWarrior, NewMage, NewArcher.

  • abilities.go: Değiştirilebilir yeteneklerle Strateji desenini uygulayın:

    Power (int) alanına sahip FireSpell struct'ı. Use() metodu şunu döner: Casts fireball for [Power] damage

    Power (int) alanına sahip IceSpell struct'ı. Use() metodu şunu döner: Casts ice shard for [Power] damage

    Multiplier (int) alanına sahip PowerStrike struct'ı. Use() metodu şunu döner: Performs power strike at [Multiplier]x damage

    Mage struct'ına Ability türünde bir ability alanı ekleyin; SetAbility(a Ability) ve UseAbility() string metotlarını tanımlayın. Eğer yetenek nil ise UseAbility No ability set döner.

  • main.go: Karakterleri oluşturun ve dövüş mekaniklerini gösterin.

    Karakter türünü (warrior, mage veya archer) okuyun, ardından karakterin adını, sağlığını ve türe özgü istatistiklerini okuyun. Uygun karakteri oluşturun.

    Ardından eylem sayısını okuyun. Her eylem şunlardan biridir:

    • status — karakterin durumunu yazdırın
    • attack[Name] attacks for [damage] damage yazdırın
    • defend [amount] — hasarı uygulayın ve [Name] takes [actual] damage yazdırın
    • setability [type] [power] — sadece büyücüler (mage) için, yeteneği ayarlayın (tür: fire, ice veya strike)
    • useability — sadece büyücüler (mage) için, yeteneğin Use() sonucunu yazdırın

Aşağıdaki girdiler sağlanacaktır:

  • Karakter türü, adı, sağlığı ve türe özgü istatistikler
  • Eylem sayısı ve ardından her bir eylem ayrı bir satırda

Örneğin, şu girdi verildiğinde:

warrior
Thorin
100
15
8
5
status
attack
defend 20
status
defend 100

Çıktınız şu olmalıdır:

Thorin: 100/100 HP
Thorin attacks for 15 damage
Thorin takes 12 damage
Thorin: 88/100 HP
Thorin takes 92 damage

Ve şu girdi verildiğinde:

mage
Gandalf
80
25
10
6
attack
useability
setability fire 30
useability
setability ice 25
useability
defend 40

Çıktınız şu olmalıdır:

Gandalf attacks for 50 damage
No ability set
Casts fireball for 30 damage
Casts ice shard for 25 damage
Gandalf takes 35 damage

Ve şu girdi verildiğinde:

archer
Legolas
90
18
15
4
status
attack
defend 24
status

Çıktınız şu olmalıdır:

Legolas: 90/90 HP
Legolas attacks for 23 damage
Legolas takes 18 damage
Legolas: 72/90 HP

Struct gömmenin her karakter türünün temel Character alanlarını ve metotlarını paylaşmasına nasıl izin verdiğine, arayüzlerin ise herhangi bir Attacker'ın hasar verebildiği ve herhangi bir Defender'ın hasar alabildiği polimorfik dövüşü nasıl mümkün kıldığına dikkat edin. Strateji deseni, Mage'in değiştirilebilir yetenekleriyle parlıyor; aynı karakter, temel uygulamasını değiştirmeden farklı büyüler kullanabiliyor!

Kendin dene

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)

	// Karakter türünü oku
	scanner.Scan()
	charType := strings.TrimSpace(scanner.Text())

	// Karakter adını oku
	scanner.Scan()
	name := strings.TrimSpace(scanner.Text())

	// Sağlık değerini oku
	scanner.Scan()
	health, _ := strconv.Atoi(strings.TrimSpace(scanner.Text()))

	// Türe özgü ilk istatistiği oku
	scanner.Scan()
	stat1, _ := strconv.Atoi(strings.TrimSpace(scanner.Text()))

	// Türe özgü ikinci istatistiği oku
	scanner.Scan()
	stat2, _ := strconv.Atoi(strings.TrimSpace(scanner.Text()))

	// TODO: charType değerine göre uygun karakteri oluştur
	// Değişkenleri kullan: charType, name, health, stat1, stat2
	// Savaşçı (warrior) için: stat1 = Strength, stat2 = Armor
	// Büyücü (mage) için: stat1 = Intelligence, stat2 = MagicResist
	// Okçu (archer) için: stat1 = Agility, stat2 = Evasion

	// Eylem sayısını oku
	scanner.Scan()
	numActions, _ := strconv.Atoi(strings.TrimSpace(scanner.Text()))

	// Her bir eylemi işle
	for i := 0; i < numActions; i++ {
		scanner.Scan()
		line := strings.TrimSpace(scanner.Text())
		parts := strings.Fields(line)
		action := parts[0]

		// TODO: Her eylem türünü ele al:
		// - "status": karakterin Status() sonucunu yazdır
		// - "attack": "[Name] attacks for [damage] damage" yazdır
		// - "defend [amount]": hasarı uygula ve "[Name] takes [actual] damage" yazdır
		// - "setability [type] [power]": büyücüler için yetenek ayarla (fire, ice veya strike)
		// - "useability": büyücüler için UseAbility() sonucunu yazdır

		_ = action // Uygulama yaparken bu satırı kaldırın
		_ = fmt.Println // Uygulama yaparken bu satırı kaldırın
	}
}

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