quinta-feira, 24 de abril de 2008

Pilha de Quadrados em Borland C++ Builder 6

Esta aplicação plota quadrados a partir de parâmetros fornecidos pela seguinte interface de usuário:

image

Ao clicar no botão "Plotar", um quadrado é instanciado e plotado com o seu canto superior esquerdo dado pelos valores (X,Y) e na largura desejada.

Para manter controle sobre a população de quadrados instanciados, esta aplicação utiliza o conceito de pilha implementado sob a forma de uma classe. Assim, ao clicar no botão "Limpar" a área do paintbox é limpa, permitindo observar a reconstrução dos quadrados na ordem em que são retirados da pilha, através do click no botão "Refazer Tudo". Observe que a aplicação ao retirar um quadrado da pilha, ela salva em outra para não perder o controle sobre todos os quadrados instanciados. Um efeito colateral a ser notado é que a reconstituição é dada na ordem inversa da criação dos quadrados, pois no conceito de pilha, o mais recente será o primeiro a ser retirado da pilha e o mais antigo o último a ser retirado dela (last in, first out - LIFO).

A seguir temos as classes utilizadas:

1) Começando pela classe "Quadrado" (arquivo Unit2.h):

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

#ifndef Unit2H
#define Unit2H

#include <graphics.hpp>             // classe de elementos gráficos do BCB6 

class Quadrado
{
        private:
                int x;
                int y;
                int largura;

        public:
                Quadrado();                                    // construtor default
                Quadrado( int, int );                         // construtor
                Quadrado( int, int, int );                   // construtor
                void Plotar( Graphics::TBitmap * );
                ~Quadrado();                                 // destrutor
};

//---------------------------------------------------------------------------
#endif

 

2) E os métodos previstos para esta classe (arquivo Unit2.cpp):

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

#pragma hdrstop

#include "Unit2.h"          // classe Quadrado

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

#pragma package(smart_init)

Quadrado :: Quadrado( )                               // construtor default
{
        this->x = 100;
        this->y = 200;
        this->largura = 90;
}

Quadrado :: Quadrado( int a, int b )                 // construtor
{
        this->x = a;
        this->y = b;
        this->largura = 50;
}

Quadrado :: Quadrado( int a, int b, int c)           // construtor
{
        this->x = a;
        this->y = b;
        this->largura = c;
}

void Quadrado :: Plotar( Graphics::TBitmap *tmp )
{
        tmp->Canvas->PenPos = TPoint( this->x, this->y );
        tmp->Canvas->LineTo( this->x + this->largura, this->y  );

        //tmp->Canvas->PenPos = TPoint( this->x + this->largura, this->y );
        tmp->Canvas->LineTo( this->x + this->largura, this->y + this->largura );

        //tmp->Canvas->PenPos = TPoint( this->x + this->largura, this->y + this->largura );
        tmp->Canvas->LineTo( this->x, this->y + this->largura  );

        //tmp->Canvas->PenPos = TPoint( this->x, this->y + this->largura );
        tmp->Canvas->LineTo( this->x, this->y  );

}

Quadrado :: ~Quadrado()
{
}

 

3) A classe que implementa o conceito de pilha (arquivo Unit3.h):

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

#ifndef Unit3H
#define Unit3H

#include "Unit2.h"      // classe Quadrado

class PilhaQuadrados
{
        private:
                class Node
                {
                        public:
                                Quadrado *itemCorrente;
                                Node *nodeAntecessor;
                        public:
                                Node( Quadrado*, Node* );        // construtor
                                ~Node( void );                         // destrutor

                };

        private:
                Node *nodeTopo;
                int qtdNodes;

        public:
                PilhaQuadrados( void );                 // construtor
                ~PilhaQuadrados( void );               // destrutor

                void Guardar( Quadrado* );
                Quadrado* Retirar( void );
                int Tamanho( void );

};

//---------------------------------------------------------------------------
#endif

 

4) E os métodos previstos para esta outra classe (arquivo Unit3.cpp):

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

#pragma hdrstop

#include "Unit3.h"     // classe PilhaQuadrados 

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

#pragma package(smart_init)

