intercambiar valores dentro de un vector

Iniciado por bash, 20 Enero 2016, 20:31 PM

0 Miembros y 1 Visitante están viendo este tema.

bash

Un saludo a todos !!

tengo una duda , yo quiero intercambiar valores dentro de un vector , pero cada vez que accedo a algun elemento usando un objeto temporal recibo un error , vi la funcion std::swap pero ella intercambia entre dos vectores y yo solo tengo uno estoy pensando probar con algun iterador pero me gustaria saber su opinion.

abajo dejo el codigo aunque es algo sencillo :D

Código (cpp) [Seleccionar]


void SwapVectorValue(vector<Tile *>&ref,int index1, int index2)
{
   Tile *temp  = NULL;
   temp->x     = ref[index1]->x;
   temp->y     = ref[index1]->y;
   temp->color = ref[index1]->color;
   temp->index = ref[index1]->index;

   ref[index1]->x     = ref[index2]->x;
   ref[index1]->y     = ref[index2]->y;
   ref[index1]->color = ref[index2]->color;
   ref[index1]->index = ref[index2]->index;

   ref[index2]->x         = temp->x;
   ref[index2]->y         = temp->y;
   ref[index2]->color     = temp->color;
   ref[index2]->index     = temp->index;

}




gracias por su pronta respuesta...!!
gracias por responder mis dudas

ivancea96

temp en ese código es, como bien ahs puesto, NULL, y no un Tile.

Si trabajas con un vector de punteros, lo ideal, salvo que requieras lo contrario, es que intercambies los punteros, y no todos los campos de las estructuras a las que apuntan.
Para ello, bastaría un:
Código (cpp) [Seleccionar]
Tile* temp = ref[index1];
ref[index1] = ref[index2];
ref[index2] = temp;

bash

#2
waooo que sencillo ,gracias aunque me gustaria decir que funcion realmente no
bueno voy a descansar dejare , el codigo completo aqui.


Código (cpp) [Seleccionar]
//============================================================================
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <SDL2/SDL.h>

#include <map>
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
/*para probar*/
#include <vector>
using namespace std;


#define RED        0
#define GREEN      1
#define BLUE       2
#define YELLOW     4
#define GRAY       5
#define NONE       6
#define COLOR_QTY  5
#define NOINDEX    -9999

SDL_Window   *window = nullptr;
SDL_Renderer *render = nullptr;
int **board  =nullptr;
static int width  = 400;
static int height = 500;

SDL_Rect cursor_pos ={0,0,16,16};

static int block_size;
static int block_height;
static int nCol   = 0;
static int nRow   = 0;

/**Touch and movement*/
static bool oneTimeClicked = true;
static int o1 = NOINDEX;
static int o2 = NOINDEX;
static int getCollide;




char title[32];
bool Run  = false;
SDL_Event event;




string color_name []=
{
"red",
"green",
"blue",
"yellow",
"gray"

};

const char *filename[] =
{
  "red.bmp",
  "green.bmp",
  "blue.bmp",
  "yellow.bmp",
  "gray.bmp"

};


SDL_Color color[]=
{
{0xff, 0,0,0xff},
{0, 0xff,0,0xff},
{0, 0,0xff,0xff},
{0xff, 0xff,0,0xff},
{0x90, 0x90,0x90,0xff}
};

struct Tile
{

   int x;
   int y;
   int color;
   int index;
   Tile(int x_,int y_, int color_ ,int indexVal)
   :x(x_),y(y_), color(color_), index(indexVal){}
   SDL_Rect getRect()
   {
   SDL_Rect rect ={x,y,block_size, block_height};
   return rect;
   }
};


map<string, SDL_Texture *>texture_list;
vector<Tile *>tile_set;


void CreateBlocks();
void AlignBlocks();
void CreateBoard();
void DrawBoard();
bool check_collision( SDL_Rect A, SDL_Rect B);
void SwapVectorValue(vector<Tile *>&ref,int index1, int index2);
int isCollide();

void CopiarTile(vector<Tile*> &tile, int index1,int index2);




