Ange King
Ange King

Reputation: 147

save game (minesweeper) progress using serialization java

I am completing an assignment for uni, we were given the source code for a minesweeper game and we have certain requirements to implement. One of these is that all games are read from disk after a user logs in, and users can save game progress at any time. I have been reading into serialization to save/load game progress but I am finding it a little hard to grasp the concept. I'm not exactly sure on where to start to write code for this. The game does not use a 2D array as a lot of other minesweeper games do. Can someone point me to any good documentation that is easy to understand, I find some webpages get a little too technical and I get lost! Or if anyone knows of a better way to save the progress of a minesweeper game? Sorry if my question is broad, I'm not 100% sure on what I should be reading to learn about this so that's why I'm asking for help, to get pointed in the right direction.

Upvotes: 1

Views: 3765

Answers (2)

Menelaos
Menelaos

Reputation: 25725

You want to save all information that are related to the STATE that the game is in. This means, game board (2D grid or however you store), player name, scores, etc.

The technical part about how to serialize an object is relatively easy... see http://www.javapractices.com/topic/TopicAction.do?Id=57. However, you have to be careful with stuff like static or transient variables and know how these affect serialization (e.g. static class objects are not serialized but are lost).

Once you decide what needs saving, you can create a Class that contains variables/references to all the important objects - like a wrapper. This is if you want to avoid saving many different files. You also need to add implements Serialiable to all the class definitions of objects that will be serialized.

So, in my example below we write the SavedState wrapper object, but as this contains Board, Board must also be serializable. You could write each object you want to save in a separate file but I prefer to have an object that holds all important information in 1 object/file because I find it is cleaner.

You then make assignments and write your object.

So Example:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;

public class Game {

    Board board;
    String name;

    public static void main(String[] args) {
        Game game = new Game();
        game.InitBoard();

        //Now save the board
        game.SaveBoard();
        System.out.println("Player Name is:"+game.name);
        System.out.println("Saved Board, changing in memory playername to 'test'.");
        game.name = "test";
        game.LoadBoard();

        System.out.println("Loaded Board, Player Name is:"+game.name);  
    }

    public void InitBoard()
    {
        board = new Board();
        name = "player...";
    }

    public void SaveBoard()
    {
        try {
            SavedState state = new SavedState(board, name);
            OutputStream file = new FileOutputStream("game.mine");
            OutputStream buffer = new BufferedOutputStream(file);
            ObjectOutput output = new ObjectOutputStream(buffer);
            output.writeObject(state);
            output.flush();
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void LoadBoard()
    {
        SavedState state;

         InputStream file;
        try {
            file = new FileInputStream("game.mine");
            InputStream buffer = new BufferedInputStream(file);
            ObjectInput input = new ObjectInputStream (buffer);
            state = (SavedState)input.readObject();
            this.board = state.board;
            this.name = state.playerName;
            input.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

}

class Board implements Serializable {
    ArrayList<Integer> boardElements = new ArrayList<Integer>(); // or however
                                                                    // else you
                                                                    // store
                                                                    // your
                                                                    // values

    // etc...

    public Board() {
        boardElements.add(1); // etc...
    }

}

class SavedState implements Serializable {

    Board board;
    String playerName;

    public SavedState(Board board, String playerName) {
        this.board = board;
        this.playerName = playerName;
    }

}

Upvotes: 1

RamonBoza
RamonBoza

Reputation: 9038

Basically you implement Serialization what forces you to convert all the objects it hold to a serialization process so it can be saved on memory.

Serialization is correctly implemented if used only on entities

class MinesweeperState implements Serializable {
    private Board board;
}

class Board implements Serializable {
    private int[][] mineTable;
}

And no more than sets and gets, the logic within initializating the table, filling the mines and setting its surrounding mine counters I would like to set on a Proxy or Adapter.

for the saving itself, just use a Manager with this code

FileOutputStream fos = null;
    ObjectOutputStream out = null;
try {
    fos = new FileOutputStream(YOUR_FILENAME_CONSTANT,false);
    out = new ObjectOutputStream(fos);
    out.writeObject(minesweeperState);
    out.close();
    System.out.println("Minesweeper state persisted");
} catch (IOException ex) {
    LOGGER.err(ex);
}

Upvotes: 1

Related Questions