PilhaQuadrados :: PilhaQuadrados( void )                                 // construtor
{
        this->qtdNodes = 0;
        this->nodeTopo = NULL;
}
PilhaQuadrados :: ~PilhaQuadrados( void )                               // destrutor
{
        Node *nodeCorrente = this->nodeTopo,  *nodeAntecessor;
        while ( nodeCorrente != NULL ) {
                nodeAntecessor = nodeCorrente->nodeAntecessor;
                delete nodeCorrente->itemCorrente;                       // destruir quadrado corrente
                delete nodeCorrente;                                           // destruir node corrente
                nodeCorrente = nodeAntecessor;
        }
}
void PilhaQuadrados :: Guardar( Quadrado *qdr )
{
        this->nodeTopo = new Node( qdr, this->nodeTopo );
        this->qtdNodes ++;
}
Quadrado* PilhaQuadrados :: Retirar( void )
{
        Node *nodeCorrente = this->nodeTopo ;
        Quadrado *qdr = nodeCorrente->itemCorrente;
        this->nodeTopo = nodeCorrente->nodeAntecessor;
        this->qtdNodes --;
        delete nodeCorrente;
        return ( qdr );
}
int PilhaQuadrados :: Tamanho( void )
{
        return ( this->qtdNodes );
}

PilhaQuadrados :: Node :: Node( Quadrado *item, Node *no )
{
        this->itemCorrente = item;
        this->nodeAntecessor = no;
}
PilhaQuadrados :: Node :: ~Node( void )
{
}

 

5) A interface de usuário da aplicação é composta pela classe TForm1 (arquivo Unit1.h):

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

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>

#include "Unit2.h"              // classe Quadrado
#include "Unit3.h"              // classe PilhaQuadrados

//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TLabel *Label1;
        TEdit *Edit1;
        TLabel *Label2;
        TEdit *Edit2;
        TLabel *Label3;
        TEdit *Edit3;
        TButton *Button1;
        TButton *Button2;
        TButton *Button3;
        TPaintBox *PaintBox1;
        TLabel *Label4;
        void __fastcall Button1Click(TObject *Sender);
        void __fastcall Button2Click(TObject *Sender);
        void __fastcall Button3Click(TObject *Sender);
        void __fastcall PaintBox1Paint(TObject *Sender);
private:    // User declarations
        Graphics::TBitmap *figura;              // bitmap
        PilhaQuadrados *minhaPilha;             // pilha

public:        // User declarations
        __fastcall TForm1(TComponent* Owner);   // construtor
        __fastcall ~TForm1(void);                       // destrutor
  void __fastcall CriarFigura(void);                    // limpar figura
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

 

6) E os métodos da classe TForm1 são definidos a seguir (arquivo Unit1.cpp):

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

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)  // construtor
{
        this->minhaPilha = new PilhaQuadrados();        // criar pilha
        this->CriarFigura();                                     // criar bitmap figura
}
//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1(void)                             // destrutor
{
        delete this->figura;                      // destruir figura
        delete this->minhaPilha;               // destruir pilha
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)           // plotar
{
        int x, y, larg;

        x    = StrToIntDef( this->Edit1->Text, 0 );
        y    = StrToIntDef( this->Edit2->Text, 0 );
        larg = StrToIntDef( this->Edit3->Text, 0 );

        Quadrado *qdr;                                 // declarar ponteiro de quadrado
        qdr =  new Quadrado( x, y, larg );        // instanciar quadrado
        qdr->Plotar( this->figura );                 // plotar no bitmap

        this->PaintBox1->Refresh();               // refazer paintbox

        this->minhaPilha->Guardar( qdr );       // guardar quadrado na pilha

        this->Label4->Caption = "Qtd.Quadrados: " +
                                IntToStr( this->minhaPilha->Tamanho() );
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)           // limpar
{
        delete this->figura;                 // deletar figura atual
        this->CriarFigura();                 // criar nova figura
        this->PaintBox1->Refresh();     // refazer paintbox
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button3Click(TObject *Sender)           // refazer tudo
{
        // criar uma nova pilha

        PilhaQuadrados *pilhaInvertida = new PilhaQuadrados();

        while ( this->minhaPilha->Tamanho() > 0 )
        {
                // obter quadrado do topo da pilha

                Quadrado *tmp = this->minhaPilha->Retirar();

                // plotar quadrado

                tmp->Plotar( this->figura );

                // guardar quadrado na nova pilha

                pilhaInvertida->Guardar( tmp );

                // refazer paintbox

                this->PaintBox1->Refresh();

                // aguardar 500ms

                Sleep( 500 );
        }

        // destruir pilha velha

        delete this->minhaPilha;

        // copiar referencia da nova pilha para a velha

        this->minhaPilha = pilhaInvertida;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::PaintBox1Paint(TObject *Sender)   // refazer paintbox
{
        // exibir bitmap no paintbox

        this->PaintBox1->Canvas->Draw( 0, 0, this->figura );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CriarFigura()                    // criar bitmap
{
        this->figura = new Graphics::TBitmap();

        // redimensionar largura e altura

        this->figura->Width = this->PaintBox1->Width ;
        this->figura->Height = this->PaintBox1->Height;
}
//---------------------------------------------------------------------------

 

Até  próxima.

Nenhum comentário: