Java - error NullPointerException

 
Vista:

error NullPointerException

Publicado por MyTrAxXx (3 intervenciones) el 01/04/2020 19:00:22
Mi pregunta : porque me surge un NullPointerException la calse JugadorDeGeneralita.
He estado buscando por internet y de mirar he sacado que es porque a lo mejor no la he inicializado, pero por mas que le doy vueltas al codigo no consigo corregiir el error.
Alguien que eche un cable ??

os dejo las clases de mi proyecto :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
import java.util.*;
 
public class Dado {
	private int numCaras;
	private int Valor = 0; // almacena todos los valores de las tiradas
 
	Random aleatorio = new Random(); // Objeto de la clase Random que crea un generador de numeros aleatorios
                                     // cuya semilla esta inicializada automaticmente en linea de tiempo
	public Dado( int numCaras) { // constructor de del dado - recibe el numero de caras
		if(numCaras > 1)
			this.numCaras = numCaras;
		else
			System.out.println("Error : El numero de caras debe ser mayor a 1 ");
	}
 
	public int getnumCaras() {
		return numCaras;
	}
 
	public void tirar() {
 
		Valor = aleatorio.nextInt(numCaras) + 1;
 
	}
 
	public int tirada() {
		if(numCaras==0) {
			System.out.println("El dado no ha sido tirado");
		}else {
			return Valor;
		}
	return Valor;
	}
 
}
 
public class Cubilete {
	private int maxNumDados;
	private Dado[] cubilete = null; // significa que no hemos resarvado memoria para el array
	private int contadorDado ;
 
	public Cubilete( int maxNumDados ) {
		if(maxNumDados > 0) {
			this.maxNumDados = maxNumDados;
			cubilete = new Dado[maxNumDados];
			contadorDado = 0;
		}
		else
			System.out.println("Error : El numero de dados maximos tiene que ser mayor que 0");
	}
 
	public void añadirDado( Dado dado ) {
 
		// precondicion, al añadir un dado, no se puede superar el maxNumDados
 
		if( contadorDado <= maxNumDados ) {
 
			cubilete[contadorDado] = dado;
			contadorDado ++;
 
		}else
			System.out.println("Error : El cubilete ya esta lleno ");
	}
 
	public Dado[] tirarDados() {
 
		Dado[] tirada = new Dado[contadorDado];
 
		for(int i = 0; i < contadorDado; i++) {
 
			cubilete[i].tirar();
			tirada[i] = cubilete[i];
		}
 
		contadorDado = 0;
 
		// postcondicion, despues de cada jugada de cada jugador el cubilet queda vacio, es decir,
		// que la el maximo numero de dados que puede tener el cubilete, tiene que ser igual a 0
 
		return tirada;
	}
 
	public int getNumeroDeDados() {
		return contadorDado;
	}
}
 
public class JugadorDeGeneralita {
	private String nombreJugador;
	private int puntuacion;
 
	public JugadorDeGeneralita( String nombreJugador) {
		this.nombreJugador = nombreJugador;
		puntuacion = 0;
	}
 
	public String getNombre() {
		return nombreJugador;
	}
 
