CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Tablice w klasach. Dziwny problem

Tablice w klasach. Dziwny problem

dział ogólny

Re: Tablice w klasach. Dziwny problem

Nowy postprzez Krzysiu555 » sobota, 28 sierpnia 2010, 14:29

W makao w sumie nie jest potrzebna znajomość liczby oczek, więc w sumie wystarczyła by zwykła tablica REKA[52] i KARTY[52] poza tym do liczby oczek można by dostać się po stringu karty 2T, 3P itd.
Ale profilaktycznie na przyszłość zamieniłem te tablice na StringList'y, z tego co piszecie wygląda na to że będzie to dobre rozwiązanie.

Edit:
Tak zmieniłem sposób identyfikacji kart:
Kod: Zaznacz cały
TALIA->Add("2 trefl=2");
TALIA->Add("3 trefl=3");
TALIA->Add("4 trefl=4");
TALIA->Add("5 trefl=5");
TALIA->Add("6 trefl=6");
TALIA->Add("7 trelf=7");
TALIA->Add("8 trefl=8");
TALIA->Add("9 trefl=9");
TALIA->Add("10 trefl=10");
TALIA->Add("Walet trefl=11");
TALIA->Add("Dama trefl=12");
TALIA->Add("Król trefl=13");
TALIA->Add("As trefl=14");

sądzicie że będzie dobrze? z tego co mówiliście będę mógł się do nich dostać zarówno po indexach jak i po nazwach i po dostaniu się przez nazwę otrzymam wartość oczek. Czy tak?
Avatar użytkownika
Krzysiu555
Intelektryk
Intelektryk
 
Posty: 161
Dołączył(a): sobota, 23 sierpnia 2008, 16:55
Podziękował : 2
Otrzymał podziękowań: 1
System operacyjny: Windows 7 Professional 64
Kompilator: C++ Builder 6 Personal
Gadu Gadu: 0
    Windows 7Firefox

Re: Tablice w klasach. Dziwny problem

Nowy postprzez Krzysiu555 » sobota, 28 sierpnia 2010, 14:47

a no i jeszcze drugie pytanie.
to są deklaracje obiektów które wrzucam zamiast tych tablic do klas gracz i do TForm1:
Kod: Zaznacz cały
TStringList *KARTY;
TStringList *REKA;

a to są konstruktory które muszą być przed użyciem:
Kod: Zaznacz cały
KARTY = new TStringList();
REKA = new TStringList();

ale czy to wszystko jedno gdzie stworzę konstruktorami te stringlisty KARTY i REKA? bo potrzebuję mieć do nich dostęp z każdej funkcji w programie
Avatar użytkownika
Krzysiu555
Intelektryk
Intelektryk
 
Posty: 161
Dołączył(a): sobota, 23 sierpnia 2008, 16:55
Podziękował : 2
Otrzymał podziękowań: 1
System operacyjny: Windows 7 Professional 64
Kompilator: C++ Builder 6 Personal
Gadu Gadu: 0
    Windows 7Firefox

Re: Tablice w klasach. Dziwny problem

Nowy postprzez Corvis » sobota, 28 sierpnia 2010, 15:15

Wszystko zależy jak budujesz program. Nieznam struktury twego programu dlatego ciężko mi coś powiedzieć. Ale jeżeli jest to główna klasa z Formą i musisz mieć dostęp do tych obiektów z poziomu tej klasy. To zadeklaruj je w sekcji private, otwórz obiekt w OnCreate i zwolnij w OnDestroy formy.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaOpera

Re: Tablice w klasach. Dziwny problem

Nowy postprzez Krzysiu555 » sobota, 28 sierpnia 2010, 15:32

Cyfrowy Baron napisał(a):Nie trudno przewidzieć, że jeszcze nie raz zada pytanie na tym forum odnośnie tego programu.


Na to wygląda=\. Teraz tak. W StringLiscie TALIA trzymam talię kart uporządkowanych natomiast ich tasowanie przeprowadzam w Stringliscie KARTY. Więc tak wygląda przerobione z array'ów na stringlisty kopiowanie:

KOD cpp:     UKRYJ  
        for(int i=0;i<TALIA->Count;i++){
         KARTY->Add(TALIA->Names[i] + "=" + TALIA->Values[TALIA>Names[i]]);                //kopiowanie kart z TALIA do KARTY
        }

mam nadzieję że dobrze to zrobiłem. Natomiast tak wyglądało tasowanie no i teraz nie wiem jak je przerobić:

KOD cpp:     UKRYJ  
       
        srand(time(NULL));
        int x,y,z;
        for(int i=0;i<52*3;i++){                //mieszanie skopiowanych kart w KARTY
         x = rand() % 51;
         y = rand() % 51;
         z = KARTY[x];
         KARTY[x] = KARTY[y];
         KARTY[y] = z;
        }


Edit:
Znalazłem funkcje Move(int,int) i Exchange(int,int) więc może jakoś ich użyć?
Ostatnio edytowano sobota, 28 sierpnia 2010, 16:18 przez Krzysiu555, łącznie edytowano 1 raz
Avatar użytkownika
Krzysiu555
Intelektryk
Intelektryk
 
Posty: 161
Dołączył(a): sobota, 23 sierpnia 2008, 16:55
Podziękował : 2
Otrzymał podziękowań: 1
System operacyjny: Windows 7 Professional 64
Kompilator: C++ Builder 6 Personal
Gadu Gadu: 0
    Windows 7Firefox

Re: Tablice w klasach. Dziwny problem

Nowy postprzez Cyfrowy Baron » sobota, 28 sierpnia 2010, 16:13

Jeżeli obiekt KARTY i TALIA są tego samego typu i chcesz przekopiować z jednego obiektu do drugiego dane, tylko potasowane, to nie potrzebujesz do tego pętli, gdyż możesz to zrobić tak:

KOD cpp:     UKRYJ  
KARTY->AddStrings(TALIA);


wszak układ listy names=values jest identyczny w obu listach, więc nie ma sensu ich przetwarzanie.



Natomiast tak wyglądało tasowanie no i teraz nie wiem jak je przerobić:


KOD cpp:     UKRYJ  
 srand(time(NULL));
 int x, y;
 String z; // z musi być typu String gdyż przechowuje nazwę karty.
 for(int i = 0; i < 52*3; i++)
 {                //mieszanie skopiowanych kart w KARTY
  x = rand() % 52; // 52 nie 51 tyle ile jest kart
  y = rand() % 52;

  z = KARTY->Strings[x];

  KARTY->Strings[x] = KARTY->Strings[y];
  KARTY->Strings[y] = z;
 }


Tylko dlaczego w pętli jest wartość liczba kart razy 3?!
Trochę niezwykłe to sortowanie, ale jakoś działa.



Corvis napisał(a):otwórz obiekt w OnCreate i

To obiekty klasy gracz, więc najlepiej będzie je zdefiniować w konstruktorze klasy i usunąć w destruktorze, tylko trzeba jeszcze dodać do tej klasy destruktor.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Tablice w klasach. Dziwny problem

Nowy postprzez Krzysiu555 » sobota, 28 sierpnia 2010, 16:25

Cyfrowy Baron napisał(a):Tylko dlaczego w pętli jest wartość liczba kart razy 3?!
Trochę niezwykłe to sortowanie, ale jakoś działa.


By zwiększyć prawdopodobieństwo wylosowania wszystkich liczb. Gdy w rzeczywistości tasujesz karty robi się to też zwykle klika razy. Zwykle parzyście bo rozdawanie jest jeszcze jednym tasowaniem ale ponieważ moje rozdawanie pierwotnie nie było na przemienne zrobiłem tu nieparzysty mnożnik.

x = rand() % 52; // 52 nie 51 tyle ile jest kart
y = rand() % 52;


Czy jesteś tego pewnien? Bo przecież kart jest 52. Ale indeksy rozpoczynają się od 0, więc 52 karta ma 51 index. Więc gdy rand() wylosuje liczbę z przedziału 0-52 (% 52) i trafi akurat na 52 to ten index będzie pusty. No chyba że w StringList indexy zaczynają się od 1 wtedy będzie o ile mi wiadomo % 52 + 1.
Avatar użytkownika
Krzysiu555
Intelektryk
Intelektryk
 
Posty: 161
Dołączył(a): sobota, 23 sierpnia 2008, 16:55
Podziękował : 2
Otrzymał podziękowań: 1
System operacyjny: Windows 7 Professional 64
Kompilator: C++ Builder 6 Personal
Gadu Gadu: 0
    Windows 7Firefox

Re: Tablice w klasach. Dziwny problem

Nowy postprzez Cyfrowy Baron » sobota, 28 sierpnia 2010, 16:38

Czy jesteś tego pewnien? Bo przecież kart jest 52. Ale indeksy rozpoczynają się od 0, więc 52 karta ma 51 index. [...] No chyba że w StringList indexy zaczynają się od 1 wtedy będzie o ile mi wiadomo % 52 + 1.


W TStringList indeksy zaczynają się od 0, ale wielokrotny test z liczbą 51 wykazał, że ostatnia karta nie jest wogóle sortowana. Dzieje się tak dlatego, że jeżeli każesz funkcji rand losować z 51 liczb, to ona losuje z przedziału 0-50, czyli z 51 liczba, ale liczonych o 0 a nie od 1. Zauważ, że gdyby rand losował z przedziału 1-51 to pierwszy indeks listy nie byłby wogóle brany pod uwagę, a przecież jest sortowany i ma wartość 0.



Obiekt TALIA jest zbędny, gdyż od razu możesz przechowywać karty w obiekcie KARTY bez potrzeby przepisywania. Wszak przed każdym tasowaniem karty nie muszą być poukładane w takiej samej kolejności jak na początku gry. Gdy będziesz tasował już potasowane karty zwiększysz tylko przypadkowość tasowania.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Tablice w klasach. Dziwny problem

Nowy postprzez Krzysiu555 » sobota, 28 sierpnia 2010, 17:04

Dobra wszystko poprzerabiałem.
Sytuacja wygląda tak:
TStringList *REKA; jest w public klasy gracz
TStringList *KARTY; jest w public klasy TForm1

tworzę obiekty w zdarzeniu OnCreate dla TForm1

KOD cpp:     UKRYJ  
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  KARTY = new TStringList();
  REKA = new TStringList();
}
a kompiler wyrzuca błąd:

[C++ Error] Unit1.cpp(79): E2451 Undefined symbol 'REKA'


jakby nie widział tej REKI?!?
Avatar użytkownika
Krzysiu555
Intelektryk
Intelektryk
 
Posty: 161
Dołączył(a): sobota, 23 sierpnia 2008, 16:55
Podziękował : 2
Otrzymał podziękowań: 1
System operacyjny: Windows 7 Professional 64
Kompilator: C++ Builder 6 Personal
Gadu Gadu: 0
    Windows 7Firefox

Re: Tablice w klasach. Dziwny problem

Nowy postprzez Corvis » sobota, 28 sierpnia 2010, 18:20

bo nie widzi :P

REKE musisz utworzyć w konstruktore klasy GRACZ
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaOpera

Re: Tablice w klasach. Dziwny problem

Nowy postprzez Krzysiu555 » sobota, 28 sierpnia 2010, 20:21

zrobiłem to tak i działa
KOD cpp:     UKRYJ  
void __fastcall TForm1::FormCreate(TObject *Sender)
{
KARTY = new TStringList();
player1 = new gracz();
player2 = new gracz();
player3 = new gracz();
player4 = new gracz(true);
}
KOD cpp:     UKRYJ  
gracz::gracz(void)
{
  stop = 0;
  human = false;
  REKA = new TStringList();
}


tylko poprzednio nigdzie nie używałem zapisu: playerx = new gracz(); a mimo to działało. czemu tak było? jest w takim razie konieczne deklarowanie w public klasy TForm1 gracz player1; itd.?
Avatar użytkownika
Krzysiu555
Intelektryk
Intelektryk
 
Posty: 161
Dołączył(a): sobota, 23 sierpnia 2008, 16:55
Podziękował : 2
Otrzymał podziękowań: 1
System operacyjny: Windows 7 Professional 64
Kompilator: C++ Builder 6 Personal
Gadu Gadu: 0
    Windows 7Firefox

Re: Tablice w klasach. Dziwny problem

Nowy postprzez Cyfrowy Baron » niedziela, 29 sierpnia 2010, 08:16

tylko poprzednio nigdzie nie używałem zapisu: playerx = new gracz(); a mimo to działało. czemu tak było? jest w takim razie konieczne deklarowanie w public klasy TForm1 gracz player1; itd.?


Nie wiem czemu to Tobie działało, ale wcześniej źle robiłeś.

Jeżeli obiekt klasy gracz ma być używany globalnie, czyli w całym programie, to musi być zadeklarowany w sekcji private lub public pliku nagłówkowego. Klasę możesz zdefiniować w konstruktorze klasy formularza, nie musi to być od razu zdarzenie OnCreate. By lepiej zrozumieć dlaczego musisz deklarować obiekty klasy gracz w pliku nagłówkowym i definiować je w pliku źródłowym proponuję być zajrzał do serwisu Cyfrowy Baron, do działu: teoria -> Przekazywanie obiektów i funkcji pomiędzy formularzami. oraz: teoria -> Tworzenie klas.

Proponuję być poczytał o tym czym są obiekty lokalne, publiczne, prywatne i globalne.



Crovis napisał(a):bo nie widzi :P
REKE musisz utworzyć w konstruktore klasy GRACZ


