elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Arreglado, de nuevo, el registro del warzone (wargame) de EHN


  Mostrar Mensajes
Páginas: 1 [2]
11  Programación / Programación C/C++ / Rompecabezas numerico en: 8 Agosto 2014, 17:18 pm
Hola buenos días, tardes... me encuentro armando un rompecabezas numericos, de eso que tienes que acomodar los numeros moviendolos de uno en uno. El problema que tengo es que al intentar hacer movimientos, al presionar las flechas de arriba o la flecha izquierda, esta funcion se repite hasta que recorre todos los números en esa fila/columna :huh: , creo que va a ser algo en las funciones de mover para  arriba o para abajo, que tienen en comun el "num-1", pero no se exactamente que hace eso o el porque... de antemano gracias y perdonen algunas anomalías en el codigo en caso de haber, soy prinicipante en esto de la programación  ;D

saludos


Código:
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<math.h>
#include<time.h>

#define num 4

#define arriba 72
#define abajo 80
#define izquierda 75
#define derecha 77

void generar_rompecabezas();
void imprimir_rompecabezas();
void comprobar_completo();
void mover();
void desordenar();

int main(){
int puzzle[num][num],reg=0, mov;
//unsigned char mov;
generar_rompecabezas(puzzle);
desordenar(250,puzzle);
imprimir_rompecabezas(puzzle);

do{
system("cls");
imprimir_rompecabezas(puzzle);
comprobar_completo(puzzle, reg);
if(reg==0){
mov=getch();
mover(mov,puzzle);
}
else{
system("cls");
printf("Completado");
}
}
while(reg!=1);

getch();
return 0;
}



void generar_rompecabezas(int puzzle[num][num]){
int aux=1;
int x,y;

for(x=0;x<num;x++){
for(y=0;y<num;y++){
puzzle[x][y]=aux;
if(x==num-1 && y==num-1){
puzzle[x][y]=0;
}
//printf("matriz %d %d = %d\n",x,y,puzzle[x][y]);
aux++;
}
}
}

void imprimir_rompecabezas(int puzzle[num][num]){
int x,y;

for(x=0;x<num;x++){
if(x==0)
printf("\t\t\t---------------------\n");
printf("\t\t\t|");
for(y=0;y<num;y++){
if(puzzle[x][y]<10){
printf(" ");
}
if(puzzle[x][y]==0)
printf("   |");
else
printf(" %d |", puzzle[x][y]);
}
printf("\n");
printf("\t\t\t---------------------\n");
}
}

void comprobar_completo(int puzzle[num][num],int reg){
int x,y;
int aux=1;
int z=num*num;

for(x=0;x<num;x++){
for(y=0;y<num;y++){
if(puzzle[x][y]==aux){
aux++;
}
}
}


if(aux==z){
printf("resuelto");
reg=1;

}
else{
printf("No Resuelto");
reg=0;
}

}

void mover(int direccion, int puzzle[num][num]){
int x,y,aux;
for(x=0;x<num;x++){
for(y=0;y<num;y++){
if(puzzle[x][y]==0){
switch(direccion){
case izquierda:
if(y!=num-1){
aux=puzzle[x][y];
puzzle[x][y]=puzzle[x][y+1];
puzzle[x][y+1]=aux;
printf("\nMovimiento izquierda\n");
}
break;

case derecha:
if(y!=0){
//printf("%d a cambiar con %d",puzzle[x][y], puzzle[x][y-1]);
aux=puzzle[x][y];
puzzle[x][y]=puzzle[x][y-1];
puzzle[x][y-1]=aux;
printf("\nMovimiento derecha\n");
}
break;

case arriba:
if(x!=num-1){
aux=puzzle[x][y];
puzzle[x][y]=puzzle[x+1][y];
puzzle[x+1][y]=aux;
printf("\nMovimiento Arriba\n");
}
break;

case abajo:
if(x!=0){
aux=puzzle[x][y];
puzzle[x][y]=puzzle[x-1][y];
puzzle[x-1][y]=aux;
printf("\nMovimiento abajo\n");
}
break;
}
}
}
}
}

