AYUDA URGENTE CON FICHEROS DE LECTURA Y ESCRITURA

Marques
31 de Agosto del 2004
El problema que tengo es que he hecho un buscaminas y tengo que salvar la partida en un fichero y no se como se hace a pesar de tener la estructura del fichero ( se muestra al final). Asi que necesito ayuda y para eso os dejo tambien el codigo fuente del buscaminas por si os hace falta.
Muchas gracias es de vital importancia.

class PruebaBuscaminas{
public static void main(String[] args){
if(args.length==4){
try{
String[] datos={args[0],args[1],args[2],args[3]};
int[] numeros=new int[args.length];
for(int i=0;i<args.length;i++){
numeros[i]=Integer.parseInt(args[i]);
}
Buscaminas buscaminas=new Buscaminas(numeros[0],numeros[1],numeros[2],numeros[3]);
buscaminas.jugar();
}
catch(Exception e){
System.out.println("Los parametros introducidos no son validos.");
}

}
else{
if(args.length==1){
//jugar por fichero.
}
else{
System.out.println("Los parametros introducidos no corresponden a ninguna modalidad de juego.");
}
}
}
}

LA SIGUIENTE CLASE:

import java.io.*;
class Buscaminas{
int _intentos;
int _minas;
boolean _juegoGanado;
boolean _juegoPerdido;
BufferedReader p=new BufferedReader(new InputStreamReader(System.in));
Tablero _tablero;
Buscaminas(int minas,int fila,int columna,int intentos){
if(minas>(fila*columna) || minas<=0){
System.out.println("El numero de minas introducido no es valido. Se asignan "+ (fila*columna/2) + " minas por defecto.");
_minas=(fila*columna/2);
}
else{
_minas=minas;
}
_tablero=new Tablero(_minas,fila,columna);
if(intentos<_minas){
System.out.println("No puede tener menos intentos que minas. El numero de intentos sera igual que el numero de minas");
_intentos=_minas;
}
else{
_intentos=intentos;
}
}
void jugar(){
boolean movimiento=false;
boolean salir=false;
String jugada;
mostrar();
while(!_juegoGanado && !_juegoPerdido && !salir){
movimiento=false;
System.out.println("nIntroduzca su opcion: marcar(m x y) / descubrir (d x y) / salir");
try{
jugada=p.readLine();
salir=salir(jugada);
if(!salir){
movimiento=jugadaValida(jugada);
}
}
catch(Exception e){
System.out.println("Vuelva a intentarlo");
}
if(movimiento){
mostrar();
}
}
}
boolean marcar(int x, int y){
boolean marcado=_tablero.marcar(x,y);
if(marcado){
_juegoGanado=_tablero.obtenerJuegoGanado();
_intentos--;
if(_intentos<(_minas-_tablero.obtenerMinasEncontradas())){
System.out.println("El numero de intentos es menor que el de minas restantes. Ha perdido");
_juegoPerdido=true;
_tablero.asignarJuegoPerdido();
}
}
return marcado;
}
boolean descubrir(int x, int y){
boolean descubierto=_tablero.descubrir(x,y);
if(descubierto){
_juegoPerdido=_tablero.obtenerJuegoPerdido();
}
return descubierto;
}
void mostrar(){
System.out.println("nEl estado actual del juego es:");
_tablero.mostrar();
System.out.println("nMinas encontradas: ..." + _tablero.obtenerMinasEncontradas());
System.out.println("Minas no encontradas: ..." + (_minas-_tablero.obtenerMinasEncontradas()));
System.out.println("Intentos restantes: ..." + _intentos);
}
boolean jugadaValida(String jugada){
boolean jugadaValida=false;
char letra;
int[] coordenadas;
letra=jugada.charAt(0);
if(letra=='m' || letra=='M'){
jugada=jugada.substring(1);
coordenadas=obtenerCoordenadas(jugada);
jugadaValida=marcar(coordenadas[0],coordenadas[1]);
}
else{
if(letra=='d' || letra=='D'){
jugada=jugada.substring(1);
coordenadas=obtenerCoordenadas(jugada);
jugadaValida=descubrir(coordenadas[0],coordenadas[1]);
}
else{
System.out.println("No ha podido efectuarse la jugada. Vuelva a intentarlo.");
}
}
return jugadaValida;
}
int[] obtenerCoordenadas(String jugada){
boolean finNumero=false;
int coordenadas[]={-1,-1};
int i=0;
int j=0;
do{
if(jugada.charAt(0)==' '){
jugada=jugada.substring(1);
while(!finNumero && i<jugada.length()){
if(jugada.charAt(i)==' '){
finNumero=true;
}
else{
i++;
}
}

try{
coordenadas[j]=Integer.parseInt(jugada.substring(0,i));
jugada=jugada.substring(i);
j++;
}
catch(Exception e){
System.out.println("Las coordenadas introducidas no son validas");
}
}
}
while(j<=1);
return coordenadas;
}
boolean salir(String cadena){
String salir="salir";
String s="s";
String n="n";
boolean esSalir=false;
if(salir.compareToIgnoreCase(cadena)==0){
String aux;
boolean error=false;
esSalir=true;
do{
try{
error=false;
System.out.println("¿Desea guardar la partida?(s/n)");
aux=p.readLine();
if(aux.compareToIgnoreCase(s)==0){
//guardar la partida
}
else{
if(aux.compareToIgnoreCase(n)==0){
System.out.println("No se guardara la partida. Fin del juego");
}
else{
error=true;
System.out.println("Introduzca una opcion valida");
}
}
}
catch(Exception e){
System.out.println("Se ha producido un error");
error=true;
}
}
while(error);
}
return esSalir;
}
}

LA SIGUIENTE CLASE ES:

import java.util.Random;
class Tablero{
Casilla[][] _tablero;
int _fila;
int _columna;
int _minas;
int _minasEncontradas;
boolean _juegoGanado;
boolean _juegoPerdido;
Tablero(int minas,int x,int y){
_fila=x;
_columna=y;
_minas=minas;
_minasEncontradas=0;
_juegoGanado=false;
_juegoPerdido=false;
_tablero=new Casilla[_fila][_columna];
for(int i=0;i<_fila;i++){
for(int j=0;j<_columna;j++){
_tablero[i][j]=new Casilla();
}
}
ponerMinas();
asignarMinasProximas();
}
void ponerMinas(){
Random r=new Random();
int aux1=0;
int aux2=0;
boolean minaPuesta=false;
r.setSeed(System.currentTimeMillis());
for(int i=0;i<_minas;i++){
minaPuesta=false;
while(!minaPuesta){
aux1=(int)r.nextInt(_fila);
aux2=(int)r.nextInt(_columna);
if(!_tablero[aux1][aux2].obtenerMina()){
_tablero[aux1][aux2].asignarMina();
minaPuesta=true;
}
}
}
}
void asignarMinasProximas(){
int aux=0;
for(int i=0;i<_fila;i++){
for(int j=0;j<_columna;j++){
aux=calcularMinasProximas(i,j);
_tablero[i][j].asignarMinasProximas(aux);
}
}
}
int calcularMinasProximas(int x, int y){
int contador=0;
int[][] vecindad={{-1,-1,-1,0,0,1,1,1},{-1,0,1,-1,1,-1,0,1}};
int aux1=0;
int aux2=0;
for(int i=0;i<vecindad[0].length;i++){
aux1=vecindad[0][i];
aux2=vecindad[1][i];
if(x+aux1>=0 && x+aux1<_fila && y+aux2>=0 && y+aux2<_columna){
if(_tablero[x+aux1][y+aux2].obtenerMina()){
contador++;
}
}
}
return contador;
}
void mostrar(){
int i=0;
int j=0;
if(_juegoGanado){
for(i=0;i<_fila;i++){
for(j=0;j<_columna;j++){
_tablero[i][j].juegoTerminado(true);
}
}
}
else{
if(_juegoPerdido){
for(i=0;i<_fila;i++){
for(j=0;j<_columna;j++){
_tablero[i][j].juegoTerminado(false);
}
}
}
}
System.out.println("nEl tablero actual es:");
for(i=-1;i<_fila;i++){
for(j=-1;j<_columna;j++){
if(i==-1 && j!=-1){
System.out.print("("+j+")");
}
else{
if(i!=-1 && j==-1){
System.out.print("n("+i+")");
}
else{
if(i==-1 && j==-1){
System.out.print(" ");
}
else{
_tablero[i][j].mostrar();
}
}
}
}
}
}
boolean marcar(int x,int y){
boolean marcado=false;
if(x>=0 && y>=0 && x<_fila && y<_columna){
marcado=_tablero[x][y].marcar();
if(_tablero[x][y].obtenerMina()){
if(_tablero[x][y].obtenerMarcada()){
_minasEncontradas++;
if(_minasEncontradas==_minas){
_juegoGanado=true;
System.out.println("Enhorabuena, ha ganado.");
}
}
else{
_minasEncontradas--;
}
}
}
else{
System.out.println("Las coordenadas introducidas no son validas");
}
return marcado;
}
boolean descubrir(int x,int y){
int[][] vecindad={{-1,-1,-1,0,0,1,1,1},{-1,0,1,-1,1,-1,0,1}};
boolean descubierto=false;
int aux1=0;
int aux2=0;
if(x>=0 && y>=0 && x<_fila && y<_columna){
descubierto=_tablero[x][y].descubrir();
if(descubierto){
if(_tablero[x][y].obtenerExplotada()){
_juegoPerdido=true;
}
else{
if(_tablero[x][y].obtenerVacia()){
for(int i=0;i<vecindad[0].length;i++){
aux1=vecindad[0][i];
aux2=vecindad[1][i];
if(x+aux1>=0 && x+aux1<_fila && y+aux2>=0 && y+aux2<_columna){
if(!_tablero[x+aux1][y+aux2].obtenerMarcada() && !_tablero[x+aux1][y+aux2].obtenerDescubierta()){
descubrir(x+aux1,y+aux2);
}
}
}
}
}
}
}
else{
System.out.println("Las coordenadas introducidas no son validas");
}
return descubierto;
}
void asignarJuegoPerdido(){
_juegoPerdido=true;
}
int obtenerMinasEncontradas(){
return _minasEncontradas;
}
boolean obtenerJuegoGanado(){
return _juegoGanado;
}
boolean obtenerJuegoPerdido(){
return _juegoPerdido;
}
}
LA ULTIMA CLASE DEL BUSCAMINAS ES:

class Casilla{

boolean _mina;
boolean _marcada;
boolean _descubierta;
boolean _explotada;
boolean _vacia;
boolean _juegoGanado;
boolean _juegoPerdido;
int _minasProximas;

Casilla(){
_mina=false;
_marcada=false;
_descubierta=false;
_explotada=false;
_vacia=false;
_juegoGanado=false;
_juegoPerdido=false;
_minasProximas=0;
}

void mostrar(){
System.out.print("[");
if(_juegoGanado){
if(_mina){
System.out.print("X");
}
else{
if(_vacia){
System.out.print(".");
}
else{
System.out.print(_minasProximas);
}
}
}
else{
if(_juegoPerdido){
if(_explotada){
System.out.print("X");
}
else{
if(_mina){
System.out.print("*");
}
else{
if(_vacia){
System.out.print(".");
}
else{
System.out.print(_minasProximas);
}
}
}
}
else{
if(_marcada){
System.out.print("X");
}
else{
if(_descubierta){
if(_vacia){
System.out.print(".");
}
else{
System.out.print(_minasProximas);
}
}
else{
System.out.print(" ");
}
}
}
}
System.out.print("]");
}

boolean marcar(){
boolean marcar=true;
if(_descubierta){
System.out.println("La casilla seleccionada ya esta descubierta");
marcar=false;
}
else{
if(_marcada){
_marcada=false;
}
else{
_marcada=true;
}
}
return marcar;
}
boolean descubrir(){
boolean descubrir=false;
if(_marcada){
System.out.println("La casilla seleccionada esta marcada. Para descubrirla hay que desmarcarla primero.");
}
else{
if(_descubierta){
System.out.println("La casilla seleccionada ya esta descubierta");
}
else{
_descubierta=true;
descubrir=true;
}
}
if(_mina){
System.out.println("Ha explotado la mina. Ha perdido.");
_explotada=true;
_juegoPerdido=true;
}
return descubrir;
}
void asignarMinasProximas(int minas){
_minasProximas=minas;
if(_minasProximas==0){
_vacia=true;
}
}
void juegoTerminado(boolean victoria){
if(victoria){
_juegoGanado=true;
}
else{
_juegoPerdido=true;
}
}
void asignarMina(){
_mina=true;
}
boolean obtenerMina(){
return _mina;
}
boolean obtenerMarcada(){
return _marcada;
}
boolean obtenerDescubierta(){
return _descubierta;
}
boolean obtenerExplotada(){
return _explotada;
}
boolean obtenerVacia(){
return _vacia;
}
int obtenerMinasProximas(){
return _minasProximas;
}
}
AHORA PONGO EL CODIGO DE LOS FICHEROS PERO PREVIAMENTE UNAS ACLARACIONES SOBRE COMO FUNCIONA EL PROGRAMA:

