wtorek, 21 października 2014

Programowanie w C dla kucharzy

  Każdy od czegoś musi zacząć, więc i my ruszmy nasze szacowne rączki. Wybrano język C z pewnych powodów, o których nie będę tu wspominał. Ma być przystępnie i dla każdego zatem ruszajmy dookoła świata zwanego programowaniem.
   Zawsze zaczyna się każdy kurs programowania od kodu, który kojarzy się z rozmową ze światem.  Wielu wyczekuje odpowiedzi, ale większość wie, że trzeba najpierw zagaić. Więc zagajajmy: Hello, World!
Rys. 1 Hello, World!
  Pierwszy program, może wyglądać tak jak przedstawiony na Listingu nr 1.

Listing 1.
Rys. 2. Wykonanie programu z Listing 1
  1. #include<stdio.h>
  2.  
  3. int main(void)
  4. {
  5.  
  6.    printf("Hello, World!\n");
  7.  
  8. return 0;


Na Rys. 2 pokazano, efekt wykonania programu. Może to nie jest fascynujące, ale to dopiero początek, który dawno temu (1979r.), zaproponowano jako podstawę przy pisaniu programów w Języku C.

No i zaczęła się nasza przygoda. Coś napisaliśmy, udało się to uruchomić i już możemy serwować światu naszą twórczość podaną na talerzu. Mhhhhhhhhhhhhhhhhhmmm jak pięknie pachnie. Ale to dopiero początek, wsiedliśmy do pociągu zwanego Język C. Poczujmy więc jego osobowość i spróbujmy zrobić cosik więcej. Bo cóż to znaczy wydrukować na ekranie łańcuch znakowy, jak dopiero co zaczynamy nasze boje czytaj przygodę z programowaniem.

Zacznijmy od podstaw, które musimy poznać. Zakładam, że posiadamy jakikolwiek kompilator  Języka C, no i umiemy go posługiwać. Jeżeli nie to wkrótce o tym napiszę osobnego posta. Zatem do dzieła.

Prosty kod, a ile w nim dla początkującego niejasności. Rozproszmy wszystkie niejasności i przystąpmy do wyjaśniania podstaw.

  • #include<stdio.h>
Linia, która rozpoczyna program, służy do porozumiewania się z Preprocesorem. Co to oznacza, samym Preprocesorem zajmiemy się później i w tym celu powstanie osobny post. Przyjmijmy, że zadaniem dyrektywy #include będzie przyłączenie pliku stdio.h do naszego kodu. Rozszerzenie *.h jest natywne dla Języka C. Para nawiasów < > wskazuje, że zasoby zawarte w nawiasach (w tym przypadku stdio.h), będą poszukiwane w miejscu domyślnym dla naszego kompliatora. W przypadku Visual Studio jest to miejsce wskazane przez ścieżkę dostępu:

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include

Ale po co? Odpowiedź jest prosta bardzo prosta. W pliku tym są zapisane niezbędne informacje na temat funkcji printf( ), o której zaraz więcej się dowiemy. Jezyk C, jego standard nie przewiduje obsługi wejścia/wyjścia zatem musimy skorzystać z dodatkowych funkcji, które połączą nasz program ze światem zewnętrznym/ W trym przypadku to będzie monitor.

  • int main(void)
Pisząc programy w Języku C musimy pamiętać o jednym bardzo ważnym szczególe. W każdym programie musi być zawarta funkcja main od której rozpoczyna się wykonanie programu. Skąd wiemy, że to funkcja. To proste, para nawiasów okrągłych ( ) wskazuje kompilatorowi, że będzie miał do czynienia z funkcją. Ale, jak zwykle mogą też być i tu wyjątki od reguły. Jest kilka instrukcji w Języku C, które nie są funkcjami, a też korzystają z nawiasów okrągłych. O tym już wkrótce. Nie przejmujmy się zawczasu. Z nabytym doświadczeniem nie sprawią najmniejszego kłopotu, a zapewniam, że będą one często wykorzystywane w praktyce.Słowo kluczowe int wskazuje, że nasza funkcja będzie zwracała (ang. return), wartość typu całkowitoliczbowego. Natomiast słowo kluczowe void mówi kompilatorowi (ang. compiler), że funkcja nie posiada argumentów (o tym już niebawem).

  • {
Nawias klamrowy otwierający. Wskazuje, że  będziemy w tym miejscu umieszczali więcej niż jedną linię kodu. Mówi się często w takim przypadku o ciele funkcji. Istnieje jedna bardzo ważna zasada, że liczba nawiasów otwierających musi być równa liczbie nawiasów zamykających. Stąd też jeżeli występują błędy to warto zwrócić na to uwagę. Edytor programu Microsoft Visual Studio, wskazuje który nawias (według programu, ale nie polegajmy wyłącznie na jego inteligencji) otwierający jest stowarzyszony z nawiasem zamykającym. Nowe wersje programu Microsoft Visual Studio pozwalają na automatyczne uzupełnianie nawiasów. Rzecz może i dobra (wyręcza nas od myślenia), ale pamiętajmy, że pisząc programy nie zawsze musimy to robić od razu na komputerze.

  • printf ()
Zadaniem funkcji printf(), jest wydrukowanie na ekranie monitora (w przypadku programu z Listng 1), sekwencji znaków (którą nazywać będziemy łańcuchem znakowym) Hello,World!. Dzięki temu, że umieszczono na początku programu tzw. plik nagłówkowy stdio.h , który dostarcza niezbędnych informacji dla kompilatora (tak sobie myślę, że w następnym poście chyba trzeba będzie opisać jak tak naprawdę powstaje program komputerowy, no i jakie procesy rządzą tworzeniem programu, w tym miejscu byłoby tego za dużo). Dla dociekliwych polecam stronę:


To, tak z sympatii do tego repozytorium, posiada ono całkiem fajne zasoby, no i według mnie jest tam umieszczony przejrzysty opis dla większości funkcji, które są wykorzystywane przez programistów.
  • printf("Hello, World!\n);  
Zadaniem funkcji printf(), którą wywołujemy z parametrem Hello,World!\n. Łańcuch znakowy zostaje następnie umieszczony w domyślnym urządzeniu wyjściowym jakim zwykle jest ekran monitora komputerowego. Zauważmy, że nasz łańcuch znakowy zakończony został jakimś dziwnym znakiem \n (ang. backslash end). Tak naprawdę para tych znaków reprezentuje znak określany jako tzw. znak nowej linii (ang. newline). Tego typu znak jest niewidoczny na ekranie. Jest to po prostu informacja, która zostaje wykorzystywana przez kompilator. Po napotkaniu takiej informacji, kursor przechodzi do nowej linii i od niej rozpoczyna drukowanie nowych znaków na ekranie.
  •  return 0;
 Instrukcja return pozwala na tzw. zwracanie wartość (w tym przypadku tylko pojedynczej, ale jak zwykle mogą się zdarzyć wyjątki od reguły). Wartość 0, oznacza, że program został wykonany pomyślnie. Po co to wszystko. Otóż wywoływanie funkcji sprawia, że system operacyjny zostaje poinformowany o tym, że sterowanie wykonanie programu przebiegło bez zarzutu. Jakakolwiek inna wartość świadczyłaby o tym, że coś poszło nie po naszej myśli. Problem interpretacji dlaczego, należałoby prześledzić
  • }
Bez nawiasu klamrowego zamykającego, nasz program byłby niekompletny i pojawiłyby się błędy informujące nas o tym, że:

Więc nie zapominajmy o takich kosmetycznych zabiegach. Wspomnę tu jeszcze tylko, że dzięki nawiasom klamrowym {} istnieje możliwość grupowania fragmentów kodu. Robimy to w kilku ważnych celach jak:
    • deklaracjach funkcji
    •  wydzielania bloków programowych
    • przejrzystości kodu (nie wpływają na rozmiar programu)
I tak na koniec mała uwaga, mam nadzieję, że widać to w programie. Każda linia kodu czy to reprezentująca funkcje czy instrukcje (odpowiednio wykorzystane), jest zakończona znakiem średnika. To samo czynimy z deklaracjami oraz wyrażeniami.  Chociaż nie zawsze (np.funkcja  main(), nie kończy się średnikiem).
Rys. 3. Your cook
No i to byłoby na tyle. Zapraszam do testowania programów. Liczę na dyskusję.

Zadanie 1.
Przy użyciu funkcji  printf(), drukującej łańcuch znakowy na ekranie , napisz program pozwalający wydrukować  wzorek inspirowany inicjałami jpochm w postaci przedstawionej na Rys. 4. Proszę zoptymalizować kod, by wykorzystać jak najmniejszą liczbę funkcji printf(). 

Rys. 4. Logo jpochm
Zadanie 2.
Zmodyfikuj Zadanie 1, tak by móc wyświetlić własne logo reprezentujące swój podpis. Kod ten będzie pojawiał się wkrótce przed każdym przez nas napisanym programem.

Zadanie 3.
Zapoznać się z funkcjami pozwalającymi obsługiwać pliki tekstowe. W tym celu należy skorzystać z pomocy zawartej pod adresem:

niedziela, 11 maja 2014

Welcome to the jungle

Od czegoś trzeba było zacząć. Stworzenie postaci bohatera rodem z 8bit form było podstawą tego projektu. Grafika prawie wektorowa, nie mówiąc już o braku płynności ruchów.
 Super bohater o nieskazitelnej fizys, blondyn z lwią grzywą noszący pampersa, który porusza się niczym Frankenstein. Inteligencja na poziomie żaby, by jej nie obrazić. Niestety nie dorobił się nasz super bohater do dnia dzisiejszego imienia. Można powiedzieć, że należy do bezimiennych.
Głównym celem gry były błękitne przedmioty kojarzące się ze skarbami. Przynajmniej dla mnie ma to takie skojarzenie. Przeciwnicy dość statyczni, monotonnie poruszający się po określonych torach. Minimalistyczne tło no i reszta da się sprowadzić do lekkiego zawrotu głowy. Ruch i skoki ograniczone do niezbędnego minimum. No i dźwięki, których prawie nie ma, jakieś plum przy zdobyciu punktów i zgrzyt w przypadku zejścia z tego świata naszego herosa. Walhalla niestety na niego nie czeka. Interfejs użytkownika minimalistyczny. Ruchy wykonywane tylko przy użyciu klawiszy kursorów.
Dziś wydaje mi się, że to trochę trąci (3xt) starością, ale patrząc z perspektywy innych aplikacji niewiele posunęliśmy się na przód co do idei tworzenia gier tego typu. Czy tak naprawdę to dalej się rozwijamy, czy też wciąż bazujemy na sprawdzonych wzorcach. Trudno jest jednoznacznie powiedzieć kto ma rację.
Ja jednak z sympatii do staroci wciąż mam ochotę, by trochę przy nim pomajstrować. Chodzi mi po głowie przerobienie tej gierki, by całkowicie przypominała 8bitowe realizacje z przeszłości. Może to wynikać z sentymentu do tamtej epoki, gdzie gry były na tyle inteligentne, że trzeba było intensywnie myśleć, żeby pomyślnie ukończyć etap bez saveowania.
No takie były początki. Fascynacja grami platformowymi sprawiła, że pojawił się on i był pierwszym moim dzieckiem. Dziś projekt ten może wydawać się archaiczny, ale wiele sprawiło mi zabawy tworzenie tej aplikacji.
Gra w swej strukturze jest stosunkowo prosta oparta na mapie przeszkód, która prezentuje się jako pewien rodzaj labiryntu. Typowa platformówka idziesz według wyznaczonej ścieżki, uważaj tylko czasami na przeciwników, których ruch jest z reguły przewidywalny przez użytkownika. Czasami trzeba mu cosik podrzucić, by bohater mógł się nacieszyć, ze zdobytej nagrody. Zwykle nasi bohaterowie są pazerni na złoto lub kamienie szlachetne. W tym przypadku stwierdziłem, że kamienie szlachetne są wystarczającą nagrodą. Kopnięty kwadrat.  Może niezbyt to spektakularne, ale na pierwszy raz wystarczyło, by poczuć się trochę niczym odkrywca nowych wspaniałych światów. wycieniowany trochę mi je przypominał. A tak naprawdę czy ktoś się kiedykolwiek zastanawiał, gdzie to oni wszystko przechowują. Pewnie trzyma to w RAMie.
Opis powstawał dosyć szybko chodziło tylko o stworzenie pewnego szkicu dla gry oraz o sprawdzenie jak to będzie działać i czy sobie z tym poradzę. Level może nie jest imponujący, ale cały projekt zrodził się w jeden weekend. Oczywiście gra nigdy nie ujrzała na oczy świata, z prostych przyczyn była to tylko wprawka. Ale działająca po dziś dzień.
Tworzenie tego typu gier nie należy do skomplikowanych, trzeba mieć tylko pomysł no i trochę czasu, by się zaangażować w projekt. Reszta sama się rodzi. Głupio się przyznać, ale całość powstała w głowie, bez wstępnych szkiców. Stopień trudności określiłbym na podstawowy. Zadowolenie z produkcji na 5. Razem dałbym sobie ze 4. No i takie to były początki. Następnym razem przedstawię mój pierwszy projekt realizowany na specjalne zamówienie.

środa, 16 października 2013

.: od czego by tu zacząć czyli oswajanie się z demonem :.

Zaczynamy cykl spotkań ze środowiskiem Visual Studio 2012 oraz językiem programowania C. Postaram się tu w sposób przejrzysty opisywać pewne aspekty tego języka, by przybliżyć jego formę osobom, które dopiero co zaczynają przygody w świecie informatyki. Chciałbym, aby była to dobra zabawa, która sprawi wam wiele uciechy. 



W tym celu postaram się przedstawić rozwiązania na tyle czytelne, że nie sprawią nikomu kłopotu. Zatem spróbujmy okiełznać tego demona i zmusić go do pracy.
Zatem zanurzmy nasze stopy w potoku binarnym i spróbujmy z nim popłynąć. Od czegoś trzeba zacząć. Zwykle jest to środowisko, które będzie przez nas wykorzystywane. W tym celu uruchommy nasz program.
Na rys. 1. pokazano w jaki sposób należy tego dokonać.


under construction

rys.1.


No i mamy pierwsze koty za płoty. To niestety nie uczyni jeszcze z nas dobrych rzemieślników, ale jak na początek to i tak jest niezłe.

środa, 12 grudnia 2012

Sztuka z komputera

Tworząc programy staramy się wykonywać je zgodnie z określonymi algorytmami. Algorytmy, które są w pełni określone i w jasny sposób tłumaczą użytkownikowi jak dojść do upragnionego celu. A co, by było w przypadku gdy algorytm zależałby od inwencji twórczej jego autora. Dobrym przykładem może być tutaj zagadnienie fraktali czy też chaosu.
Zastanówmy się jak w prosty sposób wygenerować coś np. obraz dwuwymiarowy, który spełni nasze oczekiwania i przedstawi jakąś formę przekazu matematyczno-plastycznego. Zmuśmy do pracy te szybkie maszynki, by na nasz pożytek coś wygenerowały. Zaczniemy od czegoś prostego. Zbioru punktów pseudolosowych, które posłużą dalej do generacji znanego efektu śnieżenia telewizora.
Od czego zacząć. Wystarczą podstawy algebry oraz trygonometrii no i trochę cierpliwości. Zacznijmy od przykładu, który pozwoli przygotować ekran do tworzenia naszej aplikacji.
Do doświadczeń wybrano język Java. Zakładam podstawową znajomość tego języka w zakresie programowania. Dalsze szczegóły zostawmy sobie na później.

niedziela, 13 maja 2012

Zadanie 2

Wyobraźmy sobie, że żyjemy w kraju bardzo odległym od naszego jakim są Chiny. Odbywamy właśnie staż w urzędzie pocztowym w Pekinie. Bagatela mieszka tam/przebywa około 20 mln ludzi. Naszym zadaniem jako listonosza jest dotarcie do mieszkańców w wybranej dzielnicy. Trudność polega na tym, że liczba mieszkańców jest stosunkowo duża, a listonosz jest jeden. Zatem należy wypracować sobie taki algorytm, który pozwoliłby nam zoptymalizować naszą trasę. W końcu doba ma tylko 24 godziny.

Zatem przejdźmy do czynów. W 1962 roku chiński matematyk Mei-Kowan by rozwiązać ten problem w następujący sposób: 

wędrując od skrzynki do skrzynki (w wybranej dzielnicy), listonosz odwiedza mieszkańców swojego rejonu w taki sposób, by wędrować od domu do domu po czym wrócić na pocztę; duża liczba mieszkańców sprawia, że listonosz pragnie przebyć trasę jak najkrótszą drogą. 

I właśnie wyszukanie takiej trasy nazywamy problemem chińskiego listonosza ang. Chinese Postman Problem  CPP

W oparciu o teorię grafów zaimplementuj ten problem. Można wykorzystać materiały publikowane w:
Co się może przydać w rozwiązaniu problemu:
  • podstawowe pojęcia z teorii grafów
  • algorytm Dijkstry
  • cykl Eulera

niedziela, 6 maja 2012

Zadanie 1


Zaprojektuj program, który pozwoli skrócić ułamek zwykły zdefiniowany jako wyrażenie:


gdzie licznik oraz mianownik to liczby całkowite.

Chcemy skrócić ułamek do jak najprostszej postaci. Uwaga na mianownik, który może przyjąć wartość 0. Może również się zdarzyć, że wartość dla licznika będzie większa lub równa  mianownikowi, wówczas mamy do czynienia z tzw. ułamkami niewłaściwymi. Ułamki takie można wówczas przedstawić przy pomocy sumy liczby całkowitej i ułamka właściwego.

Przykład:
Rozważmy skracanie ułamka zwykłego określonego przy pomocy wyrażenia:


W łatwy sposób można zauważyć, że licznik oraz mianownik ułamka są podzielne przez 7. Możemy zatem w końcu zapisać, że: