Tüm Platformlar için Hızlı Uygulama Geliştirme Kitabı... Delphi
Ön Sipariş Talebinde Bulunan Üyelerimiz
Sipariş Talebinde Bulunan Üyelerimiz

Konuyu Paylaş : facebook gplus twitter

Konuyu Oyla:
  • Derecelendirme: 5/5 - 1 oy
  • 1
  • 2
  • 3
  • 4
  • 5
[Çözüldü] String Grid Sayı Algoritması
#1
Tombala kartı oluşturmaya çalışıyorum. Bunun için Stringgrid kullandım. Sıra geldi içlerine rakamları yerleştirmeye ve boyamaya . Malum tasarım anında bunu gördüğüm kadarıyla yapamıyoruz. Bende çalışma anında yapayım dedim ama olay biraz karışık geldi.
a) Karttaki sayılar rastgele değil. Her kartın sayıları belli. 
b) Bu sayıların aşağıda görüldüğü üzere bir dizilim şekli var. (örnek ilk kartta sayı 2 ilk kutuda ikinci kutu boş ve rengi farklı)

Bununun mantığını nasıl olmalı ?

1) İlk aklıma gelen her kart için sayı dizisi oluşturmak ve bir döngüyle yerleştirmek ( toplam 135 kart)
2) Her kart için bir sınıf tanımlamak. (hangi hücre boş hangisi dolu , hangisinde sayı var gibi)

Tasarım anında düzenlemeye izin verseydi iyidiii Smile)


0RyqpR.png
Cevapla
#2
Kural sıralaması
1 - Tombala kartları 9 kolon 3 satırdan oluşur
2 - Her satırda en fazla 5 hücre dolu olabilir
3- Hücrelere konacak sayı 1-99 arası ve daha önceden yerleştirilmemiş bir sayı olmalıdır.

Şimdi bu mantıkta çok basit olarak tasarlamaya çalışalım
2 döngü olsun
1.döngü satır 2.döngü sutun içeriği olsun (for 1 to 3 ve for 1 to 9 gibi)
istediğin sayısı hücreye yerleştir (Random yada sabit)

Sonra grid için bir boyama yap (OnDrawCell'i biraz incele) hüçre içi dolu ise renk 1 değil ise renk 2 olarak boya
Bu dünyada kendine sakladığın bilgi ahirette işine yaramaz. 
Cevapla
#3
Gözünüzdan kaçan bir şey var , sayı dizilim şekli . Dikkat ettiyseniz örnek birici kart birinci satıra ile ikici kart ilk satırına bakalım.
İlkinde bir dolu bir renkli , ikincisinde bir boş bir renkli. Birde son satırları karşılaştırın. Nerede boşluk vericez nerede boyucaz her kartta bu farklı.  Beni düşündürende o Smile
Bazı kartlarda 5 boşluktan sonra sayılar girilmiş bazısında tam tersi.. Yoksa aşağıdaki gibi sayı ekleyebiliyorum.

procedure sayi_doldur(Grid:TStringGrid);
var
x,y,c:integer;
begin
y:=0;
c:=0;
with Grid do begin
    for y := 0 to RowCount -1 do
    for x := 0 to ColCount -1 do
     begin
        Inc(c,1);
        Cells[x,y]:=IntToStr©;
    end;
end;
end;


procedure kutu_boya(Grid:TStringGrid; satir,sutun:integer; kutu_rengi:TColor);
var
a:TRect;
uretilen_sayı:integer;
begin
   Randomize;
   a:=Grid.CellRect(sutun,satir);
   with Grid.Canvas do begin
    Brush.Color:=kutu_rengi;
    FillRect(a);
   end;
end;
Cevapla
#4
Aslında zor olan bişey yok
OnDrawCell kısmında hücreye bak eğer boş ise background color turuncu
eğer dolu ise background color beyaz, text color siyah

eğer çıkan rakamları yesil yapmak istiyorsan
hücre içeriği çıkan rakam ile aynı ise ozaman background color yesil
Bu dünyada kendine sakladığın bilgi ahirette işine yaramaz. 
Cevapla
#5
Siz beni yanlış anlıyorsunuz, Amacım zaten hücrelere sayıları yerleştirmek. Peki şöyle yapalım daha açıklayıcı olsun.
2,24,31,70,19 rakamlarını karttaki ilk sıraya dizmenizi isityorum. Ama şöyle

1) ilk  hücre boş bırakın , 2 hücreye 2 ,  3 hücreye 24 rakamını koyun.
2) 3 hücre boş bırakın
3)Sona kalan 3 hücereyede 31,70 ve 19 rakamlarını yerleştirin.

şimdi ikinci sıraya geçelim,
1) ilk  4 hücre , boş kalsın
2) sona kalan 5 hücreyede 54,22,65,47,11 rakamlarını yerleştirin

şimdi 3 cü satıra geçelim
Bir tek bir çift hücre boş bırakarak bu beş sayıyı yerleştirin 78,96,52,37,82

Umarım şimdi daha açıklayıcı olmuştur. Her kartta 15 rakam var bunları resimde görüldüğü şekilde nasıl dizerim .
Bu sadece bir kart için geçerli her kartta bu kombinasyon değişiyor.
Cevapla
#6
Ozaman her kart için kombinasyon şekillerini bir matris gibi tutarsınız
[1,1]='2', [1,2] = '', [1,3]='24', [1,4]=31......
sonra aşağıdaki şekilde boyama yaparsınız.
sade örnek olsun diye aşağıdaki kodu koydum siz istediğiniz gibi değiştirin

procedure TForm1.Button1Click(Sender: TObject);
var
 x,y,c:integer;
begin
   y:=0;
   c:=0;
   with Grid do begin
       for y := 0 to RowCount -1 do
       for x := 0 to ColCount -1 do
        begin
           Inc(c,1);
           Cells[x,y]:= IntToStr(Y+1) + IntToStr(X+1);
       end;
   end;
end;


procedure TForm1.GridDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
begin
 with (Sender as TStringGrid) do
 begin
     if Cells[ACol, ARow] = '25' then
     begin
        Canvas.Brush.Color := clGreen;
        Canvas.Font.Color := clWhite;
        Canvas.FillRect(Rect);
        Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, Cells[ACol, ARow]);
    end
    else
     if Cells[ACol, ARow] = '31' then
     begin
        Canvas.Brush.Color := clYellow;
        Canvas.Font.Color := clBlack;
        Canvas.FillRect(Rect);
        Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, Cells[ACol, ARow]);
    end;

 end;

end;

Bu dünyada kendine sakladığın bilgi ahirette işine yaramaz. 
Cevapla
#7
İşte o matris delphide nasıl neyle oluşturulur onu bilmiyorum Smile  Şimdilik Diziler ile deniyorum. Her kartın alacağı rakamları dizilere tanımlıyorum. Rakamların ekleneceği hücre içinde dizler tanımlayıp işi çözmeyi umuyorum. Rakamların yerleri için şöyle bir düşüncem var. Binary sistem gibi bir sayı oluşturup yer belirlicem. 

Örnek olarak karttaki ilk satırı ele alırsak, bir dolu , 4 boş olsun, sonraki 4 tane dolu olsun.  Bunun için şöyle bir dizi içeri olucak  
 A1:array[1..9]of integer=(1,0,0,0,0,1,1,1,1,1); boş olanlara 0 dolulara 1  sanırım bunları döngüye aldık mı iş olur gibi geliyor ama hadi bismillah Big Grin

const
Kart1:array[1..15]of integer=(1,14,59,35,5,9,11,30,38,41,81,13,76,62,88);
Kart2:array[1..15]of integer=(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);

Cevapla
#8
Demek ki her programcının ömründe en az bir kez tombala algoritması yazmış olması yüksek bir ihtimal!
Rasgele sayı dizisi oluşturan bir fonksiyon yazarsan problemin yarısını çözmüş olursun.

"27 farklı kart hücresinden tekrarsız rasgele 15 tanesini, 1-99 aralığında tekrarsız değerlerle doldur."


uses
  Math;


type
  TSayiDizi = array of Integer;


procedure Dizi_QuickSort(var A: array of Integer; iLo, iHi: Integer);
var
  Lo, Hi, Pivot, T: Integer;
begin
  Lo := iLo;
  Hi := iHi;
  Pivot := A[(Lo + Hi) div 2];
  repeat
    while A[Lo] < Pivot do Inc(Lo) ;
    while A[Hi] > Pivot do Dec(Hi) ;
    if Lo <= Hi then
    begin
      T := A[Lo];
      A[Lo] := A[Hi];
      A[Hi] := T;
      Inc(Lo) ;
      Dec(Hi) ;
    end;
  until Lo > Hi;
  if Hi > iLo then Dizi_QuickSort(A, iLo, Hi) ;
  if Lo < iHi then Dizi_QuickSort(A, Lo, iHi) ;
end;


function RasgeleSayilar(Bas,Bit,Adet:Integer):TSayiDizi;
var
  Dizi:TSayiDizi;
  Sira,Rasgele:integer;
begin
  SetLength(Dizi,Bit-Bas+1);
  SetLength(Result,Adet);

  for sira := Bas to Bit do
  begin
    Dizi[sira-Bas] := sira;
  end;

  for sira := 0 to Adet-1 do
  begin
    Rasgele := RandomRange(Bas,Bit);
    Result[sira] := Dizi[Rasgele-1];
    Dizi[Rasgele-1] := Dizi[Bit-1];  // Seçilenin yerine, kalan sonuncuyu taşı.
    dec(Bit);
  end;

  Dizi_QuickSort(result,low(result),high(result));

end;


procedure KartDiziRasgeleDoldur(var KartDizi:TSayiDizi);
const
  SEC_ADET = 15;
  HUCRE_LIMIT = 27;
  DEGER_LIMIT = 99;
var
  KartHucreler: TSayiDizi;
  HucreDegerler: TSayiDizi;
  sira:integer;
begin
  Randomize;

  KartHucreler := RasgeleSayilar(1,HUCRE_LIMIT, SEC_ADET);
  HucreDegerler := RasgeleSayilar(1,DEGER_LIMIT,SEC_ADET);

  SetLength(KartDizi,HUCRE_LIMIT);

  for sira := low(KartHucreler) to high(KartHucreler) do
  begin
    KartDizi[ KartHucreler[sira]-1 ] := HucreDegerler[sira];
  end;

end;


procedure TForm1.Button1Click(Sender: TObject);
var
  KartDizi:TSayiDizi;
begin
  KartDiziRasgeleDoldur(KartDizi);
  ...
end;
WWW
Cevapla
#9
Emeğinize sağlık, teşekkürler. Bu paylaşımınızı inceleyip , yapmak istediğim iş için uyarlamayı deneyeceğim. Paylaşmış olduğum resimdeki kart şablonunu , stringgride uyarlamaya çalışıtığım için rastgele sayı üretip karta dizmeyi düşünmüyorum. Yinede benim işimi kolaylaştıracak bir yapı kurmuşsunuz. Çok teşekkürler
Cevapla
#10
StringGridteki hücrelere sayıları belli bir formatta nasıl girerim diye ararken şöyle bir şey öğrendim sizle paylaşmak istedim.
Her bir hücre içerisindeki bilgiyi dilersek aşağıdaki kod ile bir text dosyaya kaydedebiliyor ve istediğimiz an geri yükleyebiliyoruz.  

procedure TForm1.Dosyadan_Yukle(StringGrid: TStringGrid; FileName: String);
var
 F: TextFile;
 Tmp, x, y: Integer;
 TmpStr: string;
begin
 AssignFile(F, FileName);
 Reset(F);
 Readln(F, Tmp);
 StringGrid.ColCount:=Tmp;
 Readln(F, Tmp);
 StringGrid.RowCount:=Tmp;
 for x:=0 to StringGrid.ColCount-1 do
   for y:=0 to StringGrid.RowCount-1 do
   begin
     Readln(F, TmpStr);
     StringGrid.Cells[x,y]:=TmpStr;
   end;
 CloseFile(F);
end;

procedure TForm1.Dosyaya_Kaydet(StringGrid: TStringGrid; FileName: String);
var
 F: TextFile;
 x, y: Integer;
begin
 AssignFile(F, FileName);
 Rewrite(F);
 Writeln(F, StringGrid.ColCount);
 Writeln(F, StringGrid.RowCount);
 for x:=0 to StringGrid.ColCount-1 do
   for y:=0 to StringGrid.RowCount-1 do
     Writeln(F, StringGrid.Cells[x,y]);
 CloseFile(F);
end;

procedure TForm1.KAYDETClick(Sender: TObject);
var
 i, j: Integer;
begin
 for i:=1 to StringGrid1.ColCount-1 do
   for j:=1 to StringGrid1.RowCount-1 do
     StringGrid1.Cells[i,j]:=IntToStr(i+j);
 Dosyaya_Kaydet(StringGrid1, 'fff.txt');
end;

procedure TForm1.YUKLEClick(Sender: TObject);
begin
 Dosyadan_Yukle(StringGrid1, 'fff.txt')
end;


Dilerseniz şöyle bir şey yapabiliyoruz. Bir metin dosyasına elle yazarak rakamlardan bir şablon oluşturabiliyoruz. Mesela ilk hücre dolu ikincisi boş üçüncüye yaz gibi.. Bununda mantığı aşağıda resimde görülüyor. Text dosyasının ilk satırındaki rakam gridde kaç satır olduğunu ikinci satır ise  kaç sütün olduğunu tutuyor.
Yüklemeyi de yukarıdan aşağı doğru yapıyor. Örneğin üçüncü sütünun ilk hücresine 23 rakamını koymak için txt dosyamızın 9 satırına 23 yazmak yeterli oluyor. Neden dokuz derseniz her sütünümda 3 hücre var , üçüncü sutunun ilk satırı yedinci hücrede ve buna iki satırda hücre ve satır bilgisini eklediğinizde 9 uncu satıra yazmanız gerekiyor.
Bir text dosya kullanmak istemeyenler için TStringlist veya memo ilede aynı yöntemi kullanabilir. Böylece her bir grid için txt dosya tutmanıza gerek kalmaz. Şuan onu yapmaya çalışıyorum, yapabilirsem onuda paylaşırım.

Umarım birilerine faydalı olur. Ekte örnek çalışmayı paylaşıyorum.

Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol

7aANnl.png
Cevapla

Konuyu Paylaş : facebook gplus twitter



Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  [Çözüldü] FMX VLC Player Desteği CesuR 6 142 18-01-2019, Saat: 09:18
Son Yorum: Tuğrul HELVACI
  DBGRID Indicator Sorunu [Çözüldü] SenayAkgun 10 179 16-01-2019, Saat: 18:10
Son Yorum: masteryoda
  [Çözüldü] Stringgrid özellik iptal etme CesuR 4 130 11-01-2019, Saat: 15:18
Son Yorum: CesuR
  FastReport - Runtime Band Gizleme - [ÇÖZÜLDÜ] hi_selamlar 5 116 10-01-2019, Saat: 23:02
Son Yorum: hi_selamlar
  is not a valid floating point value Hatası [ÇÖZÜLDÜ] SenayAkgun 16 378 23-12-2018, Saat: 22:07
Son Yorum: mustafaozpinar



Konuyu Okuyanlar: 1 Ziyaretçi