C# Console’da Adam Asmaca
Bu yazıda bir Adam Asmaca (Hangman) oyununu inceleyeceğiz.
Ama odak noktamız oyun değil; değişkenlerin nerede yaşadığı (scope), hangi satırın neden orada olduğu ve kodun akışının nasıl kontrol edildiği.
Problem: Bizden ne isteniyor?
Ekrandaki gereksinimler şunlar:
- Bir kelime listesinden rastgele kelime seç
- Kullanıcıdan harf iste
- Kelimede harf var mı bak
- Varsa kelimedeki harfi göster
- Yoksa bir hak azalt
- Kelimeyi tahmin etmesini iste
- Kelime doğruysa bildi
- Yanlışsa 2. adıma dön (yani döngü devam etsin)
Bu akışın doğal çözümü: while döngüsü + metotlar.
Kodun tamamı
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
string[] words =
{
"bilgisayar", "programlama", "metot", "degisken",
"nesne", "kalitim", "polimorfizm", "kuyruk", "yigin"
};
string secretWord = SelectRandomWord(words);
HashSet<char> guessedLetters = new HashSet<char>();
int lives = 6;
bool won = false;
Console.WriteLine("🎯 Adam Asmaca'ya Hoş Geldin!");
Console.WriteLine($"Hak: {lives}");
Console.WriteLine();
while (lives > 0 && !won)
{
ShowWordState(secretWord, guessedLetters);
char letter = GetLetterFromUser(guessedLetters);
bool exists = secretWord.Contains(letter);
if (exists)
{
guessedLetters.Add(letter);
Console.WriteLine("✅ Var!");
}
else
{
lives--;
Console.WriteLine($"❌ Yok! Kalan hak: {lives}");
}
string guess = GetWordGuessFromUser();
if (guess.Equals(secretWord, StringComparison.OrdinalIgnoreCase))
{
won = true;
break;
}
Console.WriteLine("🔁 Kelime tahmini yanlış, devam!");
Console.WriteLine();
}
Console.WriteLine("---------------------------------");
if (won)
{
Console.WriteLine($"🏆 Tebrikler! Kelime: {secretWord}");
}
else
{
Console.WriteLine($"💀 Hak bitti! Kelime: {secretWord}");
}
}
static string SelectRandomWord(string[] words)
{
Random rnd = new Random();
int index = rnd.Next(words.Length);
return words[index];
}
static char GetLetterFromUser(HashSet<char> guessedLetters)
{
while (true)
{
Console.Write("Bir harf gir: ");
string input = (Console.ReadLine() ?? "").Trim().ToLower();
if (input.Length != 1)
{
Console.WriteLine("⚠️ Lütfen TEK bir harf gir.");
continue;
}
char letter = input[0];
if (!char.IsLetter(letter))
{
Console.WriteLine("⚠️ Lütfen bir harf gir (rakam/işaret olmaz).");
continue;
}
if (guessedLetters.Contains(letter))
{
Console.WriteLine("⚠️ Bu harfi zaten girdin.");
continue;
}
return letter;
}
}
static void ShowWordState(string secretWord, HashSet<char> guessedLetters)
{
Console.Write("Kelime: ");
foreach (char c in secretWord)
{
if (guessedLetters.Contains(c))
Console.Write(c + " ");
else
Console.Write("_ ");
}
Console.WriteLine();
Console.WriteLine("Tahmin edilen harfler: " + (guessedLetters.Count == 0 ? "-" : string.Join(", ", guessedLetters)));
Console.WriteLine();
}
static string GetWordGuessFromUser()
{
Console.Write("Kelime tahminin (enter ile geçebilirsin): ");
string guess = (Console.ReadLine() ?? "").Trim().ToLower();
if (string.IsNullOrWhiteSpace(guess))
return "";
return guess;
}
}using Bildirimleri
using System;
using System.Collections.Generic;System
→Console,String,Randomgibi temel sınıfları kullanabilmek için.System.Collections.Generic
→HashSet<char>kullanabilmek için.
Bu satırlar dosya scope’undadır.
Yani bu dosyanın tamamında geçerlidir.
Program Sınıfı (Class Scope)
class Program
{- Burada bir class scope başlar.
- Bu süslü parantez kapanana kadar yazılan her şey
Programsınıfına aittir. Mainve diğer metotların tamamı bu scope içindedir.
Main Metodu (Method Scope)
static void Main()
{- Program buradan başlar.
Mainiçindeki her değişken sadece Main scope’unda yaşar.- Başka metotlar bu değişkenlere doğrudan erişemez.
Kelime Listesi Tanımı
string[] words =
{
"bilgisayar", "programlama", "metot", "degisken",
"nesne", "kalitim", "polimorfizm", "kuyruk", "yigin"
};words→ Main scope’unda tanımlı.- Türü:
string[](dizi). - Bu dizi:
- sadece
Mainiçinde bilinir - ama parametre olarak başka metotlara gönderilebilir
Rastgele Kelime Seçimi
string secretWord = SelectRandomWord(words);SelectRandomWordçağrılırwordsdizisi parametre olarak gönderilir- Metot bir
stringdöndürür - Dönen değer
secretWorddeğişkenine atanır
secretWord:
- Main scope’undadır
- Oyunun tek gerçek kelimesidir
- Döngü boyunca değişmez
Oyun Durum Değişkenleri
HashSet<char> guessedLetters = new HashSet<char>();
int lives = 6;
bool won = false;guessedLetters
- Kullanıcının doğru tahmin ettiği harfler
HashSetseçilme sebebi:- Aynı harf 2 kez eklenemez
Containskontrolü hızlı
lives
- Kalan hak sayısı
intolduğu için her yanlışta--ile azalır
won
- Oyunun kazanılıp kazanılmadığını tutar
- Döngü kontrolünde kullanılır
Hepsi Main scope’unda yaşar.
Başlangıç Mesajları
Console.WriteLine("🎯 Adam Asmaca'ya Hoş Geldin!");
Console.WriteLine($"Hak: {lives}");
Console.WriteLine();$"{lives}"→ string interpolation- O anki
livesdeğeri yazdırılır
Oyun Döngüsü (while scope)
while (lives > 0 && !won)
{Bu satır oyunun kalbidir.
Döngü devam ederken:
- Hak bitmemiş olmalı
- Oyun kazanılmamış olmalı
Bu parantezden itibaren while scope başlar.
Kelimenin Mevcut Halini Gösterme
ShowWordState(secretWord, guessedLetters);Main scope’taki değişkenler
parametreyle metoda gönderilir
Metot:
- kelimeyi
_ _ a _ _şeklinde yazar - tahmin edilen harfleri listeler
Kullanıcıdan Harf Alma
char letter = GetLetterFromUser(guessedLetters);Kullanıcıdan tek bir harf alınır
Get Heda GÜLER’s stories in your inbox
Join Medium for free to get updates from this writer.
Metot:
- boş girişleri
- 2 harfli girişleri
- rakamları
- daha önce girilmiş harfleri
engeller
letter değişkeni:
- while scope’unda yaşar
- Döngü turu bitince yok olur
Harf Kontrolü
bool exists = secretWord.Contains(letter);Contains→ string içinde karakter var mı?exists:- true → harf var
- false → harf yo
Bu değişken de while scope’undadır.
if / else Bloğu (Block Scope)
if (exists)
{
guessedLetters.Add(letter);
Console.WriteLine("✅ Var!");
}
else
{
lives--;
Console.WriteLine($"❌ Yok! Kalan hak: {lives}");
}if bloğu
- Harf doğruysa:
guessedLettersiçine eklenir- Hak azalmaz
else bloğu
- Harf yanlışsa:
lives--→ hak düşer
⚠️ exists if’ten önce tanımlandığı için hem if hem else tarafından görülebilir.
Kullanıcıdan Kelime Tahmini Alma
string guess = GetWordGuessFromUser();- Kullanıcı:
- isterse kelime girer
- isterse Enter’a basar
- Enter’a basarsa metot
""döndürür
guess yine while scope’undadır.
Kelime Doğru mu Kontrolü
if (guess.Equals(secretWord, StringComparison.OrdinalIgnoreCase))
{
won = true;
break;
}Equals:
- büyük/küçük harf farkını yok sayar
Doğruysa:
won = truebreak→ while döngüsünü anında bitirir
⚠️ break sadece en yakın döngüyü kırar.
Yanlış Tahmin Durumu
Console.WriteLine("🔁 Kelime tahmini yanlış, devam!");
Console.WriteLine();- Bu satırlar çalışır
- Döngü başa döner
- Kullanıcı tekrar harf girer
Bu, ekrandaki “2. adıma dön” maddesinin birebir karşılığıdır.
Döngü Sonrası (Main scope’a dönüş)
Console.WriteLine("---------------------------------");Artık while bitti:
- ya
won == true - ya
lives == 0
Sonuç Kontrolü
if (won)
{
Console.WriteLine($"🏆 Tebrikler! Kelime: {secretWord}");
}
else
{
Console.WriteLine($"💀 Hak bitti! Kelime: {secretWord}");
}secretWordhâlâ erişilebilir- Çünkü Main scope’undaydı
Metotlar: Kendi Scope’ları Olan Yapılar
SelectRandomWord
static string SelectRandomWord(string[] words)- Parametre:
words→ metot scope Randomile index seçilir- Seçilen kelime
returnedilir - Metot bittiği anda içindeki tüm değişkenler silinir
GetLetterFromUser
while (true)- Sonsuz döngü
returngelene kadar çalışır
continue;- Sadece bu metodun içindeki while’ı başa sarar
ShowWordState
foreach (char c in secretWord)foreach→ kendi küçük scope’una sahiptircdeğişkeni sadece foreach içinde yaşar
GetWordGuessFromUser
if (string.IsNullOrWhiteSpace(guess))
return "";- Enter’a basılırsa:
- boş string döner
Equalsfalse olur- oyun devam eder
Özet (Kapanış)
Bu kodda şunları net olarak gördük:
- Scope = parantez
- Main → oyunu yönetir
- Metotlar → tek işi yapar
- while → akışı kontrol eder
- if/else → karar verir
- break / continue → döngüyü yönlendirir
Bu seviyede bu kodu okuyabiliyorsan, artık:
- LeetCode Easy soruları
- OOP konularına geçiş
- Daha büyük console projeleri
için altyapın hazır demektir.







