Nasıl çalışılır?

  1. Görevleri sırayla yapın; her görev bir öncekinin üzerine bir şey ekler.
  2. Her görev için simülasyonun klasöründe, kütüphane dosyasının yanında yeni bir dosya açın (ör. c_room/gorev01.c veya py_room/gorev01.py) ve kütüphaneyi ekleyin.
  3. Önce simülasyonu başlatın, sonra programınızı çalıştırın. Sonsuz döngülü programları Ctrl+C ile durdurun.
  4. Takıldığınızda önce ipucuna bakın; cevabı en son açın.

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.

1 Başlangıç

Bağlanma, çıkışları açıp kapatma ve bekleme.
01

Simülasyona bağlan

Cevabı gör

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?

İpucu
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.
sim_connect()sim_disconnect()printf / print
02

Kabin ekranında sayı göster

Cevabı gör

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.

İpucu
cabin_display(sayı) ekrana yazar. Beklemek için C'de Sleep(1000) (milisaniye), Python'da time.sleep(1) (saniye) kullanın.
cabin_display()Sleeptime.sleep
03

Kabin düğme ışıkları

Cevabı gör

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.

İpucu
cabin_button_light(kat, durum): durum 1 yakar, 0 söndürür.
cabin_button_light()Sleep
04

Kat çağırma ışıkları

Cevabı gö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ı.)

İpucu
floor_button_light(kat, yön, durum); yön için DIR_UP veya DIR_DOWN kullanın.
floor_button_light()DIR_UPDIR_DOWN
05

Kabini biraz hareket ettir

Cevabı gör

Ö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.

İpucu
cabin_motor() için CABIN_DOWN, CABIN_UP ve CABIN_STOP sabitlerini kullanın. Motor siz durdurana kadar döner.
cabin_motor()CABIN_STOP
06

Kapıyı süreyle arala

Cevabı gör

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).

İpucu
door(kat, komut); komut DOOR_OPEN, DOOR_CLOSE veya DOOR_STOP olabilir.
door()DOOR_OPENDOOR_CLOSEDOOR_STOP

2 Temel

Sensör okuma, ekrana yazdırma ve if/else ile karar verme.
07

Kabin nerede?

Cevabı gör

Üç 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?

İpucu
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);
cabin_sensor_read()değişken / variable
08

Kat numarasını ekranda göster

Cevabı gör

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.

İpucu
Bir değişkene 0 verin; 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.
if / else if / elsecabin_sensor_read()cabin_display()
09

Kapı ne durumda?

Cevabı gö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.

İpucu
İki sensör var: 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.
door_sensor_read()door_open_read()if / else if / else
10

Düğmeye basıldı mı?

Cevabı gör

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?

İpucu
cabin_button_read(2) düğme o anda basılıysa 1 döndürür.
cabin_button_read()if / else
11

Hata bayrağını gör

Cevabı gö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.

İpucu
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.
get_error()if / else
12

Motor ne yapıyor?

Cevabı gör

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.

İpucu
cabin_motion_read() 0 (CABIN_STOP), 1 (CABIN_UP) veya 2 (CABIN_DOWN) döndürür. Sabitlerle karşılaştırın.
cabin_motion_read()if / else if
13

Asansör hazır mı?

Cevabı gör

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.

İpucu
Katı Görev 8'deki gibi bulun. İki koşulu birleştirmek için C'de &&, Python'da and kullanın.
&& / anddoor_sensor_read()cabin_sensor_read()

3 Orta

Döngüler, sürekli kontrol ve durum takibi.
14

Ekranda say

Cevabı gör

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.

İpucu
C: for (int i = 1; i <= 9; i++) { ... } Python: for i in range(1, 10):
forcabin_display()
15

Sürekli kat göstergesi

Cevap sende

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.

İpucu
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.
whiledurum değişkeni / state variableSleep
16

Basılı tutarken yansın

Cevabı gör

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.

İpucu
Düğmenin bir önceki turdaki değerini bir değişkende saklayın. Yeni okunan değer eskisinden farklıysa bir değişiklik olmuştur.
değişim algılama / change detectioncabin_button_read()cabin_button_light()
17

Basılan düğmeyi hatırla

Cevabı gör

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.

İpucu
Her kat için yanık mı bilgisini tutan bir dizi kullanın: C'de 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.
dizi / arrayforcabin_button_read()cabin_sensor_read()
18

Sensörle 2. katta dur

Cevap sende

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.

İpucu
'Bir şey olana kadar bekle' döngüsü: C'de while (cabin_sensor_read(2) == 0) { }, Python'da while cabin_sensor_read(2) == 0: pass. Bu döngüye Sleep koymayın.
while (bekleme / wait)cabin_sensor_read()cabin_motor()
19

Kapıyı sensörle aç ve kapat

Cevabı gör

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).

İpucu
Açarken 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.
door()door_open_read()door_sensor_read()while
20

Nereden olursa olsun 1. kata in

Cevap sende

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.

İpucu
Kabin her zaman 1. katın üstünde ya da 1. kattadır; bu yüzden aşağı gitmek her zaman 1. kata ulaştırır. Önce if ile 1. katta olup olmadığına bakın.
if / elsewhilecabin_sensor_read()
21

İstenen kata git

Cevabı gör

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.

İpucu
Üç adım: (1) Görev 8'deki gibi bulunulan katı bulun. (2) 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.
whileforif / else ifcabin_button_read()

4 İleri

Fonksiyonlar, zamanlama, durum makineleri ve hataya dayanıklılık.
22

Fonksiyon: kata git

Cevabı gör

İ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.

İpucu
Fonksiyon, bir işe isim vermektir. C: 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.
fonksiyon / functionreturnparametre / parameter
23

Fonksiyon: kapıyı aç ve kapat

Cevap sende

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.

İpucu
Fonksiyonun başında 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.
fonksiyon / functionreturnfor
24

Güvenlik kilidi: kapı açıkken hareket yok

Cevabı gör

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.

İpucu
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.
güvenlik / safetyfonksiyon / functiondoor_sensor_read()
25

Çağrılara sırayla cevap ver

Cevap sende

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.

İpucu
Her turda üç katın üç düğmesini okuyup basılan katı 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.
whilefonksiyon / functionfloor_button_read()cabin_button_read()
26

Çağrıları biriktir, en yakına git

Cevabı gö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?

İpucu
Üç küçük fonksiyon yazın: 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.
dizi / arrayfonksiyon / functionen yakın / nearest
27

Hareket hâlinde basışları kaçırma

Cevap sende

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ı.

İpucu
Sensör bekleyen boş döngülerin gövdesine 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).
bloklamayan bekleme / non-blocking waitscan_buttons()GetTickCounttime.monotonic
28

Yön okları

Cevabı gör

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.

İpucu
Adresleri, kat numarasıyla erişebileceğiniz iki diziye koyun: 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.
write_mem()adres dizisi / address arrayADR_GOS_UP1
29

Durum makinesi

Cevabı gör

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.

İpucu
Durumlar için sabitler tanımlayın (C: #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.
durum makinesi / state machineGetTickCounttime.monotonic#define

5 Proje

Her şeyi birleştiren tam sistemler.
30

Tam 3 katlı asansör denetleyicisi

Cevabı gör

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ı.

İpucu
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.
durum makinesi / state machinetoplayıcı kontrol / collective controlfonksiyon / function
31

Kapıyı yeniden aç

Cevap sende

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.

İpucu
Yalnızca OPEN ve CLOSING durumlarına birer 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.
durum geçişi / state transitionhas_call()door()
32

Boştayken 1. katta bekle

Cevap sende

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.

İpucu
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.
zaman aşımı / timeoutGetTickCountdurum makinesi / state machine
33

Hata bekçisi ve acil durdurma

Cevap sende

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).

İpucu
Bir 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.
get_error()zaman aşımı / timeoutacil durdurma / emergency stop
34

Hizmet istatistikleri

Cevap sende

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.

İpucu
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.
sayaç / counterortalama / averagezaman damgası / timestamp