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

 

 


Tema destacado: Guía rápida para descarga de herramientas gratuitas de seguridad y desinfección


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  consejos con optimizacion de codigo snake
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: consejos con optimizacion de codigo snake  (Leído 2,696 veces)
rulovive

Desconectado Desconectado

Mensajes: 46



Ver Perfil WWW
consejos con optimizacion de codigo snake
« en: 27 Marzo 2014, 20:57 pm »

que tal amigos.... al grano:
hace poco terminé un juego snake en consola en borland c++. hice una biblioteca conio independiente del entorno (mi programa corre donde quiera). y el juego no tiene errores -que yo haya descubierto-.... el caso es que este juego es una prueba para cierto empleo y antes de enviar mi codigo y el ejecutable quise que un amigo me dijera sus opiniones...
en resumen el me dijo que la logica estaba bien, que el juego corre perfecto pero... en cuestion de optimizacion y posicion del codigo estaba horrible. coloco el codigo:

Código:
# include<iostream.h>
# include<conio1.h>
# include<windows.h>
#include<stdio.h>
#include<time.h>

#define ARRIBA 72
#define ABAJO 80
#define DERECHA 77
#define IZQUIERDA 75


void nocursor()                                     //FUNCTION TO DISSAPEARS THE CURSOR OF THE WINDOW
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cci;
cci.dwSize=20;
cci.bVisible=FALSE;
SetConsoleCursorInfo(hStdout,&cci); }
void sicursor()                                     //FUNCTION TO APEARS THE CURSOR OF THE WINDOW
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cci;
cci.dwSize=20;
cci.bVisible=TRUE;
SetConsoleCursorInfo(hStdout,&cci); }


class vibora{
char comptecla,tecla,comida,*head;
int x,y,cx,cy,*hx,*hy,tamano;
public:
int timer,timer1,vel;
bool perder;
vibora(int _x,int _y): x(_x),y(_y){}
void inicializar();
void mover();
void borrar();
void pintar();
void generarcomida();
void comer();
};

void vibora::inicializar()
{tamano=3;
perder=false;
comida='©';
tecla=IZQUIERDA;
comptecla=IZQUIERDA;
timer1=clock()/100;

head=(char *) malloc(tamano *sizeof(int));
head[0]='@';
for (int i = 1; i <= tamano-1; i++)
head[i]='o';

hx=(int *) malloc(tamano *sizeof(int));
hy=(int *)malloc(tamano *sizeof(int));
for(int i=0; i<=tamano-1; i++)
{hx[i]=x+i; hy[i]=y;}

borrar();
pintar();
generarcomida();
}

void vibora::pintar()
{
for (int i = 0; i <= tamano-1; i++)
{gotoxy(hx[i],hy[i]); cout<<head[i];}
}

void vibora::generarcomida()
{int i=0;
cx=2+rand()%37;
cy=2+rand()%9;

do{
   if(cx==hx[i]&&cy==hy[i])
{cx=2+rand()%39;
cy=2+rand()%9;
i=0;}
   else
i++;
}while(i<=tamano-1);

gotoxy(cx,cy); cout<<comida;
}

void vibora::comer()
{
if(hx[0]==cx&&hy[0]==cy)
  {tamano++;
  hx=(int *)realloc(hx, tamano *sizeof(int));
  hy=(int *)realloc(hy, tamano *sizeof(int));
  head=(char *)realloc(head, tamano *sizeof(int));
  head[tamano-1]='o';
  generarcomida();}
}

void vibora::mover()
{
timer=clock()/100;
if(kbhit()) tecla=getch();   //registra pulsacion
if(tecla!=ARRIBA&&tecla!=ABAJO&&tecla!=DERECHA&&tecla!=IZQUIERDA) tecla=comptecla; //si la tecla pulsada es diferente de la de direccion, copia el ultimo movimiento
if((hx[1]==x-1&&tecla==IZQUIERDA )||(hx[1]==x+1&&tecla==DERECHA)||(hy[1]==y-1&&tecla==ARRIBA)||(hy[1]==y+1&&tecla==ABAJO))tecla=comptecla;  //si quiero ir para el lado contrario al que voy, no lo dejo, sino que copio el ultimo movimiento

if((tecla==IZQUIERDA&&comptecla!=DERECHA)||(tecla==DERECHA&&comptecla!=IZQUIERDA)||(tecla==ARRIBA&&comptecla!=ABAJO)||(tecla==ABAJO&&comptecla!=ARRIBA))comptecla=tecla;  //si pulso tecla de direccion y no es contraria, copio a comptecla


if(timer1==timer)
{
if(tecla==IZQUIERDA)
x--;
if(tecla==DERECHA)
x++;
if(tecla==ARRIBA)
y--;
if(tecla==ABAJO)
y++;







if(x==1||x==40||y==1||y==12)     //si choca en la orilla pierde...
for (int i = 0; i <= 2; i++)
  {borrar();
  Sleep(500);
  pintar();
  Sleep(500);
  perder=true;}
else                             //...pero si no choca en la orilla...
{
for (int i = 1; i <= tamano-1; i++)    //...reviso eslabon por eslabon...
if(x==hx[i]&&y==hy[i])    //...y si las coordenadas estan en un eslabon
for (int i1 = 0; i1 <= 2; i1++)
{borrar();
Sleep(500);                //...pierdo...
pintar();
Sleep(500);
perder=true;}
else                         //...pero si no estan en el eslabon...
   if(i==tamano-1&&perder==false)            //...compruebo si ya reviso todos y si ya lo hizo...
   {borrar();
for(int i=tamano-1; i>=1; i--)
{hx[i]=hx[i-1];
hy[i]=hy[i-1];}                     //... se mueve
hx[0]=x;
hy[0]=y;
pintar();
timer1=timer+vel;}
}

}

}

void vibora::borrar()
{
for (int i = 0; i <= tamano-1; i++)
{gotoxy(hx[i],hy[i]); cout<<" ";}
}


void main()
{
randomize();
bool nuevamente=true;
char resp;
for (int i = 1; i <= 40; i++)  //limite superior
{gotoxy(i,1); cout<<"*";}
for (int i = 2; i <= 12; i++)  //limite izquierdo
{gotoxy(1,i);cout<<"*";}
for (int i = 2; i <= 40; i++)  //limite inferior
{gotoxy(i,12); cout<<"*";}
for (int i = 2; i <= 12; i++)  //limite derecho
{gotoxy(40,i);cout<<"*";}





do{                    //do que sirve solo para comenzar y recomenzar el juego despues de perder

 
//este do sirve para elegir nivel de cada partida
  do{ gotoxy(1,13); cout<<"Bienvenido a Snake. Selecciona un nivel para comenzar a jugar (1-5): ";
  sicursor();
  cin>>resp;
  if(resp!='1'&&resp!='2'&&resp!='3'&&resp!='4'&&resp!='5')
{cout<<"Opcion no permitida...Debes seleccionar una opcion del 1 al 5."; Sleep(2000);
gotoxy(1,13);cout<<"                                                                                                                                                     ";
}
  else
{nocursor();
cout<<"Elegiste el nivel "<<resp; Sleep(1000);
gotoxy(1,13);cout<<"                                                                                                                                                     ";
gotoxy(11,13);cout<<"EL JUEGO COMIENZA EN";
gotoxy(20,14); cout<<"3"; Sleep(1000);
gotoxy(20,14); cout<<"2"; Sleep(1000);
gotoxy(20,14); cout<<"1"; Sleep(1000);
gotoxy(19,14); cout<<"YA"; Sleep(1000);
gotoxy(1,13);cout<<"                                                                                                                                                     ";
}         
  }while(resp!='1'&&resp!='2'&&resp!='3'&&resp!='4'&&resp!='5');


  vibora n(20,6);
  n.inicializar();
  switch (resp)
{case '1': n.vel=9; break;
case '2': n.vel=7; break;
case '3': n.vel=5; break;             //switch para la velocidad elegida
case '4': n.vel=3; break;
case '5': n.vel=1; break;}



 
  do{                                //bucle del juego en proceso
n.mover();
n.comer();
}while(n.perder==false);




  gotoxy(15,13);cout<<"HAS PERDIDO"; Sleep(1500);
  gotoxy(1,15); cout<<"Si quieres jugar de nuevo presiona 's', de lo contrario, presiona cualquier otra tecla: ";
  sicursor();
  cin>>resp;
  if(resp=='s'||resp=='S')
{
nocursor();
nuevamente=true;
gotoxy(15,13); cout<<"               ";
gotoxy(1,15); cout<<"                                                                                           ";
for(int i=2; i<=39; i++)
   for(int j=2; j<=11; j++)       //for que sirve para limpiar el campo de juego al perder
   {gotoxy(i,j);cout<<" ";}
Sleep(1000);
}
  else
  nuevamente=false;
 
}while(nuevamente==true);  //do que termina cuando le respondes que ya no quieres jugar


cout<<endl<<"Has elegido salir. ";
system("pause");
}


