• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed C++ Builder prosta symulacja - prośba o pomoc

Object Storage Arubacloud
0 głosów
436 wizyt
pytanie zadane 9 czerwca 2020 w C i C++ przez kielek123 Nowicjusz (150 p.)
zamknięte 13 czerwca 2020 przez kielek123

Cześć wszystkim,

piszę prostą symulacją: w zagrodzie poruszają się w losowych kierunkach owce i wilk. Gdy wilk napotka owce, zjada ją (obrazek owcy znika). Mam już prawie cały kod tylko zostały mi dwie rzeczy z którymi nie mogę sobie poradzić.

1. Chcę aby ruch wilka został zatrzymany po zjedzeniu 3 owiec. Funckcja if w TTimer  mi nie działa - wilk się nie zatrzymuje.

2. Chcę, aby po kolejnym kliknięciu startu symulacji poprzednie obiekty zniknęły i pojawiły się nowe - taki reset symulacji. Nie wiem w jaki sposób usunąć poprzednie obiekty. Próbowałem działać atrybutem Visible.

 

Z góry dzięki za pomoc.

zagroda

 

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"


#define Sx 500
#define Sy 500
#define N 5
bool spotkanie_owieczki(TImage *owca, TImage *wilk)
{
     if (owca->Left >= wilk->Left-owca->Width &&
        owca->Left <= wilk->Left+wilk->Width &&
        owca->Top >= wilk->Top-owca->Height &&
        owca->Top <= wilk->Top+wilk->Height)
        {
                return true;
        }
        else return false;

}

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{

}
//---------------------------------------------------------------------------



class Zwierze //klasa abstrakcyjna
  {
  public:
  int x0,y0,  vx,vy;
  int masa,q;

  virtual void ruch() =0;

  };

  //KLASA OWCA////////////////////////////////////////
  class Owca:public Zwierze
  {
        public:
        TImage *ksz_o;
        virtual void ruch()
      {
      x0+=vx;
      y0+=vy;
      if(x0>=Sx) { vx=-vx; x0=Sx-1; }
      if(x0<0)   { vx=-vx; x0=0;    }
      if(y0>=Sy) { vy=-vy; y0=Sy-1; }
      if(y0<0)   { vy=-vy; y0=0;    }
      ksz_o->Left=x0;
      ksz_o->Top=y0;
      }
      Owca();     //konstruktor owcy
      ~Owca(void);//
  };

  Owca::Owca()     //konstruktor owcy - stworzenie ksztaltu i przypisanie wartosci poczatkowych
      {
      x0=random(Sx);
      y0=random(Sy);
      while( (vx=random(7)-3)==0);
      while( (vy=random(7)-3)==0);
      //stwarza ksztalt
      ksz_o=new TImage(Form1);
      ksz_o->Parent=Form1;
      ksz_o->Left=x0;
      ksz_o->Top=y0;
      ksz_o->Width=100;
      ksz_o->Height=100;
      ksz_o->AutoSize=true;
      ksz_o->Visible=true;
      ksz_o->Picture->LoadFromFile("img/sheep.bmp");
      }

  //KLASA WILK////////////////////////////////////////
  class Wilk :public Zwierze
  {
        public:
        TImage *ksz_w;
        int masa_wilka;
        virtual void ruch()
      {
      masa_wilka=0;
      x0+=vx;
      y0+=vy;
      if(x0>=Sx) { vx=-vx; x0=Sx-1; }
      if(x0<0)   { vx=-vx; x0=0;    }
      if(y0>=Sy) { vy=-vy; y0=Sy-1; }
      if(y0<0)   { vy=-vy; y0=0;    }
      ksz_w->Left=x0;
      ksz_w->Top=y0;
      }



      int zjedzOwce( Owca *owca )    //funkcja, ktora sprawdza czy wilk napotkal owieczke, jesli tak to ja zjada
        {
                if(spotkanie_owieczki(owca->ksz_o, ksz_w) )
                        {
                                owca->ksz_o->Visible=false;
                                masa_wilka+=1;      // gdy wilk zje owce masa wzrasta o 1
                                return masa_wilka;
                        }

        }


        Wilk();     //konstruktor wilka
        ~Wilk(void);
  };

     Wilk::Wilk()     //konstruktor wilka - stworzenie ksztaltu i przypisanie wartosci poczatkowych
      {
      x0=random(Sx);
      y0=random(Sy);
      vx=20;
      vy=20;


      //stwarza ksztalt
      ksz_w=new TImage(Form1);
      ksz_w->Parent=Form1;
      ksz_w->Left=x0;
      ksz_w->Top=y0;
      ksz_w->Width=60;
      ksz_w->Height=60;
      ksz_w->Visible=true;
      ksz_w->AutoSize=true;
      ksz_w->Picture->LoadFromFile("img/wolf.bmp");
      }

        Owca *to[N];
        Wilk *tw;

  Owca::~Owca()
      {
        delete [] to;
      }

  Wilk::~Wilk()
      {
        delete [] tw;
      }


void __fastcall TForm1::Timer1Timer(TObject *Sender)
{


        int i;
        for(i=0; i<N;i++)
        {
          to[i]->ruch();
          tw->zjedzOwce(to[i]);

        }


        if(tw->masa_wilka<3)tw->ruch();  //ruszaj wilkiem dopoki nie zje 3 owiec





}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button2Click(TObject *Sender)
{
        int i;
        for(i=0;i<N;++i) to[i]= new Owca;
        tw= new Wilk;
        Timer1->Enabled = 1;

}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------





 

komentarz zamknięcia: rozwiązanie problemu

1 odpowiedź

0 głosów
odpowiedź 9 czerwca 2020 przez j23 Mędrzec (194,920 p.)
Owca* to[N];
Wilk* tw;

Owca::~Owca()
{
    delete[] to;
}

Wilk::~Wilk()
{
    delete[] tw;
}

A co Ty tu usuwasz?

Funckcja if w TTimer  mi nie działa - wilk się nie zatrzymuje.

if oczywiście działa, tylko nie wiedzieć czemu za każdym wywołaniem Wilk::ruch zerujesz Wilk::masa_wilka:

class Wilk : public Zwierze {
...
    virtual void ruch()
    {
        masa_wilka = 0;
        ...

Popracuj nad formatowaniem, bo koszmarnie się to czyta. Dlaczego definicje klas wplecione są w definicje metod klasy TForm1? Nie można ich dać na początku pliku?

komentarz 9 czerwca 2020 przez kielek123 Nowicjusz (150 p.)
Racja, zdefiniowałem już masę wilka w konstruktorze klasy Wilk i już działa jak należy. Pozostaje mi problem z punktem drugim czyli resetem. Masz jakąś wskazówkę?

 

Czytałem że należy w destruktorach niszczyć obiekty, może czytałem błędny artykuł.
komentarz 9 czerwca 2020 przez j23 Mędrzec (194,920 p.)

Masz jakąś wskazówkę?

Nie rozumiem, dlaczego masz z tym problem. Przecież wystarczy reinicjować proces od nowa:

// usuwasz stare...
for (int i = 0; i < N; ++i) delete to[i];
delete tw;

// ... i tworzysz nowe
for (int i = 0; i < N; ++i) to[i] = new Owca;
tw = new Wilk;

Timer1->Enabled = 1;

Czytałem że należy w destruktorach niszczyć obiekty, może czytałem błędny artykuł.

Owszem, ale powinno się niszczyć obiekty, które obiekt klasy sam stworzy i/lub jest ich właścicielem. Jak by na to nie patrzeć, to i tw nie wskazują na obiekty stworzone przez klasy Wilk i Owca. Te obiekty są tworzone w TForm1 i destruktorze tej klasy powinno odbywać się usuwanie.

delete[] tw;

Używasz wyrażenia delete[], który jest dla tablic, a nie pojedynczych obiektów.

delete[] to;

Byłoby OK, gdyby nie fakt, że próbujesz usunąć tablicę, która nie jest stworzona na stercie (wyrażeniem new[]). To wyrażenie usuwa tablicę, ale nie obiekty wskazywane przez wskaźniki. Czyli wyciek...

Jeszcze jeden błąd: w klasach Wilk i Owca tworzysz obiekty klasy TImage, ale nie usuwasz ich w destruktorach ~Wilk() i ~Owca(). Wprawdzie obiekt Form1  jest odpowiedzialny za usunięcie tych image'ów, ale on jest usuwany pod koniec działania programu, więc można to uznać za wyciek pamięci.

 

 

komentarz 10 czerwca 2020 przez kielek123 Nowicjusz (150 p.)

Właśnie próbowałem w ten sposób i nie działa, klikam przycisk i pojawią się nowe ale nie kasują się stare.

// usuwasz stare...
for (int i = 0; i < N; ++i) delete to[i];
delete tw;
 
// ... i tworzysz nowe
for (int i = 0; i < N; ++i) to[i] = new Owca;
tw = new Wilk;
 
Timer1->Enabled = 1;

Próbowałem też ustawiać zamiast delete obiektu to atrybut Visible na false. Jednak program się wysypuje i daje błąd.

komentarz 10 czerwca 2020 przez j23 Mędrzec (194,920 p.)

Pokaż kod po przeróbkach.

ale nie kasują się stare.

Pewnie nie usuwasz ksz_o w destruktorach Wilk i Owca (o czym pisałem).

komentarz 10 czerwca 2020 przez kielek123 Nowicjusz (150 p.)

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"


#define Sx 500
#define Sy 500
#define N 8
bool spotkanie_owieczki(TImage *owca, TImage *wilk)  //warunki na pokrycie się wilka i owcy
{
     if (owca->Left >= wilk->Left-owca->Width &&
        owca->Left <= wilk->Left+wilk->Width &&
        owca->Top >= wilk->Top-owca->Height &&
        owca->Top <= wilk->Top+wilk->Height)
        {
                return true;
        }
        else return false;

}

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{

}
//---------------------------------------------------------------------------



class Zwierze //klasa abstrakcyjna
  {
  public:
  int x0,y0,  vx,vy;

  virtual void ruch() =0;

  };

  //KLASA OWCA//
  class Owca:public Zwierze
  {
        public:
        TImage *ksz_o;
        virtual void ruch()
      {
      x0+=vx;
      y0+=vy;
      if(x0>=Sx) { vx=-vx; x0=Sx-1; }
      if(x0<0)   { vx=-vx; x0=0;    }
      if(y0>=Sy) { vy=-vy; y0=Sy-1; }
      if(y0<0)   { vy=-vy; y0=0;    }
      ksz_o->Left=x0;
      ksz_o->Top=y0;
      }
      Owca();     //konstruktor owcy
      ~Owca();//  //destruktor owcy
  };

  Owca::Owca()     //konstruktor owcy - stworzenie ksztaltu i przypisanie wartosci poczatkowych
      {
      x0=random(Sx);
      y0=random(Sy);
      while( (vx=random(7)-3)==0);
      while( (vy=random(7)-3)==0);
      //stwarza ksztalt
      ksz_o=new TImage(Form1);
      ksz_o->Parent=Form1;
      ksz_o->Left=x0;
      ksz_o->Top=y0;
      ksz_o->Width=100;
      ksz_o->Height=100;
      ksz_o->AutoSize=true;
      ksz_o->Visible=true;
      ksz_o->Picture->LoadFromFile("img/sheep.bmp");
      }

 //KLASA WILK//
  class Wilk :public Zwierze
  {
        public:
        TImage *ksz_w;
        int zjedzonych_owiec;
        int masa_wilka;
        virtual void ruch()
      {
      x0+=vx;
      y0+=vy;
      if(x0>=Sx) { vx=-vx; x0=Sx-1; }
      if(x0<0)   { vx=-vx; x0=0;    }
      if(y0>=Sy) { vy=-vy; y0=Sy-1; }
      if(y0<0)   { vy=-vy; y0=0;    }
      ksz_w->Left=x0;
      ksz_w->Top=y0;
      }



      int zjedzOwce( Owca *owca )    //funkcja, ktora sprawdza czy wilk napotkal owieczke, jesli tak to ja zjada
        {
                 if(  owca->ksz_o->Visible == true  &&  spotkanie_owieczki(owca->ksz_o, ksz_w) )
                        {
                                owca->ksz_o->Visible=false;
                                zjedzonych_owiec+=1;
                                masa_wilka+=4;      // gdy wilk zje owce masa wzrasta o 1
                                return masa_wilka;
                        }
                  
        }


        Wilk();     //konstruktor wilka
        ~Wilk(void);   //desttruktor wilka
  };

     Wilk::Wilk()     //konstruktor wilka - stworzenie ksztaltu i przypisanie wartosci poczatkowych
      {
      x0=random(Sx);
      y0=random(Sy);
      vx=20;
      vy=20;
      masa_wilka=0;
      zjedzonych_owiec=0;
      //stwarza ksztalt
      ksz_w=new TImage(Form1);
      ksz_w->Parent=Form1;
      ksz_w->Left=x0;
      ksz_w->Top=y0;
      ksz_w->Width=60;
      ksz_w->Height=60;
      ksz_w->Visible=true;
      ksz_w->AutoSize=true;
      ksz_w->Picture->LoadFromFile("img/wolf.bmp");
  }
        Owca *to[N];
        Wilk *tw;

  Owca::~Owca()
      {

      }

  Wilk::~Wilk()
      {

      }


void __fastcall TForm1::Timer1Timer(TObject *Sender)
{

        if(tw->zjedzonych_owiec<5)
        {
        tw->ruch(); //ruszaj wilkiem dopoki nie zje 35 owiec
        }
        int i;
        for(i=0; i<N;i++)
        {
          to[i]->ruch();
          tw->zjedzOwce(to[i]); //sprawdzaj czy zjadl owce
          Masa->Text=tw->masa_wilka;
          Zjedzone_owce->Text=tw->zjedzonych_owiec;
        }
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button2Click(TObject *Sender)
{
       for (int i = 0; i < N; ++i) delete to[i];
       delete tw;


        for (int i = 0; i < N; ++i) to[i] = new Owca;
        tw = new Wilk;
       Timer1->Enabled = 1;

}
//---------------------------------------------------------------------------



Podobne pytania

+5 głosów
2 odpowiedzi 535 wizyt
pytanie zadane 29 kwietnia 2017 w Nasze projekty przez criss Mędrzec (172,590 p.)
0 głosów
1 odpowiedź 225 wizyt
+5 głosów
0 odpowiedzi 294 wizyt
pytanie zadane 19 sierpnia 2022 w Nasze projekty przez wojtek_suchy Mądrala (6,880 p.)

92,565 zapytań

141,416 odpowiedzi

319,597 komentarzy

61,948 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...