int main(int argc, char *argv[])
{





SDL_Init(SDL_INIT_EVERYTHING);




window = SDL_CreateWindow("table", SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,
                   width, height, SDL_WINDOW_SHOWN|SDL_WINDOW_BORDERLESS);
    render = SDL_CreateRenderer(window, -1 , SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);


    CreateBlocks();
AlignBlocks();
CreateBoard();


    Run = (render == NULL  ? false : true);
    while(Run)
    {
    while(SDL_PollEvent(&event))
    {
    if(event.type ==SDL_QUIT)
    {
    Run = false;
    }
    if(event.type == SDL_MOUSEMOTION)
    {
    cursor_pos.x = event.motion.x;
    cursor_pos.y = event.motion.y;
    }
            if(event.type == SDL_MOUSEBUTTONDOWN)
            {
                getCollide  = isCollide();
            if( getCollide != NOINDEX && oneTimeClicked == true)
                   {
                       o1 =getCollide;
                      /// cout <<"el indice seleccionado es : "<<tile_set[o2]->index<<endl;
                       oneTimeClicked = false;
                    }
            else if(getCollide != NOINDEX && oneTimeClicked == false)
{
                o2 = getCollide;
                //cout <<"El segundo es este"<<tile_set[o2]->index<<endl;
                SwapVectorValue(tile_set,o1, o2);
                oneTimeClicked = true;
                o1 = NOINDEX;
                o2 = NOINDEX;
}


            }


    }
    const Uint8* key = SDL_GetKeyboardState(NULL);
if(key[SDL_SCANCODE_Q])
{
Run = false;
}




       SDL_SetRenderDrawColor(render, 0x0,0x0,0x0, 0xff);
       SDL_RenderClear(render);
       DrawBoard();
       SDL_RenderPresent(render);

    }
    SDL_DestroyRenderer(render);
    SDL_DestroyWindow(window);
    SDL_Quit();


return 0;
}









void CreateBlocks()
{
   SDL_Surface* SurfaceTemp[COLOR_QTY] = {nullptr};
   for(int i(0); i < COLOR_QTY ;i++)
   {
   SurfaceTemp[i] = SDL_LoadBMP(filename[i]);
   /*if(SurfaceTemp[i] == NULL) {
           fprintf(stderr, "CreateRGBSurface failed: %s\n", SDL_GetError());
           exit(1);
       }*/
   }
   for(int i(0); i < COLOR_QTY ;i++)
      {
     SDL_SetColorKey(SurfaceTemp[i],SDL_TRUE ,SDL_MapRGB(SurfaceTemp[i]->format,0,0,0));
         texture_list[color_name [i]] = SDL_CreateTextureFromSurface(render ,SurfaceTemp[i]);
      SDL_FreeSurface( SurfaceTemp[i]);
      }
   SDL_Surface *cursor = SDL_LoadBMP("cursor.bmp");
   SDL_SetColorKey(cursor,SDL_TRUE ,SDL_MapRGB(cursor->format,0,0,0));
   texture_list["cursor"] = SDL_CreateTextureFromSurface(render ,cursor);
   SDL_FreeSurface(cursor);

}


void AlignBlocks()
{
srand(time(nullptr));

  block_size   = 48;
  block_height = block_size-3;
  for(int i(0); i < height; i += block_size)
  {
  cout << " i [ "<< i<< "]\n";
  nRow++;
  }
  for(int k(0);k < width; k +=block_size)
  {
  cout << " k [ "<< k<< "]\n";
  nCol++;
  }
  board = new int*[nRow];
  for(int o(0); o < nRow; o++)
    board[o] = new int[nCol];

    for(int iter1(0); iter1<nRow; iter1++)
    {
    for(int iter2(0); iter2<nCol; iter2++)
    {
              board[iter1][iter2] = rand() % YELLOW + RED;
              cout <<"||" <<board[iter1][iter2]<<"||";
    }
    cout <<"\n";
    }

}




void CreateBoard()
{

    static int index = 0;
int x = 32;
int y = 32;
  for(int iter1(0); iter1<nRow; iter1++)
    {
    index++;
    for(int iter2(0); iter2<nCol; iter2++)
    {

              Tile *temp = new Tile(x ,y,board[iter1][iter2],index);
              ::tile_set.push_back(temp);
              if(x >=(width -48*2))
              {
              x = 32;
              if(y <= width)
                   y +=45;
              else if(y >= height )
              {
              cout <<"Sorry \n";
              break;
              }
              }
              else
              {

              x +=48;
              }


    cout <<"x : "<< x <<" Y :" << y <<endl;
    }
    cout <<"-------------------------------------------------------------------"<<endl;
    }

}

void DrawBoard()
{
  for(unsigned int f = 0; f < tile_set.size(); f++)
  {
SDL_Rect rect ={tile_set[f]->x,tile_set[f]->y,block_size, block_height };
SDL_RenderCopy(render, texture_list[color_name[tile_set[f]->color]],NULL,&rect );
SDL_RenderCopy(render, texture_list["cursor"],NULL,&cursor_pos );
  }
}


bool check_collision( SDL_Rect A, SDL_Rect B )
{
    //The sides of the rectangles
    int leftA, leftB;
    int rightA, rightB;
    int topA, topB;
    int bottomA, bottomB;

    //Calculate the sides of rect A
    leftA = A.x;
    rightA = A.x + A.w;
    topA = A.y;
    bottomA = A.y + A.h;

    //Calculate the sides of rect B
    leftB = B.x;
    rightB = B.x + B.w;
    topB = B.y;
    bottomB = B.y + B.h;
    //If any of the sides from A are outside of B
        if( bottomA <= topB )
        {
            return false;
        }

        if( topA >= bottomB )
        {
            return false;
        }

        if( rightA <= leftB )
        {
            return false;
        }

        if( leftA >= rightB )
        {
            return false;
        }

        //If none of the sides from A are outside B
        return true;
}

