Oyun Karakter Sistemi
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 107 / 107.
Görev
KolayEsnek 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 birCharacterstruct'ı tanımla:Name(string),Health(int) veMaxHealth(int). BirNewCharacteroluşturucusu ve şu metotları ekle:IsAlive() bool: health değerinin 0'dan büyük olması durumunda true döndürürStatus() 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:Attackerarayüzü veAttack() int: verilen hasarı döndürürDefenderarayüzü veTakeDamage(damage int) int: hasar azaltmayı uygular ve alınan gerçek hasarı döndürürAbilityarayüzü veUse() string: yetki etkisinin açıklamasını döndürür
characters.go:Characteröğesini gömen ve hemAttackerhem deDefenderarayüzlerini uygulayan üç karakter türü oluştur:Warrior:Strength(int) veArmor(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) veMagicResist(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) veEvasion(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,NewMageveNewArcheroluş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:FireSpellstruct'ıPower(int) alanına sahiptir.Use()şunu döndürür:Casts fireball for [Power] damageIceSpellstruct'ıPower(int) alanına sahiptir.Use()şunu döndürür:Casts ice shard for [Power] damagePowerStrikestruct'ıMultiplier(int) alanına sahiptir.Use()şunu döndürür:Performs power strike at [Multiplier]x damageMage struct'ına
abilitytüründe birAbilityalanı ekle; ayrıcaSetAbility(a Ability)veUseAbility() stringmetotlarını ekle. Ability nil ise UseAbility,No ability setdöndürür.main.go: Karakterler oluştur ve savaş mekaniklerini göster.Karakter türünü (
warrior,mageveyaarcher) 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ırattack:[Name] attacks for [damage] damageyazdırdefend [amount]: hasarı uygula ve[Name] takes [actual] damageyazdırsetability [type] [power]: yalnızca büyücüler için yeteneği ayarla (type,fire,iceveyastrikedeğ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 damageVe ş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 damageVe ş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 HPStruct 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
1Go OOP Temelleri
Harici DosyalarGo Çalışma Alanı ve ModüllerPaketler ve İçe AktarmalarDışa Aktarılan ve Aktarılmayan İsimlerGo'da OOP'ye GirişSınıf Olarak Struct'larStruct'larda Metot TanımlamaPointer ve Değer AlıcılarStruct BaşlatmaYapıcı FonksiyonlarÖzet - Basit Hesap Makinesi4Arayüzler
Arayüzlere GirişÖrtük UygulamaSözleşme Olarak ArayüzBoş Arayüz (any)Tür OnaylamaTür SeçimiArayüz BileşimiStringer ve Error ArayüzleriÖzet - Şekil Hesaplayıcı7Kapsülleme
Dışa Aktarılan ve Aktarılmayan AlanlarPaket Seviyesinde KapsüllemeGetter ve Setter MetotlarıGo'da Bilgi GizlemeÖzet - Öğrenci Kayıtları10Generics (Go 1.18+)
Generics'e GirişTür ParametreleriTür KısıtlamalarıGeneric Struct'larGeneric Metotlar İçin Geçici ÇözümÖzet - Generic Koleksiyon13Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıAbstract Factory KalıbıObserver KalıbıStrategy Kalıbı2Türler ve Struct'lar: Derinlemesine İnceleme
Temel ve Bileşik TürlerÖzel Tür TanımlamalarıStruct EtiketleriAnonim Struct'larİç İçe Geçmiş Struct'larSıfır Değerler ve VarsayılanlarÖzet - Rehber5Kalıtım Yerine Kompozisyon
Go'da Neden Kalıtım YokStruct Gömme TemelleriMetot YükseltmeBirden Fazla Struct GömmeGömme vs AgregasyonGömülü Metotları GölgelemeÖzet - Çalışan Hiyerarşisi8Hata Yönetimi ve OOP
error ArayüzüÖzel Hata TürleriHata Sarmalama (fmt.Errorf)Sentinel Hatalarerrors.Is() ve errors.As()Panic, Defer ve RecoverÖzet - Dosya Ayrıştırıcı3İşaretçiler ve Bellek
Go'da İşaretçi TemelleriStruct İşaretçileriDeğer ile Geçme ve Referans ile Geçmenew() FonksiyonuGo'da Garbage CollectionÖzet - Linked List Oluşturucu6Go'da Polimorfizm
Interface'ler ile PolimorfizmGo'da Duck TypingInterface Karşılama KurallarıPolimorfik KoleksiyonlarDependency InjectionÖzet - Payment Processor9Eşzamanlılık ve OOP
Goroutine TemelleriKanallar ve İletişimTamponlu ve Tamponsuz KanallarSelect İfadesisync.Mutex ve sync.RWMutexsync.WaitGroupThread-Safe Struct TasarımıÖzet - Worker PoolKendi başına pratik yap: Online Go derleyicisi