jueves, 28 de agosto de 2014

Introducción a la GUI de Java



Una "listener interface" es el puente entre el "listener" (tu) y el origen del evento (el botón).

Un origen de evento o "event source" es un objeto que puede retornar acciones de usuario (ya sean las acciones del mouse o teclear algo, etc...) en forma de "eventos". Los "eventos" son lógicamente otros Objetos, objetos de alguna "clase evento" o "event class". Hay muchas "event class" en la API de Java, y todas son facilmente identificables por tener la palabra "Event" dentro de su nombre (MouseEvent, KeyEvent, WindowEvent...).

Por lo tanto, un "event source" u origen de evento (como puede ser un botón) crea un OBJETO EVENTO cuando el usuario hace algo como pulsarlo. La mayoría del código que escribiré recibirá eventos en lugar de crearlos. En otras palabras, seré mas tiempo un "event listener" que un "event source".

Cada "evento" tiene su correspondiente interface listener. Si, por ejemplo quiero los eventos del ratón, tendríamos que implementar la "MouseListener interface" y recuerda, cuando implementamos una interface, debemos escribir la implementacion de todos los métodos de dicha interface en las subclases (recordar que si implementamos la interface en una superclase, no tenemos que implementar sus métodos en dicha clase, si no en las subclases de dicha clase, o mejor dicho, en las clases de más bajo nivel).

Algunas interfaces tienes más de un método, porque el mismo evento puede venir de diferentes formas, es decir, si implemento el MouseListener obtendré eventos para mousePressed, mouseReleased, mouseMoved, etc... Cada uno de esos eventos del ratón tiene un método diferente en la interface. Si implementamos el MouseListener el método mousePressed () será llamado cuando el usuario presiona el ratón y así con cada uno de los eventos.

En definitiva, para los eventos del ratón hay solo un objeto "evento", pero diferentes métodos representando los diferentes tipos de eventos del ratón.


Un JFrame es el objeto que representa una ventana en la pantalla. Es donde colocamos todos los elementos que representa una interface, elementos como botones, checkboxes, text fields, etc.

Clase Main

public class Main {

    public static void main(String[] args) {

        graphic grafica = new graphic();
        grafica.comenzarInterface();

    }
}

Clase Graphic:

import javax.swing.*;

public class graphic {

    JFrame frame = new JFrame ();
    JButton button = new JButton ("click me");

    void comenzarInterface() {

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(button);
        frame.setSize(300,300);
        frame.setVisible(true);
    }

}


Si lanzamos este código veremos una ventaja con un gran botón en el centro, ¡La primera aplicación!.

Pero no ocurre nada cuando pulsamos el botón, bueno, realmente si que ocurre, se lanza un aviso de que el usuario ha pulsado el botón. Pero como no hemos creado código para ese caso, el botón no hace nada. Para hacer algo necesitamos dos cosas. La primera es un METODO y la segunda es SABER cuando el usuario ha pulsado el botón.

Vamos a cambiar, cuando el botón sea pulsado, el título del botón de "click me" a "I´ve been clicked"

Creamos  un método llamado "changeIt"

    public void changeIt() {
        button.setText("I´ve been clicked!");
    }
}


Pero ¿Como se comunica el usuario con el botón?. La respuesta es sencilla, implementando una interface ActionListener en nuestra clse.

import javax.swing.*;
import java.awt.event.*;

public class graphic implements ActionListener {

    JFrame frame = new JFrame();
    JButton button = new JButton("click me");

    public void comenzarInterface() {

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(button);
        frame.setSize(300, 300);
        frame.setVisible(true);
        button.addActionListener(this);
    }
    public void actionPerformed (ActionEvent event){
        button.setText("I´ve been clicked");
    }

}


* Importamos el paquete donde se encuentran los ActionListener y los ActionEvent.
* Implementamos la interface. "una instancia de "graphic" es un ActionListener. El botón dará los eventos solamente a aquellas clases que implementen ActionListener.
* Hazte ver interesado en el botón, mediante este código le decimos "añademe a tu lista de Listeners"
El argumento que le pasas debe ser un objeto de la clase que implementa "ActionListener".
* Implementa la ActionListener (actionPerformed() de la interface). 

domingo, 24 de agosto de 2014

Hundir la Flota (parte 2)


Volvemos a Java! por fin!.
Bueno, estábamos con el juego de hundir la flota, había puesto las tres clases de la que constaba el juego, tres clases bastante grandes como para entenderlo todo a la primera.
Lo que voy a hacer es sacar la información útil de este gran ejemplo, por lo tanto, vamos a ello.

Para entender mejor el código debemos estudiar primero un par de aspectos importantes, el primero se trata de "los ArrayList"


ArrayList

Primero vamos a ver la necesidad de utilizar un arraylist, como nuestro juego va sobre localizar un conjunto de "posiciones" con el fin de hundir un barco vamos a ver que es mas o menos lo que deberíamos hacer.

Cuando iniciamos el programa, éste nos crea 3 barcos aleatorios (la creación de "barcos" se lleva a cabo en la clase GameHelper, es un proceso un poco complejo para estudiarlo por ahora) los barcos no son más que 3 celdas consecutivas, ya sea en horizontal o en vertical, que han sido elegidas y puestas en una "especie de Array inteligente"... de eso se trata un ArrayList. Pongamos un ejemplo para entenderlo mejor.

Imaginar que queremos colocar un "barco" (3 celdas) dentro de una tabla 1x7 (una fila y 7 columnas):

[1][2][3][4][5][6][7]

Por ejemplo, el barco estará localizado en la posición 2,3,4.
para guardas estas posiciones vamos a crear un Array de los que hemos estudiado.

int [] posicion = {2,3,4};



El usuario tiene que adivinar los 3 valores que se encuentran dentro del array. Cuando adivina uno de estos valores el array debería cambiar para evitar que el usuario no vuelva a elegir el mismo valor.

Forma 1:
Creando un nuevo array que contenga los valores que el usuario ha adivinado. Así, si la elección del usuario vuelve a ser la misma, no será válida puesto que ya está guardada en el array.
Forma 2:
Cambiando el valor original de los valores adivinados por -1. De esta forma el código solo se percatará de los valores positivos (Trabajando así con un solo array)
Forma 3:
Cada vez que el usuario adivine un valor creamos otro nuevo array con los valores restantes.


Como vemos, son muy "rudimentarios" estas soluciones, pero gracias a la librería de Java nuestros problemas se harán realidad!

"Imagina un array que pudiese cambiar su tamaño cuando borremos cosas, un array al que solo basta con preguntarle si contiene el elemento que buscamos y que él nos conteste. Además de poder extraer elementos sin necesidad de saber en que posición está realmente."

Aquí es donde entra la Clase ArrayList, viene incorporada en la librería de Java (API) .

Declarando un ArrayList:
ArrayList <caja> miArrayList = new ArrayList <caja>

Lo que está entre < > es el tipo de objeto que vamos a introducir en Array. Recordar que es un array "automático" en el cual no tenemos que preocuparnos en la posición en la que se encuentran los objetos que agregamos, pero justo a causa de esto, tenemos que especificarle o, mejor dicho,  asegurarle al Array que lo que vamos a introducir son objetos de la MISMA CLASE.

Introduciendo valores:
caja a = new caja();
 miArrayList.add (a);

caja b = new caja();
 miArrayList.add (b);

Cuantas cosas hay en el array:
int elTamaño = miArrayList.size ();

Descubrir si contiene algún objeto:
boolean contiene = miArrayList.contains (b);

Descubrir en que posición se encuentra un objeto:
int donde = miArrayList.indexOf (b);

Saber si está vacio:
boolean vacio = miArrayList.isEmpty ();

Borrar algo del array:
miArrayList.remove (a);


Arrays vs ArrayList:

* Los arrays requieren que se le definan un tamaño, los ArrayList no.
* Los arrays usan una sintaxis que no se usa en ninguna parte más de java, me refiero a los corchetes [ ]
cuando decimos miArray [2] refiriéndonos a aquello que hay en la tercera posición del array [0][1][2]
* Para añadir algo a un array tenemos que elegir nosotros la posición en la que queremos añadirlo, en los ArrayList NO.
* A pesar de ello, los ArrayList tienen una "parametrización" (lo que va dentro de < >) que te obliga a introducirle dentro SOLAMENTE objetos de esa clase.
* Los ArrayList necesitan ser importados de la librería de java mediante el código:
import java.util.ArrayList;
al inicio del código.



Convertir un String a un Int

Esto se estudiará más adelante de una forma mucho más detallada pero como lo necesitamos para entender el código...

int guess = Integer.parseInt(stringGuess);

Pasamos la cadena de caracteres "stringGuess" a un "int", lógicamente la cadena de caracteres stringGuess debería ser un valor entero (sin decimales).



Función "For" mejorada y no mejorada.

Con la versión 5 de Java llegó una revolución a la función "for", que nos permitía ahorrarnos varios pasos facilitando la creación del código.

"for" clásico:

for (int i = 0; i < 10; i++) {
//Repetir esto 10 veces
 }


"for" mejorado:

for (String name: nameArray) { 

//Para cada valor del Array "nameArray" copia dicho valor en la variable name y recorre el array.

}

sábado, 23 de agosto de 2014

Aplicando un poco de CSS




Gracias a HTML hemos podido definir una estructura del contenido de la web, pero el estilo que lleva por defecto es horrible, es el momento de utilizar CSS (Cascading Style Sheets) que le va a decir al explorador como debe presentar esa información.
Para añadir estilo, deberemos añadir una nueva etiqueta: <style> </style>

Volvemos con el ejemplo del capítulo anterior:


<html>
<head>
<title>Menu de la Cafeteria de mi abuela</title>
<style type="text/css">
</style>

</head>
<body>
<h1>Cafes</h1>
<h2>Cafe largo, 0.70$</h2>
<p>Los lunes y martes a mitad de precio</p>
<h2>Cafe expresso, 1$</h2>
<p>Los viernes no hay</p>
</body>
</html>




Vemos que la etiqueta <style> tiene un atributo extra llamado type, que le dice al explorador el tipo de estilo que estamos usando. Es lógico, ya que si usamos CSS es para que seamos nosotros los que elijamos el tipo de estilo. *¿A que se referirá con "tipo de estilo"?

Vale, ahora a modo de ejemplo y como todavía no se absolutamente nada de CSS voy a poner un ejemplo ya hecho, por ahora no hace falta entenderlo. Ya mas adelante iré viendo que significa cada cosa:

<style type="text/css">
body {
background-color: #d2b48c;
margin-left: 20%;
margin-right: 20%;
border: 2px dotted black;
padding: 10px 10px 10px 10px;
font-family: sans-serif;
}
</style>


Vamos a guardar los cambios y volvemos a abrir el archivo .html



*Vaya, ahora se ve mucho mejor. 

Es hora de dar el siguiente paso, vamos a comenzar con los enlaces hacia nuevas páginas, porque con un simple menú de cafés no será suficiente, quizás el cliente quiera un menú de bocadillos... o de bebidas en general.

Vale, ahora vamos a hacer algo más complejo. 

*Antes de seguir, un dato que he estado mirando sobre los acentos: Los acentos aparecen con la codificación UTF-8, si lo tenemos codificado de otra forma no aparecerán.
también podemos conseguir las tildes de la siguiente forma:

á = &aacute
é = &eacute
í = &iacute
ó = &oacute
ú = &uacute
ñ = &ntilde
€= &euro

colocando esto nos aparece la tilde.
también, podríamos intentar colocando esta linea de código a todos los archivos html (Justo debajo de la etiqueta <head> pegamos esto:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 


Pero de esto último no lo he probado aún.

1) Vamos a descargar la carpeta que he preparado para este ejemplo del siguiente enlace: Descargar

2) Abrimos la carpeta y localizamos el archivo: "Menu.html" . Lo abrimos en el blog de notas.

El archivo Menu.html contiene lo siguiente:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 

<title> Menú del dia </title>
</head>
<body>

<h1> Hamburguesas especiales del día </h1>
<img src="imagenes/menu.png">
<p>
Con nuestros menús del día podrás disfrutar de 
todo el sabor de los mejores ingredientes locales
así como de una carne de exelente calidad.
Para acceder solo tienes que hacer clic <a                                     href="hamburguesa/hamburguesa.html">aquí</a>
</p>
<h2>Encuéntranos</h2>
<p>
Nos encontrarás en la localidad de Telde, para más información haz clic 
<a href="direccion.html">aquí también</a>.
Te esperamos!

</p>
</body>

</html>

Vale, aquí la novedad es lo que está coloreado:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 

Nos permitirá cambiar el formato del archivo a UTF-8 con lo que podremos mostrar las tildes, las ñ, etc, sin ningún problema.

<a href="hamburguesa.html">aquí</a>

De esta forma vamos a poder añadir ENLACES a otros archivos .html que tengamos.
Todos sabemos lo que es un enlace, haces click y te manda a otra página. 
Lo que hacemos aquí es crear un menú de hamburguesa (un poco cutre, si) en el cual nos dirige a otras dos páginas más, una llama hamburguesa.html y otra llama direccion.html .

*No sé exactamente donde tienen que estar localizados los archivos .html para que tu los puedas usar (crear un enlace), no se si basta con que estén dentro de tu disco duro o tienen que estar en la misma carpeta que el archivo desde el que se hace la "llamada"

Es importante ver la estructura del <a> </a> tenemos que poner href="nombreDelArchivoAlQueQueremosDirigirnos.html"
Lo que se encuentra dentro del <a> </a> es el texto que contendrá el enlace (el texto que se pone de color azulito).

Pero ¿Que demonios es eso que meten dentro de los simbolos < Etiqueta yAlgoMas>?!!! Vale, eso se llama ATRIBUTOS y sirven para especificar mucho más el contenido que va dentro de la etiqueta. Por ejemplo, imaginate que tenemos una etiqueta llama <casa></casa> (no existe, solo es un ejemplo) pues así, a secas, sería: <casa>miCasa </casa> 
Pero si yo quiero ser más específico, podría usar atributos, entonces podría decir:
<casa hacer="apartamento" color="azul" tamaño="mediana"> miCasa </casa>

¿Pillas la idea? Vamos siendo más específicos a la hora de definir el contenido de mi etiqueta.
En el caso de <a href="hamburguesa.html">aquí</a> 
el atributo href quiere decir "enlace" mas o menos.

Por otro lado tenemos: 

<img src="menu.png">

Con lo que podremos poner una imagen. (Importante poner la extensión del archivo, si es .jpeg, o .png o .gif etc...

Bueno, abrimos el archivo Menu.html y si tenemos los demás archivos (imágenes y .html) en la misma carpeta veremos un ejemplo de una web muy simple. Donde al hacer clic en los enlaces nos dirigimos a otras páginas.





Organización:

Seamos ordenados, así que a partir de ahora vamos a organizar los proyectos web de esta manera:

- Creamos una carpeta General con el nombre del proyecto ejemplo: WebMenu
- Dentro de esta carpeta vamos a guardar nuestro archivo principal (Menu.html) además vamos a crear una carpeta por cada archivo HTML extra que tengamos (hamburguesa.html y direccion.html) con el mismo nombre que el archivo (sin la terminación .html lógicamente).
- Vamos a introducir en cada carpeta, el correspondiente archivo HTML
- Además de estas carpetas, vamos a crear otra carpeta llamada "imagenes" donde efectivamente, vamos a meter las imágenes. 




Pero hay un pequeñito problema (esta era la duda que tenía antes)

Aparece un error muy feo:



El explorador no encuentra los archivos que NO estén en la misma carpeta. ¿Esto por qué ocurre?
Bueno, ocurre porque el explorador piensa que los archivos están en la misma carpeta que el archivo original... Esto es debido a que cuando escribimos:

<a href="hamburguesa.html">aquí</a> 

Le decimos al explorador "busca en mi misma carpeta otro archivo llamado hamburguesa.html"
que deberíamos hacer?, fácil, modificamos el código con la ruta del archivo. Es decir, 

- ¿Donde estamos? Estamos en el archivo Menu.html
- ¿Donde queremos ir? Queremos entrar en la carpeta hamburguesa y abrir el archivo hamburguesa.html


por lo tanto modificamos nuestro código así:
 <a href="hamburguesa/hamburguesa.html">aquí</a> 

<img src="imagenes/menu.png">

Todo perfecto!!! pero, un momento... Si hacemos clic en el enlace del archivo hamburgesa.html vemos el archivo html PERO SIN IMÁGENES! 



 En fin, continuaré con este tema más adelante, ahora toca seguir repasando Java que la tengo muy abandonada.
Un saludo!





jueves, 21 de agosto de 2014

Comenzando con HTML



Como paso fundamental en el conocimiento de la programación me llama mucho la atención conocer como funciona el mundo de Internet. Para ello voy a comenzar a estudiar paralelamente con Java las nociones básicas de HTML (seguramente muchas de las cosas que aprenderé estén algo desfasadas puesto que el libro que voy a usar (este) es del 2012, pero igualmente me sirve.
Destaco que la serie de libros de O`Reilly me ha gustado mucho, ojalá los demás libros sean igual de interesantes que el de Java que estoy actualmente estudiando.

Esquema general

Cuando accedemos a una web lo que estamos haciendo es, mediante el explorador de nuestro dispositivo (Internet explorer, firefox, chrome, safari,...) conectarnos con un servidor web (un ordenador que también está conectado a internet) el cual busca entre los archivos HTML (HyperText Markup Language)  que tiene hospedados hasta encontrar aquel que le estamos requiriendo, devolviéndolo nuevamente a nuestro explorador.


¿Que forma tiene un código HTML?

<table>
<tr>
    <td>Comprar mouse</td>
    <td align=right>$14.99</td>
</tr>
<tr>
    <td>Comprar comida</td>
    <td align=right>$20.00</td>
</tr>
</table>


Esto se vería así:

         Comprar mouse   $14.99
         Comprar comida  $20.00

En otras palabras, el código HTML contiene unas especies de etiquetas que le dicen al explorador como tiene que poner el texto.

"El explorador interpreta las "Tags" o etiquetas que contiene tu texto, estas tags informan al explorer acerca de la estructura y el significado 

"Los comentarios en HTML se colocan <!-- lo que querramos comentar --> "


Creando nuestra primera Web

Para crear una web podemos hacerla en cualquier editor de texto, por lo cual es mucho mejor, no tenemos que estar descargando mas cosas. La única cuestión es que después, al guardar el archivo, debemos colocarle un .html al final del nombre. De esta manera lo reconocerán los exploradores.

En el caso de que uses Windows  usaremos el Notepad. (Es importante que modifiquemos la opción de "Ocultar la extensión de archivos conocidos" o algo así. Lo podemos encontrar en Panel de Control --> Apariencia --> Opciones de Carpetas --> View o Vista --> en el menú de Opciones avanzadas desmarcar la opción.)

En el caso de Mac que es el que uso yo, usaremos TextEdit. (Debemos ir a Preferencias --> New Document --> marcar Plain Text (o texto plano) // también debemos ir a Preferencias --> Open and Save --> Marcar "ignore the rich text commands in HTML files" y desmarcar "Add ".txt" extension to plain text files".

De esta forma ya tenemos preparado el software para diseñar nuestra web.

Como recomendación, un amigo me ha dicho que es buena idea que programe HTML en el software Coda 2. Es para mac, es un programa orientado a la programación web en general. Voy a escribir el código en este editor de texto en principio, pero vamos, que es lo mismo.


Voy a escribir en el editor de Texto:


Menú de la Cafetería de mi abuela

Café largo, 0.70€
Los lunes y martes a mitad de precio


Café expresso, 1€
Los viernes no hay

*Lo voy a guardar con el nombre Index.html (para los que usen windows, en la opción de "encoding" elegiremos UTF-8)
*A partir de ahora, el código HTML irá resaltado con esta fuente de letra, así no habrá confusión.

Vamos ahora al explorador (yo uso el Google Chrome, creo que es el mejor actualmente), buscamos en archivo --> abrir archivo
Elegimos el archivo que hemos creado.

*----------------------------------------------
Menú de la Cafetería de mi abuela Café largo, 0.70€ Los lunes y martes a mitad de precio Café expresso, 1€ Los viernes no hay
*----------------------------------------------
A partir de ahora voy a colocar entre *---------------------------------------------- lo que aparece en el explorer, siempre que no sea algo demasiado grande, en cuyo caso le hago una captura de pantalla.
*Vaya, que cosa mas fea. Parece ser que no muestra los acentos correctamente.

Vale, ahora vamos a editar el archivo .html que hemos creado, abrimos nuevamente el editor de texto.

Recordar esto:

--------Básicas---------------------------
<h1> Cabecera </h1>
<h2> Subcabecera </h2>
<p> oraciones o paragraph </p>
-----------------------------------------------

-------No tan básicas---------------------
<html> Le dice al explorador que el contenido es html </html>
<head> Contiene info sobre tu web, le das al explorador información sobre tu web</head>
<body>  Contiene el cuerpo o contenido que se verá en la web </body>
----------------------------------------------

Modifico ahora el texto anterior con lo que he aprendido.

<html>
<head>
<title>Menú de la Cafetería de mi abuela</title>
</head>

<body>
<h1>Cafés</h1>
<h2>Café largo, 0.70€</h2>
<p>Los lunes y martes a mitad de precio</p>

<h2>Café expresso, 1€</h2>
<p>Los viernes no hay</p>
</body>
</html>

Le he añadido la línea <h1> Cafés </h1> para poder usar la etiqueta <h1></h1> de una forma mas clara.

Guardamos y abrimos con el explorador a ver que pasa.

*----------------------------------------------

Cafés

Café largo, 0.70€

Los lunes y martes a mitad de precio

Café expresso, 1€

Los viernes no hay

*----------------------------------------------

Vaya, las tildes siguen sin aparecer, bueno en principio voy a ignorarlas, mas adelante veré que pasa.
Hago lo mismo pero sin poner las tildes en el archivo .html

*----------------------------------------------

Cafes

Cafe largo, 0.70€

Los lunes y martes a mitad de precio

Cafe expresso, 1€

Los viernes no hay

*---------------------------------------------

Demonios!, ahora que le pasa al símbolo de euro?. bueno voy a quitarlo también, lo pongo en dólares.

*---------------------------------------------

Cafes

Cafe largo, 0.70$

Los lunes y martes a mitad de precio

Cafe expresso, 1$

Los viernes no hay
*---------------------------------------------

Vale, ahora sí. (^_^)


Por ahora he visto lo más básico de HTML, en la próxima entrada veré como funciona CSS para darle "estilo" a nuestra web además de muchas otras cosas. Nos vemos!





Juego de hundir la flota (Parte 1)




Hoy vamos a repasar la primera aplicación (juego) que he creado gracias al libro. Se trata de el clásico juego de Hundir la Flota. Cuando el juego comienza pide que se le introduzcan los valores de las casillas correspondientes donde queremos "atacar", si en esa casilla se encuentra alguna porción de barco (creado anteriormente por el programa) nos devolverá un "hit". Si por el contrario fallamos nos devolverá un "miss". Cada elección irá sumando un "intento" y al final, cuando hayamos conseguido hundir los 3 barcos nos saldrá el número de intentos. En esta primera parte solo voy a mostrar el código necesario para crear el juego, en la segunda parte explicaremos un poco como funciona.

El juego se compone de 3 clases, una de ellas se conoce como "GameHelper" y es la que nos va a crear los 3 barcos al inicio del programa de forma aleatoria. También será la encargada de recoger la petición del usuario en la consola. La clase GameHelper no vamos a estudiarla por ahora puesto que contiene código que aún no tengo ni idea muy bien como funciona.

Las otras dos clases son DotCom y DotComBust. Serán las encargadas de llevar el conteo de los intentos, mostrar los mensajes por pantalla en función de cada situación e iniciar el programa.

Vamos a comenzar por crear las 3 clases. 

No se si lo he dicho antes, la aplicación que utilizo para programar en Java es IntelliJ IDEA 13 CE, me parece una aplicación muy buena, al menos para las cosas básicas que estoy haciendo aquí.


Clase: DotCom

import java.util.*;
public class DotCom {
    private ArrayList<String> locationCells;
    private String name;

    public void setLocationCells (ArrayList<String> loc) {
        locationCells = loc;
    }

    public void setName (String n) {
        name = n;
    }

    public String checkYourself (String userInput){
        String result = "fallo";
        int index = locationCells.indexOf(userInput);
        if (index>=0) {
            locationCells.remove(index);

            if (locationCells.isEmpty()) {
                result = "Hundido!";
                System.out.println ("Joder tío, te has cargado a "+ name + "   : ( ");
            } else {
                result = "Tocado!";
            }
        }
        return result;
    }
}


Clase: DotComBust

import java.util.*;
public class DotComBust {

    private GameHelper helper = new GameHelper();
    private ArrayList<DotCom> dotComsList = new ArrayList<DotCom>();
    private int numOfGuesses = 0;

    private void setUpGame() {
        DotCom one = new DotCom();
        one.setName("Pets.com");
        DotCom two = new DotCom();
        two.setName("eToys.com");
        DotCom three = new DotCom();
        three.setName("Go2.com");

        dotComsList.add(one);
        dotComsList.add(two);
        dotComsList.add(three);

        System.out.println("Tu objetivo es hundir los tres punto coms.");
        System.out.println("Pets.com, eToys.com, Go2.com");
        System.out.println("intenta hundirlos a todos en el menor número de intentos");

        for(DotCom dotComToSet:dotComsList){
            ArrayList<String> newLocation = helper.placeDotCom(3);
            dotComToSet.setLocationCells(newLocation);
        }
    }

    private void startPlaying() {
        while (!dotComsList.isEmpty()) {
            String userGuess = helper.getUserInput("Atacar a la casilla: ");
            checkUserGuess(userGuess);
        }
        finishGame();
    }

    private void checkUserGuess(String userGuess) {
        numOfGuesses++;
        String result = "Fallo";

        for (DotCom dotComToTest : dotComsList) {
            result = dotComToTest.checkYourself(userGuess);
            if (result.equals("Tocado!")) {
                break;
            }
            if (result.equals("Hundido!!!")) {
                dotComsList.remove(dotComToTest);
                break;
            }
        }

        System.out.println(result);

    }

    private void finishGame() {

        System.out.println("Tío, te has cargado todos los punto coms!");
        if (numOfGuesses <= 18) {
            System.out.println("Necesitastes " + numOfGuesses + " intentos");
            System.out.println("Eres un jodío crack tío!.");
        } else {
            System.out.println("Necesitastes. " + numOfGuesses + " intentos.");
            System.out.println("Los pobres peces te quieren dar las gracias por animarles el mar.");
        }


    }

    public static void main (String [] args) {
        DotComBust game = new DotComBust();
        game.setUpGame();
        game.startPlaying();
    }


}



Clase: GameHelper

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.*;
import java.util.ArrayList;

public class GameHelper {

    private static final String alphabet = "abcdefg";
    private int gridLength = 7;
    private int gridSize = 49;
    private int [] grid = new int[gridSize];
    private int comCount = 0;

    public String getUserInput(String prompt) {
        String inputLine = null;
        System.out.print (prompt +" ");
        try {
            BufferedReader is =new BufferedReader(new InputStreamReader(System.in));
            inputLine = is.readLine();
            if (inputLine.length() == 0) return null;
        } catch (IOException e) {
            System.out.println ("IOException: " + e);
        }
        return inputLine;
    }

    public ArrayList<String> placeDotCom (int comSize) {
        ArrayList<String> alphaCells = new ArrayList<String>();
        String [] alphacoords = new String [comSize];
        String temp = null;
        int [] coords = new int [comSize];
        int attempts = 0;
        boolean success = false;
        int location = 0;

        comCount++;
        int incr = 1;
        if ((comCount % 2) ==1){
            incr = gridLength;
        }

        while ( !success & attempts++ < 200) {
            location = (int) (Math.random() * gridSize);

            int x= 0;
                success=true;
            while (success && x < comSize) {
                if (grid[location] == 0) {
                    coords [x++] = location;
                    location += incr;
                    if (location >= gridSize) {
                        success= false;
                    }
                    if (x>0 && (location % gridLength == 0)) {
                        success = false;
                    }
                } else {
                    success = false;
                }
            }
        }

        int x = 0;
        int row = 0;
        int column = 0;

        while (x< comSize) {
            grid [coords [x]] = 1;
            row = (int) (coords [x] / gridLength);
            column = coords [x] % gridLength;
            temp = String.valueOf ( alphabet.charAt(column));

            alphaCells.add(temp.concat(Integer.toString(row)));
            x++;

        }
        return alphaCells;
    }

}




Cuando iniciamos el juego, nos pide que introduzcamos una casilla. Los inputs (valores que debemos introducir) son del estilo "a0, a1, a2, ..., a6" .... "f0, f1,..., f6"






miércoles, 20 de agosto de 2014

Arrays y variables locales

Comportamiento de los objetos en un Array


Volviendo nuevamente con los Arrays voy a estudiar como se comporta un Array formado por objetos.
Se comportan como cualquier otro objeto (valga la redundancia), la única diferencia es el acceso a dichos objetos.

// Ejemplo
//Declaramos un array que contenga 7 referencias Perro.

Perro [] mascota;
mascota = new Perro [7];

// Creamos dos nuevos objetos Perro y le asignamos los dos primeros elementos del array

mascota [0] = new Perro ();
mascota [1] = new Perro ();

// Podemos llamar los métodos de los objetos creados;

mascota [0]. setAltura (30); //Suponemos que ya hemos definido los getters y setters
int x = mascota [0]. getAltura ();
mascota [1]. setAltura (8);
...

lógicamente, en los espacios de array en los que no hayamos introducido nada no podremos llamar ningún método (lógico, si no hemos metido nada).
mascota [4].setAltura (8)... No funcionará porque no hemos metido un "new Perro()" ahí.

Valores por defecto

Ya sabemos que una variable necesita al menos un nombre y un tipo y que podemos inicializarla al mismo tiempo que la declaramos.

int altura = 30;

Pero cuando NO inicializamos una variable (no le asignamos un valor) ¿que ocurre cuando llamamos un método getter?. En otras palabras, ¿Cuál es el valor de las variables antes de iniciarlas?

Antes que nada hay que saber que diferenciar 2 tipos de variables. Las "Instance variables" y las "Local variables" .

Instance variables: Son las que hemos visto hasta ahora, las que declaramos antes de comenzar a definir los métodos.
Local variables: Son las que están declaradas e inicializadas al mismo tiempo dentro de un método, es decir... 

Ejemplo de Instance variable:


 

Ejemplo de Local variable:



Es interesante resaltar que la variable (y) y la variable (z) deben ser declaradas he inicializadas antes del método (fuera del método)

La razón por la cual diferencio entre estos dos tipos de variables es porque la primera (Instance variable) se carga al mismo tiempo que el programa comienza a ejecutarse (vamos, que desde que abrimos el programa estas variables YA TIENEN UN VALOR, aunque no se lo hayamos puesto nosotros. Mientras que para las variables Locales, no ocurre esto. Si en lugar del código anterior, hubiéramos puesto esto:



Vemos como la variable localVariable no está inicializada, por tanto no podemos mostrarla en la consola. Esto ocurre porque cuando java "arranca" un código, "carga" por decirlo así, todas las clases pero NO carga los métodos hasta que sean "llamados" por alguna linea de código. De ahí que las variables que van dentro de un método no tengan un valor predeterminado como lo tienen las instanciadas.

Como he dicho, para las "instance variable" no ocurre así. Los valores que le da java a las diferentes variables según su tipo es el siguiente.

integers = 0 
floating points = 0.0 
booleans = false 
references = null 

Reflexión sobre nomenclatura anglosajona

Desde el comienzo del blog he intentado emplear una nomenclatura en castellano para intentar entender mejor lo que iba pasando, pero a medida que avanzo me doy cuenta de que será mejor comenzar a llamar a las cosas por su nombre original (en inglés).

Por lo tanto a partir de ahora voy a hacer eso mismo, llamar a las cosas por su nombre tal y como fue escrito (Y como lo escriben en el libro) .

También pedir perdón por no haber escrito nada desde hace semanas, es que las vacaciones hay que disfrutarlas, aunque sea un poquito.

lunes, 28 de julio de 2014

Encapsulación

Encapsulación:

Hasta ahora no hemos caído en el detalle de que no siempre queremos que se acceda a un objeto creado por nosotros (mediante el operador "punto"). Hemos estado creando variables que están "expuestas" a ser modificadas en otro lugar del código y no siempre vamos a querer esto.

Un ejemplo sería el de una variable, por ejemplo:

elGato.altura = 30;  //que en un inicio tenemos ésta variable con un valor de 30 cm.

elGato.altura = 0; //cambiamos el valor a 0. Esto hay que evitarlo a toda costa puesto que un gato nunca va a medir "0" cm.

Para evitar estas modificaciones de variable que no corresponden con el objetivo de la variable hacemos una encapsulación.

public void setAltura (int al) {
   if (al > 9) {
      altura = al;
   }
}
Vemos que dentro del propio método setter colocamos un condicionante.

Ocultando los datos:

Podemos ocultar nuestros datos escribiendo "public" o "private". La regla de oro de la encapsulación: 

Haz "private" tus variables instanciadas
Haz "public" tus getters y setters.


Ejemplo de "Encapsulating":

El ejemplo lo copio del libro:

class GoodDog {

  private int size;

  public int getSize () {
   return size;
{

public void setSize (int s) {
  size = s;
}

void bark () {
  if (size > 60) {
   System.out.println ("Woof! Woof");
} else if (size >14) {
   System.out.println ("Ruff! Ruff!");
} else {
   System.out.println (" Yip! Yip!");
    }
  }
}

class GoodDogTestDrive {

   public static void main (String [] args) {
    GoodDog one = new GoodDog ();
    one.setSize (70);
    GoodDog two = new GoodDog ();
    two.setSize (8);
    System.out.println ("Dog one :" +one.getSize () );
    System.out.println ("Dog two: " + two.getSize () );
    one.bark ();
    two.bark ();

 }
}




  

Comportamiento de Objetos

Hemos visto que los objetos tienen "estados" y "comportamientos" representados mediante "variables de referencia" y "métodos", ahora vamos a ver de que forma podemos relacionar estos dos elementos.

Se podría decir que: Los métodos usan los valores de las variables de la clase.

Un ejemplo claro es:

class Perro {
int altura;
String nombre;

void ladrar () {
if (altura > 60) {
System.out.println("que grande soy");
} else if (altura >15) {
System.out.println("bueno, no soy tan pequeño");
} else {
System.out.println ("vaya marrón");
}
}
}
class PerroTestDrive {

public static void main (String[] args) {
Perro uno = new Perro ();
Perro dos = new Perro ();
Perro tres = new Perro ();
uno.altura = 70;
dos.altura = 8;
tres.altura = 35;

uno.ladrar();
dos.ladrar();
tres.ladrar();
}
}

Vemos como el método puede utilizar las variables definidas en su código.


Enviando cosas al objeto:

Podemos pasar valores a los métodos, por ejemplo, podríamos decir:

Perro uno = new Perro ();
uno.ladrar (3);                //Donde el 3 es el argumento

void ladrar (int numeroDeLadridos) {    //Donde numeroDeLadridos es el parámetro)

while (numeroDeLadridos > 0) {
System.out.println ("Jáu Jáu");
numeroDeLadridos = numeroDeLadridos -1;
}
}

 Recibiendo cosas de un método:


Hasta ahora hemos visto métodos que no devolvían nada, es el caso de:

void ejemplo () {
}

Pero podemos también declarar métodos que devuelvan un tipo de valor específico:

int devuelveAlgo () {

     return 10;
}
// Debemos tener una variable que pueda almacenar el valor que nos devuelve el método, en este caso es un valor entero, por lo tanto podremos decir que:

int dameLoQueDevuelves = unaClase.devuelveAlgo;


Mandando más de una cosa a un objeto:

Podemos enviar mas de una variable a la vez;

void unMetodo () {

   nuevoObjeto nuevo = new nuevoObjeto ();
   nuevo.tomaDos (10, 20);
}

void tomaDos (int x, int y) {

   int z = x + y;
   System.out.println ("El total es " + z);
}

El 10 se corresponde con la x y el 20 con la y.

* Podemos enviar también variables que contengan el valor deseado:

void unMetodo () {

   int uno = 10;    // Creamos unas variables nueva
   int dos = 20;
   nuevoObjeto nuevo = new nuevoObjeto ();
   nuevo.tomaDos (unodos);
}

void tomaDos (int x, int y) {

   int z = x + y;
   System.out.println ("El total es " + z);
}


Un detalle a tener en cuenta es que el argumento no está conectado con el parámetro, es decir, una vez que le pasemos el valor de uno y dos al método tomaDos (int x, int y) El valor que tenga x e y no modificarán el valor de uno y dos. Es decir, el valor de uno y dos se "copia" en los valores de x e y. A partir de ese momento todo lo que hagamos con x e y no influirá en el valor inicial de uno y dos.


Getters y Setters:

Los getters y setters te permitirán obtener y establecer/definir cosas. Valores de variables instanciadas por lo general. La estructura generar que se emplear es:

Ejemplo:

class GuitarraElectrica {

  String marca;
  int numeroDeGuitarras;
  boolean artistaLaUsa

//Esto es un Getter
String getMarca () {
  return marca;
}

//Esto es un Setter
void setMarca (String aMarca) {
  marca = aMarca;
}

//Lo hacemos con cada una de las variables
 int getnumeroDeGuitarras () {
  return numeroDeGuitarras;
}

void setNumeroDeGuitarras (int num) {
numeroDeGuitarras = num;
}

//Y con la ultima:

boolean getArtistaLaUsa () {
   return artistaLaUsa;
}
void setArtistaLaUsa (boolean siONo) {
artistaLaUsa = siONo;
}
}



domingo, 27 de julio de 2014

Las Variables

He visto que las Variables son "cosas" que guardan otras "cosas".
Hay dos tipos de variables: variables primitivas y variables referenciadas.

Declarando variables:

En primer lugar hay que tener en cuenta que las variables se preocupan por el "tipo", es decir, no podemos crear una variable float (variable con valores decimales) y luego introducirla dentro de una variable tipo integer (variable sin valores decimales) .
Como ya dije, hay dos tipos de variables, las primitivas que almacenan valores fundamentales (un entero, flotante, boleano...) y las referidas a objetos almacenan precisamente referencias a objetos... esto ya se verá mas adelante ;-(

Las variables deben tener siempre un tipo y un nombre.

por ejemplo: int number; (donde int es el tipo y number es el nombre).

Imaginando variables:

Se debe imaginar una variable como un vaso o una taza... un contenedor en definitiva.

Cada vaso tiene un tamaño y un objetivo, existen vasos de pequeños, grandes, incluso muy grandes, cada cual para un objetivo diferente.

En java ocurre algo similar, cuando vamos a definir una variable, tenemos que elegir el "tamaño" de esa variable sabiendo de antemano lo que vamos a meter en ella.







Variables primitivas:

boolean y char:

boolean:  true o false
char: 16 bits es decir desde 0 hasta 65535 

numeric:

integer   byte   8 bits
             short   16 bits
             int       32 bits
             long    64 bits

floating point   float    32  bits
                        double 64 bits

Nombres prohibidos:

Una vez sepamos el tipo de variable que vamos a necesitar, debemos elegir un nombre que deberá cumplir con las siguientes reglas:

* Debe comenzar con una Letra, barra baja, o símbolo de dólar $. Nunca deberemos comenzar con un número.
* Después de la primera letra podremos usar números también.
* Puede ser cualquier palabra, siempre que no sea una de las palabras reservadas de Java.

Algunas de las palabras reservadas se muestran en la tabla.


boolean
byte
char
double
float
int
long
short
public
private
protected
abstract
final
native
static
strictfp
synchronized
transient
volatile
if
else
do
while
switch
case
default
for
break
continue
assert
class
extends
implements
import
instanceof
interface
new
package
super
this
catch
finally
try
throw
throws
return
void
const
goto
enum

Controlando los objetos


Ya sabemos declarar variables y asignarles un valor, pero ¿Que hay de las variables no primitivas?, es decir, de los objetos.
Los objetos no son como las variables anteriormente vistas, en este caso se guarda una "dirección" al contenido en lugar del contenido mismo.

Es decir, debemos entender una variable objeto como algo que NO contiene el objeto, si no como algo que le dice al compilador donde encontrar ese objeto... Algo parecido a un control remoto.

Esta "llamada" al objeto se realiza mediante el símbolo "punto" ( . ) como en el siguiente ejemplo.

miPerro.ladrar () ;

Usa el objeto referenciado por la variable "miPerro" para invocar el método "ladrar".

En resumen: Las variables primitivas almacenan el valor que le hemos asignado mientras que las variables de referencia almacenan un valor que nos direcciona hacia un objeto específico.

Los Array

Los arrays son variables que almacenan otras variables. Un array es una estructura matricial con una sola fila (o una sola columna) que almacena variables ya sean bien variables primitivas o variables de referencia (pero no las dos a la vez).

Para declarar un array hacemos lo siguiente:

- int [] numeros; //Declaramos un array de variables enteros (int), como mismo hacíamos con los objetos
- numeros = new int [7];  //Creamos una instancia de ese array con una longitud de 7 y se lo asignamos a "numeros"
- //Le añadimos a cada espacio del array su valor:

numero [0] = 2;
numero [1] = 4;
numero [2] = 1;
numero [3] = 6;
numero [4] = 2;
numero [5] = 8;
numero [6] = 4;

Notar que el array en sí mismo es un objeto, a pesar de que los 7 elementos que contenga son primitivos.
En lugar de emplear valores primitivos, podríamos haber rellenado el array con otros objetos. En cuyo caso en lugar de poner: numero [1] = 4; deberíamos poner numero [1] = new loQueSea (); debemos crear un objeto y asignarlo a la variable.