void SwapVectorValue(vector<Tile *>&ref,int index1, int index2)
{
  /* Tile *temp  = NULL;
   temp->x     = ref[index1]->x;
   temp->y     = ref[index1]->y;
   temp->color = ref[index1]->color;
   temp->index = ref[index1]->index;

   ref[index1]->x     = ref[index2]->x;
   ref[index1]->y     = ref[index2]->y;
   ref[index1]->color = ref[index2]->color;
   ref[index1]->index = ref[index2]->index;

   ref[index2]->x         = temp->x;
   ref[index2]->y         = temp->y;
   ref[index2]->color     = temp->color;
   ref[index2]->index     = temp->index;

Tile *temp  = ref[index1];

ref[index1] = ref[index2];
//ref[index1]->color = temp->color;
ref[index2] = temp;
*/

  CopiarTile(ref, index1,index2);

}

int isCollide()
{
    for(unsigned int g=0; g < tile_set.size();g++)
       {
  if(check_collision( cursor_pos, tile_set[g]->getRect()))
  {
  cout <<"posicion "<< tile_set[g]->x<<" type "<<tile_set[g]->color<<endl;
  return tile_set[g]->index;
  }
       }
cout <<"-9999"<<endl;
return -9999;
}

void CopiarTile(vector<Tile*> &tile, int index1,int index2)
{
cout <<"preparando para copiar "<<endl;
    cout <<"     x1 : " <<tile[index1]->x<<endl;
    cout <<"     x1 : " <<tile[index1]->y<<endl;
    cout <<"     x1 : " <<tile[index1]->color<<endl;
    cout <<"     x1 : " <<tile[index1]->index<<endl;
    cout <<"---------------------------------------------------------------------------------------\n";
    cout <<"     x2 : " <<tile[index2]->x<<endl;
    cout <<"     x2 : " <<tile[index2]->y<<endl;
    cout <<"     x2 : " <<tile[index2]->color<<endl;
    cout <<"     x2 : " <<tile[index2]->index<<endl;


Tile *temp1 = tile[index2];
Tile *temp2 = tile[index1];


cout <<" copiar "<<endl;
    cout <<"     x : " <<temp1->x<<endl;
    cout <<"     y : " <<temp1->y<<endl;
    cout <<" color : " <<temp1->color<<endl;
    cout <<"----------------------------------------------------------------------------\n";
    cout <<"copiar "<<endl;
    cout <<"     x2 : " <<temp2->x<<endl;
    cout <<"     y2 : " <<temp2->y<<endl;
    cout <<" color2 : " <<temp2->color<<endl;
    cout <<"----------------------------------------------------------------------------\n";
    tile[index1]=temp1;
    tile[index2]=temp2;

}



hay esta too lo que he hecho :D espero que puedna ayudarme y esto lo ayude a ustedes tambien :D
gracias por responder mis dudas

ivancea96

Bueno, no sé qué pretendes hacer. Pero ten en cuenta que la función "copiar", más que copiar, intercambia :o

bash

realmente puse mal el identificador
pero si te fijas en esta linea

Código (cpp) [Seleccionar]


Tile *temp1 = tile[index2];
Tile *temp2 = tile[index1];
....
          tile[index1]=temp1;
          tile[index2]=temp2;




eso seria el intercambio aunque al final la aplicacion explota immediatamente uso el evento.

gracias por responder mis dudas

ivancea96

'explota' no ayuda a encontrar el error xD
Localiza la línea que tira el error. Para ello, si es necesario, coloca salidas por consola, cout, y así ver la línea exacta que lanza el error.

bash

#6
deja de trabajar en la funcion CopiarTile(swapear)

la salida de cout es
Código (cpp) [Seleccionar]

-------------------------------------------------------------------
posicion 416 type 0
posicion 368 type 1
CopiarTilepreparando para copiar
    x1 : 80
    x1 : 32
    x1 : 0
    x1 : 1
---------------------------------------------------------------------------------------
    x2 : 80
    x2 : 32
    x2 : 0
    x2 : 1

copiar
    x : 80
    y : 32
color : 0
----------------------------------------------------------------------------
copiar
    x2 : 80
    y2 : 32
color2 : 0
----------------------------------------------------------------------------






pero hasta me doy cuenta que lo que hace es lo siguiente los elementos se copian pero como se copian todos los datos quedan igual. estoy pensando cambiar std::map o unordered_map ya que con ellos puedo usar clear() es mas facil copiar segun entiedo.
gracias por responder mis dudas

ivancea96


bash

se cerraba , pero no lo veo claro , ahora voy tener que apender a usar el GDB por que realmente nunca he depurado, voy a ver que sale en los trace y publico , y descubri que con std::map me hace lo mismo :D publicare en un par de horas voy a casa a ver si sigo alla ,escribo en un rato. gracias
gracias por responder mis dudas