## 21. Uygulama - bölüm 5

### Daha karmaşık durumlar

Aşağıdaki şekilde bir dünya ile karşılaşırsanız:

Bir önceki derste yazdığınız program çalışır mı? Deneyin!

Sizin de tahmin ettiğiniz gibi, çalışmıyor. Çalışması için if'i while ile değiştirmeniz gerekir. Deneyin ve programı kaydedin.

### Amacımız nedir

Karşılaşabileceğimiz her türlü durumda çalışabilecek bir program oluşturuldu. Bu program Reeborg'un herhangi bir dünyasında bir tur atmasını sağlar. Program kısa ve temiz bir yapıya sahip olmasına rağmen, bunu ilk kez gören birisi için kolay anlaşılır olmayabilir. Bu programa açıklamalar eklemek anlaşılmasını kolaylaştıracaktır.

    # sağa dönmek için bir tanımlama yapıyoruz.
    def turn_right():
        repeat(turn_left, 3)

    # başlangıç noktasını bir bip koyarak işaretliyoruz.
    put_beeper()

    # Önün boş olduğunu kontrol edip harekete başlıyoruz.
    while not front_is_clear():
        turn_left()
    move()

    # işaret olarak bıraktığımız bip'e ulaştığımızda
    # turun tamamlandığını anlıyoruz.

    while not next_to_a_beeper():
        if right_is_clear(): # sağı kontrol et
            turn_right()
            move()
        elif front_is_clear(): # ön boş mu
            move()
        else: # sola dön
            turn_left()

    turn_off()

Bu açıklamalar komutlar yardımıyla ne yaptığımızı açıklamasına rağmen problemin çözümünde kullanılan metodun (algoritmanın) açıklanmasını sağlamaz. Bu nedenle bu açıklamalar bu programı okuyan başka bir kişiye umduğumuz kadar yardımcı olmayabilir. Programımız iki kısımdan oluşuyor:
1) başlangıç noktasını işaretle.
2) sağdaki duvarı başlangıç noktasına gelinceye kadar takip et.
Açıklamaları daha farklı yazarak bu iki kısmı daha açıkça ifade edecek şekilde programı yeniden yazalım.

    # Bu program Reeborg'a dünyasının etrafında bir tur attırır.
    # saat yönünün zıttında ve başlangıç noktasına geldiğinde
    #  durmasını sağlayarak.

    def turn_right():
        repeat(turn_left, 3)

    def mark_starting_point_and_move():
        put_beeper()
        while not front_is_clear():
            turn_left()
        move()

    def follow_right_wall():
        if right_is_clear():
            turn_right()
            move()
        elif front_is_clear():
            move()
        else:
            turn_left()

    found_starting_point = next_to_a_beeper   # bip başlangıç noktasını işaret eder.

    #=== Tanımlamaların sonu; çözüm başlıyor

    mark_starting_point_and_move()

    while not found_starting_point():
        follow_right_wall()

    turn_off()

Bu program daha anlaşılır değil mi? Şimdi programımızı çalıştırdığımızda her köşede bir bip olduğunu varsayalım. Bu durumda başlangıç noktamızı bir bip'i yerinden alarak belirleyebilirdik. Tanımlamalarda ufak değişiklikler yapmamız da gerekirdi ama bulmuş olduğumuz çözümü değiştirmeye gerek kalmazdı.

### İlk Sürpriz

Yukarıdaki programdan `put_beeper()` komutunu kaldırın, kaydedin ve bu programı aşağıdaki engelli koşuda deneyin. (dosya: hurdles3.wld).

Sürpriz! Bu program engelli koşu problemini çözüyor, tek sıra dışı durum yarışma tamamlandığında Reeborg'un yüzünün farklı bir yöne dönük olması (belki yarışmayı tamamladıktan sonra seyircileri selamlıyordur!) . Bu program aşağıda olduğu gibi birbiriyle eşit olmayan engellerle de çalışır (dosya: hurdles4.wld). Daha önceden engelli koşu için yazmış olduğumuz programın aşağıdaki durumda çalışmayacağı göz önüne alınırsa oldukça iyi bir iş ortaya çıkarttığımızı söyleyebiliriz.

### Şaşırtıcı sürpriz

Az önceki programı ilk derslerde bahsettiğimiz labirent problemine uygulayın (dosya: maze1.wld).

Göreceğiniz gibi program labirentin çıkışını da bulabiliyor, şaşırtıcı değil mi.

### Sonuç

Basit bir problemin çözümüyle başladık (dikdörtgen bir dünyanın etrafında bir tur atmak) ve bu programı adım adım geliştirerek, görünüşte birbirinden farklı durumlar içeren problemlere çözüm getirdik. Her adımda küçük değişiklikler yaptık, karmaşık problemlere başlamadan önce, programımızın değişikliklerden sonra hala çalışıyor olduğundan emin olduk. Bunun yanında algoritmanın daha iyi anlaşılabilmesini ve programın daha kolay okunabilir hale gelmesini sağlamak için açıklamalar ve açıklayıcı isimler kullandık. Kendi programlarınızı yazarken sizde böyle bir strateji uygulayın.

Kural # 4
  Bir program yazarken takip edilecek adımlar:

- basit başla;
- Küçük değişiklikleri bir defada bir tane olacak şekilde ekle;
- yaptığın değişikliklerin programının çalışmasını bozmadığından emin ol;
- her komutun ne iş yaptığını tekrarlamayan, uygun açıklamalarla yaz. ; ve
- açıklayıcı adlar seç.

Uygulama - bölüm 4 - - Yağmur Yağıyor!