Snake (Java)

aNuBiS

Hola!, pues si, como pensais estais ante otro de esos "maravillosos" y didacticos ejercicios que nos mandan en la facultad sin habernos dado lo necesario para terminarlos...Una joyita.

Andamos haciendo un snake, jueguecito de la serpiente, y en principio he diseñado todas las clases siguiendo la practica pero tengo problemas a la hora de juntarlo:

public class Laberinto {

Casilla[][] tablero;
Serpiente serpiente;
Raton[] raton;
int puntuacion;
Record record;

public Laberinto (){	
	tablero = new Casilla[30][30];		
	for (int a = 0; a < 30; a++){
		for (int b = 0; b < 30; b++){
			tablero[a][b] = new Casilla ("vacio",a,b);
						}
	}

	serpiente = new Serpiente ();

¿Esto estaria bien hecho? Entiendo que asi crearia un array bidimensional de objetos casilla y despues en cada hueco del array crearia un tipo casilla con el constructor definido (por ejemplo)...Pero asi me da un error al crear la posicion x,y de la casilla en cuestion...Y en el debug aparece el valor como tablero [30][] ¿Eso es que no toma los dos valores o siempre sale asi?

Como veis no pido que me hagais la practica ni nada de eso, solo es para ver si me podeis echar una mano con las dudas que me vayan surgiendo, gracias :P.

JuAn4k4

for (int a = 0; a < 30; a++){
for (int b = 0; ->a<- < 30; a++){

Ahi esta el problema, de nada ; )

erdanblo

Esos fallos son los tipicos que posteo yo xD.

aNuBiS

#2 y #3 Corregido y gracias, pero ese no era el problema ya que el problema se daba para a = 0 y b = 0...Por lo tanto seguimos en las mismas...El constructor de casilla es:

// Constructor 
public Casilla (String a, int b, int c) { 
	setTipo (a);
	pos.setX(b);
	pos.setY(c);
} 

Tipo es muro o vacio, y pos es un atributo (Posicion pos;) que tiene como atributos x e y...Entonces el problema lo da al entrar al constructor de casilla y poner el setX se queda pillado dando un error de fuera del array o algo asi...Pero claro, el compilador no da ningun error y no se si es que lo planteo mal, o que le pasa...

IAF

Pues en el setX que hay ?
En el 2o for sigue habiendo un error, incrementas a en vez de b

JuAn4k4

pos = new posicion(b,c); ?
#5 cierto mira, yo encontre un error y pare xD

PD: Madre mia que identificadores de parametros mas identificativos.

aNuBiS

#5 El set es un public void setX (int a) {
x = a;
}
Vamos, que hace que la x tenga el valor que se le pase (a).
Por eso digo que es mas simple que na...No se por que falla.

Sobre el otro "a", hice c&p para probar y lo deje asi, pero como dije falla en 0, asi que no es por el bucle, pero gracias, que luego ni lo hubiera revisado.

#6 Joder, yo era de los que ponian letras, pero entre que casi nos obligan a poner los id tan claritos y sobretodo, que despues de meses miro mis codigos y ni me enteraba, corte por lo sano..Jajaja

MTX_Anubis

#7 porque no tienes creado el objeto pos xD
// Constructor
public Casilla (String a, int b, int c) {
setTipo (a);
pos = new Posicion();
pos.setX(b);
pos.setY(c);
}
o mejor haz una constructora como ha dicho juanaka ;P

Pero vamos, eso viendo las excepciones que te da deberías darte cuenta rápido

En java son todo punteros menos los int, char, float, etc. (que me hace gracía eso de que me decían "como mola java, no tiene punteros"), antes de acceder a un objeto pues tienes que crearlo xD

Tú haciendo un snake, otro con el parchís y yo con un hundir la flota que acabará siendo un juego de la guerra de las galaxias por lo menos xD

cabron

Off topic:

#8:

Java no tiene punteros. Un puntero es una dirección de memoria.

Java tiene referencias a objetos.

aNuBiS

#8 Claro, esa era una de las cosas que preguntaba...Yo tenia declarado como atributo: Posicion pos; Entonces...¿no puedo utilizar directamente un atributo pos? Tendria que crear el pos como un objeto y darle valores con el constructor POR HUEVOS ¿no? Es que ya os digo no hemos dado demasiado de esto y no se que se puede hacer y que no.

Sobre los errores, pues yo no lo veo tan claro, lo he puesto con el constructor y ya no se queja "tanto" pero da estos errores:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 30
at Laberinto.<init>(Laberinto.java:15)
at Jugar.main(Jugar.java:5)

En laberinto se queja de esta linea:

			tablero[a][b] = new Casilla ("vacio",a,b);

Y en jugar, pues como solo tiene la creacion de tablero pues... nada relevante.

Por lo tanto volvemos a #1...¿Eso esta bien hecho? Se puede crear un array de Objetos pero luego se tendira que ir creando el objeto en cada hueco? o comor..?

Gracias por vuestra paciencia

MTX_Anubis

#9 siempre tienes que poner la puntilla a todo? :(

Creo que se me entendió perfectamente lo que quería decir pero sí, vaya, tienes razón. Como siempre xD

cabron

#11:

Hombre, es que dijiste que sí hay punteros, y no hay, por eso lo decía xD

#10:

Te lo ha comentado ya #8, pero te lo extiendo un poco más.

En java los objetos se instancian con el operador new, en plan new Miclase()

Ahora si tú coges y pones:

new Miclase();

El objeto que acabas de crear se pierde en la nada. Para que puedas utilizar el objeto, necesitas hacer referencia a él de alguna forma, y para eso sirve Miclase miobjeto, quedando así:

MiClase miObjeto = new Miclase();

new MiClase() creó el objeto, y MiClase miObjeto es la referencia, y con el operador = haces que la referencia apunte al objeto, y por tanto puedes manipular el objeto a través de esa referencia.

Pero si solo pones MiClase miObjeto; no has creado ningún objeto, solo tienes una referencia, que no referencia a nada...

La excepción son los tipos de datos primitivos (int, char, boolean), donde en ese caso al poner:

int a;

Si que has creado ya un int.

Sobre esta excepción:



Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 30

Te dice que te has salido de los límites del array. Has intentado acceder a la posición 30, cuando las posiciones van de 0 a 29.

MTX_Anubis

#10 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 30

ese 30 te está diciendo que intentas acceder a la posición 30 del array, mira a ver que tienes por ahí que te lleva a la casilla 30. Usa el debugger a ver, lo que tienes en #1 está bien, doy por hecho de que en tu practica lo tienes igual xd

Sobre lo otro pues sí, como ha dicho cabron, en java todo son referencias a objetos (menos los tipos primitivos vaya) así que si declaras una referencia después tienes que crear el objetoo decirle que apunte a algun objeto ya creado. Por ejemplo puedes hacer esto:

casilla a1 = new casilla("vacio",x,y);
casilla a2 = a1;

a2 no es una copia de la casilla a la que apunta a1, a2 y a1 tratan con el mismo objeto. Los cambios que le hagas desde a2 afectan a esa casilla.

aNuBiS

#12 y #13 Gracias, creo que me ha quedado claro...Es que al principio pensaba que si tenias una clase creada podias definir "algo" con las propiedades de esa clase sin crear el objeto, royo a los tipos basicos vaya...Pero todo claro ahora :P.

Y lo del Array es el problema, si el error en si, lo entiendo, pero cuando uso el debug el error sale cuando intenta acceder a "tablero[0][0]" ¿como ******* se queja de la posicion 30?! No es posible, por eso pensaba que habia alguna otra cosa mal, asi que nada, ya seguire revisando que hoy nos dan un poco mas de teoria XD (Odio esto xD)

Soltrac

Copia todas las clases juntas como las tengas, porque no logro ver el error así.

aNuBiS

#15 Gracias!, pero aun no es el momento, jajaja.

No se si os importara, pero yo seguire poniendo mis progresos por aqui...En la ultima clase que tuvimos ya nos enseñaron a usar objetos, que habia que crearlo dentro de la clase si era un tipo objeto, blablabla y en resumen, todo lo que me habiais dicho.

Pero claro, me seguia dando errores el array de Objetos, y me ha dado por buscar y bingo, mismo problema, hay que crear los objetos dentro del array, no sirve con decir "array de objetos" por que estara vacio... Asi que nada...Sigo con ello!!

[editado]

Bueno, esto ya va cogiendo algo mas de rumbo, despues de toquetear aqui y alla ya he conseguido que por lo menos parezca un snake, imprime la serpiente donde deberia salir y los muros...Algo es algo! jajaja.

B

#12

new MiClase() creó el objeto, y MiClase miObjeto es la referencia, y con el operador = haces que la referencia apunte al objeto, y por tanto puedes manipular el objeto a través de esa referencia.

Te pillamos! juas xDD

Os he dicho ya que reniego de java? xD

14 días después
aNuBiS

Hola otra vez!,

Ya esta terminada!!, o por lo menos funciona, jajaja.
Estoy con las partes opcionales y una de ellas es utilizar ficheros, un archivo que guarde el ranking de los mejores jugadores, que lo mustre al finalizar y grabe en el la puntuacion. Pero como no hemos dado ficheros ando bastante perdido, de momento nos han dado codigos de ejemplo para leer y grabar en fichero, y hacerlo lo hace, pero tengo problemas segun tenia planteado el ranking.

public void mirarRecord(){
jugador = new Jugador ();
// Se inicializa la lista
/**record.jugador[0] = new Jugador ("Letto", 1000);
record.jugador[1] = new Jugador ("Oz4ma4", 1000);
record.jugador[2] = new Jugador ("Cabron", 500);
record.jugador[3] = new Jugador ("Cosma", 300);
record.jugador[4] = new Jugador ("Ottel", 200);*/

	
	System.out.print ("Introduce tu nombre: ");
	jugador.setNombre(leerTeclado());
	jugador.setPuntuacion(puntuacion);
		
	/**for (int a = 0; a < record.jugador.length; a++){
		System.out.println ((a+1) +" - " +record.getJugador(a));
	}*/
	}

Cuando no tenia lo del fichero creaba un objeto record, que a su vez tenia un array de jugadores, los creaba para que no estuvieran vacios y si hacia mas puntos lo actualizaba.

Ahora con el fichero funciona bien, muestra el top, sustituye la puntuacion y jugador y graba el fichero, pero claro, cada vez que ejecuto este metodo me vuelve a poner los 5 que estan ahi...

La pregunta: ¿Como puedo hacer para que ese array se llene con los datos del archivo? Es algo relacionado con leer fichero claro, pero como son objetos que tiene nombre y puntuacion por separado...Eso no lo guarda el array...Se os ocurre alguna forma?.

Aqui el codigo ya cambiado que nos dieron para leer:

void leerFichero(){
//Creamos el flujo de entrada con FileReader
//Usamos el constructor que recibe un objeto de tipo String para el nombre del fichero
try {
FileReader flujoEntrada= new FileReader ("texto1.txt");
//Conectamos la salida del flujo de entrada con el búfer
BufferedReader bufer = new BufferedReader (flujoEntrada);
//BufferedReader implementa un método String readLine() para leer líneas enteras
String cadena="";
//readLine devuelve null cuando llega al final del fichero (EOF)
while (cadena!=null) {
cadena=bufer.readLine();
if (cadena!=null) System.out.println(cadena);
}//fin while
//cerramos los flujos
bufer.close();
flujoEntrada.close();
}
catch (FileNotFoundException e){
System.out.println("Error al abrir el fichero");
}
catch (IOException e){
System.out.println("Error al leer el fichero");
}

Gracias como siempre :p

MTX_Anubis

Mira el API de java pero vamos, una vez tienes el string es sacar el index del espacio y hasta ahí, pasarselo como nombre, saltas el espacio y lo otro lo transformas a integer. Creas jugador con esos datos.

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html

Algo así por ejemplo aunque lo mismo hay mejores maneras, no conozco muy bien el api de java xD

int cont=0;
cadena=bufer.readLine();

while (cadena!=null) {
int index=cadena.lastIndexOf(' ');
record.jugador[cont] = new Jugador(cadena.substring(0,index-1),Integer.parseInt(cadena.substring(index+1)));
cont++;
cadena=bufer.readLine();
}

aNuBiS

Yep, mas o menos lo entiendo, y lo he intentado implementar pero no me chuta, ahora mismi lo tengo asi:

// Leer fichero
public void leerFichero(){
int a = 0;
//Creamos el flujo de entrada con FileReader
//Usamos el constructor que recibe un objeto de tipo String para el nombre del fichero
try {
FileReader flujoEntrada= new FileReader ("texto1.txt");
//Conectamos la salida del flujo de entrada con el búfer
BufferedReader bufer = new BufferedReader (flujoEntrada);
//BufferedReader implementa un método String readLine() para leer líneas enteras
String cadena;
cadena=bufer.readLine();
//readLine devuelve null cuando llega al final del fichero (EOF)
while (cadena!=null) {
int index=cadena.indexOf(' ');
jugador[a] = new Jugador(cadena.substring(0,index-1),Integer.parseInt(cadena.substring(index+1)));
a++;
cadena=bufer.readLine();
if (cadena!=null) System.out.println(cadena);
}//fin while
//cerramos los flujos
bufer.close();
flujoEntrada.close();
}
catch (FileNotFoundException e){
System.out.println("Error al abrir el fichero");
}
catch (IOException e){
System.out.println("Error al leer el fichero");
}
}

Y en el fichero:

Lalala 0
Lelele 0
Lolol 0
lili 0
juas 0

Pues bien, asi solamente muestra 4 de los 5, y ademas va acortando letras no se porque, y si tengo alguna burrada, lo siento, pero es que de esto 0 patatero :S.

Gracias anubiz :*

Ej. como ha quedado despues de varias pruebas:

Anubis 0
Anubi 0
Anub 0
Lal 0
Lel 0

Y el caso es que el primero lo guarda bien, pero los demas, los va acortando...

cabron

anubis, si tienes un objeto (en este caso un ojbeto jugador), y quieres guardarlo en disco y luego recuperarlo, lo que te interesa es la serialización, que básicamente, hace eso, te guarda un objeto en un archivo tal y como lo tienes en memoria, y luego te permite recuperarlo del disco a memoria.

No he usado nunca la serialización en Java, pero si en PHP, y el concepto viene a ser el mismo. He estado echando un ojo a este tutorial: http://java.sun.com/developer/technicalArticles/Programming/serialization/ y no creo te resulte complicado, yo le daría un intento, te ahorras todo el problema de los substrings para leer bien las líneas, y luego recrear el objeto a partir de lo que has leído del fichero.

B

Desde luego el método que propone cabron es muy recomendable.

Yo lo hacía así para guardar objetos que contenían floats, comboxes etc, y va como un tiro. Basicamente haces al objeto "serializable" guardando en byte a byte (es obvio sin más xD) de lo que ocupa en memoria.

aNuBiS

Pfff...Tengo una saturacion bastante considerable y tendre que mirarmelo detenidamente...Pero asi a priori me parecia mas sencillo el metodo "a lo bruto" de ir guardando substrings. Aun tengo hasta el domingo asi que ya ire comentando xD.

MTX_Anubis

#23 creeme, es mejor serializando xD. Prueba a ver cambiando los index-1 o +1 que en java no he tratado con substrings ni nada de eso nunca sí que no sé. Yo también tenía una parte opcional en la última practica con ficheros y sudé de hacerla, los odio :(

para que te muetres los 5 en vez de 4, pon el System.out.println(cadena) antes de volver a leer del buffer que si no te comes el primero y además quita el

if (cadena!=null)

que ya no hace falta

aNuBiS

#24 ¡Eso era! Veia mucho readBuffer pero no entendia que hacia cada uno, poniendolo detras del primero ahora si que muestra los 5.
Para el tema de la letra cortada era por el index-1, el index empieza en el espacio, donde tiene que empezar, asi que era index a secas.

Y el != null si que es necesario, si no muestra las 5 posiciones mas 1 null al final :S No tengo ni idea de por que.

Y con esto y un bizcocho...Amen :_). En estos dias supongo que la repasaremos, meteremos pijotadas y tal, pero vamos, que mola mil que por fin salga, jajaja.

Muchas gracias a todos.

erdanblo

Nada mas que he leido lo de serializarlo, solo decir que es fácil, implements serializable y ya esta :P

Tengo un ejercicio hecho con eso, si te interesa te lo paso.

R

Si esto te satura no te quiero imaginar en un proyecto real que tengas que hacer en tiempo record.

Tampoco entiendo que se aprende si te lo dan así de "masticado".

aNuBiS

#27 Entiendo que un proyecto REAL lo tendre que hacer cuando tenga las herramientas necesarias para ello, o si no, tenga los recursos...En este caso cuando empece a hacer la practica no tenia esos recursos, y cuando estaba con lo de ficheros, tampoco...Por eso pido ayuda para que me expliquen como leer ficheros.

¿Masticado? No lo se, pero enseñandome el codigo ya puedo entender como funciona y como leer desde ficheros, en vez de buscar por internet he pedido que alguien me lo enseñe/explique...¿En algun momento he dicho: Hazme esto? Creo que no, de todas formas contaba con que salia gente asi...descuida :P.

R

precisamente de java es de lo que más documentación encontrarás por la red, poniendo las palabras mágicas en google "ficheros java" te saldrán 4000 páginas (en español) de mini-tutoriales muy sencillos para tratar con ficheros.

No se si te refieres a eso como herramientas necesarias o recursos, pero realmente no necesitas nada más que paciencia.

Y no te lo tomes a mal porque no te estoy metiendo mierda en ningún momento, solo te motivo a que lo saques por tu cuenta, la única razón por la que trabajo como programador es la satisfacción de conseguir algo costoso que al principio lo veías muy negro, esa sensación de sentirse "útil" por así decirlo es única.

Ánimo y perdoname si te ha molestado el 'tono' de mi anterior mensaje.

aNuBiS

#29 No hombre, entiendo tu postura y yo estoy de acuerdo. Busque en google, pero no me terminaba de quedar claro como pasar del fichero a un objeto (Y era una tonteria claro, pasar los "parametros" directamente como los substring...Ahora lo entiendo) y ya te digo, no queria que cogieran y me lo hicieran (aunque anubis se lo curro jaja). Tambien hay que tener en cuenta que es epoca de entregar trabajos, estudiar, navidades...Y no tengo todo el tiempo que desearia para andar mirando y buscando entre muchas paginas para dar concretamente con la forma de guardar el objeto.

Pero vamos, que en el fondo comparto tu opinion, es MUY satisfactorio cuando consigues sacar algo y yo tambien sigo con esto por esos momentos...Jajaja.

Un saludo.

Usuarios habituales