Si se fijan tengo una clase vibora, sus metodos y la funcion main que es donde va el bucle del juego... este compañero y amigo me dijo que los metodos de la clase definen (o deberian definir) de manera muy especifica y delimitada las propiedades y parametros del objeto, pero no colocar la mayoria del flujo del programa en esas partes... es decir. el me dijo que todos los metodos deberian ser parecidos a lo que hice con el metodo inicializar() y/o borrar(), no como en el metodo de mover(), donde se supone que solo deberia recibir instrucciones y ejecutarlas, mas no tomar  valores ni procesarlos ni nada ahi mismo...
ustedes que opinan? mi codigo es optimo de la forma que está? o podria sacar muchas partes de codigo de los metodos y colocarlo en main o en alguna funcion para que los metodos solo ejecuten instrucciones y parametros recibidos de dichas funciones??
NOTA: Aclaro que este codigo es 100% mio y que en realidad la critica no fue hacia este codigo sino hacia uno mucho mas largo y engorroso (un tetris) en el que el metodo llamado eliminacion tenia aprox el 70% del codigo total del programa... pero como ese codigo no tiene sangrias ni comentarios ni nada (lo hice hace como 4 meses y ni quiero meterme al codigo del metodo eliminacion porque es un reborujo que ni yo entiendo...por culpa de no ponerle los comentarios), puse mejor el del snake, que ilustra un poco mas ordenada la logica que use para el tetris, ya que es igual en casi todo el flujo del codigo... me podrian decir si debo modificarlo o asi esta bien?


En línea

eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: consejos con optimizacion de codigo snake
« Respuesta #1 en: 27 Marzo 2014, 21:34 pm »

El código francamente es mejorable:

* En C++ se suele emplear const en vez de defines

* Deberías tabular el código para hacerlo legible.

* La clase víbora no debería encargarse de cosas que no dependiesen de la propia vibora, como "generar la comida"

* Ya que usas coordenadas, ¿qué tal usar una clase para encapsular las coordenadas?

* ¿Por qué usas malloc en vez de new?

* ¿Y los correspondientes free?

* La interfaz del usuario debería ser independiente del código del juego.

Código
  1.  
  2. class Punto
  3. {
  4.  public:
  5.    Punto( int x, int y );
  6.  
  7.    int X( ) const;
  8.    int Y( ) const;
  9.  
  10.  private:
  11.    int _x;
  12.    int _y;
  13. };
  14.  
  15. class Tamano
  16. {
  17.  public:
  18.    Tamano( int ancho, int alto );
  19.  
  20.    int Ancho( ) const;
  21.    int Alto( ) const;
  22.  
  23.  private:
  24.  
  25.    int _alto;
  26.    int _alto;
  27. }
  28.  
  29. class Rectangulo
  30. {
  31.  public:
  32.    Rectangulo( const Punto& punto, const Tamano& tamano );
  33.  
  34.    Punto EsqSupIzq( ) const;
  35.    Punto EsqSupDer( ) const;
  36.    Punto EsqInfIzq( ) const;
  37.    Punto EsqInfDer( ) const;
  38.  
  39.    Tamano Tamano( ) const;
  40.  
  41.    // Verifica si el punto se encuentra dentro del rectangulo o no
  42.    bool EstaDentro( const Punto& punto );
  43.  
  44.  private:
  45.  
  46.    Punto _origen;
  47.    Tamano _tamano;
  48. };
  49.  
  50. class Vibora
  51. {
  52.  public:
  53.    enum Direccion
  54.    {
  55.      Arriba, Abajo, Derecha, Izquierda
  56.    };
  57.  
  58.    Vibora( const Punto& inicio, Direccion direccion );
  59.  
  60.    // Obtiene las coordenadas del cuerpo de la serpiente... la primera coordenada es la cabeza
  61.    std::vector< Punto > Cuerpo( ) const;
  62.  
  63.    // Permite cambiar la direccion en la que se mueve la serpiente
  64.    void SetDireccion( Direccion direccion );
  65.  
  66.    // Mueve la serpiente en la direccion establecida
  67.    void Mover( );
  68.  
  69.    // Se llama cuando la serpiente come una fruta, hace que su tamaño crezca
  70.    void Comer( );
  71.  
  72.  private:
  73.  
  74.    std::vector< Punto > _cuerpo;
  75.    Direccion _direccion;
  76. };
  77.  
  78. class Juego
  79. {
  80.  public:
  81.  
  82.    // El parametro indica el tamaño del tablero de juego
  83.    Juego( Tamano tamano, int nivel );
  84.  
  85.    // Inicia el algoritmo de juego
  86.    void Jugar( );
  87.  
  88.  private:
  89.  
  90.    // Posicion de la comida ( si no se admite mas de una por vez se puede quitar el vector )
  91.    std::vector< Point > _comida;
  92.  
  93.    // Serpiente del juego
  94.    Serpiente _serpiente;
  95.  
  96.    // Tamaño del tablero de juego
  97.    Tamano _tablero;
  98.  
  99.    // Para controlar la velocidad de juego
  100.    int _nivel;
  101.  
  102.    // Comprueba si el usuario ha pulsado una tecla para cambiar de direccion
  103.    void ComprobarTecla( );
  104.  
  105.    // Pinta el tablero de juego
  106.    void PintarTablero( );
  107.  
  108.    // Pinta la serpiente
  109.    void PintarSerpiente( );
  110.  
  111.    // Coloca una nueva pieza de comida
  112.    void CrearComida( );
  113. };

El diseño que te presento tiene una estructura más definida y organizada, además permite reutilizar código.


« Última modificación: 27 Marzo 2014, 21:37 pm por eferion » En línea

amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: consejos con optimizacion de codigo snake
« Respuesta #2 en: 27 Marzo 2014, 22:26 pm »

¿Por que dices que es independiente del SO? Yo ahí veo la windows.h y la conio.h.

Para resolver el problema de la portabilidad necesitas compilación condicional:
http://foro.elhacker.net/programacion_cc/duda_sobre_portabilidad-t393915.0.html
En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
rulovive

Desconectado Desconectado

Mensajes: 46



Ver Perfil WWW
Re: consejos con optimizacion de codigo snake
« Respuesta #3 en: 28 Marzo 2014, 18:41 pm »

gracias por responder chicos ^^
amchacon: las librerias son estandarizadas, la conio1 la descargue para el dev y la windows si esta ahi pero me refeia mas bien a que lo puedo correr en cualquier compu que no tenga instalado borland :p

en cuanto al codigo del compañero eferion. muchas gracias ^^ tratare de estudiar el tuyo y acomodar el propio. si tuvieran alguna otra sugerencia estaria agradecido :D
En línea

amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: consejos con optimizacion de codigo snake
« Respuesta #4 en: 28 Marzo 2014, 19:08 pm »

conio no es estandar ni windows.h :huh:
En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
vangodp


Desconectado Desconectado

Mensajes: 455



Ver Perfil
Re: consejos con optimizacion de codigo snake
« Respuesta #5 en: 28 Marzo 2014, 19:25 pm »

Este de aqui es el snake de paueky para miniwin pero lo hice con SFML  :laugh:

Código
  1. #include <SFML/Graphics.hpp>
  2. #include <SFML/Window.hpp>
  3. #include <windows.h>
  4. #include <list>
  5. #include <iostream>
  6. using namespace std;
  7.  
  8. const int XTAM = 66, YTAM = 40;
  9. const int SZ = 12;
  10.  
  11. struct Punto{
  12.    int x, y;
  13. };
  14.  
  15.  
  16. void cuadrado ( Punto &p,  sf::RenderWindow &laventana ){
  17.    sf::RectangleShape rectangle;
  18.  
  19.    rectangle.setPosition ( p.x*SZ, p.y*SZ );
  20. rectangle.setSize ( sf::Vector2f ( SZ-1, SZ-1) );  // *_*  
  21.  
  22. rectangle.setFillColor(sf::Color::Red);
  23.  
  24. laventana.draw(rectangle);
  25. }
  26.  
  27. bool colision( const Punto &cabeza, const list<Punto>& cola ){
  28.    if( cabeza.x >= XTAM || cabeza.x < 0 ){
  29.        return true;        
  30.    }
  31.    if( cabeza.y >= YTAM || cabeza.y < 0 ) {
  32.        return true;
  33.    }
  34.    list<Punto>::const_iterator it;
  35.    for( it = cola.begin(); it != cola.end(); it++ ){
  36.        if( cabeza.x == it->x && cabeza.y == it->y ){
  37.            return true;            
  38.        }
  39.    }
  40.    return false;
  41. }
  42.  
  43. Punto aleatorio(){
  44.    Punto p = { rand() % XTAM, rand() & YTAM } ;
  45.    return p;
  46. }
  47.  
  48.  
  49. int main() {
  50.    sf::RenderWindow window ( sf::VideoMode ( XTAM * SZ, YTAM * SZ, 32 ), "SFML APP" );
  51.    window.setVerticalSyncEnabled(true);
  52.    window.setFramerateLimit(60);
  53.    Punto cabeza = {XTAM/2, YTAM/2}; //cabeza, punto salida
  54.    Punto comida = aleatorio();
  55.    Punto temp = {0, 0};  
  56.    int vx = 1, vy = 0;              //Velocidad
  57.    int engorda = 0;
  58.    bool choque = false;
  59.    list<Punto> cola;
  60.    int retraso = 0;
  61.    while ( window.isOpen() && !choque ) {
  62.        retraso++;
  63.  
  64.        sf::Event tecla;
  65. while ( window.pollEvent ( tecla ) ) {
  66. switch ( tecla.type ) {
  67.                case sf::Event::Closed:
  68.                    std::cout << "Fin de juego!" << std::endl;
  69. window.close();
  70. break;
  71. case sf::Event::KeyPressed:
  72.                    if(tecla.key.code == sf::Keyboard::Up )
  73.                        vx = 0, vy = -1;
  74.                    else if(tecla.key.code == sf::Keyboard::Down )
  75.                        vx = 0, vy = +1;
  76.                    else if(tecla.key.code == sf::Keyboard::Left )
  77.                        vx = -1, vy = 0;
  78.                    else if(tecla.key.code == sf::Keyboard::Right )
  79.                        vx = +1, vy = 0;
  80.                    else if(tecla.key.code == sf::Keyboard::Space )
  81.                        engorda = 1;
  82.                    break;
  83. default:
  84.                    break;
  85. }
  86.  
  87. }        
  88. window.clear ();
  89. if ( retraso == 7 ) {
  90.            cola.push_front(cabeza);    
  91.            if ( engorda > 0 ){
  92.                engorda --;            
  93.            }else{
  94.                cola.pop_back();
  95.            }
  96.  
  97.  
  98. cabeza.x = cabeza.x + vx;
  99. cabeza.y = cabeza.y + vy;
  100.  
  101. if ( colision( cabeza, cola) ) {
  102.                choque = true;
  103. } else if (cabeza.x == comida.x && cabeza.y == comida.y){
  104.                engorda = 1;
  105.                comida = aleatorio();
  106.                while ( colision(comida, cola) || comida.x == cabeza.x && comida.y == cabeza.y ){
  107.                    comida = aleatorio();
  108.                }
  109. }
  110.  
  111. retraso = 0;
  112. }
  113.  
  114. if ( !choque ) {
  115.  
  116. list<Punto>::const_iterator it;
  117.  
  118. for ( it = cola.begin(); it != cola.end(); it++ ) {
  119. temp = *it;
  120. cuadrado ( temp, window );
  121. }
  122.  
  123. cuadrado ( cabeza, window );
  124. cuadrado (comida, window );
  125. window.display();
  126. }
  127.    }//END BUCLE
  128.  
  129.    //return EXIT_SUCCESS;
  130. }
  131.  

Se que el código es una chapuza XDD
pero funciona ^^
los controles son WASD y la barra de espacio agranda la serpiente es solo para probar.
Tampoco hice mucho, solo la hice andar y poco mas XDD
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Optimizacion de codigo PHP.
PHP
Hadess_inf 7 3,378 Último mensaje 31 Octubre 2009, 01:12 am
por HardieVon
Como guardar mi codigo? consejos..
.NET (C#, VB.NET, ASP)
Edu 4 2,568 Último mensaje 21 Junio 2011, 01:03 am
por Edu
Optimizacion de codigo en C.
Programación C/C++
oblivionxor 2 2,768 Último mensaje 10 Febrero 2013, 05:01 am
por oblivionxor
Ayuda en Código de Snake
Programación C/C++
Firu 5 3,272 Último mensaje 26 Marzo 2013, 22:08 pm
por 85
[Opinion] Problema acerca de optimización en código - Uso dinámico de arrays « 1 2 3 »
Programación C/C++
Miky Gonzalez 21 7,550 Último mensaje 19 Noviembre 2014, 18:51 pm
por Miky Gonzalez
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines