viernes, 4 de marzo de 2016

Regresa al GATO ahora es Android

Para la impartición de cátedra de asignaturas relacionadas a la programación de computadoras se han utilizado un sin fin de ejercicios, algoritmos, proyectos y artilugios para demostrar habilidades para el manejo de estructuras de control.

Es inevitable por lo tanto, no pensar en desarrollar un juego para motivar a los estudiantes, uno de los clásicos infaltables es sin duda el tres en raya, tres en línea, TIC - TAC - TOE, o el Gato o con el nombre que se conozca en cada país.


Es por ello, que por motivos de la programación de dispositivos móviles ANDROID hemos puesto manos a la obra y desarrollado nuestra app demostrativa mediante el empleo de orientación a objetos. Esperemos este material sea de ayuda a los que quieran aprender el desarrollo de apps móviles.

PASO 1. Lo que necesitamos

  • Y un poco de paciencia para la instalación de las herramientas 

Algo importante a mencionar, una vez finalizada la instalación del IDE será necesario definir cual será el lugar donde podremos ver y probar las aplicaciones, para ello existen algunas alternativas:

1.- Crear un AVD (Android Virtual Device) desde el menu "Tools-Android-AVD Manager" 


donde deberemos elegir "+ Create Virtual Device", yo personalmente he preferido crear una unidad virtual con la API 15 con Android 4.0.3 "Ice Cream Sandwich" con la finalidad de que mis aplicaciones sean soportadas por muchos mas dispositivos. Y para gozar de las ventajas de las nuevas APIs dejo la maquina virtual creada por default con la versión actual de android. Los detalles de las características del AVD no nos he analizado a profundidad, pero la imagen muestra algunos datos que podrán guiarles.

¡Aquí tenemos una pequeña nota importante a considerar! en muchas de las ocasiones el emulador no quiere arrancar pues indica que tu computadora no soporta aceleración de hardware o que falta la instalación del componente de aceleración; yo conozco dos formas de solucionarlo:  a) Debemos ir a la BIOS de la computadora e indicar soporte de HAXM , b) Podemos descargar el paquete de la aceleración de gráficos de Intel https://software.intel.com/en-us/android/articles/installation-instructions-for-intel-hardware-accelerated-execution-manager-windows no olvidando instalar el programa que queda en <sdk folder>/sdk/extras/intel/Hardware_Accelerated_Execution_Manager/ 


2.- Utilizar tu dispositivo android fisico o smartphone, todos los dispositivos que cuenten con el sistema operativo android tienen una opción denominada "Depuración USB", la localización de dicha opción ha variado con algunas versiones, aunque casi siempre se encuentra en el menu CONFIGURACIONES. 

Aqui hay un link donde puedes ver información relacionada http://www.elandroidelibre.com/2015/01/como-activar-el-modo-depuracion-usb-en-android.html

Una vez realizado los pasos anteriores solo habrá que conectar vía USB tu dispositivo para que el entorno de programación lo detecte al momento de ejecutar un programa Android.


3.- Utilizar un emulador externo de dispositivos Android, como lo es "Bluestacks"
Donde solo es necesario instalar la aplicación y cuando intente ejecutar un programa el IDE lo reconocerá siempre y cuando este funcionando dicho emulador.

Si has librado el paso 1, estas listo para empezar a desarrollar cualquier aplicación Android y realizar las pruebas necesarias.


PASO 2. El diseño

Para obtener un resultado visual agradable y evitando pelear con el código XML junto con "donde pongo esto", es necesario planear la interfaz final del proyecto.
Este gato en particular fue planeado como el siguiente diagrama:



Como los dispositivos android son muy variados en tamaño, es muy recomendable desarrollar una interfaz basada en tamaños relativos y no absolutos, por lo tanto, haciendo uso de los controles "LinearLayout" vertical y horizontal logramos el acomodo de las partes principales y además para indicar el "peso" de cada elemento dentro del layout utilizamos la propiedad android:layout_weight. En el siguiente link esta la explicación completa del manejo de esto:
http://androideity.com/2012/06/01/ui-fluidas-y-la-propiedad-weight-en-android/

Finalmente, el código XML de la vista de la aplicación quedo de la siguiente manera (las imágenes pueden descargarse a continuación y colocarse dentro de la carpeta "drawable":
















    

        

        
    

    

        

        

        
    


    

    

        

        

        
    

    


    

        

        

        
    

    

        

        

    





PASO 3. La programación

Una vez completado el diseño, es tiempo de empezar a programar, aunque si lo has notado en el mismo diseño del XML ya hemos agregado un poco de código mediante una propiedad llamada android:onClick="Tirando", más adelante platicaremos de ésta.

Sin lugar a dudas la parte más difícil de programar una aplicación es decidir por donde comenzar, nosotros hemos optado por programar una clase llamada Gato (además recuerdo que este juego tiene su origen dentro de una clase de programación orientada a objetos je).  Pues el diseño de la clase Gato y también una llamada Jugador son las siguientes:
quedando el código de ambas clase de la siguiente manera:

Clase GATO
/**
 * @author MartinC
 */
public class Gato {
    public int JugadorActual;
    public int Tamanio;
    public String Color;
    private String[] tablero;
    
    public Gato(){
        tablero = new String[10];
    }
    
    
    public boolean ColocarTiro(int posicion) {
        if (tablero[posicion]!=null) {
            return false;
        }
        
        if (JugadorActual==1) {
            tablero[posicion] = "X";
        } else {
            tablero[posicion] = "O";
        }
        
        return true;
    }
    
    public char BuscarGanador() {
        // Existen 8 combinaciones para ganar
        String cadena="";
        String valores = "";
        char resultado =' ';
        boolean ganador = false;
        
        if (JugadorActual ==1) 
            cadena = "XXX";
        else
            cadena = "OOO";
        
        valores = tablero[1] + tablero[2] + tablero[3];
        if (valores.equals(cadena)) { ganador = true; }

        valores = tablero[4] + tablero[5] + tablero[6];
        if (valores.equals(cadena)) { ganador = true; }

        valores = tablero[7] + tablero[8] + tablero[9];
        if (valores.equals(cadena)) { ganador = true; }

        valores = tablero[1] + tablero[4] + tablero[7];
        if (valores.equals(cadena)) { ganador = true; }

        valores = tablero[2] + tablero[5] + tablero[8];
        if (valores.equals(cadena)) { ganador = true; }

        valores = tablero[3] + tablero[6] + tablero[9];
        if (valores.equals(cadena)) { ganador = true; }

        valores = tablero[1] + tablero[5] + tablero[9];
        if (valores.equals(cadena)) { ganador = true; }

        valores = tablero[3] + tablero[5] + tablero[7];
        if (valores.equals(cadena)) { ganador = true; }
        
        if (ganador){ 
            if (JugadorActual ==1) 
                resultado = 'X';
            else
                resultado = 'O';
        }
        else {
            if (EstaLleno()) {
                resultado = '-';
            }
        }
        
        return resultado;
    }
    
    private boolean EstaLleno() {
        boolean lleno = true;
        for (int i=1; i<=9; i++) {
            if (tablero[i]==null) {
                lleno = false;
            }
        }
        return lleno;
    }
    
    public void CambiarTurno() {
        if (JugadorActual==1) {
            JugadorActual=2;
        }else
        {
            JugadorActual=1;
        }        
    }
}


Clase JUGADOR
/**
 * @author MartinC
 */
public class Jugador {
    public String Nombre;
    public String Simbolo;
}


Ahora,  recordemos el onClick de cada imageView del tablero del gato, dicho atributo permite el llamado de una función Java denominada "Tirando" que a su vez mandara a llamar al objeto Gato en este caso "Miau" para que este se encargue de procesar el tiro. NOTA: para que esta propiedad funcione debe indicarse también el atributo  "clickeable= true" como lo muestra el siguiente fragmento de código:

        

Otra cosa interesante es que cada ImageView se inicia con una imagen en blanco (algunos no están tan en blanco, al final de este paso se aclara la razón), y tiene un número de posición:



El código de la función "Tirando" que debe colocarse dentro de la clase que contiene el método Main(), es bueno aclarar que dicho método se vale de otros auxiliares llamados RealizarTiro (que hace uso del objeto "miau" para decidir la acción a realizar en la interfaz) y MostrarMarca (que muestra efectos visuales mediante la clase animation):

    public void Tirando(View v) {
        ImageView img = (ImageView) findViewById(v.getId());
        int index = Integer.parseInt(img.getTag().toString());
        RealizarTiro(index, img);
    }

    private void RealizarTiro(int posicion, ImageView btn) {
        if (!miau.ColocarTiro(posicion)) {
            return;
        }

        MostrarMarca(btn, posicion);

        char valor = miau.BuscarGanador();
        if (valor!=' ') {
            switch (valor){
                case 'X':
                    MostrarMensaje("Ganaste " + Jugador1.Simbolo);
                    break;
                case 'O':
                    MostrarMensaje("Ganaste " + Jugador2.Simbolo);
                    break;
                case '-':
                    MostrarMensaje("EMPATE!!!");
                    break;
            }
        }
        else {
            miau.CambiarTurno();
            if (miau.JugadorActual == 1) {
                txtNombre.setText(Jugador1.Nombre + " " + Jugador1.Simbolo);
                imagen.setImageResource(R.drawable.hombre);
            }
            else {
                txtNombre.setText(Jugador2.Nombre + " " + Jugador2.Simbolo);
                imagen.setImageResource(R.drawable.hombre2);
            }
        }
    }

    private void MostrarMarca(ImageView btn, int posic) {
        AnimationSet animacion = new AnimationSet(true);

        int rs = ScaleAnimation.RELATIVE_TO_SELF;
        ScaleAnimation escala = new ScaleAnimation(1,2,2,5,rs,0.5f, rs, 0.5f);
        escala.setDuration(500);

        ScaleAnimation escala2 = new ScaleAnimation(2,1,2,1,rs,0.5f, rs, 0.5f);
        escala2.setDuration(500);
        escala2.setStartOffset(500);

        AlphaAnimation aparicion = new AlphaAnimation(0,1);
        aparicion.setDuration(1000);

        animacion.addAnimation(escala);
        animacion.addAnimation(escala2);
        animacion.addAnimation(aparicion);

        int recurso=0;
        if (miau.JugadorActual == 1) {
            recurso = R.drawable.x;
            if (posic==2 || posic==5 || posic==8) {
                recurso = R.drawable.x_;
            }
        }
        else {
            recurso = R.drawable.o;
            if (posic==2 || posic==5 || posic==8) {
                recurso = R.drawable.o_;
            }
        }

        btn.setImageResource(recurso);

        btn.startAnimation(animacion);

    }

    private void MostrarMensaje(String msj) {
        Dialog dialogo = null;
        Builder builder = new Builder(this);

        builder.setTitle(msj);
        builder.setIcon(R.drawable.gato);
        builder.setPositiveButton("Volver a iniciar", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                miau = new Gato();
                miau.JugadorActual = 1;
                txtNombre.setText(Jugador1.Nombre + " - " + Jugador1.Simbolo);
                VaciarTablero();
            }
        });
        builder.setNegativeButton("Salir", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                finish();
            }
        });
        dialogo = builder.create();
        dialogo.show();
    }
    
    private void VaciarTablero() {
        ((ImageView)findViewById(R.id.imageView1)).setImageResource(R.drawable.blancoc);
        ((ImageView)findViewById(R.id.imageView2)).setImageResource(R.drawable.blanco);
        ((ImageView)findViewById(R.id.imageView3)).setImageResource(R.drawable.blancoc);
        ((ImageView)findViewById(R.id.imageView4)).setImageResource(R.drawable.blancoc);
        ((ImageView)findViewById(R.id.imageView5)).setImageResource(R.drawable.blanco);
        ((ImageView)findViewById(R.id.imageView6)).setImageResource(R.drawable.blancoc);
        ((ImageView)findViewById(R.id.imageView7)).setImageResource(R.drawable.blancoc);
        ((ImageView)findViewById(R.id.imageView8)).setImageResource(R.drawable.blanco);
        ((ImageView)findViewById(R.id.imageView9)).setImageResource(R.drawable.blancoc);
    }


IMPORTANTE:
Las lineas horizontales del tablero del gato fueron agregadas fácilmente con:

    
    

pero las lineas verticales, la verdad no fue algo a lo que encontré una solución rápida en su momento, por lo cual opte por generar una imagen que tuviera lados con linea, para que hicieran el efecto de linea vertical, tal como este:
lo cual hizo necesario también, la modificación de O y X para que si lanzaban a la posición correspondiente 2, 5 o 7 se mostrará la variante con linea jejeje, si alguien logra hacerlo sin dicho truco por favor compartan.


El código completo estará disponible más adelante...

PASO 4. La publicación

Para publicar aplicaciones es necesario registrarse como desarrollador Android Developer http://developer.android.com/intl/es/index.html e ingresar a la consola del desarrollador, pero para publicar es necesario realizar un pago de aprox. 25 dólares a la fecha de hoy. Los detalles de como publicar espero en algún momento poder subirlos, más no es el objetivo de esta entrada.

El resultado final esta publicada en el play store
https://play.google.com/store/apps/details?id=martinc.elgato

O puedes buscarla mediante las palabras clave:

martinc.elgato

Esto de esperar a que pasen las horas de salida del autobús, no dejan nada bueno....
Saludos Ing PAGA

miércoles, 11 de febrero de 2015

Algoritmos de estructura simple

1. SUMA DE DOS NÚMEROS

# include <iostream>
  using namespace std;
  int main () {

      int a;
      int b;
      int res;
      cout<<"Dame el primer valor: ";
      cin>> a;
      cout<<"Dame el segundo valor: ";
      cin>> b;

      res=a+b;
      cout<<"El resultado es: ";
      cout<<res;

      cin.get(); cin.get(); // Detiene hasta presionar una tecla
}

2.CALCULAR EL VALOR NÚMERICO DEL ÍNDICE DE MASA CORPORAL DE UNA PERSONA

  #include <iostream>
  using namespace std;
  int main () {
      float peso;
      float altura;
      float IMC;


      cout<<"Dame tu peso en kgs= ";
      cin>>peso;
      cout<<"Dame tu altura en metros= ";
      cin>>altura;


      IMC=peso/(altura*altura);
      cout<<endl<<"El IMC es= ";
      cout<<IMC;
      cin.get();

      cin.get();  
  }


3. CALCULAR LA SUMA Y EL PROMEDIO DE 3 NÚMEROS

# include <iostream>
  using namespace std;
  int main (){
  float a;
  float b;
  float c;
  float suma;
  float promedio;


  cout<<"Dame el primer valor= ";
  cin>>a;
  cout<<"Dame el segundo valor= ";
  cin>>b;
  cout<<"Dame el tercer valor= ";
  cin>>c;


  suma=a+b+c;
  cout<<"La suma es= ";
  cout<<suma;
  promedio=(a+b+c)/3;
  cout<<endl<<"El promedio es; ";
  cout<<promedio;
 

  cin.get(); cin.get();

  }


4. CALCULAR EL ÁREA DE UN TRIANGULO

# include <iostream>
  using namespace std;
  int main (){
      int b;
      int h;
      int area;


      cout<<"Dame la base= ";
      cin>> b;
      cout<<"Dame la altura= ";
      cin>> h;


      area=(b*h)/2;
      cout<<"Area es = a : ";
      cout<<area;


      cin.get();

      cin.get();
   }



sábado, 15 de diciembre de 2012

Proyecto final Dic 2012

El proyecto del GATO propuesto en clase representa un reto importante lógico para la programación modular en C++ del curso que esta por terminar.




Las estructuras que deberan utilizarse son:
- Variables globales que serán visibles a todo el proyecto
- Variables locales y parámetros dentro de cada función
- Declaración, definición y uso de funciones
- WHILE que controle los eventos de tiro
-  SWITCH que defina la acción a realizar basado en un valor devuelto por una función
- IF para la toma de decisiones
- Salida de datos COUT
- Entrada de datos CIN
- Otros...

Más adelante en los próximos días les ire subiendo tips sobre como ir desarrollando dicho proyecto, pero creo que con el código fuente que les deje tendrán para iniciar este trabajo.

Ahhhh y antes que se me olvide, no se que tienen que ver las "cucas..."  en la materia de C++ pero les dejo el link de la anecdota que comentabamos en clase de una persona con "éstos" bichos (con un lenguaje regularmente anti-sonante jeje):

http://metalgirl.wordpress.com/2007/10/15/invasion-de-cucarachas/


Volveré a publicar el día martes que viene...

martes, 13 de noviembre de 2012

Estructuras de control y examen

Las estructuras de control son básicamente la razón por la cual los programas de computadora puedan resolver las diversas situaciones de la vida del hombre.
Recordando un poco de pasado, encontraremos que el mayor problema con el cual se enfrento el hombre fue: "...existían muchas operaciones y procesos repetitivos que debían hacerse una y otra vez, que aparte de cansados no estaban exentas de errores..."; las estructuras while, for y do while permiten al programador realizar dichas tareas eficazmente.

Hoy corresponde detallar en este blog la estructura while (Mientras) cuya finalidad es permitir la ejecución de ciertas acciones siempre y cuando exista una condición verdadera.

Por ejemplo: El ser humano come, bebe, camina, trabaja, etc. siempre y cuando haya aire que pueda respirar
* Observaciones:
  • ¿Qué es lo que el hombre hace? come, bebe, camina, trabaja, etc.
  • ¿Cuál es la condición que limita el quehacer del hombre? Debe haber aire

Por lo consiguiente el diagrama de flujo es el siguiente:
Es importante recordar que comúnmente las "Acciones" que están dentro de la estructura de control deberán de contener alguna opción por medio de la cual "Respira" se convierta en "Falso", en caso de no ser así es muy probable que el programa se bloquee creando un ciclo eterno (jejeje); para el caso del hombre sería como ser inmortal.

Otra de las estructuras de control vista en clase es el "switch" que nos permite la decisión multiple sobre una sola variable, este es el caso del siguiente programa:

Crear un programa que basado en el número de día de la semana mostrar el nombre del día:

int main() {
    int dia;
    cin>>dia;
   switch(dia) {
       case 1:
           cout<<"Domingo";
           break;
       case 2:
           cout<<"Lunes";
           break;
       case 3:
           cout<<"Martes";
           break;
       case 4:
           cout<<"Miércoles";
           break;
       case 5:
           cout<<"Jueves";
           break;
       case 6:
           cout<<"Viernes";
           break;
       case 7:
           cout<<"Sábado";
           break;
       default:
           cout<<"Error";
           break;
   }
}

Por favor realiza los siguientes ejercicios:
TAREA
* Basado en el número de MES muestra el nombre del mes
* Basado en la numeración del 1 al 4 muestra la estación del año: primavera, verano, otoño e invierno
* Desarrollar un programa que muestre un menú de opciones para el calculo de perímetros de las siguientes figuras: cuadrado, rectángulo y triangulo

GUÍA DE EXAMEN
* Partes de un programa de C++
* Tipos de datos en C++
* Declaración de variables
* Entrada y salida de datos
* Estructuras de control: if, switch, for, while

Recuerden llevar el día del examen todos los programas (en .exe) que hemos desarrollado durante las sesiones para realizar el conteo de evidencias de clase y asentar la primera calificación.

Sin mas, para dudas estoy en el correo.

sábado, 3 de noviembre de 2012

Sin clases :-(

Los saludos a todos desde este medio, desafortunamente no hubo clases el día de hoy, lo cual afecta seriamente el avance del curso; el primer examen de la materia estaba programada para la siguiente semana lo cual recorreremos una semana más, por lo cual aprovecho este medio para detallarles las actividades de esta semana:

1.- Deben enviarme el ejercicio de factorial (o será mas bien sumarial) que les explique en clase y que pedí lo terminaran entre todo el grupo.
2.- Debemos desarrollar otros ejercicios utilizando la instrucción "for", por lo cual les dejo a continuación el listado:
  1. Programa que pida la edad de 10 personas y que muestre el promedio de edades
  2. Programa que imprima los primeros 20 múltiplos del número indicado por el usuario
3.- Les pido por favor investiguen las sintaxis de la estructura de control "while"

Sin mas. les encargo esas actividades
Por favor realícenlas pues contaran como parte de la primera evaluación que haremos.

  PD. Aquí les dejo su calavera: 1 punto para examen a quienes me entreguen el segundo ejercicio con una bonita APARIENCIA ( Me refiero a algo parecido al primer ejercicio que les pase que mostraba una figura, pónganle imaginación)

miércoles, 24 de octubre de 2012

Estructura de control: CONDICIONAL C++

Al igual que en nuestra vida, en la programación de computadoras debemos tomar decisiones/caminos dependiendo de lo que acontezca.

Ej.
  • Si sales de tu casa, y te das cuenta que empieza a llover: por sentido común piensa en un paraguas ¿Hubieras pensado en dicho objeto si no hubiera estado lloviendo? (En forma instantánea has tomado una decisión basada en la situación actual) .

    Este ejemplo puede dibujarse a través de un diagrama de flujo como el que se muestra aquí.

     


     
     
     

     
    Es por ello, que todos los lenguajes de programación tienen tienen soporte en forma nativa de la primera estructura que veremos, llamada CONDICIONAL
     En C++ es definida por la palabra reservada "if" quedando el código fuente de la siguiente forma:
     
    if (Condición) {
         //Acciones en caso de SE CUMPLE la condición
    }
    else{
         // El código en caso de NO SE CUMPLE la condición
    }
     
     Para el ejemplo anterior de la lluvia el código fuente sería:
    #include <iostream>
    using namespace std;
     
    int main() {
         int clima = "2" // 1=Despejado  2=Lloviendo
         if (clima=2) {
                  cout<<"Llevar paraguas";
         } 
         else {
                  cout<<"SIN paraguas";
         }
    }

    TAREA:

  1. Realizar un programa que pida 3 números y muestre cuál es el mayor
  2. Realizar un programa que muestre si una persona es mayor de edad basado en su edad
  3. Realizar un programa que indique si un número X es múltiplo de 7



Espero no tengan inconvenientes para realizar estos pequeños ejercicios que requieren el uso de IF

Estamos en contacto por correo para dudas

sábado, 20 de octubre de 2012

Ejercicio 2. Entrada de datos C++: CIN

Saludos nuevamente
Recordando un poco sobre principios básicos de la computadora, creo que todos recordamos el siguiente diagrama:


La impresión de la hoja de presentación de la semana pasada solo tenía proceso y salida, y ahora la tabla de multiplicar cumple perfectamente con el principio básico de la computadora:

CIN <--- Entrada de datos


for (i=1; i<=10;i++){   <--- Proceso de la información
}


COUT  <--- Salida de la información


Es importante recordar que todo programa deberá cumplir con esa característica (habrá casos especiales que no tengan las 3 características pero probablemente no estarán destinadas a usuarios)

A continuación les dejo el código para la impresión de la tabla por si alguno no logró terminarla en clase, recuerden que todos sin excepción deberán probarlo en su computadora: portatil o de escritorio en su casa.

#include<iostream>
using namespace std;

int main() {
    /* Este programa va a imprimir el número de
    tabla que el usuario indique */

    int tabla;
    cout<<"Escribe el número de tabla:";
    cin>>tabla;

    // Aquí inicia la estructura de control FOR
    int i;
    for (i=1; i<=10; i++) {
        cout<<endl<<tabla<<" x "<<i<<" = "<<i*tabla;
    }

    cin.get();
}



Y para no perder el ritmo, les dejo la tarea para la clase siguiente:

TAREA:
- Desarrollar un pequeño programa, que realice la suma de 3 números e imprima el resultado.
- Desarrollar un programa que imprima "n" veces el texto "Tengo que revisar el blog de Programación II los JUEVES por la tarde. Atte.: YO", recuerden cambiar la palabra YO por su nombre.