Thread overview
Türler ile ilgili basit bir alıştırma örneği
Apr 09, 2011
mert
Apr 10, 2011
mert
Apr 10, 2011
erdem
Apr 15, 2011
mert
Apr 15, 2011
mert
April 09, 2011

Yapılar üzerinde alıştırmalar yapıyorum. Derslerde sunulan örneklerden bağımsız olarak ileride sınıflar ile de kullanabileceğim bir model geliştireyim istedim.

Bu alıştırmada hem temel türleri, hem işlevleri hem de yapı, enum gibi türleri kullanmaya çalıştım. İlerledikçe ve alıştıkça örneğimi de geliştirebileceğimi düşünüyorum.

import std.stdio;

enum DarbeTipi {Bıçak = 10, Kılıç = 20, Tabanca = 50, Tüfek = 70, Bomba = 100 }

struct Kahraman
{
	double güç;
	double para;
}

double değerlendir(in double parametre, in double değer)
{
	double ölçek;
	ölçek = parametre - (parametre * değer);

	return ölçek;
}

Kahraman darbeAl(in Kahraman karakter, in double darbe)      // daha kısa yollar dene
{
	Kahraman darbeli;
	if (darbe == 10) {
		darbeli.güç  = değerlendir(karakter.güç, 0.1);       // Başka bir işlev ile
		darbeli.para = değerlendir(karakter.para, 0.1);
	} else if (darbe == 20) {
		darbeli.güç  = değerlendir(karakter.güç, 0.2);
		darbeli.para = değerlendir(karakter.para, 0.2);
	} else if (darbe == 50) {
		darbeli.güç  = karakter.güç - (karakter.güç  * 0.5); // Başka bir işlevsiz
		darbeli.para = karakter.para - (karakter.para * 0.2);
	} else if (darbe == 70) {
		darbeli.güç  = karakter.güç - (karakter.güç  * 0.7);
		darbeli.para = karakter.para - (karakter.para * 0.2);
	} else if (darbe == 100) {
		darbeli.güç  = değerlendir(karakter.güç, 0.9);
		darbeli.para = değerlendir(karakter.para, 0.3);
	} else {
		darbeli.güç  = 0;
		darbeli.para = 0;
	}
	return darbeli;
}

void main()
{
	Kahraman başlangıç = Kahraman(100, 10_000);

	writefln("Herhangi bir kahraman için başlangıç  %s - %s ",
				başlangıç.güç, başlangıç. para);
	writeln();
	Kahraman benimKahramanım = başlangıç;
	writefln("Yeni bir kahraman için başlangıç %s - %s",
				benimKahramanım.güç, benimKahramanım.para);

	writeln("Kahramanın bir tür darbe aldı");

	enum darbe = DarbeTipi.Bomba;  // Bıçak, Kılıç, Tabanca, Tüfek, Bomba

	auto kahramanDurumu = darbeAl(benimKahramanım, darbe);

	writefln("Kahramanın durumu:  ♥ %s - € %s",
				kahramanDurumu.güç, kahramanDurumu.para);
}

Örneğimde darbe tipini değiştirerek kahramanı çeşitli biçimlerde güçsüz ve parasız bırakabiliyorum. Yine ek bir yapı tanımlayarak yeni güçler ve kazanç kaynakları veya donatımsal araç gereçler eklemek mumkun. Öğrenme sürecindeki arkadaşlarımla paylaşmak istedim.

mert

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 09, 2011

Ne güzel programlar gelmeye başladı! :)

Hemen gözüme çarpan bir iki nokta oldu.

  1. Mümkünse değişkenin ilk değerinin tanımlandığı yerde verilmesi önerilir:
   double ölçek = parametre - (parametre * değer);

Her zaman öyle olması gerekmez ama burada olabilir gibi görünüyor.

  1. Bence darbeAl'ın içinde bir if zinciri değil, 'final switch' kullanılması daha uygun olur. DarbeTipi diye okunaklı değerleri olan okunaklı bir tür varken 10, 20 gibi değerler anlaşılamıyor:
   final switch (darbe) {
   case DarbeTipi.Bıçak:
       darbeli.güç  = değerlendir(karakter.güç, 0.1);       // Başka bir işlev ile
       darbeli.para = değerlendir(karakter.para, 0.1);

       break;
// ...

Tabii onu yapmak için işlevin parametresinin türü de DarbeTipi olmalı.

  1. Bir de şu satır üzerinde düşüncelerim var:
   auto kahramanDurumu = darbeAl(benimKahramanım, darbe);

darbeAl, bir Kahraman alıyor ve onun darbe almışı olan yeni bir Kahraman döndürüyor. Fonksiyonel programcılık açısından çok güzel ve belki de en doğrusu o. Ancak, nesne yönelimli bakış açısına alışmış birisi olarak ben burada yan etki olmasının daha uygun olabileceğini düşündüm. Eğer darbeAl()'ı bir üye işlev yaparsak, var olan karakterin kendisi değişir. (Bu konu 'Üye İşlevler' bölümü ile ilgili):

struct Kahraman
{
   double güç;
   double para;

   void darbeAl(in DarbeTipi darbe)
   {
       // ... burada 'güç' ve 'para' üyeleri değiştirilir ...
   }
}

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2011

Alıntı:

>
  1. Mümkünse değişkenin ilk değerinin tanımlandığı yerde verilmesi önerilir:

Tamamen haklısınız. Daha fazla dikkat gerekiyor.

Alıntı:

>
  1. Bence darbeAl'ın içinde bir if zinciri değil, 'final switch' kullanılması daha uygun olur. DarbeTipi diye okunaklı değerleri olan okunaklı bir tür varken 10, 20 gibi değerler anlaşılamıyor:

final switchbir sonraki alıştırma olarak aklımdaydı. Örneği birçok açıdan tekrar tekrar yazacağım. Hem ayrıca "sihirli sabitlerden kaçınınız" demiştiniz, hatırladım.

Alıntı:

>

3)Bir de şu satır üzerinde düşüncelerim var:

auto kahramanDurumu = darbeAl(benimKahramanım, darbe);

darbeAl, bir Kahraman alıyor ve onun darbe almışı olan yeni bir Kahraman döndürüyor. Fonksiyonel programcılık açısından çok güzel ve belki de en doğrusu o. Ancak, nesne yönelimli bakış açısına alışmış birisi olarak ben burada yan etki olmasının daha uygun olabileceğini düşündüm. Eğer darbeAl()'ı bir üye işlev yaparsak, var olan karakterin kendisi değişir. (Bu konu 'Üye İşlevler' bölümü ile ilgili):

Yapılar bölümüne geldiğimde o tür olanaklarla ilk kez karşılaşmış olduğumdan sınıflara kadar bir ön okuma yapıp yeniden geriye dönmeyi seçmiştim. Temel türler ve tür tanımlama bölümlerini tüm kitap boyunca yeniden gözden geçirerek özet bir hızlı başvuru kaynağı hazırladım kendime. Aynı özet çalışmasını işlevler için de hazırladım, üye işlevlere kadar. konuları iyice öğrenip içselleştirmeyi başardıkça - ki bu içselleştirme yeteri kadar alıştırma çözmeden pek oluşmuyor- belli başlı konularda hızlı başvuru kaynağım da olmuş olacak böylelikle. Bu sayede eksiklerimi doğru biçimde tamamlayabileceğimi düşünüyorum.

Benim gibi betik dillerinden derlemeli bir dile geçen öğrencilerin D içerisindeki bilgiler, olanaklar kurallar veya disiplinlerle aşina olması değil, öğrenmeye başlaması bu tür çabaları gerekli hale getiriyor. Çünkü kaynaklar yeterli ve bol. (örneğin forum, örneğin d.ershane, örneğin özenli bir öğretmen) kolay bulunmuyor hepsi bir arada.

Örneğin php'de nesne yönelimi olmakla beraber yapılar gibi olanaklarla karşılaşamıyorsunuz. Hem ayrıca php öğrenirken önümüze bu kadar ayrıntılı bir öğrenme mekanizmasını da kimse alıp koymamıştı işin doğrusu. Kaynağı bol, bilgi yönünden verimliliği kıt olan öğrenme mekanizmalarının, öğretme yerine aşina etme gibi bir işlevi olduğunun farkına varıyorum. Şimdi D öğrenirken, doğru kaynaklardan doğru yöntemlerle öğrenmenin keyfini çıkarmaya çalıştığımı itiraf etmeliyim :-)

Örnek alıştırmamı belirttiğiniz noktalara dikkat ederek geliştireceğim.Teşekkür ederim hocam.

mert

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2011

Alıntı (acehreli):

>

Örneğin "sihirli sabitlerden kaçınınız" gibi bir söz, herhalde her okuyanda farklı bir iz bırakmıştır.

Evet. Bunu 7 sene önce sizden duyduğumda bir değişken nasıl sihirli olur diye düşünmüştüm.

Demek ki değişkenin de sihirlisi oluyormuş :-p

Ben kendi adıma konuşmak gerekirse, o tekrarlardan aklımda kalanlar C++ konusunda öğrendiklerimin temelini oluşturuyor. Unuttuklarımı da zaten defalarca soruyorum :)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2011

Öğrenmenin nasıl olması gerektiğini görüyoruz! ;)

Umarım benim tekrarlarımdan rahatsız olmuyorsunuzdur. Ben C++ forumlarını izlerken hiç bilmediğim konularda hiç anlamadığım öneriler okurdum. Örneğin birisi bir şey sorardı; yanıtlar arasında "bir de şu çözüm var" diye bir öneri geçerdi. Tabii ben baştan hiç bir şey anlamazdım; kafamda küçücük bir iz kalırdı. Ama o tekrarlar eninde sonunda bende de bilgi haline geldiler.

Örneğin "sihirli sabitlerden kaçınınız" gibi bir söz, herhalde her okuyanda farklı bir iz bırakmıştır. Ama aynı konuyu böyle bir program üzerinde görüp konuşunca herhalde unutulmaz.

Programlara devam! :)

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 15, 2011

Örneğimi belirttiğiniz noktalara dikkat ederek yeniden toparladım. Böylelikle hem daha kısa kod yazmış oldum, hem daha iyi anlaşılır oldu benim için işlevler ve türler. Üye işlevler çok şık.

import std.stdio;
import std.string;

enum DarbeTipi { Bıçak, Kılıç, Tabanca, Tüfek, Bomba }

struct Kahraman
{
	double güç;
	double para;

	const string toString()
	{
		return format("♥ %02s € %02s", güç, para);
	}

	void darbeAl(in DarbeTipi darbe)
	{
			final switch(darbe) {

			case DarbeTipi.Bıçak:
			güç  = değerlendir(güç,  0.1);
			para = değerlendir(para, 0.1);
			break;

			case DarbeTipi.Kılıç:
			güç  = değerlendir(güç,  0.2);
			para = değerlendir(para, 0.2);
			break;

			case DarbeTipi.Tabanca:
			güç  = değerlendir(güç,  0.5);
			para = değerlendir(para, 0.3);
			break;

			case DarbeTipi.Tüfek:
			güç  = değerlendir(güç,  0.7);
			para = değerlendir(para, 0.4);
			break;

			case DarbeTipi.Bomba:
			güç  = değerlendir(güç,  0.9);
			para = değerlendir(para, 0.5);
			break;

		   }

	   }
}

double değerlendir(in double parametre, in double değer)
{
	double ölçek = parametre - (parametre * değer);

	return ölçek;
}

void main()
{
	auto başlangıçKahramanı = Kahraman(100, 10_000);

	auto benimKahramanım    = başlangıçKahramanı;

	enum darbe = DarbeTipi.Tüfek;

	benimKahramanım.darbeAl(darbe); // benim kahramanım artık tüfek darbeli

	writefln("%s - %s", başlangıçKahramanı, benimKahramanım);
}

İlerledikçe hem örneği geliştirip hem kod satırlarını mümkün olduğu kadar kısaltmayı düşünüyorum.
Teşekkürlerimle.

mert

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 16, 2011

Yönlendirmeniz yeni yeni yollar açıyor önümde. Ama daha sınıflara girmiş bile değilim. O aşamalara geldiğimde ise sanırım bir hava - yer savaş oyununun basit örneklerine adımlar atabilirim. (barışçıl biriyim oysa, sırf alıştırma için:-)
Örneğin hızı, tipi kapasiteleri belirgin bir uçak sınıfımız olur. Bu bir yerden havaya füze sistemi ile karşı karşıya gelebilir. Farklı uçaklar farklı kapasite ve menzillerde farklı mac hızlarında ve dönüş kabiliyetleri belli g değerleri üzerinde olan füzelerle karşılaştırılabilinir.

Dediğiniz gibi sonu yok hiç. Burada önemli olan tasarım sanıyorum. İnterface olanakları müthiş bir yetenek. Bir cgi bağı ile internet üzerinde bile bir çok kullanıcının ortaklaşa rahatlıkla oynayabileceği bir simülasyon oluşturmak çok zor olmasa gerek.

Demek ki daha çok alıştırma yaparak daha iyi kavramam gerekiyor D'ili.

Yönlendirmeniz nerelere aldı götürdü örneği görüyor musunuz? :-)

mert

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 16, 2011

Çok güzel. :) Tabii bu işin sonu yok...

Mutlaka bir şey söylemek gerekirse, gözüme ilk çarpan, 'değerlendir' işlevi oluyor. Kendi ismi ve parametre isimleri anlaşılmasına yardımcı olmuyor. Ancak işlevin içine baktıktan sonra 'değer''in "yüzde şu kadar azalt" demek olduğunu anlayabildim.

Tabii her zaman azaltma anlamına gelmeyeceğini de biliyorum. O yüzden 'değerlendir' gibi genel bir isim kullanmak zorunda kalınıyor.

Bundan sonraki adım, DarbeTipi'ni enum yapmak yerine Darbe diye bir sınıf sıradüzeni kurmak olabilir. Nesne yönelimli programlamaya tam sadık olanlar için 'switch' deyimi bir işarettir: o deyimin görüldüğü yere bir sıradüzen gelebilir. :)

Darbenin etkisi, sınıfları olmayan C'de 'switch' ile yazılmak zorundadır. (Aslında işlev göstergeleriyle C'de de nesne yönelimli programlama yapılır ama çetrefillidir.) D gibi dillerde ise aşağıdaki gibi de olabilir. (Not: 'enum' ve 'switch' yasak değildir. :) Bir işaret olarak görülebileceğini söylemek istiyorum.) (Ayrıca kodu derlemedim bile; hatalıdır.)

interface Darbe
{
   double güçDeğerlendir(in double güç);
   double paraDeğerlendir(in double para);
}

class BıçakDarbesi : Darbe
{
   double güçDeğerlendir(in double güç)
   {
       return güç - (güç * 0.1);
   }

   double paraDeğerlendir(in double para)
   {
       return para - (para * 0.1);
   }
}

// ... diğer darbeler de benzer şekilde ...

Şimdi 'darbeAl' çok daha kısa olur. Hatta yüzde değerleri bütünüyle darbelerle ilgili sınıflar içinde bulunurlar:

struct Kahraman
{
// ...
   void darbeAl(in Darbe darbe)
   {
       güç = darbe.güçDeğerlendir(güç);
       para = darbe.paraDeğerlendir(para);
   }
}

Sonra çağrıldığı yerde:

   auto darbe = new TüfekDarbesi;

   benimKahramanım.darbeAl(darbe);

Bu yöntem, darbelerin davranışlarındaki farklılıkların sayısı fazla olduğunda daha da yararlı olacaktır.

Ama fikir olarak gösteriyorum. Kendim de 'enum' ve 'switch' ile yapardım herhalde. :)

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]