void desordenar(int cantidad, int puzzle[num][num]){
int x,opc;
srand (time(NULL));
for(x=0;x<cantidad;x++){

opc=(rand()%4+1);

switch(opc){
case 1:
mover(arriba, puzzle);
break;
case 2:
mover(abajo, puzzle);
break;
case 3:
mover(izquierda, puzzle);
break;
case 4:
mover(derecha, puzzle);
break;
}
}
}
12  Programación / Programación C/C++ / Re: Lista enlazada guardar y cargar datos en: 7 Mayo 2014, 18:34 pm
Gracias por la ayuda, ya me sirvio el programa, solo tuve que modificar el resto de la lista enlazada al metodo de las dos estructuras y ya estuvo  ;D
13  Programación / Programación C/C++ / [Solucionado]Lista enlazada guardar y cargar datos en: 6 Mayo 2014, 23:00 pm
Hola, tengo un problema con una lista enlazada...lo que haria el programa  es guardar una lista de paises ademas de un ID para cada uno... basicamente al querer cargar los datos al abrir el archivo, pareciera que me da un loop o un error la funcion  "cargarPaises();" o mas bien una funcion  que esta adentro de ella que se llama "insertarPaisesG()" que lo que buscaria es que ingrese los datos de un .bat a la lista enlazada de acuerdo a los parametros que tenga la funcion.

aqui les dejo el codigo de las funciones especificas donde tengo el problema.


Estas seria la estrutura basica de la lista enlazada y sus punteros del principio y final
Código:
typedef struct paises{
int IDpais;
char Pais[20];
int NoParticipantes;
int NoMedallas;

struct paises* p;
} Paises;

Paises*PAIprimero=NULL;
Paises*PAIultimo=NULL;



estas serian las funciones con las que tendria problemas, agrego la funcion que usè para guardar los datos, que al parecer me sirvio, pero por si llega a ser el problema lo dejo (soy algo novato, asi que espero me perdonen algunas redundancias o errores de novato aqui  ;D )
Código:

void insertarPaisesG(int ID, char Nombre[]){
Paises * nuevo;
nuevo = (Paises *)malloc(sizeof(Paises));

nuevo->IDpais=ID;
strcpy(nuevo->Pais, Nombre);


if(PAIprimero->p!=PAIultimo){
PAIprimero=nuevo;
PAIprimero->p=PAIultimo;

}
else{
nuevo->p=NULL;
PAIultimo->p=nuevo;
PAIultimo=nuevo;
}

}







void guardarPaises(){
printf("\n\n\nGuardando informaci�n de paises");
FILE * archivo = fopen("Paises.dat", "wb");
if(archivo == NULL){
printf("\n\n\nError al guardar en archivo");
return;
}

Paises * recorre = PAIprimero;
while (recorre != NULL){
fwrite(recorre, sizeof(Paises), 1, archivo);
recorre = recorre->p;
}

fclose(archivo);
}








void cargarPaises(){
FILE * archivo = fopen("Paises.dat", "rb");
if(archivo == NULL){
printf("\n\n\nError al cargar desde archivo");
return;
}

Paises * actual = (Paises *) malloc(sizeof(Paises));
int leidos;
do{
leidos = fread(actual, sizeof(Paises), 1, archivo);
if (leidos == 1)
insertarPaisesG(actual->IDpais, actual->Pais);
} while (leidos == 1);

fclose(archivo);
}


de antemano gracias por la ayuda, y si se llegara a ocupar el codigo completo lo pondria mas adelante  ;D
14  Programación / Programación C/C++ / guardar datos Lista enlazada en: 17 Abril 2014, 14:09 pm
Hola a todos, mi duda, es el como guardar datos en un fichero para una lista enlazada, osease un conjunto de estructuras que contienen un puntero apuntando a otra estructura sucesivamente(por lo menos una explicaciòn muy, muy, muy generalizada :D).

mi duda es si alguien me podria instruir de que pasos o como deberia implementar los FILE de manera que se queden almacenados todos los elementos que agregue a la lista.
No pido un codigo que pueda copiar y pegar ya que seria contra las reglas del foro,pero por lo menos me seria de utilidad el saber en que momentos aplicar los ficheros y a que dirigirlos de manera justificada.
:)
15  Programación / Programación C/C++ / Re: Puzzle 8 en: 16 Abril 2014, 00:29 am
yo una vez hize algo similar a lo que buscas:

las funciones que puedes hacer es generar numeros de al cuadrado de numero que tenga de largo la cuadricula (N). en este caso seria 3*3, Y guardarlo en una matriz que represente el rompezcabezas dejando el espacio mas grande de la matriz como 0.

algo como esto:
Código:
void generar_puzzle(int puzzle[N][N]){

     int i,j,num;
     num=1;
     for(i=0;i<N;i++){
          for(j=0;j<N;j++){
               puzzle[i][j]=num;
               num++;
               if(i==3 && j==3){
               puzzle[i][j]=0;
   }
          }
     }
}