Corvis nie napisał dlaczego musisz obiekt REKA zdefiniować w klasie gracz. Dlatego, że deklarując obiekt REKA w sekcji public lub private klasy gracz, czynisz właścicielem tego obiektu klasę gracz, więc definiować również musisz ten obiekt w tej klasie, gdyż klasa formularza TForm1 (Form1) nic nie wie o obiekcie REKA. Podobnie sytuacja wygląda z obiektem KARTY, deklarując ten obiekt w sekcji private lub public klasy TForm1 czynisz właścicielem tego obiektu klasę TForm1.

Trochę mnie dziwi Twoja niewiedza w tym temacie. :o Tworzysz klasę gracz, a zdajesz się nie wiedzieć po co są sekcje private i public, dlaczego trzeba deklarować obiekty w tych sekcjach i definiować je wewnątrz klasy.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Tablice w klasach. Dziwny problem

Nowy postprzez Krzysiu555 » poniedziałek, 6 września 2010, 21:52

no i narodziło się kolejne pytanie;\

zająłem się teraz funkcją odpowiadającą na zadaną kartę. mam już pomysł na jej działanie i wiem jak mniej więcej będzie wyglądać.

jest ona zadeklarowana tak w sekcji public klasy gracz:
KOD cpp:     UKRYJ  
class gracz
{
private:
 //int numer;     //przochowuje numer gracza
   int stop;      //ilosc kolejek ktore stoi
   bool human;    //jesli true to człowiek, default false komputer
public:
   String odpowiedz(String karta); //zwraca string z kartą wybraną na podstawie podanego stringa karta
   gracz(bool hum);  //konstruktor człowieczeństwa
   gracz(void);      //konstruktor domniemany  human=false stop=0
   TStringList *REKA;//karty ktore gracz ma w reku
};


i teraz moją intencja jest że gdy chcę by funkcja odpowiedziała na zadaną kartę z kart danego gracza po wywołaniu jej w ten np sposób: player1.odpowiedz("2 trefl")

więc robię coś takiego:
KOD cpp:     UKRYJ  
String gracz::odpowiedz(String karta)
{
//algorytm odpowiedzi
}


a kompilator wyrzuca:

[C++ Error] Unit1.cpp(156): E2171 Body has already been defined for function 'gracz::odpowiedz(AnsiString)'



jestem początkujący i nie wiem o co mu chodzi
Avatar użytkownika
Krzysiu555
Intelektryk
Intelektryk
 
Posty: 161
Dołączył(a): sobota, 23 sierpnia 2008, 16:55
Podziękował : 2
Otrzymał podziękowań: 1
System operacyjny: Windows 7 Professional 64
Kompilator: C++ Builder 6 Personal
Gadu Gadu: 0
    Windows 7Firefox

Re: Tablice w klasach. Dziwny problem

Nowy postprzez Corvis » poniedziałek, 6 września 2010, 22:45

Zobacz czy przez przypadek nie zdefiniowałeś funkcji 2 razy.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows VistaOpera

Re: Tablice w klasach. Dziwny problem

Nowy postprzez Cyfrowy Baron » wtorek, 7 września 2010, 09:37

Z treści błędu wynika, że ta funkcja została zdefiniowana dwukrotnie.

Tak wogóle to sugerowałbym trzymać się pewnych niepisanych zasad programowania. Czyli np. nazwę klasy piszemy z dużej litery i poprzedzamy literą T, czyli nie gracz lecz TGracz. To jak ją nazwałeś nie jest błędem, ale bardziej doświadczeni programiści wyrobili w sobie pewne przyzwyczajenia. Podobnie z nazwami funkcji, nadawaj im nazwy zaczynające się z wielkiej litery by odróżniały się od zmiennych, które zaczynają się u Ciebie również z małej litery. Poza tym używaj raczej nazw angielskich, gdyż język polski zawiera znaki diakrytyczne, których nie można używać w nazwach, a często nadanie funkcji, klasie lub zmiennej polskiej nazwy bez polskich znaków sprawia, że trudno się domyślić, czemu taka funkcja ma służyć, bo nazwa nic nie mówi.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Tablice w klasach. Dziwny problem

Nowy postprzez polymorphism » wtorek, 7 września 2010, 10:44

A'propos litery T. W C++ przyjęte jest, że na początku nazw klas dodaje się literę C, od "class". To T to zwyczaj wzięty z Delphi (podejrzewam, że od "type"), i nikt poza programistami Delphi i C++ Buildera nie stosuje go.

Z małych liter z reguły pisze się nazwy klas lub funkcji szablonowych (vide dokumentacja STL-a).
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Poprzednia stronaNastępna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 5 gości