İçeriğe geç
XDD.baby Yazılım Öğrenme
Sözlük Hata rehberi 0/56

Blok 1 · Ders 6

return ve ilk mini proje: takım savaşı

Fonksiyonların sonuç döndürmesini öğreniyor, şimdiye kadarki her şeyi birleştirip rastgele hasarla dönen bir takım savaşı simülasyonu yazıyorsun.

  • 120–150 dk
  • Önce: Ders 5
  • Proje dersi

Bu dersin sonunda

  • return ile fonksiyondan sonuç alıp değişkene koyabilir, hesapta kullanabilir ve başka bir fonksiyona verebilirsin
  • return ile console.log farkını açıklayabilir, undefined gördüğünde sebebini bulabilirsin
  • Erken return ile fonksiyondan zamanında çıkabilir, döngünün içindeki erken return tuzağını fark edebilirsin
  • Math.random ve Math.floor ile istediğin aralıkta rastgele tam sayı üretebilirsin
  • Bir problemi önce Türkçe plana, sonra küçük fonksiyonlara bölüp her parçayı ayrı deneyebilirsin
  • İki takımın tur tur savaştığı ve kazananı ilan eden bir simülasyon yazabilirsin
Bu sayfada
  1. Fonksiyonun sonucu nereye gidiyor?
  2. return: sonucu geri vermek
  3. return ile console.log aynı şey değil
  4. Dönen değeri kullanmak
  5. return'den sonrası çalışmaz: erken çıkış
  6. Döngünün içinde return
  7. Rastgele sayı: Math.random ve Math.floor
  8. Önce plan: problemi Türkçe adımlara bölmek
  9. Proje: takım savaşı
  10. Sık hatalar
  11. Görevler
  12. Kendini sına
  13. Kayıt noktası

Ders 3'te fonksiyon yazmayı öğrendin, ama fonksiyonlarının bir eksiği vardı: işlerini yapıp sonucu ekrana yazıyorlardı, sana geri vermiyorlardı. Bu derste return ile fonksiyondan sonuç almayı, Math.random ile rastgele sayı üretmeyi ve büyük bir işi küçük parçalara bölmeyi öğreneceksin. Sonra şimdiye kadar öğrendiğin her şeyi tek bir programda birleştireceksin: iki takımın tur tur savaştığı bir simülasyon. Bu senin ilk projen.

Dersin ilk yarısında VS Code'da C:\kod\ogren klasöründe çalışacaksın: orada ders6.js adında yeni bir dosya aç. Her yeni örnekte dosyadaki eski kodu sil ya da satırların başına // koy. Örneklerde aynı adlar (hasar, takim) tekrar geçiyor; eskisini silmezsen Ders 1'deki Identifier 'hasar' has already been declared hatasını alırsın. Projeye geçince ayrı bir klasör açacağız.

Fonksiyonun sonucu nereye gidiyor?

Ders 3'teki gibi bir fonksiyon yaz: şampiyonun gücüne ve seviyesine göre hasarı hesaplasın. Sonra o hasarı bir değişkene koymaya çalış.

ders6.js — ogren — Visual Studio Code
ders6.js
function hasarHesapla(guc, seviye) {    console.log(guc + seviye * 2)} const hasar = hasarHesapla(20, 3)console.log("Hasar: " + hasar)
PROBLEMSOUTPUTDEBUG CONSOLETERMINAL
PS C:\kod\ogren> node ders6.js26Hasar: undefined
Ln 1, Col 1Spaces: 4UTF-8JavaScript

Ekranda doğru sayı (26) çıktı, ama hasar kutusunda undefined var.

Fonksiyon hesabı yaptı ve sonucu ekrana yazdı. Ama hasar kutusuna hiçbir şey gelmedi: undefined, Ders 4'ten hatırlayacağın gibi "burada değer yok" demek. Sonucu ekranda görmek güzel, ama programın onu kullanamıyor: candan düşemiyor, başka bir sayıyla karşılaştıramıyor.

Belki şöyle düşünürsün: hesabı fonksiyonun içinde bir kutuya koyarım, sonra dışarıdan okurum.

ders6.js
function hasarHesapla(guc, seviye) {    const hasar = guc + seviye * 2} hasarHesapla(20, 3)console.log(hasar)
Hata çıktısı
C:\kod\ogren\ders6.js:6console.log(hasar)            ^ ReferenceError: hasar is not defined    at Object.<anonymous> (C:\kod\ogren\ders6.js:6:13)    ... Node.js v24.20.0

Ders 3'ten hatırla: fonksiyonun içinde açılan kutu dışarıdan görünmez. hasar kutusu fonksiyonun içinde açıldı ve fonksiyon bitince ortadan kalktı. Sonucu fonksiyondan dışarı çıkarmanın doğru yolu return.

return: sonucu geri vermek

ders6.js
function hasarHesapla(guc, seviye) {    return guc + seviye * 2} const hasar = hasarHesapla(20, 3)console.log("Hasar: " + hasar)
Çıktı
Hasar: 26

Tek değişiklik, console.log(...) yerine return yazmak. return İngilizcede "geri dön" demek ve iki iş yapar:

  1. Fonksiyonu o anda bitirir.
  2. Yanındaki değeri, fonksiyonun çağrıldığı yere geri gönderir.

Yani hasarHesapla(20, 3) çağrısı çalışıp bittiğinde, bu yazının yerine sanki 26 yazılmış olur. Satır const hasar = 26 hâline gelir ve 26 kutuya girer.

console.log ile 20 + 3 * 2 = 26 sonucu ekrana yazar geri dönen yok Terminal 26 hasar undefined Fonksiyon 26 yazdı, kutu boş. return ile 20 + 3 * 2 = 26 sonucu geri verir çağrıya döner Terminal (boş) hasar 26 Fonksiyon yazmadı, kutuda 26 var.
Şekil 6.1 console.log sonucu ekrana yazar, return sonucu çağrıldığı yere geri verir.

return ile console.log aynı şey değil

İkisi de "sonucu gösteriyor" gibi durduğu için çok karıştırılır. Farkı tabloda:

console.log(...)return ...
Ne yapar?Değeri terminale yazarDeğeri çağrıldığı yere geri verir
Kimin için?Senin gözlerin içinProgramın geri kalanı için
Fonksiyonu bitirir mi?Hayır, sonraki satırdan devam ederEvet, fonksiyon hemen biter
Kaç tane olabilir?İstediğin kadarBirden çok yazabilirsin, ama her çağrıda en fazla biri çalışır

Bu farkın iki sonucu var.

return ekrana bir şey yazmaz

Fonksiyonu çağırıp dönen değeri hiçbir yerde kullanmazsan ekranda hiçbir şey görmezsin:

ders6.js
function hasarHesapla(guc, seviye) {    return guc + seviye * 2} hasarHesapla(20, 3)console.log("Program bitti")
Çıktı
Program bitti

26 hesaplandı ve geri döndü, ama onu kimse almadı. Ders 1'deki hp - 10 satırını hatırla: hesap yapıldı, sonuç hiçbir kutuya konmadı ve kayboldu. Burada da aynısı oldu. Sonucu görmek istiyorsan dönen değeri yazdır: console.log(hasarHesapla(20, 3)).

return yoksa undefined döner

Her fonksiyon çağrısı bir değer döndürür. Sen return yazmadıysan JavaScript senin yerine undefined döndürür. Ders 3'teki selamla fonksiyonunu hatırla ve çağrının sonucunu bir kutuya koy:

ders6.js
function selamla(isim) {    console.log("Hoş geldin, " + isim)} const sonuc = selamla("Ahri")console.log(sonuc)
Çıktı
Hoş geldin, Ahriundefined

Ekrana yazan fonksiyonlar da işe yarar; selamla'nın işi zaten selam vermek. Ama sonucunu kullanacağın her hesap fonksiyonu return ile bitmeli. Bir yerde beklemediğin bir undefined görürsen kendine önce şunu sor: "Bu değeri üreten fonksiyonda return var mı?"

Dönen değeri kullanmak

Dönen değer sıradan bir değerdir; bir sayıyı ya da metni nerede kullanabiliyorsan orada kullanabilirsin. Kutuya koyabilir, hesaba katabilir, karşılaştırabilir, başka bir fonksiyona verebilirsin.

ders6.js
function temelHasar(seviye) {    return 10 + seviye * 3} function kritikHasar(hasar) {    return hasar * 2} const normal = temelHasar(5)const kritik = kritikHasar(temelHasar(5))console.log("Normal vuruş: " + normal)console.log("Kritik vuruş: " + kritik)
Çıktı
Normal vuruş: 25Kritik vuruş: 50

kritikHasar(temelHasar(5)) satırında bir fonksiyonun dönüş değeri doğrudan ötekine argüman oluyor. İç içe çağrılar içeriden dışarı çalışır: önce temelHasar(5) çalışıp 25 döndürür, satır kritikHasar(25) hâline gelir, o da 50 döndürür. console.log(...) da bir fonksiyon; ona verdiğin her şey de aynı şekilde önce hesaplanır.

Dönen değeri bir hesabın ya da karşılaştırmanın içinde de kullanabilirsin:

ders6.js
function kritikHasar(hasar) {    return hasar * 2} let hp = 200hp = hp - kritikHasar(30)console.log("Kalan can: " + hp)console.log(kritikHasar(30) > 50)
Çıktı
Kalan can: 140true

true ya da false döndüren fonksiyonlar

Ders 2'den biliyorsun: 450 <= 550 gibi bir karşılaştırmanın sonucu true ya da false değeridir. Bu değeri de return edebilirsin. Böyle fonksiyonlar if'in içinde soru sorar gibi okunur:

ders6.js
function menzildeMi(mesafe, menzil) {    return mesafe <= menzil} console.log(menzildeMi(450, 550))console.log(menzildeMi(600, 550)) if (menzildeMi(450, 550)) {    console.log("Ahri saldırabilir")} else {    console.log("Önce yaklaşman lazım")}
Çıktı
truefalseAhri saldırabilir

Aynı fonksiyonu şöyle de yazabilirdin:

JavaScript
function menzildeMi(mesafe, menzil) {    if (mesafe <= menzil) {        return true    } else {        return false    }}

Bu da doğru çalışır ama gereksiz uzun: mesafe <= menzil zaten true ya da false. Onu olduğu gibi döndürmek yeter.

return'den sonrası çalışmaz: erken çıkış

return çalıştığı anda fonksiyon biter. Altında satır kalmışsa onlar çalışmaz:

ders6.js
function iksirIc(hp) {    return hp + 50    console.log("İksir içildi")} console.log(iksirIc(30))
Çıktı
80

"İksir içildi" hiç yazılmadı. JavaScript hata da vermedi; satır sessizce atlandı. VS Code böyle satırları soluk (gri) gösterir; fareyle üstüne gelirsen Unreachable code detected (ulaşılamayan kod bulundu) yazar. Soluk bir satır görürsen üstünde bir yerde return olduğunu düşün.

Bu bir kusur gibi görünüyor ama çok işe yarar. Bir fonksiyonun başında "bu durumda devam etmenin anlamı yok" dediğin durumları return ile hemen eleyebilirsin:

ders6.js
function yetenekKullan(sampiyon, bedel) {    if (sampiyon.mana < bedel) {        return "Mana yetmiyor"    }    sampiyon.mana = sampiyon.mana - bedel    return "Yetenek kullanıldı, kalan mana: " + sampiyon.mana} const lux = { isim: "Lux", mana: 120 }console.log(yetenekKullan(lux, 50))console.log(yetenekKullan(lux, 50))console.log(yetenekKullan(lux, 50))
Çıktı
Yetenek kullanıldı, kalan mana: 70Yetenek kullanıldı, kalan mana: 20Mana yetmiyor

İlk iki çağrıdan sonra Lux'un 20 manası kaldı. Üçüncü çağrıda if koşulu tuttu (20, 50'den az), return "Mana yetmiyor" çalıştı ve fonksiyon orada bitti. Mana düşen satıra hiç inilmedi, bu yüzden mana eksiye düşmedi.

Üçüncü çağrı: lux.mana 20, bedel 50 1 2 3 4 5 6 7 function yetenekKullan(sampiyon, bedel) { if (sampiyon.mana < bedel) { return "Mana yetmiyor" } sampiyon.mana = sampiyon.mana - bedel return "Yetenek kullanıldı…" } fonksiyondan çıkar "Mana yetmiyor" atlandı, hiç çalışmadı çalıştı çalışmadı
Şekil 6.2 Erken çıkış: return çalışınca altındaki satırlar atlanır.

return varsa else gerekmez

Her if bir return ile bitiyorsa else yazmana gerek kalmaz: bir return çalıştığı anda aşağıdaki satırlara zaten inilmez.

ders6.js
function canDurumu(hp) {    if (hp === 0) {        return "öldü"    }    if (hp < 30) {        return "tehlikede"    }    return "iyi"} console.log(canDurumu(0))console.log(canDurumu(29))console.log(canDurumu(30))console.log(canDurumu(100))
Çıktı
öldütehlikedeiyiiyi

Fonksiyonda üç return var, ama her çağrıda yalnız biri çalışır. 29 ile 30'u ayrı ayrı denediğimize dikkat et: biri sınırın hemen altı, öteki sınırın kendisi. Ders 2'deki kural burada da geçerli: "çalışıyor" ile "doğru" aynı şey değil.

Döngünün içinde return

Bir dizide bir şey ararken aradığını bulduğun anda durmak istersin.

return döngünün içinde de çalışır ve hem döngüyü hem fonksiyonu bitirir:

ders6.js
function ilkCanliyiBul(takim) {    for (const sampiyon of takim) {        if (sampiyon.hp > 0) {            return sampiyon        }    }} const takim = [    { isim: "Garen", hp: 0 },    { isim: "Lux", hp: 60 },    { isim: "Jinx", hp: 80 }]console.log(ilkCanliyiBul(takim)) const herkesOlu = [    { isim: "Annie", hp: 0 },    { isim: "Teemo", hp: 0 }]console.log(ilkCanliyiBul(herkesOlu))
Çıktı
{ isim: 'Lux', hp: 60 }undefined

Garen'in canı 0 olduğu için koşul tutmadı ve döngü Lux'a geçti. Lux'ta return çalıştı; Jinx'e hiç bakılmadı. Fonksiyon bir sayı değil, bütün bir obje döndürdü.

İkinci çağrıda kimse canlı değil: döngü sonuna kadar döndü, hiçbir return'e uğramadı ve fonksiyonun sonuna gelindi. return'e uğramadan sonuna gelen fonksiyon ne döndürür? undefined.

Sık tuzak: else içinde return false

Şimdi "takımda canlı kalan var mı?" sorusunu cevaplayan bir fonksiyon yazalım. İlk akla gelen yazım şu:

ders6.js✗ Yanlış
function takimHayattaMi(takim) {    for (const sampiyon of takim) {        if (sampiyon.hp > 0) {            return true        } else {            return false        }    }} const takim = [    { isim: "Garen", hp: 0 },    { isim: "Lux", hp: 60 },    { isim: "Jinx", hp: 80 }]console.log(takimHayattaMi(takim))
Çıktı
false

Takımda iki canlı var ama cevap false. Hata mesajı yok, program sessizce yanlış cevap veriyor: Ders 2'deki adıyla bir mantık hatası. Sebebi: döngünün ilk turunda Garen'e bakıldı, canı 0, else çalıştı ve return false fonksiyonu ilk elemanda bitirdi. Lux ve Jinx'e sıra hiç gelmedi.

Yanlış: return false döngünün içinde Garen hp 0 Lux hp 60 Jinx hp 80 ölü: return false bakılmadı bakılmadı false yanlış: iki canlı var Doğru: return false döngüden sonra Garen hp 0 Lux hp 60 Jinx hp 80 ölü: sıradaki canlı: return true gerek kalmadı true doğru
Şekil 6.3 else içindeki return false fonksiyonu ilk elemanda bitirir. "Hiçbiri yok" cevabı ancak döngü bitince verilebilir.

Düzeltmesi: else'i sil, return false'u döngünün altına taşı. "Hepsine baktım, hiçbiri tutmadı" cevabı ancak döngü bittikten sonra verilebilir.

ders6.js✓ Doğru
function takimHayattaMi(takim) {    for (const sampiyon of takim) {        if (sampiyon.hp > 0) {            return true        }    }    return false} const takim = [    { isim: "Garen", hp: 0 },    { isim: "Lux", hp: 60 },    { isim: "Jinx", hp: 80 }]const herkesOlu = [    { isim: "Annie", hp: 0 },    { isim: "Teemo", hp: 0 }]console.log(takimHayattaMi(takim))console.log(takimHayattaMi(herkesOlu))console.log(takimHayattaMi([]))
Çıktı
truefalsefalse

Son satıra da bak: boş takım ([]) için döngü hiç dönmez ve fonksiyon false döndürür. Doğru cevap bu: kimsesi olmayan takım hayatta sayılmaz. Boş liste, her arama fonksiyonunda denemen gereken bir sınır değeridir.

Rastgele sayı: Math.random ve Math.floor

Projede her saldırı hep aynı hasarı verirse her maç aynı biter; bir kez izledikten sonra sonucu ezbere bilirsin. Gerçek oyunlarda hasar biraz oynar, kritik vuruşlar olur, şans işin içindedir. Bunun için rastgele sayı gerekiyor.

JavaScript'te matematik araçları Math adlı hazır bir objenin içinde durur. Math.random() yazımı Ders 5'teki takim.push("Lux") gibidir: random, Math objesinin bir metodu, yani ona bağlı bir fonksiyon. Bu yüzden sonuna () koyup çağırırsın, tıpkı console.log gibi. Math'in bütün araçlarını Ders 9'da göreceksin; bu derste yalnız ikisi lazım.

Math.random(): 0 ile 1 arası bir sayı

ders6.js
console.log(Math.random())console.log(Math.random())console.log(Math.random())
Çıktıörnek, sende farklı çıkabilir
0.20222764812345240.76964279889155420.1439393545064247

random İngilizcede "rastgele" demek. Her çağrı 0 ile 1 arasında küsuratlı bir sayı döndürür: 0 çıkabilir, 1 asla çıkmaz. Programı her çalıştırdığında başka sayılar görürsün; çıktının yanındaki "örnek" notu bu yüzden.

Math.floor(): aşağı yuvarlamak

ders6.js
console.log(Math.floor(4.9))console.log(Math.floor(4.1))console.log(Math.floor(7))console.log(Math.floor(0.999))
Çıktı
4470

floor İngilizcede "zemin" demek: Math.floor sayıyı aşağı, altındaki tam sayıya yuvarlar. Sıfırdan büyük sayılarda "küsuratı at" diye düşünebilirsin: 4.9 bile 4 olur. Tam sayıya dokunmaz. (Sıfırdan küçük sayılarda ne olduğunu ve öteki yuvarlama türlerini Ders 9'da göreceksin.)

İkisini birleştirmek

Math.random() 0 ile 1 arası küsuratlı bir sayı veriyor. Oyunda ise "0 ile 5 arası ek hasar" gibi tam sayılar istersin. Bunu iki adımda yaparsın: önce 6 ile çarp, sonra aşağı yuvarla.

ders6.js
const sayi = Math.random()console.log(sayi)console.log(sayi * 6)console.log(Math.floor(sayi * 6))
Çıktıörnek, sende farklı çıkabilir
0.40152574259008622.40915445554051732
Math.random() 0 1 0 çıkabilir 1 asla çıkmaz 0.4015… 6 ile çarp … * 6 0 1 2 3 4 5 6 2.4091… aşağı yuvarla Math.floor(…) 0 1 2 3 4 5 Sonuç 0 ile 5 arası 6 tam sayıdan biri; 6 hiç gelmez.
Şekil 6.4 Math.random() 0 ile 1 arasında bir sayı verir. 6 ile çarpınca 0 ile 6 arasına yayılır, Math.floor küsuratı atar.

Neden 6 hiç gelmez? Çünkü Math.random() 1'e asla ulaşmaz; 6 ile çarpınca da sonuç 6'ya asla ulaşmaz. Çıkabilecek en büyük sayı 5.99… gibi bir şeydir, aşağı yuvarlanınca 5 olur. Bu kalıbı aklında tutman için birkaç örnek:

İstediğinKodÇıkabilecek sayılar
0'dan 5'eMath.floor(Math.random() * 6)0, 1, 2, 3, 4, 5
zar: 1'den 6'yaMath.floor(Math.random() * 6) + 11, 2, 3, 4, 5, 6
10'dan 15'e10 + Math.floor(Math.random() * 6)10, 11, 12, 13, 14, 15
gücün üstüne 0–5 ekguc + Math.floor(Math.random() * 6)guc ile guc + 5 arası
takımdan rastgele bir sıra numarasıMath.floor(Math.random() * takim.length)0'dan takim.length - 1'e

Kalıp şu: çarptığın sayı kaç farklı sonuç istediğin, eklediğin sayı en küçük sonuç. 10'dan 15'e kadar 6 farklı sayı var ve en küçüğü 10. Son satır da aynı kalıp: dört kişilik takımda dört sıra numarası (0, 1, 2, 3) var, en küçüğü 0. takim[4] gibi olmayan bir sıra numarası hiç gelmez.

Rastgele bir fonksiyonu denemek

Sonucu her seferinde değişen bir fonksiyonu nasıl denersin? Çok kez çalıştırıp sonuçlara bakarak. Aşağıdaki program zarı 1000 kez atıyor ve gördüğü en küçük ve en büyük sayıyı yazıyor (Ders 5'teki "en büyüğü bulma" kalıbı):

ders6.js
function zarAt() {    return Math.floor(Math.random() * 6) + 1} let enKucuk = zarAt()let enBuyuk = enKucukfor (let i = 0; i < 1000; i++) {    const zar = zarAt()    if (zar < enKucuk) {        enKucuk = zar    }    if (zar > enBuyuk) {        enBuyuk = zar    }}console.log("En küçük: " + enKucuk)console.log("En büyük: " + enBuyuk)
Çıktı
En küçük: 1En büyük: 6

1000 atışta 1'in ya da 6'nın hiç gelmemesi pratikte imkânsız, bu yüzden bu çıktı sende de aynı olur. 0, 7 ya da küsuratlı bir sayı görseydin kodunda bir yanlış olduğunu hemen anlardın. Sık hatalar bölümündeki rastgele sayı hatalarının hepsi bu denemede anında yakalanır.

Önce plan: problemi Türkçe adımlara bölmek

Şimdiye kadar yazdığın programlar en fazla birkaç düzine satırdı. Takım savaşı yüz satırı geçecek. Bu büyüklükte bir programa doğrudan kodla girersen nereden başlayacağını şaşırırsın, bir şey bozulduğunda da yerini bulamazsın. Deneyimli yazılımcılar önce ne yapacaklarını düz cümlelerle yazar.

Takım savaşının planı şöyle:

Metin
Takımları hazırla (her şampiyonun adı, canı, gücü var)Takımları ekrana yazTur sayacı 0İki takımda da canlı varken ve tur sınıra gelmediyse tekrarla:    turu 1 artır    mavinin her canlısı, kırmızının ilk canlısına vursun    kırmızının her canlısı, mavinin ilk canlısına vursun    (vuracak canlı rakip kalmadıysa o takımın sırası biter)Takımların son hâlini ekrana yazCanlı kalan takım kazanır; ikisi de ayaktaysa kazanan yok

Planı okuyunca sorular ve işler çıkıyor: "canlı mı?", "takımda canlı var mı?", "kime vuracağım?", "ne kadar vuracağım?". Her biri bir fonksiyon olacak ve çoğu bir şey döndürecek:

Plandaki soru ya da işFonksiyonNe döndürür?
Bir şampiyon ekranda nasıl görünsün?durum(sampiyon)metin
Takım ekranda nasıl görünsün?takimDurumu(takim)metin
Bu şampiyon canlı mı?canliMi(sampiyon)true ya da false
Takımda canlı kalan var mı?takimHayattaMi(takim)true ya da false
Kime vuracağım?hedefBul(takim)ilk canlı şampiyon (kimse yoksa undefined)
Ne kadar vuracağım?hasarHesapla(saldiran)sayı
Vur, canı düşürsaldir(saldiran, hedef)verilen hasar (sayı)
Bir takımın sırasıturOyna(saldiranlar, savunanlar)hiçbir şey (undefined)
Kim kazandı?kazananBul(maviTakim, kirmiziTakim)metin

Ana döngünün akışı da şöyle (Ders 2'deki akış şemaları gibi):

Takımları hazırla, tur = 0 İki takım da hayatta ve tur < sınır mı? hayır Kazananı ilan et evet 1. Turu bir artır 2. Mavi saldırır 3. Kırmızı saldırır ölüler atlanır, hedef ilk canlı rakip sonraki tur
Şekil 6.5 Takım savaşının ana döngüsü. Soru her turun başında yeniden sorulur.

Proje: takım savaşı

Klasörü hazırladıktan sonra projeyi yedi adımda kuracağız. Her adımın sonunda program çalışır durumda olacak ve çıktını benimkiyle karşılaştıracaksın. Bir adım çalışmadan sonrakine geçme: hatayı bulmak en kolay, en son değiştirdiğin birkaç satırdadır.

Adım 0: proje klasörü

Projeler kendi klasöründe durur: ders dosyalarınla karışmasın, ileride GitHub'a ayrı bir proje olarak koyabilesin. Terminalde cd C:\kod ile kod klasörüne geç, yeni klasörü oluştur ve VS Code'da aç:

Terminal — PowerShell
PS C:\kod> mkdir takim-savasi      Directory: C:\kod  Mode                 LastWriteTime         Length Name----                 -------------         ------ ----d-----        11.10.2026     16:13                takim-savasi PS C:\kod> code takim-savasi

Tarih ve saat sende farklı olacak. Tarihin biçimi, hatta Directory gibi başlıklar da Windows'unun dil ve bölge ayarına göre değişebilir; önemli olan en altta takim-savasi adını görmek. code takim-savasi komutu VS Code'u yeni bir pencerede, takim-savasi klasörüyle açar. ogren klasörünün açık olduğu eski pencere kapanmaz; ikisi arasında görev çubuğundan geçebilirsin.

Yeni pencere "Do you trust the authors of the files in this folder?" diye sorarsa Yes, I trust the authors'a bas: klasörü sen oluşturdun. Ders 0'da kod üst klasörüne güvenmeyi seçtiysen bu soru hiç gelmez. code komutu The term 'code' is not recognized hatası verirse (Türkçe mesajlı bir Windows'ta 'code' terimi ... tanınmıyor) VS Code'da File → Open Folder... ile C:\kod\takim-savasi klasörünü seç. Bu, Ders 0'daki node hatasının aynısı; sebebi ve çözümü orada.

Sonra Explorer'da New File ile savas.js dosyasını oluştur ve VS Code'un içinden yeni bir terminal aç (Terminal → New Terminal). İstemde PS C:\kod\takim-savasi> görmelisin. Bu bölümdeki bütün kodlar savas.js'e yazılıyor ve node savas.js ile çalıştırılıyor.

Adım 1: takımlar ve görünüm

İlk iş veriyi hazırlamak: iki takım, her biri obje dizisi (Ders 5). hp can, guc bir vuruşun hasarı. Takımları ekrana düzgün yazacak iki küçük fonksiyon da yazıyoruz; ikisi de metin döndürüyor.

savas.js
const mavi = [    { isim: "Garen", hp: 120, guc: 18 },    { isim: "Lux", hp: 80, guc: 24 },    { isim: "Jinx", hp: 70, guc: 28 }]const kirmizi = [    { isim: "Darius", hp: 150, guc: 20 },    { isim: "Annie", hp: 85, guc: 31 },    { isim: "Teemo", hp: 70, guc: 26 }] function durum(sampiyon) {    if (sampiyon.hp === 0) {        return sampiyon.isim + " (öldü)"    }    return sampiyon.isim + " " + sampiyon.hp} function takimDurumu(takim) {    let metin = ""    for (let i = 0; i < takim.length; i++) {        if (i > 0) {            metin = metin + ", "        }        metin = metin + durum(takim[i])    }    return metin} // denemeconsole.log(durum(mavi[0]))console.log(durum({ isim: "Teemo", hp: 0, guc: 26 }))console.log("Mavi: " + takimDurumu(mavi))console.log("Kırmızı: " + takimDurumu(kirmizi))
Çıktı
Garen 120Teemo (öldü)Mavi: Garen 120, Lux 80, Jinx 70Kırmızı: Darius 150, Annie 85, Teemo 70
  • durum erken çıkış kullanıyor: ölü şampiyon için "(öldü)" döndürüp çıkıyor, canlı olan için ad ve can döndürüyor.
  • takimDurumu bir metni döngüyle büyütüyor. Her turda durum'un dönüş değerini metnin sonuna ekliyor. if (i > 0) virgülü ilk şampiyondan önce koymamak için: virgül yalnız iki şampiyonun arasına girer.
  • En alttaki // deneme satırları, fonksiyonları yazar yazmaz denemek için. İkinci denemede ölü bir şampiyonu elle oluşturup sınır durumunu da denedik.

Çıktın aynıysa deneme satırlarını (// deneme ve altındakileri) sil. Bir sonraki adımda yenilerini yazacaksın. Her adımdaki kod bloğu, dosyanın sonuna eklenecek kısmı gösteriyor; satır numaraları da eski deneme satırlarını sildiğinde senin dosyandakiyle aynı olmalı.

Adım 2: canlı mı, takım hayatta mı?

Şimdi planın iki sorusu: "bu şampiyon canlı mı?" ve "takımda canlı kalan var mı?". İkincisini döngüdeki return bölümünde zaten doğru hâliyle yazdın; bu sefer canlılığı canliMi'ye soruyor.

savas.js
function canliMi(sampiyon) {    return sampiyon.hp > 0} function takimHayattaMi(takim) {    for (const sampiyon of takim) {        if (canliMi(sampiyon)) {            return true        }    }    return false} // denemeconst yarisiOlu = [    { isim: "Yasuo", hp: 0, guc: 25 },    { isim: "Ashe", hp: 40, guc: 22 }]const hepsiOlu = [    { isim: "Yasuo", hp: 0, guc: 25 },    { isim: "Ashe", hp: 0, guc: 22 }]console.log(canliMi(mavi[0]))console.log(canliMi(hepsiOlu[1]))console.log(takimHayattaMi(mavi))console.log(takimHayattaMi(yarisiOlu))console.log(takimHayattaMi(hepsiOlu))console.log(takimHayattaMi([]))
Çıktı
truefalsetruetruefalsefalse

Dördüncü deneme önemli: yarisiOlu takımının ilk şampiyonu ölü, ikincisi canlı. Fonksiyonu else içinde return false ile yazsaydın burada false görürdün. Bu tuzak hata mesajı vermediği için onu ancak böyle bir denemeyle yakalarsın.

Adım 3: hedef bulmak

Bir şampiyon kime vuracak? Planımıza göre rakip takımın ilk canlısına. Bu, döngünün içinde return'ün tam yeri: ilk canlıyı bulunca hemen onu döndür.

savas.js
function hedefBul(takim) {    for (const sampiyon of takim) {        if (canliMi(sampiyon)) {            return sampiyon        }    }} // denemeconst ilkiOlu = [    { isim: "Ezreal", hp: 0, guc: 24 },    { isim: "Sona", hp: 45, guc: 18 }]const kimseKalmadi = [    { isim: "Ezreal", hp: 0, guc: 24 }]console.log(hedefBul(kirmizi))console.log(hedefBul(ilkiOlu))console.log(hedefBul(kimseKalmadi))
Çıktı
{ isim: 'Darius', hp: 150, guc: 20 }{ isim: 'Sona', hp: 45, guc: 18 }undefined

hedefBul bir sayı ya da metin değil, şampiyonun objesinin kendisini döndürüyor. Canlı kimse yoksa döngü hiçbir return'e uğramadan biter ve undefined döner. Bu undefined'ı aklında tut: 5. adımda ona karşı önlem alacağız.

Adım 4: hasar ve saldırı

Sırada planın iki işi var: "ne kadar vuracağım?" ve "vur, canı düşür". Hasarı ayrı bir fonksiyon hesaplıyor; saldir hasarı ondan alıp hedefin canından düşüyor.

savas.js
function hasarHesapla(saldiran) {    return saldiran.guc} function saldir(saldiran, hedef) {    const hasar = hasarHesapla(saldiran)    hedef.hp = hedef.hp - hasar    if (hedef.hp < 0) {        hedef.hp = 0    }    const mesaj = saldiran.isim + " -> " + hedef.isim + ": " + hasar + " hasar"    console.log(mesaj + ", kalan can " + hedef.hp)    if (hedef.hp === 0) {        console.log(hedef.isim + " öldü.")    }    return hasar} // denemeconst vuran = { isim: "Yasuo", hp: 100, guc: 25 }const vurulan = { isim: "Ashe", hp: 40, guc: 22 }const donen = saldir(vuran, vurulan)console.log("saldir şunu döndürdü: " + donen)saldir(vuran, vurulan)console.log(vurulan)
Çıktı
Yasuo -> Ashe: 25 hasar, kalan can 15saldir şunu döndürdü: 25Yasuo -> Ashe: 25 hasar, kalan can 0Ashe öldü.{ isim: 'Ashe', hp: 0, guc: 22 }
  • hasarHesapla şimdilik yalnız gücü döndürüyor. Bunun için ayrı fonksiyon yazmak gereksiz görünebilir; sebebi 7. adımda belli olacak.
  • saldir hasarı hasarHesapla'ya soruyor, candan düşüyor ve canın eksiye inmesini engelliyor. İkinci vuruşta can 15 - 25, yani -10 olacaktı; if onu 0'a çekti. Eksi can hem tuhaf görünür hem de hp === 0 kontrolünü bozardı.
  • Fonksiyona verilen obje kopyalanmaz. saldir'ın içinde hedef.hp'yi değiştirmek dışarıdaki vurulan objesini değiştirdi (son satırda hp: 0). Takımlardaki şampiyonların canı da bu sayede düşecek.
  • saldir verdiği hasarı döndürüyor. Şimdilik onu yalnız deneme satırı kullanıyor; görevlerde işe yarayacak.

Denemeyi takımlardaki şampiyonlarla değil, ayrı deneme objeleriyle yaptık. Böylece mavi ve kırmızı takımın canları denemede bozulmadı.

Adım 5: bir takımın sırası

Bir takımın her canlı şampiyonu, rakibin ilk canlısına bir kez vuracak. Planın en dikkat isteyen kısmı burası:

savas.js
function turOyna(saldiranlar, savunanlar) {    for (const saldiran of saldiranlar) {        if (!canliMi(saldiran)) {            continue        }        if (!takimHayattaMi(savunanlar)) {            return        }        const hedef = hedefBul(savunanlar)        saldir(saldiran, hedef)    }} // denemeconst denemeMavi = [    { isim: "Yasuo", hp: 0, guc: 25 },    { isim: "Ashe", hp: 50, guc: 22 },    { isim: "Ezreal", hp: 50, guc: 24 }]const denemeKirmizi = [    { isim: "Malphite", hp: 20, guc: 15 }]turOyna(denemeMavi, denemeKirmizi)console.log("Tur bitti, program çökmedi.")
Çıktı
Ashe -> Malphite: 22 hasar, kalan can 0Malphite öldü.Tur bitti, program çökmedi.

Döngünün başındaki iki kontrolün ikisi de bu denemede işe yaradı:

  1. if (!canliMi(saldiran)) { continue }: ! "değil" demek (Ders 3), yani "saldıran canlı değilse". Ölü şampiyon saldıramaz, sıradakine geç. Yasuo atlandı.
  2. if (!takimHayattaMi(savunanlar)) { return }: vurulacak canlı rakip kalmadıysa turun geri kalanını oynamanın anlamı yok. Ashe, Malphite'ı öldürdü; Ezreal'in sırası geldiğinde fonksiyon erken çıktı.

Buradaki return'ün yanında değer yok. return yalnız fonksiyondan çıkmak için de yazılabilir; o zaman dönüş değeri undefined olur. turOyna'nın dönüş değerini zaten kimse kullanmıyor.

İkinci kontrolü silersen ne olur? hedefBul undefined döndürür ve saldir olmayan bir hedefin canını okumaya çalışır. Programın nasıl çöktüğünü Sık hatalar bölümünde göreceksin.

Adım 6: maçın tamamı

Şimdi her şeyi ana döngüde birleştiriyoruz. Deneme satırlarını sildiysen dosyanın tamamı aşağıdaki gibi olmalı; bu adımda eklenen satırlar vurgulu:

savas.js
const mavi = [    { isim: "Garen", hp: 120, guc: 18 },    { isim: "Lux", hp: 80, guc: 24 },    { isim: "Jinx", hp: 70, guc: 28 }]const kirmizi = [    { isim: "Darius", hp: 150, guc: 20 },    { isim: "Annie", hp: 85, guc: 31 },    { isim: "Teemo", hp: 70, guc: 26 }] function durum(sampiyon) {    if (sampiyon.hp === 0) {        return sampiyon.isim + " (öldü)"    }    return sampiyon.isim + " " + sampiyon.hp} function takimDurumu(takim) {    let metin = ""    for (let i = 0; i < takim.length; i++) {        if (i > 0) {            metin = metin + ", "        }        metin = metin + durum(takim[i])    }    return metin} function canliMi(sampiyon) {    return sampiyon.hp > 0} function takimHayattaMi(takim) {    for (const sampiyon of takim) {        if (canliMi(sampiyon)) {            return true        }    }    return false} function hedefBul(takim) {    for (const sampiyon of takim) {        if (canliMi(sampiyon)) {            return sampiyon        }    }} function hasarHesapla(saldiran) {    return saldiran.guc} function saldir(saldiran, hedef) {    const hasar = hasarHesapla(saldiran)    hedef.hp = hedef.hp - hasar    if (hedef.hp < 0) {        hedef.hp = 0    }    const mesaj = saldiran.isim + " -> " + hedef.isim + ": " + hasar + " hasar"    console.log(mesaj + ", kalan can " + hedef.hp)    if (hedef.hp === 0) {        console.log(hedef.isim + " öldü.")    }    return hasar} function turOyna(saldiranlar, savunanlar) {    for (const saldiran of saldiranlar) {        if (!canliMi(saldiran)) {            continue        }        if (!takimHayattaMi(savunanlar)) {            return        }        const hedef = hedefBul(savunanlar)        saldir(saldiran, hedef)    }} function kazananBul(maviTakim, kirmiziTakim) {    if (!takimHayattaMi(kirmiziTakim)) {        return "Mavi takım"    }    if (!takimHayattaMi(maviTakim)) {        return "Kırmızı takım"    }    return "yok, tur sınırı doldu"} const turSiniri = 20let tur = 0console.log("Mavi: " + takimDurumu(mavi))console.log("Kırmızı: " + takimDurumu(kirmizi))while (takimHayattaMi(mavi) && takimHayattaMi(kirmizi) && tur < turSiniri) {    tur++    console.log("--- " + tur + ". tur ---")    turOyna(mavi, kirmizi)    turOyna(kirmizi, mavi)}console.log("--- Maç " + tur + " turda bitti ---")console.log("Mavi: " + takimDurumu(mavi))console.log("Kırmızı: " + takimDurumu(kirmizi))console.log("Kazanan: " + kazananBul(mavi, kirmizi))
Çıktı
Mavi: Garen 120, Lux 80, Jinx 70Kırmızı: Darius 150, Annie 85, Teemo 70--- 1. tur ---Garen -> Darius: 18 hasar, kalan can 132Lux -> Darius: 24 hasar, kalan can 108Jinx -> Darius: 28 hasar, kalan can 80Darius -> Garen: 20 hasar, kalan can 100Annie -> Garen: 31 hasar, kalan can 69Teemo -> Garen: 26 hasar, kalan can 43--- 2. tur ---Garen -> Darius: 18 hasar, kalan can 62Lux -> Darius: 24 hasar, kalan can 38Jinx -> Darius: 28 hasar, kalan can 10Darius -> Garen: 20 hasar, kalan can 23Annie -> Garen: 31 hasar, kalan can 0Garen öldü.Teemo -> Lux: 26 hasar, kalan can 54--- 3. tur ---Lux -> Darius: 24 hasar, kalan can 0Darius öldü.Jinx -> Annie: 28 hasar, kalan can 57Annie -> Lux: 31 hasar, kalan can 23Teemo -> Lux: 26 hasar, kalan can 0Lux öldü.--- 4. tur ---Jinx -> Annie: 28 hasar, kalan can 29Annie -> Jinx: 31 hasar, kalan can 39Teemo -> Jinx: 26 hasar, kalan can 13--- 5. tur ---Jinx -> Annie: 28 hasar, kalan can 1Annie -> Jinx: 31 hasar, kalan can 0Jinx öldü.--- Maç 5 turda bitti ---Mavi: Garen (öldü), Lux (öldü), Jinx (öldü)Kırmızı: Darius (öldü), Annie 1, Teemo 70Kazanan: Kırmızı takım

Önce yeni satırlar:

  • kazananBul üç yoldan birinden döner. Kırmızıda canlı kalmadıysa Mavi kazanmıştır; mavide kalmadıysa Kırmızı. İkisi de ayaktaysa döngü tur sınırı yüzünden bitmiştir ve kazanan yoktur. Her if return ile bittiği için else yok.
  • Ana döngünün koşulu üç parçalı: iki takım da hayatta ve tur sınıra gelmedi. Biri bozulunca döngü biter.
  • tur++ döngünün en başında. Böylece ilk tur "1. tur" diye yazılır ve döngü bitince tur oynanan tur sayısını tutar.

Sonra çıktıyı satır satır oku; planın her parçası orada:

  • İkinci turda Garen öldü. Teemo'nun sırası geldiğinde hedefBul sıradaki canlıyı, Lux'u buldu.
  • Üçüncü turda ölü Garen ve ölü Darius'un sırası gelince ikisi de atlandı (continue).
  • Beşinci turda Annie, Jinx'i öldürünce mavi takımda kimse kalmadı. Teemo'nun sırası geldiğinde turOyna erken çıktı ve program çökmedi.
  • Jinx, Annie'yi 1 cana kadar indirdi. Bu sayı birazdan önem kazanacak.

Tur sınırı neden var?

Bu maç 5 turda bitti, sınır hiç devreye girmedi. Ama bir gün iyileşme ekledin ve iyileşme hasarı karşılamaya başladı diyelim: kimse ölmez, while koşulu hep true kalır ve döngü sonsuza kadar döner. Sınır bunu önler. Proje klasöründe deneme.js adında yeni bir dosya aç, şunu yaz ve node deneme.js ile çalıştır:

deneme.js
let hp = 100let tur = 0const turSiniri = 5while (hp > 0 && tur < turSiniri) {    tur++    hp = hp - 20    hp = hp + 20}console.log(tur + " tur oynandı, hp: " + hp)
Çıktı
5 tur oynandı, hp: 100

Can hiç düşmedi ama program 5 turda durdu. && tur < turSiniri kısmını silsen bu döngü hiç bitmez ve Ders 5'teki gibi Ctrl+C ile durdurman gerekirdi. Her while döngüsüne "bir şey ters giderse en fazla şu kadar dön" diyen bir sınır koymak iyi bir alışkanlıktır. Projedeki sınırı denemek istersen turSiniri'ni geçici olarak 2 yap: maç 2 turda biter ve Kazanan: yok, tur sınırı doldu yazar.

Adım 7: rastgele hasar

Program doğru çalışıyor, ama her seferinde aynı maçı oynuyor. Biraz şans katalım. Hasar hesabı tek bir fonksiyonda olduğu için yalnız orayı değiştirmek yetiyor: savaşın geri kalanı hasarın nasıl hesaplandığını bilmiyor, yalnız dönen sayıyı kullanıyor. hasarHesapla'yı şununla değiştir:

savas.js
const rastgeleHasar = true function hasarHesapla(saldiran) {    if (!rastgeleHasar) {        return saldiran.guc    }    return saldiran.guc + Math.floor(Math.random() * 6)}

rastgeleHasar bir açma kapama anahtarı. false yaparsan erken return çalışır ve hasar eskisi gibi sabit kalır. true yaparsan her vuruşa 0 ile 5 arası ek hasar eklenir.

Yazdıktan sonra anahtarı önce false yap ve çalıştır: çıktın 6. adımdakiyle birebir aynı olmalı. Böylece değişikliğin hiçbir şeyi bozmadığını görürsün. Sonra yeniden true yap ve birkaç kez çalıştır:

Çıktıörnek, sende farklı çıkabilir
Mavi: Garen 120, Lux 80, Jinx 70Kırmızı: Darius 150, Annie 85, Teemo 70--- 1. tur ---Garen -> Darius: 21 hasar, kalan can 129Lux -> Darius: 29 hasar, kalan can 100Jinx -> Darius: 31 hasar, kalan can 69Darius -> Garen: 22 hasar, kalan can 98Annie -> Garen: 33 hasar, kalan can 65Teemo -> Garen: 26 hasar, kalan can 39--- 2. tur ---Garen -> Darius: 20 hasar, kalan can 49Lux -> Darius: 26 hasar, kalan can 23Jinx -> Darius: 32 hasar, kalan can 0Darius öldü.Annie -> Garen: 32 hasar, kalan can 7Teemo -> Garen: 28 hasar, kalan can 0Garen öldü.--- 3. tur ---Lux -> Annie: 28 hasar, kalan can 57Jinx -> Annie: 33 hasar, kalan can 24Annie -> Lux: 34 hasar, kalan can 46Teemo -> Lux: 26 hasar, kalan can 20--- 4. tur ---Lux -> Annie: 24 hasar, kalan can 0Annie öldü.Jinx -> Teemo: 29 hasar, kalan can 41Teemo -> Lux: 29 hasar, kalan can 0Lux öldü.--- 5. tur ---Jinx -> Teemo: 31 hasar, kalan can 10Teemo -> Jinx: 29 hasar, kalan can 41--- 6. tur ---Jinx -> Teemo: 31 hasar, kalan can 0Teemo öldü.--- Maç 6 turda bitti ---Mavi: Garen (öldü), Lux (öldü), Jinx 41Kırmızı: Darius (öldü), Annie (öldü), Teemo (öldü)Kazanan: Mavi takım

Bu maçı Mavi kazandı. 2. turda ek hasarlar Darius'u bir tur erken düşürdü; Darius o tur vuramadı ve dengeler değişti. Sabit hasarda Annie 1 canla kurtulmuştu; şans biraz Mavi'den yana dönünce sonuç da döndü.

Ben programı 40 kez çalıştırdım: 25 maçı Mavi, 15 maçı Kırmızı kazandı. Sen de birkaç kez çalıştır: her maç farklı, ama kurallar aynı.

Sık hatalar

Bu derste karşılaşabileceğin hatalar. Bir hata aldığında buraya ya da bütün derslerin hatalarının toplandığı hata rehberine bak.

Sık hataundefined ya da NaN: return yerine console.log yazmak

Ne zaman çıkar? Fonksiyon sonucu ekrana yazıyor ama geri vermiyorsa. Ekranda doğru sayıyı gördüğün için fonksiyonun çalıştığını sanırsın; sonucu kullandığın yere ise undefined gelir. undefined ile hesap yaparsan sonuç NaN olur.

ders6.js
function kritikHasar(hasar) {    console.log(hasar * 2)} let hp = 200hp = hp - kritikHasar(30)console.log("Kalan can: " + hp)
Çıktı
60Kalan can: NaN

NaN'ı Ders 3'ten tanıyorsun: İngilizce Not a Number, yani "sayı değil". Burada 200 - undefined gibi anlamsız bir hesabın sonucu. Ayrıntısını Ders 9'da göreceksin.

Nasıl düzelir? console.log(hasar * 2) yerine return hasar * 2 yaz. Sonucu görmek istiyorsan fonksiyonu çağırdığın yerde yazdır: console.log(kritikHasar(30)). return sözcüğünü unutup gövdeye yalnız hasar * 2 yazarsan ekrana 60 bile gelmez, yine Kalan can: NaN görürsün: hesap yapılır ama hiçbir yere gitmez.

Sık hataDöngünün içinde erken return false

Ne zaman çıkar? "Takımda canlı var mı?", "listede Garen var mı?" gibi arama fonksiyonlarında return false'u döngünün içine, else'e yazınca. Fonksiyon yalnız ilk elemana bakıp karar verir. Hata mesajı çıkmaz, cevap sessizce yanlış olur.

Nasıl düzelir? else kısmını sil ve return false'u döngünün altına taşı: "yok" cevabı ancak herkese bakıldıktan sonra verilir. Fonksiyonu mutlaka ilk elemanı tutmayan bir diziyle dene; hatayı yalnız böyle bir deneme gösterir. Örneği ve şekli yukarıda, döngünün içinde return bölümünde.

Sık hatareturn'den sonra yazılan satır hiç çalışmıyor

Ne zaman çıkar? Bir satırı return'ün altına yazınca. return fonksiyonu bitirdiği için o satıra hiç inilmez. Hata mesajı çıkmaz; VS Code satırı soluk gösterir ve üstüne gelince Unreachable code detected der.

Nasıl düzelir? Çalışmasını istediğin satırı return'ün üstüne taşı. "İksir içildi" yazısı gibi bir şey göstermek istiyorsan önce yazdır, sonra döndür. Örnek: erken çıkış bölümündeki iksirIc.

Sık hataHasar küsuratlı çıkıyor: Math.random() * 6 tam sayı değil

Ne zaman çıkar? Math.random()'ı bir sayıyla çarpıp tam sayı elde ettiğini sanınca.

ders6.js
const hasar = Math.random() * 6console.log("Ek hasar: " + hasar)
Çıktıörnek, sende farklı çıkabilir
Ek hasar: 5.648484269325396

Nasıl düzelir? Çarpma sonucunu Math.floor ile aşağı yuvarla: Math.floor(Math.random() * 6). Bu, 0 ile 5 arası bir tam sayı verir.

Sık hataRastgele sayı hep 0 çıkıyor

Ne zaman çıkar? Math.floor'un parantezini yanlış yerde kapatınca.

ders6.js
for (let i = 0; i < 5; i++) {    console.log(Math.floor(Math.random()) * 6)}
Çıktı
00000

Math.random() hep 1'den küçük olduğu için Math.floor(Math.random()) her zaman 0'dır; 0 kere 6 da 0.

Nasıl düzelir? Önce çarp, sonra yuvarla: çarpma Math.floor'un parantezinin içinde olmalı. Doğrusu Math.floor(Math.random() * 6). Rastgele bir fonksiyonu çok kez çalıştırıp en küçük ve en büyük sonucu yazdırırsan bu hata hemen görünür.

Sık hataReferenceError: math is not defined

Ne zaman çıkar? Math'i küçük harfle yazınca. Büyük-küçük harf farklı adlar demek; math diye bir şey yok.

ders6.js
const ekHasar = math.floor(Math.random() * 6)console.log(ekHasar)
Hata çıktısı
C:\kod\ogren\ders6.js:1const ekHasar = math.floor(Math.random() * 6)                ^ ReferenceError: math is not defined    at Object.<anonymous> (C:\kod\ogren\ders6.js:1:17)    ... Node.js v24.20.0

Nasıl düzelir? Math her zaman büyük M ile yazılır. console küçük harfle, Math büyük harfle başlar; ikisini de ezberlemen gerekiyor.

Sık hataHasar NaN çıkıyor: Math.random parantezsiz

Ne zaman çıkar? Math.random'ı çağırmayı, yani () koymayı unutunca.

ders6.js
const ekHasar = Math.floor(Math.random * 6)console.log("Ek hasar: " + ekHasar)
Çıktı
Ek hasar: NaN

Parantezsiz Math.random sayı değil, fonksiyonun kendisi. Bir fonksiyonu 6 ile çarpmak anlamsız bir hesap, sonucu da NaN. Ders 3'teki "fonksiyonu parantezsiz çağırmak" hatasının bir başka hâli.

Nasıl düzelir? Math.random() yaz: fonksiyonu çağırmak için parantez şart.

Sık hataTypeError: Cannot read properties of undefined (reading 'hp')

Ne zaman çıkar? Takım savaşında turOyna'daki if (!takimHayattaMi(savunanlar)) { return } kontrolünü silince. Rakip takımın son canlısı turun ortasında ölürse sıradaki saldıran için hedefBul undefined döndürür ve saldir olmayan bir hedefin canını okumaya çalışır.

savas.js✗ Yanlış
function turOyna(saldiranlar, savunanlar) {    for (const saldiran of saldiranlar) {        if (!canliMi(saldiran)) {            continue        }        const hedef = hedefBul(savunanlar)        saldir(saldiran, hedef)    }}
Hata çıktısı
...--- 5. tur ---Jinx -> Annie: 28 hasar, kalan can 1Annie -> Jinx: 31 hasar, kalan can 0Jinx öldü.C:\kod\takim-savasi\savas.js:57    hedef.hp = hedef.hp - hasar                     ^ TypeError: Cannot read properties of undefined (reading 'hp')    at saldir (C:\kod\takim-savasi\savas.js:57:22)    at turOyna (C:\kod\takim-savasi\savas.js:75:9)    at Object.<anonymous> (C:\kod\takim-savasi\savas.js:97:5)    ... Node.js v24.20.0

Mesaj "undefined'ın hp alanı okunamıyor" diyor. Hata 57. satırda, saldir'ın içinde çıktı; ama at satırları kimin kimi çağırdığını da gösteriyor: saldir'ı 75. satırdan turOyna çağırmış. ^ işareti hedef.hp'nin altında: hedef bir şampiyon değil, undefined. Annie, Jinx'i öldürdü ve mavide kimse kalmadı, ama Teemo yine de saldırmaya çalıştı.

Bu çıktı 6. adımdaki dosyadan. 7. adımdan sonra denersen rastgeleHasar'ı false yap; dosyaya beş satır eklendiği için satır numaraları 62, 80 ve 102 çıkar. Anahtar true iken bu çöküşü büyük ihtimalle hiç görmezsin: ben kontrolsüz programla 100.000 rastgele maç oynattım, yalnız 43'ünde çöktü. Arada bir çıkan hata en sinsi hatadır; rastgeleliği kapatıp sabit hasarla denemek bu yüzden önemli.

Nasıl düzelir? Kontrolü geri koy: rakipte canlı kalmadıysa return ile turu bitir. Genel kural: undefined döndürebilen bir fonksiyonun sonucunu kullanmadan önce o durumu ele al.

Görevler

İlk üç görevi C:\kod\ogren\ders6.js'te yap: ogren klasörünün açık olduğu VS Code penceresine dön ve her görevde önceki kodu sil ya da satırların başına // koy.

Görev 4, 5 ve 6 projeyi büyütüyor: her birini takim-savasi klasöründe, savas.js'in bir kopyasında yap ki asıl dosyan bozulmasın. Kopya için savas.js'i aç, Ctrl+A ile hepsini seç, Ctrl+C ile kopyala, New File ile görevin istediği adda yeni bir dosya aç ve Ctrl+V ile yapıştır. Kopyayı kendi adıyla çalıştırırsın: node kritik.js gibi.

Proje görevlerinin çözümleri savas.js'in 7. adımdaki hâlinden başlıyor ve rastgeleHasar = false kullanıyor; böylece çıktın benimkiyle birebir aynı olmalı. Önce kendin dene, takılırsan ipuçlarını sırayla aç; çözüme en son bak.

Görev 1

Minyon altını

Bir koridor dalgasında 6 normal minyon (3 yakın dövüş, 3 büyücü) ve bazen 1 top minyonu gelir. Bu görevde her normal minyon 20, her top minyonu 60 altın versin. minyonAltini(normal, top) adında, kazanılan altını döndüren bir fonksiyon yaz. Fonksiyonun içinde console.log olmasın: hesabı yapıp sonucu geri versin, yazdırma işini dışarıda yap.

Sonra fonksiyonu tam bir dalga (6 normal, 1 top) ve boş bir dalga (0, 0) için kullan. altin değişkenini 500'den başlat, tam dalganın altınını ona ekle. Çıktı şöyle olmalı:

Metin
Tam dalga: 180 altınBoş dalga: 0 altınKasada: 680 altın
İpucu 1

Fonksiyonun gövdesi tek satır: return ve arkasından hesap. 6 normal minyon 6 * 20 eder.

İpucu 2

Dönen değeri metnin içinde kullanabilirsin: "Tam dalga: " + minyonAltini(6, 1) + " altın". Kasaya eklemek için altin = altin + minyonAltini(6, 1).

Çözümü göster
ders6.js
function minyonAltini(normal, top) {    return normal * 20 + top * 60} let altin = 500console.log("Tam dalga: " + minyonAltini(6, 1) + " altın")console.log("Boş dalga: " + minyonAltini(0, 0) + " altın")altin = altin + minyonAltini(6, 1)console.log("Kasada: " + altin + " altın")
Çıktı
Tam dalga: 180 altınBoş dalga: 0 altınKasada: 680 altın

Boş dalga satırı sınır denemesi: hiç minyon yoksa 0 dönmeli. Fonksiyonun içinde return yerine console.log yazsaydın çıktı 180 ve Tam dalga: undefined altın diye başlar, Kasada: NaN altın diye biterdi: sayılar ekrana yazılır ama hiçbiri geri dönmez.

Görev 2

TFT faizi, bu sefer fonksiyonla

Ders 2'deki TFT faizi görevini hatırla: elindeki her 10 altın için 1 altın faiz alırsın, ama faiz 5'i geçmez (37 altında 3, 80 altında yine 5). Orada faizi tek bir altin değeri için hesaplamıştın; başka bir değeri denemek için sayıyı değiştirip programı yeniden çalıştırman gerekiyordu. Şimdi faizi döndüren bir faizHesapla(altin) fonksiyonu yaz: 50 ve üstü için erken return kullan, gerisi için Math.floor.

Sonra [0, 9, 10, 49, 50, 51, 120] dizisindeki her değeri bir döngüyle dene. Çıktı şöyle olmalı:

Metin
0 altın -> 0 faiz9 altın -> 0 faiz10 altın -> 1 faiz49 altın -> 4 faiz50 altın -> 5 faiz51 altın -> 5 faiz120 altın -> 5 faiz
İpucu 1

Önce sınırı yakala: if (altin >= 50) { return 5 }. Bu satırın altına yalnız 50'den az altınlar ulaşır.

İpucu 2

37 altında faiz 3: 37 / 10 sonucu 3.7, küsuratı atınca 3. Küsuratı atan fonksiyon hangisiydi?

İpucu 3

Döngü: for (const altin of denemeler) { ... }. İçinde console.log(altin + " altın -> " + faizHesapla(altin) + " faiz").

Çözümü göster
ders6.js
function faizHesapla(altin) {    if (altin >= 50) {        return 5    }    return Math.floor(altin / 10)} const denemeler = [0, 9, 10, 49, 50, 51, 120]for (const altin of denemeler) {    console.log(altin + " altın -> " + faizHesapla(altin) + " faiz")}
Çıktı
0 altın -> 0 faiz9 altın -> 0 faiz10 altın -> 1 faiz49 altın -> 4 faiz50 altın -> 5 faiz51 altın -> 5 faiz120 altın -> 5 faiz

Denemeler iki sınırın iki yanında: 9 ile 10 Math.floor'un sınırı, 49 ile 50 erken return'ün sınırı. Erken return olmasaydı 120 altında 12 faiz çıkardı. Bu görevde >= yerine > yazsan da sonuç değişmezdi, çünkü 50 altında Math.floor(50 / 10) de 5 verir. Bunu ancak 50'yi deneyerek öğrenebilirdin; sınırın tam üstünü denemek bu yüzden önemli.

Ders 2'deki çözümle karşılaştır: küsuratı (altin - altin % 10) / 10 ile atmıştın, Math.floor(altin / 10) aynı işi daha okunur yapıyor. Asıl kazanç da return: hesap bir kez yazıldı, yedi değer tek çalıştırmada denendi.

Görev 3

Alabileceğin ilk eşya

Dükkân rafındaki eşyalar fiyata göre sıralı değil:

JavaScript
const raf = [    { isim: "Sonsuzluk Kılıcı", fiyat: 3400 },    { isim: "Zhonya'nın Kum Saati", fiyat: 3250 },    { isim: "Uzun Kılıç", fiyat: 350 },    { isim: "Doran'ın Kalkanı", fiyat: 450 }]

ilkAlinabilen(esyalar, altin) adında bir fonksiyon yaz: eşyalara sırayla baksın ve altının yettiği ilk eşyanın adını döndürsün (en ucuzunu değil, sırada ilk geleni). Hiçbirine altın yetmiyorsa "Hiçbiri" döndürsün. Fonksiyonu 0, 349, 350, 3300 ve 5000 altınla, bir de boş bir rafla ([]) dene. Çıktı şöyle olmalı:

Metin
0 altın: Hiçbiri349 altın: Hiçbiri350 altın: Uzun Kılıç3300 altın: Zhonya'nın Kum Saati5000 altın: Sonsuzluk KılıcıBoş raf: Hiçbiri
İpucu 1

Bu bir arama: aradığını bulduğun an döndür, kalan eşyalara bakma. Asıl soru "Hiçbiri" cevabının yeri: döngünün içi mi, altı mı? Döngünün içinde return bölümündeki tuzağı hatırla.

İpucu 2

Döngünün içinde: if (esya.fiyat <= altin) { return esya.isim }. Neden < değil de <=? 350 altınla Uzun Kılıç alınabilmeli.

İpucu 3

return "Hiçbiri" döngünün kapanan süslü parantezinin altına, fonksiyonun son satırı olarak gelir; else yok. Denemeler için bir altın dizisini for...of ile gez, boş rafı ayrı bir satırla dene: ilkAlinabilen([], 5000).

Çözümü göster
ders6.js
function ilkAlinabilen(esyalar, altin) {    for (const esya of esyalar) {        if (esya.fiyat <= altin) {            return esya.isim        }    }    return "Hiçbiri"} const raf = [    { isim: "Sonsuzluk Kılıcı", fiyat: 3400 },    { isim: "Zhonya'nın Kum Saati", fiyat: 3250 },    { isim: "Uzun Kılıç", fiyat: 350 },    { isim: "Doran'ın Kalkanı", fiyat: 450 }]const denemeler = [0, 349, 350, 3300, 5000]for (const altin of denemeler) {    console.log(altin + " altın: " + ilkAlinabilen(raf, altin))}console.log("Boş raf: " + ilkAlinabilen([], 5000))
Çıktı
0 altın: Hiçbiri349 altın: Hiçbiri350 altın: Uzun Kılıç3300 altın: Zhonya'nın Kum Saati5000 altın: Sonsuzluk KılıcıBoş raf: Hiçbiri

Her deneme başka bir hatayı yakalar:

  • return "Hiçbiri"'yi döngünün içine, else'e yazsaydın 350 ve 3300 altında Hiçbiri çıkardı: ilk eşyaya altın yetmeyince fonksiyon hemen pes ederdi. Boş rafta da döngü hiç dönmez ve undefined görürdün.
  • <= yerine < yazsaydın 350 altında Hiçbiri çıkardı.
  • Döngünün altındaki return'ü unutsaydın 0 ve 349 altında, bir de boş rafta undefined görürdün.
Görev 4

Kritik vuruş

Yeni kopyanın adı kritik.js olsun.

  • Her şampiyona kritik alanı ekle: kritik vuruş şansı, 0 ile 1 arasında bir sayı (0.25 yüzde 25 demek).
  • kritikMi(sans) fonksiyonunu yaz: şans tuttuysa true, tutmadıysa false döndürsün.
  • saldir'da kritik vuruş olursa hasar iki katına çıksın ve satıra (kritik!) eklensin.

Çıktını benimkiyle karşılaştırabilmek için rastgeleHasar'ı false yap, Jinx'in kritik şansını 1, diğer herkesinkini 0 yap. Jinx'in her vuruşu kritik olmalı, ilk vuruşu şöyle görünmeli:

Metin
Jinx -> Darius: 56 hasar (kritik!), kalan can 52

Bu ayarla maçı Mavi kazanmalı.

İpucu 1

Math.random() 0 ile 1 arası bir sayı veriyor. Şans 0.25 iken bu sayının 0.25'ten küçük çıkma olasılığı yüzde 25'tir. Karşılaştırmanın sonucu zaten true ya da false; menzildeMi'deki gibi onu doğrudan döndürebilirsin.

İpucu 2

kritikMi tek satır: return Math.random() < sans. Önce onu tek başına dene: şans 0 iken hiç, 1 iken her seferinde true dönmeli. Sonra saldir'da hasar artık değişecek: const yerine let yap ve let not = "" ile boş bir not hazırla.

İpucu 3

Kritikse hasar = hasar * 2 ve not = " (kritik!)". Mesaj satırında " hasar"'dan sonra + not ekle; not boşsa satır eskisi gibi görünür.

Çözümü göster

Önce kritikMi'yi tek başına denedim (ayrı bir deneme dosyasında):

deneme.js
function kritikMi(sans) {    return Math.random() < sans} let sifirdaKritik = 0let birdeKritik = 0let ceyrekteKritik = 0for (let i = 0; i < 10000; i++) {    if (kritikMi(0)) {        sifirdaKritik++    }    if (kritikMi(1)) {        birdeKritik++    }    if (kritikMi(0.25)) {        ceyrekteKritik++    }}console.log("Şans 0: " + sifirdaKritik + " kritik")console.log("Şans 1: " + birdeKritik + " kritik")console.log("Şans 0.25: " + ceyrekteKritik + " kritik")
Çıktıörnek, sende farklı çıkabilir
Şans 0: 0 kritikŞans 1: 10000 kritikŞans 0.25: 2440 kritik

İlk iki satır her zaman aynı çıkar; üçüncüsü 2500 civarında oynar. Neden <= değil de <? Math.random() tam 0 döndürebilir. <= yazsaydın kritikMi(0) çok nadiren de olsa true dönebilirdi; < ile şans 0 hiç, şans 1 her zaman kritik verir.

Sonra projeye ekledim. Değişen satırlar vurgulu:

kritik.js
const mavi = [    { isim: "Garen", hp: 120, guc: 18, kritik: 0 },    { isim: "Lux", hp: 80, guc: 24, kritik: 0 },    { isim: "Jinx", hp: 70, guc: 28, kritik: 1 }]const kirmizi = [    { isim: "Darius", hp: 150, guc: 20, kritik: 0 },    { isim: "Annie", hp: 85, guc: 31, kritik: 0 },    { isim: "Teemo", hp: 70, guc: 26, kritik: 0 }] function durum(sampiyon) {    if (sampiyon.hp === 0) {        return sampiyon.isim + " (öldü)"    }    return sampiyon.isim + " " + sampiyon.hp} function takimDurumu(takim) {    let metin = ""    for (let i = 0; i < takim.length; i++) {        if (i > 0) {            metin = metin + ", "        }        metin = metin + durum(takim[i])    }    return metin} function canliMi(sampiyon) {    return sampiyon.hp > 0} function takimHayattaMi(takim) {    for (const sampiyon of takim) {        if (canliMi(sampiyon)) {            return true        }    }    return false} function hedefBul(takim) {    for (const sampiyon of takim) {        if (canliMi(sampiyon)) {            return sampiyon        }    }} const rastgeleHasar = false function hasarHesapla(saldiran) {    if (!rastgeleHasar) {        return saldiran.guc    }    return saldiran.guc + Math.floor(Math.random() * 6)} function kritikMi(sans) {    return Math.random() < sans} function saldir(saldiran, hedef) {    let hasar = hasarHesapla(saldiran)    let not = ""    if (kritikMi(saldiran.kritik)) {        hasar = hasar * 2        not = " (kritik!)"    }    hedef.hp = hedef.hp - hasar    if (hedef.hp < 0) {        hedef.hp = 0    }    const mesaj = saldiran.isim + " -> " + hedef.isim + ": " + hasar + " hasar" + not    console.log(mesaj + ", kalan can " + hedef.hp)    if (hedef.hp === 0) {        console.log(hedef.isim + " öldü.")    }    return hasar} function turOyna(saldiranlar, savunanlar) {    for (const saldiran of saldiranlar) {        if (!canliMi(saldiran)) {            continue        }        if (!takimHayattaMi(savunanlar)) {            return        }        const hedef = hedefBul(savunanlar)        saldir(saldiran, hedef)    }} function kazananBul(maviTakim, kirmiziTakim) {    if (!takimHayattaMi(kirmiziTakim)) {        return "Mavi takım"    }    if (!takimHayattaMi(maviTakim)) {        return "Kırmızı takım"    }    return "yok, tur sınırı doldu"} const turSiniri = 20let tur = 0console.log("Mavi: " + takimDurumu(mavi))console.log("Kırmızı: " + takimDurumu(kirmizi))while (takimHayattaMi(mavi) && takimHayattaMi(kirmizi) && tur < turSiniri) {    tur++    console.log("--- " + tur + ". tur ---")    turOyna(mavi, kirmizi)    turOyna(kirmizi, mavi)}console.log("--- Maç " + tur + " turda bitti ---")console.log("Mavi: " + takimDurumu(mavi))console.log("Kırmızı: " + takimDurumu(kirmizi))console.log("Kazanan: " + kazananBul(mavi, kirmizi))
Çıktı
Mavi: Garen 120, Lux 80, Jinx 70Kırmızı: Darius 150, Annie 85, Teemo 70--- 1. tur ---Garen -> Darius: 18 hasar, kalan can 132Lux -> Darius: 24 hasar, kalan can 108Jinx -> Darius: 56 hasar (kritik!), kalan can 52Darius -> Garen: 20 hasar, kalan can 100Annie -> Garen: 31 hasar, kalan can 69Teemo -> Garen: 26 hasar, kalan can 43--- 2. tur ---Garen -> Darius: 18 hasar, kalan can 34Lux -> Darius: 24 hasar, kalan can 10Jinx -> Darius: 56 hasar (kritik!), kalan can 0Darius öldü.Annie -> Garen: 31 hasar, kalan can 12Teemo -> Garen: 26 hasar, kalan can 0Garen öldü.--- 3. tur ---Lux -> Annie: 24 hasar, kalan can 61Jinx -> Annie: 56 hasar (kritik!), kalan can 5Annie -> Lux: 31 hasar, kalan can 49Teemo -> Lux: 26 hasar, kalan can 23--- 4. tur ---Lux -> Annie: 24 hasar, kalan can 0Annie öldü.Jinx -> Teemo: 56 hasar (kritik!), kalan can 14Teemo -> Lux: 26 hasar, kalan can 0Lux öldü.--- 5. tur ---Jinx -> Teemo: 56 hasar (kritik!), kalan can 0Teemo öldü.--- Maç 5 turda bitti ---Mavi: Garen (öldü), Lux (öldü), Jinx 70Kırmızı: Darius (öldü), Annie (öldü), Teemo (öldü)Kazanan: Mavi takım

Deneme bitince kritik şanslarını gerçekçi değerlere çek (örneğin Jinx 0.3, Garen 0.1) ve rastgeleHasar'ı true yap. Kritik şansı olmayan bir şampiyona da kritik: 0 yaz. Alan yoksa saldiran.kritik undefined olur; Math.random() < undefined her seferinde false verdiği için program hata vermez, ama bu bir tesadüf. Alanı açıkça yazınca ne istediğin kodda görünür.

Görev 5

İyileşme

Yeni kopyanın adı iyilesme.js olsun. Her turun sonunda iki takımın canlı şampiyonları 8 can yenilesin. Ama ölüler dirilmez ve kimse başlangıç canını geçemez.

  • Her şampiyona maxHp alanı ekle (başlangıç canıyla aynı).
  • iyilestir(sampiyon, miktar) canı artırsın ve gerçekten yenilenen canı döndürsün: ölüye 0, canı dolu olana 0, canı 67/70 olana 8 değil 3.
  • takimiIyilestir(takim, miktar) takımdaki herkesi iyileştirsin ve toplam yenilenen canı döndürsün.
  • Ana döngüde iki turOyna'dan sonra İyileşme: Mavi +8, Kırmızı +8 gibi bir satır yazdır.

rastgeleHasar = false ile maç yine 5 turda biter, son satırlar şöyle olmalı:

Metin
--- Maç 5 turda bitti ---Mavi: Garen (öldü), Lux (öldü), Jinx (öldü)Kırmızı: Darius (öldü), Annie 21, Teemo 70Kazanan: Kırmızı takım
İpucu 1

iyilestir'in ilk işi erken çıkış: canlı değilse return 0.

İpucu 2

Eksik can sampiyon.maxHp - sampiyon.hp. Yenilenecek miktar bundan büyükse eksik kadarını yenile. Önce iyilestir'i dört deneme objesiyle tek başına dene: ölü, canı dolu, 3 eksik, çok eksik.

İpucu 3

takimiIyilestir'de let toplam = 0; döngüde toplam = toplam + iyilestir(sampiyon, miktar); döngüden sonra return toplam.

Çözümü göster

Önce iyilestir'i dört sınır durumuyla tek başına denedim:

deneme.js
function canliMi(sampiyon) {    return sampiyon.hp > 0} function iyilestir(sampiyon, miktar) {    if (!canliMi(sampiyon)) {        return 0    }    let yenilenen = miktar    const eksik = sampiyon.maxHp - sampiyon.hp    if (yenilenen > eksik) {        yenilenen = eksik    }    sampiyon.hp = sampiyon.hp + yenilenen    return yenilenen} const olu = { isim: "Garen", hp: 0, maxHp: 120 }const dolu = { isim: "Lux", hp: 80, maxHp: 80 }const azEksik = { isim: "Jinx", hp: 67, maxHp: 70 }const yarali = { isim: "Teemo", hp: 30, maxHp: 70 }console.log(iyilestir(olu, 8), olu.hp)console.log(iyilestir(dolu, 8), dolu.hp)console.log(iyilestir(azEksik, 8), azEksik.hp)console.log(iyilestir(yarali, 8), yarali.hp)
Çıktı
0 00 803 708 38

Her satırda önce yenilenen miktar, sonra yeni can var. Sonra projeye ekledim. Değişen satırlar vurgulu:

iyilesme.js
const mavi = [    { isim: "Garen", hp: 120, maxHp: 120, guc: 18 },    { isim: "Lux", hp: 80, maxHp: 80, guc: 24 },    { isim: "Jinx", hp: 70, maxHp: 70, guc: 28 }]const kirmizi = [    { isim: "Darius", hp: 150, maxHp: 150, guc: 20 },    { isim: "Annie", hp: 85, maxHp: 85, guc: 31 },    { isim: "Teemo", hp: 70, maxHp: 70, guc: 26 }] function durum(sampiyon) {    if (sampiyon.hp === 0) {        return sampiyon.isim + " (öldü)"    }    return sampiyon.isim + " " + sampiyon.hp} function takimDurumu(takim) {    let metin = ""    for (let i = 0; i < takim.length; i++) {        if (i > 0) {            metin = metin + ", "        }        metin = metin + durum(takim[i])    }    return metin} function canliMi(sampiyon) {    return sampiyon.hp > 0} function takimHayattaMi(takim) {    for (const sampiyon of takim) {        if (canliMi(sampiyon)) {            return true        }    }    return false} function hedefBul(takim) {    for (const sampiyon of takim) {        if (canliMi(sampiyon)) {            return sampiyon        }    }} const rastgeleHasar = false function hasarHesapla(saldiran) {    if (!rastgeleHasar) {        return saldiran.guc    }    return saldiran.guc + Math.floor(Math.random() * 6)} function saldir(saldiran, hedef) {    const hasar = hasarHesapla(saldiran)    hedef.hp = hedef.hp - hasar    if (hedef.hp < 0) {        hedef.hp = 0    }    const mesaj = saldiran.isim + " -> " + hedef.isim + ": " + hasar + " hasar"    console.log(mesaj + ", kalan can " + hedef.hp)    if (hedef.hp === 0) {        console.log(hedef.isim + " öldü.")    }    return hasar} function turOyna(saldiranlar, savunanlar) {    for (const saldiran of saldiranlar) {        if (!canliMi(saldiran)) {            continue        }        if (!takimHayattaMi(savunanlar)) {            return        }        const hedef = hedefBul(savunanlar)        saldir(saldiran, hedef)    }} function iyilestir(sampiyon, miktar) {    if (!canliMi(sampiyon)) {        return 0    }    let yenilenen = miktar    const eksik = sampiyon.maxHp - sampiyon.hp    if (yenilenen > eksik) {        yenilenen = eksik    }    sampiyon.hp = sampiyon.hp + yenilenen    return yenilenen} function takimiIyilestir(takim, miktar) {    let toplam = 0    for (const sampiyon of takim) {        toplam = toplam + iyilestir(sampiyon, miktar)    }    return toplam} function kazananBul(maviTakim, kirmiziTakim) {    if (!takimHayattaMi(kirmiziTakim)) {        return "Mavi takım"    }    if (!takimHayattaMi(maviTakim)) {        return "Kırmızı takım"    }    return "yok, tur sınırı doldu"} const turSiniri = 20let tur = 0console.log("Mavi: " + takimDurumu(mavi))console.log("Kırmızı: " + takimDurumu(kirmizi))while (takimHayattaMi(mavi) && takimHayattaMi(kirmizi) && tur < turSiniri) {    tur++    console.log("--- " + tur + ". tur ---")    turOyna(mavi, kirmizi)    turOyna(kirmizi, mavi)    const maviYenilenen = takimiIyilestir(mavi, 8)    const kirmiziYenilenen = takimiIyilestir(kirmizi, 8)    console.log("İyileşme: Mavi +" + maviYenilenen + ", Kırmızı +" + kirmiziYenilenen)}console.log("--- Maç " + tur + " turda bitti ---")console.log("Mavi: " + takimDurumu(mavi))console.log("Kırmızı: " + takimDurumu(kirmizi))console.log("Kazanan: " + kazananBul(mavi, kirmizi))
Çıktı
Mavi: Garen 120, Lux 80, Jinx 70Kırmızı: Darius 150, Annie 85, Teemo 70--- 1. tur ---Garen -> Darius: 18 hasar, kalan can 132Lux -> Darius: 24 hasar, kalan can 108Jinx -> Darius: 28 hasar, kalan can 80Darius -> Garen: 20 hasar, kalan can 100Annie -> Garen: 31 hasar, kalan can 69Teemo -> Garen: 26 hasar, kalan can 43İyileşme: Mavi +8, Kırmızı +8--- 2. tur ---Garen -> Darius: 18 hasar, kalan can 70Lux -> Darius: 24 hasar, kalan can 46Jinx -> Darius: 28 hasar, kalan can 18Darius -> Garen: 20 hasar, kalan can 31Annie -> Garen: 31 hasar, kalan can 0Garen öldü.Teemo -> Lux: 26 hasar, kalan can 54İyileşme: Mavi +8, Kırmızı +8--- 3. tur ---Lux -> Darius: 24 hasar, kalan can 2Jinx -> Darius: 28 hasar, kalan can 0Darius öldü.Annie -> Lux: 31 hasar, kalan can 31Teemo -> Lux: 26 hasar, kalan can 5İyileşme: Mavi +8, Kırmızı +0--- 4. tur ---Lux -> Annie: 24 hasar, kalan can 61Jinx -> Annie: 28 hasar, kalan can 33Annie -> Lux: 31 hasar, kalan can 0Lux öldü.Teemo -> Jinx: 26 hasar, kalan can 44İyileşme: Mavi +8, Kırmızı +8--- 5. tur ---Jinx -> Annie: 28 hasar, kalan can 13Annie -> Jinx: 31 hasar, kalan can 21Teemo -> Jinx: 26 hasar, kalan can 0Jinx öldü.İyileşme: Mavi +0, Kırmızı +8--- Maç 5 turda bitti ---Mavi: Garen (öldü), Lux (öldü), Jinx (öldü)Kırmızı: Darius (öldü), Annie 21, Teemo 70Kazanan: Kırmızı takım

Üçüncü turun iyileşme satırındaki Kırmızı +0 iki sınırı birden gösteriyor: Darius ölü (0), Annie ile Teemo'nun canı dolu (0 ve 0). İyileşme hasarı karşılayacak kadar büyük olsaydı (örneğin 80), maç tur sınırına kadar sürerdi; sınırı bu yüzden koymuştuk.

Görev 6

Maçın yıldızı

Yeni kopyanın adı yildiz.js olsun. Maç bitince en çok hasar veren şampiyonu ilan et:

Metin
Maçın yıldızı: Annie (155 hasar)
  • Her şampiyona toplamHasar: 0 alanı ekle.
  • saldir verdiği hasarı zaten döndürüyor. turOyna'da bu değeri yakala ve saldıranın toplamına ekle.
  • macinYildizi(maviTakim, kirmiziTakim) iki takımdaki herkes arasından en çok hasar vereni döndürsün. Sonra yukarıdaki satırı yazdır.

rastgeleHasar = false ile sonuç yukarıdaki gibi olmalı.

İpucu 1

Önce Türkçe planını yaz: "Herkesin toplamı 0'dan başlasın. Her vuruştan sonra saldir'ın döndürdüğünü saldıranın toplamına ekle. Maç bitince iki takımı da gez, en büyüğü aklında tut."

İpucu 2

turOyna'da saldir(saldiran, hedef) satırını const hasar = saldir(saldiran, hedef) yap ve altına saldiran.toplamHasar = saldiran.toplamHasar + hasar ekle.

İpucu 3

En büyüğü bulmak (Ders 5): let enIyi = takim[0], sonra her şampiyon için if (sampiyon.toplamHasar > enIyi.toplamHasar) { enIyi = sampiyon }. Bunu bir takım için yapan bir enCokHasarVeren(takim) yaz; macinYildizi'nde iki takımın en iyisini karşılaştır.

Çözümü göster

Değişen satırlar vurgulu. Maçın kendisi 6. adımdakiyle aynı, bu yüzden kodun altında çıktının yalnız son satırları var:

yildiz.js
const mavi = [    { isim: "Garen", hp: 120, guc: 18, toplamHasar: 0 },    { isim: "Lux", hp: 80, guc: 24, toplamHasar: 0 },    { isim: "Jinx", hp: 70, guc: 28, toplamHasar: 0 }]const kirmizi = [    { isim: "Darius", hp: 150, guc: 20, toplamHasar: 0 },    { isim: "Annie", hp: 85, guc: 31, toplamHasar: 0 },    { isim: "Teemo", hp: 70, guc: 26, toplamHasar: 0 }] function durum(sampiyon) {    if (sampiyon.hp === 0) {        return sampiyon.isim + " (öldü)"    }    return sampiyon.isim + " " + sampiyon.hp} function takimDurumu(takim) {    let metin = ""    for (let i = 0; i < takim.length; i++) {        if (i > 0) {            metin = metin + ", "        }        metin = metin + durum(takim[i])    }    return metin} function canliMi(sampiyon) {    return sampiyon.hp > 0} function takimHayattaMi(takim) {    for (const sampiyon of takim) {        if (canliMi(sampiyon)) {            return true        }    }    return false} function hedefBul(takim) {    for (const sampiyon of takim) {        if (canliMi(sampiyon)) {            return sampiyon        }    }} const rastgeleHasar = false function hasarHesapla(saldiran) {    if (!rastgeleHasar) {        return saldiran.guc    }    return saldiran.guc + Math.floor(Math.random() * 6)} function saldir(saldiran, hedef) {    const hasar = hasarHesapla(saldiran)    hedef.hp = hedef.hp - hasar    if (hedef.hp < 0) {        hedef.hp = 0    }    const mesaj = saldiran.isim + " -> " + hedef.isim + ": " + hasar + " hasar"    console.log(mesaj + ", kalan can " + hedef.hp)    if (hedef.hp === 0) {        console.log(hedef.isim + " öldü.")    }    return hasar} function turOyna(saldiranlar, savunanlar) {    for (const saldiran of saldiranlar) {        if (!canliMi(saldiran)) {            continue        }        if (!takimHayattaMi(savunanlar)) {            return        }        const hedef = hedefBul(savunanlar)        const hasar = saldir(saldiran, hedef)        saldiran.toplamHasar = saldiran.toplamHasar + hasar    }} function enCokHasarVeren(takim) {    let enIyi = takim[0]    for (const sampiyon of takim) {        if (sampiyon.toplamHasar > enIyi.toplamHasar) {            enIyi = sampiyon        }    }    return enIyi} function macinYildizi(maviTakim, kirmiziTakim) {    const maviEnIyi = enCokHasarVeren(maviTakim)    const kirmiziEnIyi = enCokHasarVeren(kirmiziTakim)    if (kirmiziEnIyi.toplamHasar > maviEnIyi.toplamHasar) {        return kirmiziEnIyi    }    return maviEnIyi} function kazananBul(maviTakim, kirmiziTakim) {    if (!takimHayattaMi(kirmiziTakim)) {        return "Mavi takım"    }    if (!takimHayattaMi(maviTakim)) {        return "Kırmızı takım"    }    return "yok, tur sınırı doldu"} const turSiniri = 20let tur = 0console.log("Mavi: " + takimDurumu(mavi))console.log("Kırmızı: " + takimDurumu(kirmizi))while (takimHayattaMi(mavi) && takimHayattaMi(kirmizi) && tur < turSiniri) {    tur++    console.log("--- " + tur + ". tur ---")    turOyna(mavi, kirmizi)    turOyna(kirmizi, mavi)}console.log("--- Maç " + tur + " turda bitti ---")console.log("Mavi: " + takimDurumu(mavi))console.log("Kırmızı: " + takimDurumu(kirmizi))console.log("Kazanan: " + kazananBul(mavi, kirmizi))const yildiz = macinYildizi(mavi, kirmizi)console.log("Maçın yıldızı: " + yildiz.isim + " (" + yildiz.toplamHasar + " hasar)")
Çıktı
--- Maç 5 turda bitti ---Mavi: Garen (öldü), Lux (öldü), Jinx (öldü)Kırmızı: Darius (öldü), Annie 1, Teemo 70Kazanan: Kırmızı takımMaçın yıldızı: Annie (155 hasar)

Annie beş turun hepsinde vurdu: 5 kere 31, yani 155. Jinx de beş kez vurdu ama gücü daha düşük: 5 kere 28, yani 140.

Sınır durumu: iki şampiyonun toplamı eşitse ne olur? > kullandığımız için önce bakılan kalır: aynı takımda dizideki ilk şampiyon, iki takım arasında Mavi'nin en iyisi. >= yazsaydın eşitlikte sonraki kazanırdı. İkisi de olur, ama hangisini seçtiğini bilmelisin.

Bir de şu var: saldir hedefin canından fazla vursa da tam hasarı döndürüyor. Annie son vuruşta canı 13 olan Jinx'e 31 vurdu ve 31'in hepsi sayıldı. İstersen yalnız gerçekten düşen canı say: bunu da saldir'ın döndürdüğü değeri değiştirerek yaparsın.

Kendini sına

Soru 1

Bu program ne yazar?

JavaScript
function canYaz(hp) {    console.log("Can: " + hp)} const sonuc = canYaz(50)console.log(sonuc)
Cevabı göster

Önce Can: 50, sonra undefined. canYaz ekrana yazıyor ama hiçbir şey döndürmüyor. return olmayan fonksiyon undefined döndürür, sonuc kutusuna da o girer.

Soru 2

Bu program ne yazar? Hangi satır hiç çalışmaz?

JavaScript
function seriUnvani(kill) {    if (kill >= 5) {        return "Efsanevi"    }    if (kill >= 3) {        return "Durdurulamaz"    }    return "Normal"    console.log("Unvan verildi")} console.log(seriUnvani(7))console.log(seriUnvani(3))console.log(seriUnvani(2))
Cevabı göster

Efsanevi, Durdurulamaz, Normal. 7 için ilk return çalışır. 3 tam sınırda: 3 >= 5 tutmaz, 3 >= 3 tutar. 2 için iki if de tutmaz ve son return çalışır. console.log("Unvan verildi") satırı hiçbir çağrıda çalışmaz: her yol ondan önce bir return'e çıkıyor.

Soru 3

Hatayı bul: hangi çağrı yanlış cevap verir, neden?

JavaScript
function garenVarMi(takim) {    for (const sampiyon of takim) {        if (sampiyon.isim === "Garen") {            return true        } else {            return false        }    }} console.log(garenVarMi([{ isim: "Garen" }, { isim: "Lux" }]))console.log(garenVarMi([{ isim: "Lux" }, { isim: "Garen" }]))console.log(garenVarMi([]))
Cevabı göster

İkinci çağrı false döndürür, oysa Garen takımda. İlk eleman Lux olduğu için else çalışır ve return false fonksiyonu ilk elemanda bitirir. Üçüncü çağrı da sorunlu: boş dizide döngü hiç dönmez, hiçbir return çalışmaz ve undefined döner. Düzeltme, return false'u döngünün altına taşımak:

JavaScript
function garenVarMi(takim) {    for (const sampiyon of takim) {        if (sampiyon.isim === "Garen") {            return true        }    }    return false}

Böylece ikinci çağrı true, üçüncü false döndürür.

Soru 4

Math.floor(Math.random() * 10) hangi sayıları üretebilir? 1'den 10'a kadar (ikisi de dahil) sayı için ne yazarsın?

Cevabı göster

0'dan 9'a kadar 10 farklı tam sayı. Math.random() * 10 0 ile 10 arasında, ama 10'a asla ulaşmayan bir sayı verir; aşağı yuvarlayınca en büyük 9 olur. 1'den 10'a kadar istiyorsan en küçük sonucu 1 yap: Math.floor(Math.random() * 10) + 1.

Soru 5

Bu program ne yazar? return ile break farkına dikkat et.

JavaScript
function ilkOluyuBul(takim) {    for (const sampiyon of takim) {        if (sampiyon.hp === 0) {            return sampiyon.isim        }    }    return "kimse"} function ilkOluyuYaz(takim) {    for (const sampiyon of takim) {        if (sampiyon.hp === 0) {            console.log(sampiyon.isim)            break        }    }    console.log("döngü bitti")} const takim = [{ isim: "Lux", hp: 30 }, { isim: "Jinx", hp: 0 }]console.log(ilkOluyuBul(takim))ilkOluyuYaz(takim)
Cevabı göster

Jinx, Jinx, döngü bitti. ilkOluyuBul'da return hem döngüyü hem fonksiyonu bitirdi; return "kimse" satırına inilmedi, dönen "Jinx"'i dışarıdaki console.log yazdı. ilkOluyuYaz'da break yalnız döngüyü bitirdi; fonksiyon döngünün altından devam etti ve "döngü bitti" yazıldı.

Soru 6

Bir arkadaşın şöyle diyor: "Fonksiyonum çalışıyor, terminalde doğru sayıyı görüyorum. Ama sonucu bir değişkene koyunca undefined oluyor." Ona ne söylersin?

Cevabı göster

Fonksiyon sonucu console.log ile ekrana yazıyor, return etmiyor. console.log değeri yalnız ekrana yazar; değişkene giden değer return ile gelir. return olmayan fonksiyon undefined döndürür. Çözüm: fonksiyonun içindeki console.log(...) yerine return ... yazmak, ekrana yazma işini fonksiyonu çağıran yere bırakmak.

Kayıt noktası

Bu derste iki klasörde çalıştın; ikisini de kaydedeceksin. Proje yeni bir klasör, yani Git'in onu tanıması için orada da bir kez git init gerekiyor.

Bir sonraki derste hataları sistemli avlamayı (console.log ile iz sürmek, VS Code'un hata ayıklayıcısıyla programı adım adım çalıştırmak) öğrenecek ve takım savaşını GitHub'a koyup portföyüne ilk projeni ekleyeceksin.

İşaret yalnızca bu tarayıcıda saklanır, kimseye gönderilmez.