La ejecución del programa debe hacerse obligatoriamente de las siguientes formas :
-java PruebaBuscaminas minas filas columnas intentos
donde:

• minas es el número de minas inicial

• filas es el numero de filas del tablero

• columnas es el numero de columnas del tablero
• intentos es el numero de intentos de que dispone el usuario

No se admiten configuraciones del juego en las que el numero de intentos disponible sea inferior al numero de minas. En ese caso se tomara como numero de intentos el numero de minas descartando el dato inicial e informando de ello al usuario.

¡.
java PruebaBuscaminas fichero
donde
:
• fichero es el nombre del fichero que almacena una partida anterior que la
aplicacion debera cargar inicialmente para poder continuarla.

Ejemplos de ejecuciones correctas:

java PruebaBuscaminas 5 4 4 3

java PruebaBuscaminas 2 10 10 20

java PruebaBuscaminas a:partida.txt

java PruebaBuscaminas partidas/partidaLarga.dat

Ejemplos de ejecuciones incorrectas:

java PruebaBuscaminas 5 4 4

java PruebaBuscaminas 5 partida.txt



Formato del fichero
El fichero que almacena una partida en curso tiene el formato que se muestra en el siguiente ejemplo:

//Configuracion del juego
M-3 F-4 C-4 I-4
//Minas
M X-3 Y-0
M X-0 Y-3
M X-3 Y-2
//Comandos
m X-0 Y-3
m X-3 Y-0
d X-3 Y-1
m X-3 Y-2
Donde:
//Configuracion del juego
[minas] [filas] [columnas] [intentos]
Define la cantidad de minas iniciales, las filas y columnas del tablero y el numero de intentos de que dispone el usuario para descubrirlas. minas, filas, columnas, intentos son cuatro datos separados por uno o mas caracteres blancos. Cada uno de los datos se compone de dos partes: una letra identificadora y su valor correspondiente separados por un guion (’-’). Tanto antes como despues del guion podran de nuevo aparecer espacios en blanco.

Ejemplos validos:
M-3 F-4 C-4 I-5
M -2 f -3 c- 3 I- 5
M - 3 f - 4 c - 4 I-5.
Ejemplos no validos:
M3f4c4I-5
M-3f:4 c:4 I-5
M-3f-4 c-4I-5
//Minas
M [posicionX] [posicionY]
...
Muestra las posiciones de las minas generada de forma aleatoria por la aplicacion. Dichas posiciones se mostraran en el formato: M posicionX posicionY, siendo posicionX una cadena de caracteres que usa un guion (’-’) como separador entre la letra identificadora (X o Y) y su valor correspondiente, que debe ser una coordenada valida dentro del tablero.
Ejemplos validos: M X-0 Y-3, M X-1 Y-4, M X-0 Y-3.
Ejemplos no validos: M X--5 Y-3, M X1 Y-4, M X-0 Y3.

//Comandos
[m/d] [posicionX] [posicionY]
...
Indica la secuencia de comandos almacenada. Cada l&#305;nea define el comando ejecutado sobre las posiciones que se indican y que se definen de la manera indicada en el apartado anterior.

Ejemplos validos: m X-0 Y-0, d X-0 Y-0, M X-0 Y-0, D X-0 Y-0.
Ejemplos no validos: mX-0Y-0, m: X-0Y-0, mX0Y0.

El numero de comandos no puede superar el numero de intentos especificados al principio del fichero. Los comandos que superen el numero de intentos deben ser descartados, ya que en el momento que se supera la partida se da por concluida. El fichero puede contener espacios en blanco al principio o al final de la l&#305;nea y alrededor del caracter separador, l&#305;neas vac&#305;as o retornos de carro en cualquier lugar del fichero. Las lineas del fichero que no cumplan el formato indicado deberan descartarse emitiendo un mensaje de error al usuario por cada una de ellas.

Ahora pongo el codigo del fichero de Escritura:

import java.io.*;

public class FicheroEscritura{

//Atributos

/**
* String del nombre del fichero
*/
String _nombre;

/**
* BufferedWriter con el que nos manejaremos para escribir.
*/
BufferedWriter _fichero;

//Constructores

/**
* Constructor de FicheroEscritura.
* Le damos el nombre del fichero a escribir mediante parametros.
* @param nombre Nombre del fichero
*/
FicheroEscritura(String nombre){
_nombre=nombre;
}

//Metodos

/**
* Método que se encarga de abrir el flujo de datos para la escritura del fichero.
* @return <code> true </code> Devuelve true si consigue abrirlo.
* <code> false </code> Devuelve false en caso contrario.
*/
boolean abrir(){
boolean exito=false;
try{
_fichero=new BufferedWriter(new FileWriter(_nombre));
exito=true;
}catch(IOException e){
System.out.println("Error en la escritura del fichero");
}
return exito;
}

/**
* Escribe un caracter en el fichero de salida.
* @param c Caracter a escribir
* @return <code> true </code> Devuelve true si consigue escribirlo sin fallos.
* <code> false </code> Devuelve false en caso contrario.
*/
boolean escribirCaracter(char c){
boolean exito=false;

try{
_fichero.write(c);
exito=true;
}catch(IOException e){
System.out.println(e.getMessage());
}
return exito;
}

/**
* Escribe una cadena de texto como string al fichero
* @param cadena String que va a ser escrito
* @return <code> true </code> Devuelve true si consigue escribir la cadena.
* <code> false </code> Devuelve false en caso contrario.
*/
boolean escribirCadena(String cadena){
boolean exito=false;

try{
_fichero.write(cadena);

exito=true;
}catch(IOException e){
System.out.println(e.getMessage());
exito=false;
}
return exito;
}

/**
* Método que cierra el flujo de datos de la escritura del fichero.
* @return <code> true </code> Devuelve true si se cierra satisfactoriamente.
* <code> false </code> Devuelve false en caso contrario.
*/
boolean cerrar(){
boolean exito=false;
try{
_fichero.close();
exito=true;
}catch(IOException e){
System.out.println("Error al cerrar el fichero");
}
return exito;
}

/**
* Crea una nueva linea en el fichero de salida.
* @return <code> true </code> Devuelve true si consigue hacer la nueva linea.
* <code> false </code> Devuelve false en caso contrario.
*/
boolean nuevaLinea(){
boolean exito=false;
try{
_fichero.newLine();
exito=true;
}catch(IOException e){
System.out.println("Error al hacer una nueva linea");
}
return exito;
}
}

Y por ultimo el codigo del fichero de Lectura

import java.io.*;

class FicheroLectura{

//Atributos

/**
* Nombre o ruta de acceso del fichero.
*/
String _nombre;

/**
* Objeto de tipo BufferedReader.
*/
BufferedReader _fichero;

//Constructores

/**
* Constructor que 'confirma' que el fichero pasado por parámetros,
* realmente existe y está donde se ha escrito en la ruta del fichero.
* En caso contrario, emitirá un mensaje advirtiendo de lo sucedido.
* @param nombre Nombre o ruta de acceso al fichero en cuestión.
*/
FicheroLectura (String nombre){
boolean exito = false;
_nombre = nombre;
try {
_fichero = new BufferedReader (new FileReader (nombre));
exito = true;
}catch (FileNotFoundException e){
System.out.println ("El fichero que busca se encuentra borrado o fuera de la carpeta en este momento, por favor, intentelo de nuevo, más tarde.");
}
}

//Métodos

/**
* Abre el flujo para interactuar con el fichero.
* @return <code> true </code> Si se realiza con exito la operacion de apertura.
* <code> false </code> En caso contrario.
*/
boolean abrir (){
boolean exito = false;
try {
_fichero = new BufferedReader (new FileReader (_nombre));
exito = true;
}catch (FileNotFoundException e){
System.out.println("Por supuesto, si no se encuentra el fichero...de abrirlo, ya ni hablamos.");
}
return exito;
}

/**
* Sirve para capturar una línea de datos del fichero.
* @return Línea leída del fichero.
*/
String leerLinea (){
String linea = null;
try{
linea = _fichero.readLine();
}catch (IOException e){
System.out.println (e.getMessage ());
}
return linea;
}

/**
* Cierra el flujo tras interactuar con el fichero.
* @return <code> true </code> Si se realiza con exito la operacion de cierre.
* <code> false </code> En caso contrario.
*/
boolean cerrar (){
boolean exito = false;
try{
_fichero.close ();
exito = true;
}catch (IOException e){
System.out.println ("Error");
}
return exito;
}
}

caca
31 de Agosto del 2004
no tengo idea

IU
31 de Agosto del 2004
Siguiendo en la linea de mensajes "caca", como el arriba mostrado, intentare no extenderme mucho en mi explicacion:
Primero de todo, te recomendaria que cuando pidas ayuda no metas todo ese toston. La mayoria de la gente dara media vuelta antes de llegar al final. En todo caso, pon un enlace al codigo fuente, para quien quiera verlo completo.

Bueno, tu usas un BufferedWriter para escribir en el archivo.
Ten en cuenta que despues de cada linea que escribes, debes imprimir un caracter de fin de linea ( "n" ), o mejor llamas al metodo del BufferedWriter: newLine();, que lo hara por ti. Eso cada vez que quieras comenzar una linea nueva en el fichero. Cuando has escrito la linea, esta se queda en el Buffer. Una linea escrita en un Buffer apuntando a un archivo NO se escribe automaticamente en el archivo. Para vaciar el contenido del Buffer en el archivo, hay que llamar a su metodo flush();
Esto es valido para todos los Buffers, de archivos, de sockets, etc.

Bueno, mas o menos, lo que tienes que hacer es añadir
_fichero.newLine();
_fichero.flush();
En el metodo que llama a _fichero.write(String);
Espero haberte sido de ayuda. Sino, no me envies un correo, pregunta por aqui, y otros se beneficiaran de nuestros errores.