	public void jugar( Cubilete c, int maxTiradas, int numCarasDado) {
		//Definir un array de dados auxiliar
		Dado[] dadosAux = null;
 
		//Definir un array de dados donde almacenaré los dados que van quedando sobre la mesa
		final Dado[] dadosMesa = new Dado[c.getNumeroDeDados()];
 
		//Definir una variable para ir contando el número de tiradas que realizo y los dados de la mesa
		int numTiradas = 0;
		int numDadosMesa = 0;
 
		//Definir una variable para contar el numero de dados que hay en el cubilete, que obtengo con getNumeroDeDados()
		int dadosCubilete = c.getNumeroDeDados();
 
		//Mientras el número de tirada sea menor que el número máximo de tiradas, y haya dados en el cubilete,
		while((numTiradas < maxTiradas) && (dadosCubilete != 0)) {
 
			//ATENCION : actualizar las dos variables en el while
 
			 /* - Tiro los dados del cubilete mediante tirarDados() ,
		      almacenando el resultado en el array auxiliar
		      (al tirar los dados, el cubilete ha quedado vacio).
		     */
 
			dadosAux = c.tirarDados();
			numTiradas++;
 
			  /* - si es la última tirada permitida,
			   * se recorre el array de dados auxiliar y
			   * se suman las puntuaciones de los dados al atributo puntuación del
			   *  jugador.
			   *  Se almacenan estos dados en el array de dados sobre la mesa.
			   */
			if(numTiradas == maxTiradas) { //si es la ultima tirada
				for(int i = 0; i < dadosAux.length; i++) {
					puntuacion = puntuacion + dadosAux[i].tirada();
				}
 
			 /* - si no es la última tirada permitida,
			      se recorre el array de dados auxiliar y
				  se suman a la puntuación del jugador sólo las puntuaciones de
				  los dados que han obtenido la puntuación máxima.
				  Se almacenan en el cubilete los dados en los que no se obtuvo
				  la puntuación máxima, mediante añadirdado().
				  Los que han obtenido la puntuación máxima se almacenan en el array
				  de dados sobre la mesa.
			  */
			}else { //sino es la ultima tirada
				for(int i = 0; i < dadosAux.length; i++) {
					if(dadosAux[i].tirada() == numCarasDado) {
						puntuacion = puntuacion + dadosAux[i].tirada();
						dadosMesa[ numDadosMesa ] = dadosAux[i];
						numDadosMesa++;
						dadosCubilete--;
					}else {
						c.añadirDado(dadosAux[i]);
					}
				}
			}
 
 
		}
 
		 //Por último, recorro el array de dados sobre la mesa y los añado al cubilete.
		for(int i = 0; i < dadosMesa.length; i++) {
			c.añadirDado(dadosMesa[i]);
		}
	}
 
	public boolean ganaATodos (JugadorDeGeneralita[] otrosJugadores) {
		// El jugador principal tambien esta dentro de los otrosJugadores
 
		/* Definir la variable booleana que se llama ganador y que sea true
		si este jugador tiene una puntuacion mayor que todos los demas
		*/
		boolean ganador = true;
		int contadorJugadores = 0;
		/*Recorrer el array de jugadores para comparar las puntuaciones.
		 * Si la puntuacion de este jugador es mayor que le del resto
		 * la variable ganador debe ser true.
		 */
		while ( ganador == true ) {
			if(otrosJugadores[contadorJugadores] != this) {
				if( puntuacion <= otrosJugadores[contadorJugadores].puntuacion) {
					ganador = true;
				}
			}
 
			contadorJugadores ++;
		}
 
		// Devolver la variable booelana ganador
		return ganador;
	}
 
}

Estas dos clases ( TesCubilete y TestJugadorDeGeneralita ) han sido creadas por mis profesores, para asi con ellas comprobar las clases anteriores ( Cubilete y JugadorDeGeneralita ) y ver si estan bien

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
 
/**<p>Esta clase contiene un programa que permite probar de manera básica la clase <b><code>Cubilete</code></b>.</p>
 * <p>Si se produce algún error al probar la clase, el programa termina indicando con un mensaje aquello que se
 * estaba probando en el momento de producirse el error.</p>
 * <p>Si no se produce ningún fallo durante la ejecución, el programa indicará que el test ha terminado sin errores.</p>
 * <h2 style="background-color:yellow"><b>
 * ESTE PROGRAMA REALIZA UNA PRUEBAS BÁSICAS. EL HECHO QUE LA CLASE PROBADA PASE EL TEST NO GARANTIZA QUE SU
 * IMPLEMENTACIÓN NO TENGA ALGÚN ERROR. SE RECOMIENDA CONSULTAR CON SU PROFESOR DE LABORATORIO ANTE CUALQUIER DUDA.
 * </b></h2>
 * @author DTE. Curso 2019/2020
 * @version 1.0
 */
public class TestCubilete {
	public static void main(String[] args) {
 
		testInstanciacion();
		System.out.println("prueba pasada satisfactoriamente");
 
		testEstados();
		System.out.println("prueba pasada satisfactoriamente");
	}
 
	private static void testInstanciacion() {
		System.out.print("Prueba de instanciación de un cubilete... ");
		try{ for(int i = 1; i < 10; i++) { final Cubilete c = new Cubilete(i); }
		} catch(Exception e){ EVALUAR(false, "ERROR: "+e.toString()); }
	}
 
	private static void testEstados() {
		System.out.print("Pruebas de estado de un cubilete... ");
 
		final int maxNumDados = 10;
		final Cubilete c = new Cubilete(maxNumDados);
		int numDados = 1;
		do {
			EVALUAR(c.getNumeroDeDados() == 0, "El cubilete, tras su instanciación y después de invocar a tirar(), debe indicar tener cero dados.\"");
			final Dado[] dados = new Dado[numDados];
			final String[] dadosS = new String[numDados];
			for(int i = 0; i < numDados; i++) { dados[i] = new Dado(6); dadosS[i] = String.valueOf(dados[i]); }
			Arrays.sort(dadosS);
			int dadosIntroducidos = 0;
			do {
				c.añadirDado(dados[dadosIntroducidos++]);
				EVALUAR(c.getNumeroDeDados() == dadosIntroducidos, "El cubilete indica tener un número de dados incorrecto.\"");
			} while(dadosIntroducidos < numDados);
			final Dado[] dadosDeSalida = c.tirarDados();
			EVALUAR(c.getNumeroDeDados() == 0, "El cubilete debe quedar vacío tras invocar a tirarDados().");
			EVALUAR(dadosDeSalida != null, "El array de dados devuelto por tirar() es null.");
			EVALUAR(dadosDeSalida.length == numDados, "El array de dados devuelto por tirar() no tiene la longitud correcta.");
			final String[] ss = new String[numDados];
			for(int i = 0; i < numDados; i++) ss[i] = String.valueOf(dadosDeSalida[i]);
			Arrays.sort(ss);
			EVALUAR(Arrays.equals(ss, dadosS), "El array de dados devuelto por tirar() no contiene las referencias correctas a los dados que contiene.");
			numDados++;
		} while(numDados <= maxNumDados);
	}
	private static void EVALUAR(boolean predicado, String mensajeDeError) {
		if(!predicado) throw new AssertionError(mensajeDeError);
	}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import java.util.Arrays;
import java.util.List;
 
/**<p>Esta clase contiene un programa que permite probar de manera básica la clase <b><code>JugadorDeGeneralita</code></b>.</p>
 * <p>Si se produce algún error al probar la clase, el programa termina indicando con un mensaje aquello que se
 * estaba probando en el momento de producirse el error.</p>
 * <p>Si no se produce ningún fallo durante la ejecución, el programa indicará que el test ha terminado sin errores.</p>
 * <h2 style="background-color:yellow"><b>
 * ESTE PROGRAMA REALIZA UNA PRUEBAS BÁSICAS. EL HECHO QUE LA CLASE PROBADA PASE EL TEST NO GARANTIZA QUE SU
 * IMPLEMENTACIÓN NO TENGA ALGÚN ERROR. SE RECOMIENDA CONSULTAR CON SU PROFESOR DE LABORATORIO ANTE CUALQUIER DUDA.
 * </b></h2>
 * @author DTE. Curso 2019/2020
 * @version 1.0
 */
public class TestJugadorDeGeneralita {
	private static final String nombre = "Test";
	public static void main(String[] args) {
		testInstanciacion();
		System.out.println("prueba pasada satisfactoriamente");
		testEstados();
		System.out.println("prueba pasada satisfactoriamente");
	}
 
	private static void testInstanciacion() {
		System.out.print("Prueba de instanciación de un jugador de Generalita... ");
		try { final JugadorDeGeneralita j = new JugadorDeGeneralita(nombre); }
		catch(Exception e){ EVALUAR(false, "ERROR: "+e.toString()); }
	}
 
	private static void testEstados() {
		System.out.println("Pruebas de estado de un jugador de Generalita... ");
 
		final JugadorDeGeneralita jugador1 = new JugadorDeGeneralita(nombre);
		EVALUAR(nombre.equals(jugador1.getNombre()), "El nombre del juegador obtenido con getNombre() no coincide con el establecido al invocar al constructor.");
		final int numCarasDado = 6;
		final int numJugadores = 10;
		final Cubilete c = new Cubilete(numJugadores * numCarasDado + 1);
		final JugadorDeGeneralita[] jugadores = new JugadorDeGeneralita[numJugadores];
		int n;
		for(n = 0; n < numJugadores; n++) {
			c.añadirDado(new Dado(numCarasDado));
			jugadores[n] = new JugadorDeGeneralita(nombre + n);
			jugadores[n].jugar(c, 10, numCarasDado);
			EVALUAR(c.getNumeroDeDados() == n+1, "El jugador de Generalita debe asegurar al terminar de jugar que el cubilete tiene todos los dados que recibió al principio del juego.");
		}
		for(;n < numJugadores * numCarasDado + 1; n++) c.añadirDado(new Dado(numCarasDado));
		final JugadorDeGeneralita jugadorGanador = new JugadorDeGeneralita(nombre + "ganador");
		jugadorGanador.jugar(c, 10, numCarasDado);
		EVALUAR(jugadorGanador.ganaATodos(jugadores), "Es posible que haya un error al calcular la puntación de la jugada en jugar() y/o al evaluar el jugador ganador en ganaATodos()");
		final JugadorDeGeneralita[] jugadoresMasUno = Arrays.copyOf(jugadores, numJugadores+1);
		jugadoresMasUno[numJugadores] = jugadorGanador;
		EVALUAR(jugadorGanador.ganaATodos(jugadoresMasUno), "Si al invocar a ganaATodos() el array contiene la referencia local this, se debe ignorar. Un jugador no puede ganarse a sí mismo.");
	}
 
	private static void EVALUAR(boolean predicado, String mensajeDeError) {
		if(!predicado) throw new AssertionError(mensajeDeError);
	}
}
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Kabuto
Val: 2.713
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

error NullPointerException

Publicado por Kabuto (711 intervenciones) el 02/04/2020 00:42:52
Hola.
He estado usando el debug para descubrir el error. Y algo he encontrado, pero no logro ver por qué ocurre.
De hecho, es curioso porque ocurre un poco al azar. A veces solo se completa solo el ciclo de tiradas del primer jugador, otras veces llega hasta el 5º jugador,... no ocurre siempre en el mismo ciclo.

El problema es que en algún momento indeterminado, el Cubilete se construye con un Dado null de por medio. Mira esta captura, lo señalado en rojo:

cubilete

El Cubilete tendría que tener 3 dados (contadorDados = 3), pero el que está en la posición [1] del array se ha quedado con valor null.
Entonces, cuando el bucle llega a esa posición e invoca el método tirar(), es decir, le pide a ese Dado que ejecute tirar(), al ser null, es cuando se produce la excepción NullPointerException.

Ese es el problema, pero lo que no logro ver repito, es la causa.
Como digo, no ocurre siempre en el mismo punto del programa. El Cubilete se construye correctamente la mayoría de veces, pero en algún momento ocurre lo que he puesto en la captura, un Dado se queda con valor null.

Tu que conoces mejor la lógica de tu programa, quizás esto te de una pista de qué puede estar pasando. Yo la verdad estoy desconcertado, sobre todo por ser un error que ocurre aleatoriamente.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

error NullPointerException

Publicado por MyTrAxXx (3 intervenciones) el 02/04/2020 01:19:08
Pues la verdad no se que mas decirte, yo pensaba que ese error era por que había escrito mal el código.
Estuve igual que tu con el debuger y me parecia muy raro que al construir un Dado lo hiciera como null, pero otras veces no lo hace.
Estoy bastante rayado con este programa, sigo pensando que es un error de código.
Con la respuesta me ha hecho ver mejor el programa pero sin solucion, seguire mirando haber en que parte del codigo esta mal
Gracias amigo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Rodrigo
Val: 1.727
Plata
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

error NullPointerException

Publicado por Rodrigo (468 intervenciones) el 02/04/2020 04:57:42
anadirDado no deberia agregar dados cuando el indice es igual al maximo, el ultimo indice valido es.1 menos que el maximo.

1
if( contadorDado <= maxNumDados )
deberia cambiarse por

1
if( contadorDado < maxNumDados )
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

error NullPointerException

Publicado por MyTrAxXx (3 intervenciones) el 02/04/2020 10:46:04
Lo he probado Rodrigo y aun asi me sigue dando el mismo error. Y no se me ocurre nada, mas que esperar la respuesta de mis profesores y ver que ayuda me dan.
Pero gracias de todas formas Rodrigo.
Seguire mirando haber que puedo hacer
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar