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 savaş mekanikleri oluşturmak için struct gömmeyi, arayüzleri ve Strategy desenini bir araya getiren bir Oyun Karakteri Sistemi oluşturalım! Çalışma zamanında yetenekleri değiştirilebilen, benzersiz şekillerde saldırıp savunabilen farklı karakter türleri tasarlayacaksın.

Kodunu beş dosyaya ayıracaksın:

  • character.go: Ortak alanlara sahip temel bir Character struct'ı tanımla: Name (string), Health (int) ve MaxHealth (int). Bir NewCharacter oluşturucusu ve şu metotları ekle:
    • IsAlive() bool: health değerinin 0'dan büyük olması durumunda true döndürür
    • Status() string: şu biçimi döndürür: [Name]: [Health]/[MaxHealth] HP
  • interfaces.go: Polimorfizmi mümkün kılan savaş arayüzlerini tanımla:
    • Attacker arayüzü ve Attack() int: verilen hasarı döndürür
    • Defender arayüzü ve TakeDamage(damage int) int: hasar azaltmayı uygular ve alınan gerçek hasarı döndürür
    • Ability arayüzü ve Use() string: yetki etkisinin açıklamasını döndürür
  • characters.go: Character öğesini gömen ve hem Attacker hem de Defender arayüzlerini uygulayan üç karakter türü oluştur:

    Warrior: Strength (int) ve Armor (int) alanlarına sahiptir. Attack, hasar olarak Strength değerini döndürür. TakeDamage, gelen hasarı Armor kadar azaltır (alınan minimum hasar 1'dir).

    Mage: Intelligence (int) ve MagicResist (int) alanlarına sahiptir. Attack, hasar olarak Intelligence * 2 değerini döndürür. TakeDamage, gelen hasarı MagicResist / 2 kadar azaltır (alınan minimum hasar 1'dir).

    Archer: Agility (int) ve Evasion (int) alanlarına sahiptir. Attack, hasar olarak Agility + 5 değerini döndürür. TakeDamage: Evasion > 10 ise hasarı %25 oranında azaltır (tam sayı bölmesi), aksi takdirde hasarın tamamını alır (alınan minimum hasar 1'dir).

    Her biri için NewWarrior, NewMage ve NewArcher oluşturucularını ekle; bu oluşturucular ad, can ve türe özgü istatistik değerlerini almalıdır.

  • abilities.go: Değiştirilebilir yeteneklerle Strategy desenini uygula:

    FireSpell struct'ı Power (int) alanına sahiptir. Use() şunu döndürür: Casts fireball for [Power] damage

    IceSpell struct'ı Power (int) alanına sahiptir. Use() şunu döndürür: Casts ice shard for [Power] damage

    PowerStrike struct'ı Multiplier (int) alanına sahiptir. Use() şunu döndürür: Performs power strike at [Multiplier]x damage

    Mage struct'ına ability türünde bir Ability alanı ekle; ayrıca SetAbility(a Ability) ve UseAbility() string metotlarını ekle. Ability nil ise UseAbility, No ability set döndürür.

  • main.go: Karakterler oluştur ve savaş mekaniklerini göster.

    Karakter türünü (warrior, mage veya archer) oku, ardından karakterin adını, canını ve türe özgü istatistiklerini oku. Uygun karakteri oluştur.

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

    • status: karakterin durumunu yazdır
    • attack: [Name] attacks for [damage] damage yazdır
    • defend [amount]: hasarı uygula ve [Name] takes [actual] damage yazdır
    • setability [type] [power]: yalnızca büyücüler için yeteneği ayarla (type, fire, ice veya strike değerlerinden biridir)
    • useability: yalnızca büyücüler için yeteneğin Use() sonucunu yazdır

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

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

Örneğin, şu verildiğinde:

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

Çıktın şöyle 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 verildiğinde:

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

Çıktın şöyle 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 verildiğinde:

archer
Legolas
90
18
15
4
status
attack
defend 24
status

Çıktın şöyle 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 olanak tanıdığına, arayüzlerin ise herhangi bir Attacker'ın hasar verebildiği ve herhangi bir Defender'ın hasar alabildiği polimorfik savaşı nasıl mümkün kıldığına dikkat et. Strategy deseni, Mage'in değiştirilebilir yeteneklerinde kendini gösterir: aynı karakter, temel uygulamasını değiştirmeden farklı büyüler kullanabilir!

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())

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

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

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

	// TODO: charType'a göre uygun karakteri oluştur
	// Değişkenleri kullan: charType, name, health, stat1, stat2
	// warrior için: stat1 = Strength, stat2 = Armor
	// mage için: stat1 = Intelligence, stat2 = MagicResist
	// archer için: stat1 = Agility, stat2 = Evasion

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

	// Her 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ü işle:
		// - "status": karakterin Status() çıktısını 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 yeteneği ayarla (fire, ice veya strike)
		// - "useability": büyücüler için UseAbility() sonucunu yazdır

		_ = action // Uygularken bu satırı kaldır
		_ = fmt.Println // Uygularken bu satırı kaldır
	}
}

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

Kendi başına pratik yap: Online Go derleyicisi