c_room/gorev01.c veya py_room/gorev01.py) ve kütüphaneyi ekleyin.Asansörün 3 katı vardır. Simülasyon açıldığında (veya menüden Yenile'ye basıldığında) kabin 3. kattadır ve bütün kapılar kapalıdır. Her katın yanında ▲ (yukarı) ve ▼ (aşağı) çağırma düğmeleri, Kabin Düğmeleri panelinde ise kabin ekranı ve 1, 2, 3 düğmeleri vardır. Düğmeler yalnızca basılı tutulduğu sürece 1 okunur; düğme ışıklarını yakmak, söndürmek ve basılan düğmeleri hatırlamak programınızın işidir. Menüden açılan Elle Kontrol panelinde kabin motoru (Yukarı / Dur / Aşağı) ve her katın kapısı (Kapat / Dur / Aç) elle sürülebilir.
Kabin iki kat arasını yaklaşık 4,7 saniyede gider; bir kapı yaklaşık 0,65 saniyede tam açılır. Kabin 3. katın üstüne ya da 1. katın altına geçerse, kapı tam açıldıktan sonra açılmaya ya da tam kapandıktan sonra kapanmaya devam ederse hata bayrağı 1 olur ve menü çubuğunda HATA yazısı görünür. Bu yüzden bir motoru sensörle durduracağınız bekleme döngülerine Sleep koymayın. Motorlar siz durdurana kadar çalışır: program biterken (ya da Ctrl+C ile durdurduğunuzda) motor çalışıyorsa kabin hareket etmeye devam eder; Elle Kontrol'de Dur'a veya Yenile'ye basın. Simülasyon kapı açıkken kabinin hareket etmesini engellemez; bunu sağlamak sizin programınızın görevidir. Python kütüphanesi kapı, ışık ve ekran komutlarında konsola [SIM] ile başlayan bir satır yazar.
Asansör simülasyonunu başlatın. Simülasyona bağlanan, bağlantı kurulunca konsola bir mesaj (ör. Connected to the elevator!) yazan ve bağlantıyı kapatıp biten bir program yazın.
Sonra simülasyonu kapatıp programı tekrar çalıştırın: ne oluyor?
sim_connect() başarılı olursa 0, başarısız olursa 1 döndürür. Programın sonunda sim_disconnect() çağırın.Kabin Düğmeleri panelindeki ekranda sırayla 1, 2 ve 3 sayılarını gösterin. Her sayı ekranda 1 saniye kalsın. Program bittiğinde ekranda 3 yazmalıdır.
cabin_display(sayı) ekrana yazar. Beklemek için C'de Sleep(1000) (milisaniye), Python'da time.sleep(1) (saniye) kullanın.Kabin Düğmeleri panelindeki 1, 2 ve 3 düğmelerinin ışıklarını yakın (düğmeler turuncu olur), 3 saniye bekleyin ve üçünü de söndürün.
cabin_button_light(kat, durum): durum 1 yakar, 0 söndürür.Gerçek bir binada anlamlı olan çağırma düğmelerinin ışıklarını yakın: 1. katta ▲, 2. katta ▲ ve ▼, 3. katta ▼. 3 saniye sonra hepsini söndürün. (1. katın ▼ ve 3. katın ▲ düğmesi sönük kalmalı.)
floor_button_light(kat, yön, durum); yön için DIR_UP veya DIR_DOWN kullanın.Önce menüden Yenile'ye basın (kabin 3. kata gelir). Kabini 2 saniye aşağı indirin ve durdurun. 1 saniye bekleyin, sonra 1 saniye yukarı çıkarın ve tekrar durdurun. Kabin 3. ile 2. kat arasında bir yerde durmalıdır.
cabin_motor() için CABIN_DOWN, CABIN_UP ve CABIN_STOP sabitlerini kullanın. Motor siz durdurana kadar döner.Yenile'ye basın. 3. kat kapısını 0,3 saniye açın ve motorunu durdurun (kapı yarıya kadar açılır). 2 saniye bekleyin, sonra kapıyı 0,3 saniye kapatın ve motoru durdurun.
Kapının tam kapanıp kapanmadığına ve menü çubuğunda HATA yazısının görünüp görünmediğine dikkat edin. Birkaç kez çalıştırın (her seferinde önce Yenile).
door(kat, komut); komut DOOR_OPEN, DOOR_CLOSE veya DOOR_STOP olabilir.Üç kat sensörünü okuyup her birini ayrı bir değişkende saklayın ve üç değeri konsola yazdırın (ör. Floor 1: 0, Floor 2: 0, Floor 3: 1).
Yenile'den sonra çalıştırın. Sonra Elle Kontrol panelinde kabini Aşağı ile indirip iki katın arasında Dur'a basın ve programı yeniden çalıştırın. Ne görüyorsunuz?
cabin_sensor_read(kat) kabin o kattaysa 1, değilse 0 döndürür. C'de değişken: int s1 = cabin_sensor_read(1);Kabinin hangi katta olduğunu bulun. Kabin bir kattaysa kat numarasını kabin ekranında gösterin ve konsola yazın. Kabin katların arasındaysa ekranda 0 gösterin ve konsola kabinin katlar arasında olduğunu yazın.
if / else if ile her sensörü sırayla kontrol edip değişkene kat numarasını yazın. En sonda değişken hâlâ 0 ise kabin katlar arasındadır.3. kat kapısının durumunu konsola yazın: tam kapalı, tam açık ya da aralık.
Deneyin: Yenile'den sonra (kapalı) ve Elle Kontrol'de 3. kat için Aç'a basıp kapı yarıdayken Dur'a bastıktan sonra (aralık). Kapıyı elle tam sınırında durdurmak çok zordur (geç kalırsanız HATA görünür); tam açık durumunu Görev 19'da programla göreceksiniz.
door_sensor_read(3) kapı tam kapalıysa 0, değilse 1; door_open_read(3) kapı tam açıksa 1 döndürür. İkisini birlikte kullanın.Program önce konsola bir uyarı yazsın, sonra 5 saniye beklesin. Bu sürede Kabin Düğmeleri panelindeki 2 düğmesine basın ve basılı tutun. 5 saniye dolunca program düğmeyi okusun: basılıysa 2 düğmesinin ışığını 2 saniye yaksın ve basıldığını yazsın; değilse basılmadığını yazsın.
Bir kez de düğmeye basıp 5 saniye dolmadan bırakın. Sonuç ne oluyor, neden?
cabin_button_read(2) düğme o anda basılıysa 1 döndürür.Yenile'ye basın; 3. kat kapısı kapalıdır. Bilerek bir hata yapın: kapalı kapıyı 0,1 saniye kapatmaya çalışın. Motoru durdurmadan hemen önce hata bayrağını okuyun, sonra motoru durdurun ve sonucu yazın. 1 saniye bekleyip bayrağı tekrar okuyun ve yazın.
Menü çubuğundaki HATA yazısını izleyin. Bittikten sonra Yenile'ye basın.
get_error() bir sınır aşıldıysa 1, aşılmadıysa 0 döndürür. Bayrak kendiliğinden kısa sürede temizlenir.Yenile'ye basın. Kabini aşağı yönde çalıştırın, 0,5 saniye sonra kabin motorunun durumunu okuyun ve anlamını yazın (stopped, up veya down). Sonra motoru durdurun ve durumu bir kez daha okuyup sayı olarak yazın.
cabin_motion_read() 0 (CABIN_STOP), 1 (CABIN_UP) veya 2 (CABIN_DOWN) döndürür. Sabitlerle karşılaştırın.Asansör yalnızca kabin bir kattaysa VE o katın kapısı tam kapalıysa yola çıkmaya hazırdır. Program bu iki koşulu kontrol etsin: ikisi de doğruysa hazır olduğunu ve katı konsola yazsın, katı ekranda göstersin; değilse hazır olmadığını yazsın.
Yenile'den sonra, sonra da Elle Kontrol ile 3. kat kapısını biraz açıp (Aç, sonra Dur) deneyin.
&&, Python'da and kullanın.Kabin ekranında 1'den 9'a kadar sayın; her sayı 0,5 saniye görünsün. Bu sefer 9 ayrı komut yazmak yerine bir döngü kullanın.
for (int i = 1; i <= 9; i++) { ... } Python: for i in range(1, 10):Sürekli çalışan bir program yazın: kabin bir kata geldiğinde o katın numarasını ekranda göstersin ve konsola bir kez yazsın. Kabin katlar arasındayken ekran son katı göstermeye devam etsin. Aynı kat için konsola tekrar tekrar yazmasın.
Program çalışırken kabini Elle Kontrol panelinden (Yukarı / Dur / Aşağı) hareket ettirin. Programı Ctrl+C ile durdurun.
while (1) / while True: sonsuz döngüdür. Ekranda o an hangi sayının yazdığını bir değişkende tutun; yalnızca yeni kat bundan farklıysa ekranı güncelleyin. Döngünün sonuna kısa bir Sleep(10) koyun.Kabin Düğmeleri panelindeki 2 düğmesi basılı tutulduğu sürece ışığı yansın, bırakılınca sönsün. Işık komutunu yalnızca düğmenin durumu değiştiğinde gönderin ve konsola pressed / released yazın. Ctrl+C ile durdurun.
Kabin düğmelerinden (1, 2, 3) birine kısa basılınca ışığı yansın ve yanık kalsın. Kabin o kata ulaştığında ışık sönsün. Her istek ve her ulaşma için konsola bir satır yazın.
Program çalışırken düğmelere basın ve kabini Elle Kontrol ile katlar arasında gezdirin. Ctrl+C ile durdurun.
int lit[4] = {0};, Python'da lit = [0, 0, 0, 0] (1..3 indeksleri kullanılır). Döngü içinde for ile üç katı dolaşın.Yenile'ye basın (kabin 3. katta). Kabini aşağı gönderin ve 2. kat sensörü 1 olana kadar bekleyin; o anda motoru durdurun. Ekranda 2 gösterin ve konsola 2. kata gelindiğini yazın. Kabin tam kat hizasında durmalı ve HATA görünmemelidir.
while (cabin_sensor_read(2) == 0) { }, Python'da while cabin_sensor_read(2) == 0: pass. Bu döngüye Sleep koymayın.Görev 18'den sonra kabin 2. kattadır. Program önce kabinin 2. katta olduğunu kontrol etsin; değilse bir mesaj yazıp bitsin. Kabin oradaysa: 2. kat kapısını tam açılana kadar açın ve durdurun, 3 saniye açık bekletin, sonra tam kapanana kadar kapatın ve durdurun. HATA hiç görünmemeli (Görev 6 ile karşılaştırın).
door_open_read(2) 1 olana kadar, kapatırken door_sensor_read(2) 0 olana kadar bekleyin. Bu iki bekleme döngüsüne de Sleep koymayın.Kabin nerede olursa olsun (3. katta, 2. katta ya da katların arasında) onu 1. kata indirip tam hizada durdurun ve ekranda 1 gösterin. Kabin zaten 1. kattaysa motoru hiç çalıştırmayın, yalnızca bunu konsola yazın.
Kabini Elle Kontrol ile farklı yerlere götürüp birkaç kez deneyin.
if ile 1. katta olup olmadığına bakın.Kabin bir kattayken çalıştırın (katlar arasındaysa program bir mesaj yazıp bitsin). Program bir kabin düğmesine (1, 2 veya 3) basılmasını beklesin. Basılan düğmenin ışığını yakın, kabini doğru yöne göndererek o katta durdurun, ışığı söndürün, ekranda katı gösterin ve konsola yazın. Basılan kat zaten bulunulan katsa kabin hareket etmemelidir.
target değişkeni 0 olduğu sürece düğmeleri okuyan bir döngü yazın. (3) target ile bulunulan katı karşılaştırarak yönü seçin ve Görev 18'deki gibi bekleyin.İki fonksiyon yazın: current_floor() kabinin bulunduğu katı (katlar arasındaysa 0) döndürsün; go_to_floor(hedef) kabini hedef kata götürüp durdursun, ekranda katı göstersin ve konsola yazsın. Kabin katlar arasındaysa go_to_floor önce aşağıdaki kata insin, sonra hedefe gitsin.
Bu fonksiyonlarla şu turu yapın: 1. kata git, 2 saniye bekle, 3. kata git, 2 saniye bekle, 2. kata git.
int current_floor(void) { ... return f; } ve void go_to_floor(int target) { ... }. Python: def go_to_floor(target):. İçlerine Görev 20 ve Görev 21'deki kodları taşıyın.Görev 22'deki fonksiyonlara iki tane daha ekleyin: open_door(kat) kapıyı tam açılana kadar açıp durdursun, close_door(kat) tam kapanana kadar kapatıp durdursun. Kapı zaten tam açıksa (ya da tam kapalıysa) fonksiyon motoru hiç çalıştırmasın.
Şu turu yapın: sırayla 1., 2. ve 3. kata gidin; her katta kapıyı açın, 2 saniye açık tutun ve kapatın.
if (door_open_read(f) == 1) return; gibi bir kontrol, gereksiz (ve hataya yol açan) motor çalıştırmayı önler. Tur için for döngüsü kullanın.Gerçek bir asansör, herhangi bir kat kapısı açıkken asla hareket etmez. Görev 23'teki go_to_floor fonksiyonunu değiştirin: kabini hareket ettirmeden önce üç kapıyı da kontrol etsin; açık (tam kapalı olmayan) kapı varsa konsola bir uyarı yazıp önce o kapıyı kapatsın.
Ana program: 1. kata git, 1 saniye bekle, 3. kata git. Test: çalıştırmadan önce Elle Kontrol'de 2. kat kapısı için Aç'a, kapı yarıdayken Dur'a basın.
go_to_floor fonksiyonunun en başına üç katı dolaşan bir for döngüsü ekleyin ve close_door fonksiyonunu kullanın. C'de bir fonksiyonu kullanmadan önce tanımlamış olmanız gerekir.Sürekli çalışan bir asansör yazın. Bir kabin düğmesine ya da bir kat çağırma düğmesine (▲ veya ▼) basılınca o düğmenin ışığını yakın, kabini o kata götürün, kapıyı açın, 3 saniye açık tutun, kapatın ve o katın bütün düğme ışıklarını söndürün. Sonra yeni bir çağrı bekleyin. Görev 24'teki fonksiyonları kullanın. Ctrl+C ile durdurun.
target değişkenine yazın. Bir katın bütün ışıklarını söndüren lights_off(kat) fonksiyonu işinizi kolaylaştırır.Görev 25'teki asansörü geliştirin: birden fazla çağrı birikebilsin. Her düğmenin isteğini bir dizide saklayın (kabin düğmeleri, ▲ düğmeleri, ▼ düğmeleri için üç dizi); ışık, isteğin saklandığını göstersin. Asansör boşta olduğunda bekleyen çağrılardan bulunduğu kata EN YAKIN olana gitsin, kapıyı açınca o katın isteklerini ve ışıklarını silsin, 3 saniye sonra kapıyı kapatsın.
Test: asansör boştayken hızlıca 1 ve 2 düğmelerine basın (kabin 3. kattayken önce 2'ye gitmeli). Kabin hareket ederken basılan düğmelere ne oluyor?
scan_buttons() basılan düğmeleri dizilere kaydedip ışığını yakar, has_call(kat) o katta istek var mı söyler, clear_calls(kat) o katın isteklerini ve ışıklarını siler. En yakını bulmak için katlar arasındaki uzaklığı karşılaştırın.Görev 26'daki asansörde kabin hareket ederken ya da kapı açıkken yapılan basışlar kayboluyordu. Programı öyle değiştirin ki her bekleme sırasında da düğmeler okunsun: basılan düğmenin ışığı hemen yansın ve istek, sırası gelince karşılansın.
Test: kabin 3. kattan 1. kata giderken 2'ye ve 3. kat ▼ düğmesine basın; ikisinin de ışığı hemen yanmalı ve sonra karşılanmalı.
scan_buttons(); koyun. 3 saniyelik Sleep yerine, kısa adımlarla bekleyip her adımda düğmeleri okuyan bir wait_ms(ms) fonksiyonu yazın. Geçen süreyi saatten okuyun: C'de GetTickCount() (milisaniye), Python'da time.monotonic() (saniye).Her katta, kabinin hangi yöne gittiğini gösteren yukarı ve aşağı ok ışıkları vardır. Kütüphanede bunlar için hazır bir fonksiyon yok; adresleri ADR_GOS_UP1, ADR_GOS_YUK2, ADR_GOS_YUK3 (yukarı) ve ADR_GOS_DWN1, ADR_GOS_AS2, ADR_GOS_AS3 (aşağı) sabitleridir ve write_mem(adres, değer) ile yazılır.
show_arrows(yön) fonksiyonunu yazın: yön CABIN_UP ise üç kattaki yukarı okları, CABIN_DOWN ise aşağı okları yaksın, CABIN_STOP ise hepsini söndürsün. Görev 27'deki go_to_floor içinde, kabin hareket ederken doğru oklar yansın ve kabin durunca sönsün.
int up_arrow[4] = {0, ADR_GOS_UP1, ADR_GOS_YUK2, ADR_GOS_YUK3}; Bir karşılaştırmanın sonucu (dir == CABIN_UP) 1 ya da 0'dır; doğrudan yazılabilir.Görev 28'deki asansörü bekleme döngüsü olmadan, tek bir ana döngü ve bir durum değişkeniyle yeniden yazın. Durumlar: IDLE (boşta), MOVING (hareket), OPENING (kapı açılıyor), OPEN (kapı açık), CLOSING (kapı kapanıyor). Ana döngü her turda düğmeleri okusun ve yalnızca o anki durumun işini yapsın. Kapının 3 saniye açık kalma süresini Sleep ile değil saat okuyarak ölçün.
Davranış Görev 28 ile aynı olmalı: en yakın çağrıya git, kapıyı aç, istekleri sil, 3 saniye bekle, kapat; hareket sırasında oklar ve ekran doğru olsun. Başlangıçta önce bütün kapıları kapatın ve kabin katlar arasındaysa aşağıdaki kata indirin.
#define IDLE 0 ...). Saat: C'de GetTickCount() (milisaniye, DWORD türünde), Python'da time.monotonic() (saniye). Kapı açıldığı an saati bir değişkene kaydedin; şimdiki saatle farkı 3000 ms olunca kapatın. Bir motoru durduracak durumlarda (MOVING, OPENING, CLOSING) döngüde Sleep kullanmayın.Görev 29'daki durum makinesini gerçek asansörler gibi çalışacak hâle getirin:
• Asansör bir yöne gidiyorsa, o yönde bekleyen çağrı kaldığı sürece yönünü değiştirmesin; o yönde çağrı kalmayınca diğer yöne dönsün.
• Yol üzerinde, çağrısı olan bir kattan geçerken orada dursun (ör. 1. kattan 3. kata giderken 2. katta çağrı varsa önce 2. katta dursun).
• Her durakta kapıyı açsın, o katın isteklerini silsin, 3 saniye sonra kapatsın. Ekran ve oklar her zaman doğru olsun; kabin hiçbir zaman kapı açıkken hareket etmesin.
Test: kabin 1. kattayken kabin 3'e basın; kabin 2. kata yaklaşmadan 2. kattaki ▼ düğmesine basın. Kabin önce 2. katta, sonra 3. katta durmalı.
target yerine son hareket yönünü (dir) saklayın. calls_above(kat) ve calls_below(kat) fonksiyonları yazın. IDLE durumunda yön seçimi: eski yönde çağrı varsa o yön, yoksa diğer yön, hiç çağrı yoksa dur. MOVING durumunda her yeni katta: çağrı varsa ya da en üst / en alt kattaysanız durun.Gerçek asansörlerde kapı kapanırken birisi aynı katın düğmesine basarsa kapı yeniden açılır. Görev 30'daki denetleyiciye şunu ekleyin:
• Kapı açıkken (OPEN) bulunulan katın bir düğmesine basılırsa istek hemen silinsin ve 3 saniyelik süre baştan başlasın.
• Kapı kapanırken (CLOSING) bulunulan katın bir düğmesine basılırsa kapı hemen yeniden açılmaya başlasın.
Test: kabin bir katta kapısını kapatırken o katın ▲ düğmesine ya da kabin içinde o katın düğmesine basın.
if (has_call(floor)) eklemeniz yeter. Kapının yönünü değiştirmek için kapanırken doğrudan door(floor, DOOR_OPEN) komutu verilebilir.Binaya gelenlerin çoğu giriş katından (1. kat) biner. Görev 30'daki denetleyiciye şunu ekleyin: asansör 10 saniye boyunca hiç çağrı almadan boşta (IDLE) kalırsa ve 1. katta değilse, kapısını açmadan 1. kata insin ve orada beklesin. Bu sırada bir çağrı gelirse her zamanki gibi karşılansın.
Test: Yenile'den sonra programı başlatın ve hiçbir şeye basmayın; yaklaşık 10 saniye sonra kabin 1. kata inmeli.
idle_since adında bir değişken tutun ve IDLE durumuna her girişte (başlangıçta, kabin durunca, kapı kapanınca) saati buna yazın. IDLE'da çağrı yoksa ve süre dolmuşsa kabini aşağı gönderin. MOVING durumu 1. katta zaten durur.Güvenli bir denetleyici, bir şeylerin ters gittiğini fark edip her şeyi durdurabilmelidir. Görev 30'daki denetleyiciye şunları ekleyin:
• Başlangıçta, varsa eski hata bayrağı temizlenene kadar bekleyin.
• Ana döngünün her turunda get_error() 1 ise acil durdurma yapın.
• Kabin hareket ederken 7 saniye boyunca yeni bir kata ulaşamazsa (normalde iki kat arası yaklaşık 4,7 saniyedir) bunu da arıza sayıp acil durdurma yapın.
Acil durdurma: kabin motorunu ve üç kapı motorunu durdurun, okları söndürün, ekranda 0 gösterin, nedeni konsola yazın ve programı bitirin.
Test 1: kabin hareket ederken Elle Kontrol'de kabin motoru için Dur'a basın (7 saniye sonra zaman aşımı). Test 2: program çalışırken Elle Kontrol'de kabinin bulunmadığı bir katın kapısı için Aç'a basıp bekleyin (kapı tam açılıp devam edince hata).
emergency_stop(neden) fonksiyonu yazın. Hareketin başladığı ve her yeni kata ulaşıldığı anda saati last_floor_time değişkenine yazın; MOVING durumunda farkı kontrol edin. Programı bitirmeden önce sim_disconnect() çağırmayı unutmayın.Bir asansörün ne kadar iyi çalıştığını ölçmek için Görev 30'daki denetleyiciye istatistik ekleyin:
• Kaç durakta kapı açıldığını (hizmet sayısı),
• Kabinin toplam kaç kat yol gittiğini,
• Her kat için ilk düğmeye basılmasından o katta kapının tam açılmasına kadar geçen bekleme süresini ölçüp ortalamasını tutun.
5 hizmetten sonra, kapı kapanıp asansör boşta kalınca bu üç bilgiyi konsola yazın (ortalama bekleme süresi saniye cinsinden, bir ondalıkla), okları söndürüp programı düzgünce bitirin.
press_time[4] dizisi her katın ilk basış zamanını tutsun: scan_buttons içinde, kattaki istek yokken yeni bir istek oluşursa saati kaydedin. Kat sayısını MOVING durumunda her yeni katta bir artırın.