luego seria otra funcion para intercambiar el espacio de la matriz que guarda el valor de 0 ya sea con el de la izquierda cambiando el valor de las matricez por el de una posicion antes, derecha con el de una posicion despues, de arriba con el de una posicion menos en el otro eje de la matriz y viceversa para abajo de acuerdo a una entrada hecha por el teclado de acuerdo al codigo ascii.(tambien hay que tomar en cuenta las excepciones, ya que no puede subir uno el espacio vacio una casilla mas si esta se encuentra en la fila de hasta arriba por ejemplo)



el siguiente paso, serìa una funciòn para desordenar el puzzle para que no empiece resuelto, llamando la funcion anterior de intercambiar los valores de las matrices una cantidad determinada por un ciclo, y que seleccione cualquiera de las 4 opciones (arriba, abajo, izquierda, derecha) de manera aleatoria.



lo que restaria es imprimir la matriz en pantalla en el orden que se ha estado trabajando mediante dos for

Código:
void imprimir(int puzzle[N][N]){
     int i,j;
     for(i=0;i<N;i++){
          for(j=0;j<N;j++){
               if(puzzle[i][j]==0)
               printf(" |");
               else
               printf("%3d |",puzzle[i][j]);
               }
          printf("\n");
          if(i<N-1)
          printf("\t\t\t ------+-----+-----+------\n");
          }
     }


asi quedaria la impresion mas o menos con  una cuadricula






por ultimo serìa una funciòn que detectara cuando el puzzle esta ordenado, para indicar que se ha trerminado el juego.


espero que te sirva. :)
16  Programación / Programación C/C++ / Re: Eliminar datos de lista enlazada en: 16 Abril 2014, 00:04 am
Saber lo que está pasando es tan sencillo como usar un depurador... que no te den miedo... te vas a hartar a usarlos si en algún momento te vas a dedicar a programar. Es una buena idea familiarizarse con su uso.

Para eliminar un elemento de una lista enlazada únicamente necesitas dos punteros... "anterior" y "actual":

En tu caso, el problema es que al eliminar un nodo cualquiera desplazas "anterior". Si tu eliminas un nodo no puedes actualizar "anterior". Puedes comprobarlo si dibujas el proceso sobre un papel.

Código
  1. void eliminarLista()
  2. {
  3.  nodoLista* anterior = NULL;
  4.  nodoLista* actual = primero;
  5.  
  6.  int op;
  7.  printf("Cual es el entero a eliminar?");
  8.  scanf("%d", &op );
  9.  
  10.  while( actual != NULL )
  11.  {
  12.    if( actual->llave == op )
  13.    {
  14.      // Si eliminamos el primer elemento de la lista hay que operar de forma diferente
  15.      if ( anterior == NULL )
  16.        primero = actual->sig;
  17.      else
  18.        anterior->sig = actual->sig;
  19.  
  20.      free( actual );
  21.      actual = anterior->sig;
  22.      break; // Este break solo tiene sentido si la lista no admite duplicados
  23.    }
  24.    else
  25.    {
  26.      anterior = actual;
  27.      actual = actual->sig;
  28.    }
  29.  }
  30. }

En tu caso, "actual" y "recorre" apuntan al mismo sitio... no tiene sentido porque te obliga a tener sincronizados dos punteros sin ninguna necesidad.

Además:

Código
  1. if ( recorre != NULL){siguiente = recorre->sig;

esto para que?? la siguiente línea que se ejecuta es la condición del while, que dice que si recorre es NULL sales del while.

Además, no entiendo por qué razón guardas el puntero "ultimo". En una lista enlazada, el "sig" del último elemento apunta a NULL, luego saber si has llegado al final de la lista es tan sencillo como comprobar el "sig" de cada elemento.

También, mi consejo, es que tiendas a reutilizar código... no tiene sentido que tengas dos funciones para añadir elementos a la lista ( una para añadir al principio y otra para añadir al final ). Tiene más sentido que haya una función única y que sea ésta la que sepa añadir un elemento en cualquier posición... así cuando uses tu librería no tendrás que preocuparte por la posición concreta del elemento a insertar.

También te recomiendo no usar variables globales. Es mejor pasar estas variables como argumentos de las funciones.

Un saludo.





Gracias por la respuesta, muy completa y me funcionò, gracias ademàs por los consejos intentarè aplicarlos lo mas que pueda, tomando que soy algo nuevo en esto de la programaciòn me viene util cada cosa comentada por aqui :)
17  Programación / Programación C/C++ / Eliminar datos de lista enlazada en: 15 Abril 2014, 00:19 am
Hola, soy nuevo en este foro , tengo un problema al intentar hacer un codigo que borre los datos de una lista enlazada:

lo que intente fue que al declarar apuntadores de los nodos llamados anterior, actual y siguiente, dados que apuntaran a 3 nodos diferentes de la lista mientras se va recorriendo dentro del    "while(recorre != NULL){}"   y que si encontraba el valor de llave , el apuntador del nodo anterior , apunte a "siguiente" , y y "eliminar" el nodo "actual" mediante el comando free();


El problema es que al ejecutar el programa entero y entra en la funcion de eliminarLista();  se detiene el programa despues de pedir el valor del entero a eliminar (o tal vez esta teniendo un loop el ciclo, la verdad no estoy seguro) estaria muy agradecido si me ayudaran con este problema, ya que es una base para un trabajo de la universidad del cual me basarè.


he aqui el codigo, o por lo menos la parte que de eliminar datos, tambien pongo la estructura con la que anda trabajando el codigo.

Código:

typedef struct nodo{
int llave;
struct nodo * sig; /* auto referencia */
}nodoLista;



void eliminarLista(){
nodoLista* anterior;
nodoLista* actual;
nodoLista* siguiente;
nodoLista* recorre=primero;

int op;
printf("Cual es el entero a eliminar?");
scanf("%d", &op);

anterior=primero;
actual=primero;
siguiente=primero->sig;

while(recorre != NULL){

if(recorre->llave == op){
anterior->sig=siguiente;
free(actual);
}
else{}
anterior=recorre;
recorre = recorre->sig;
actual=recorre;
if(recorre != NULL){siguiente = recorre->sig;}
}
}












y por si acaso, aqui va el codigo entero(tomen en cuenta que es un archivo sencillo para practicar  ;D ) :

Código:
#include <stdio.h>
#include <stdlib.h>

#define FALSE 0
#define TRUE 1

typedef int boolean;

boolean estaVacia();

typedef struct nodo{
int llave;
struct nodo * sig; /* auto referencia */
}nodoLista;

nodoLista * primero = NULL;
nodoLista * ultimo = NULL;

void insertarInicio();
void insertarFinal();
void mostrarLista();
void eliminarLista();

int main(void) {
setvbuf(stdout, NULL, _IONBF, 0);
int opcion;
do{
printf("\n\nMENU");
printf("\n0.- Salir");
printf("\n1.- Agregar un nodo al inicio");
printf("\n2.- Mostrar los valores de la lista");
printf("\n3.- Agregar un nodo al final");
printf("\n4.- Eliminar un elemento");

printf("\n\nDame tu opci�n");
scanf("%d", &opcion);

switch(opcion){
case 0:
break;
case 1:
insertarInicio();
break;
case 2:
mostrarLista();
break;
case 3:
insertarFinal();
break;
case 4:
eliminarLista();
break;
}

} while (opcion != 0);


return EXIT_SUCCESS;
}

void insertarInicio(){
nodoLista * nuevo;
nuevo = (nodoLista *)malloc(sizeof(nodoLista));

printf("\n\nDame el valor de la llave");
scanf("%d", &nuevo->llave);
nuevo->sig = primero;
primero = nuevo;

if(primero->sig == NULL)
ultimo = primero;
}

void insertarFinal(){
if (estaVacia()){
insertarInicio();
return;
}

nodoLista * nuevo;
nuevo = (nodoLista *)malloc(sizeof(nodoLista));

printf("\n\nDame el valor de la llave");
scanf("%d", &nuevo->llave);
nuevo->sig = NULL;
ultimo->sig = nuevo;
ultimo = nuevo;
}

void mostrarLista(){
if (estaVacia()){
printf("\n\nLa lista est� vac�a");
return;
}
nodoLista * recorre = primero;
while (recorre != NULL){
printf("%d  ", recorre->llave);
recorre = recorre->sig;
}
}

void eliminarLista(){
nodoLista* anterior;
nodoLista* actual;
nodoLista* siguiente;
nodoLista* recorre=primero;

int op;
printf("Cual es el entero a eliminar?");
scanf("%d", &op);

anterior=primero;
actual=primero;
siguiente=primero->sig;

while(recorre != NULL){

if(recorre->llave == op){
anterior->sig=siguiente;
free(actual);
}
else{}
anterior=recorre;
recorre = recorre->sig;
actual=recorre;
if(recorre != NULL){siguiente = recorre->sig;}
}
}

boolean estaVacia(){
if (primero == NULL)
return TRUE;
else
return FALSE;
}
Páginas: 1 [2]
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines