game-client

Play TicTacToe and Reversi
Log | Files | Refs

HistoryBoard.java (1834B)


      1 package nl.isygameclient.models.board;
      2 
      3 
      4 import java.util.*;
      5 import nl.isygameclient.util.Vector2D;
      6 
      7 public class HistoryBoard<T> extends Board<T> {
      8 	public record Move<T>(T current, T previous) {
      9 	}
     10 
     11 	public record Change<T>(T player, Map<Vector2D<Integer, Integer>, Move<T>> moves) {
     12 	}
     13 
     14 	private int	  index;
     15 	private final Stack<Change<T>> stack;
     16 
     17 	public HistoryBoard(int width, int height) {
     18 		super(width, height);
     19 		this.stack = new Stack<>();
     20 		this.index = 0;
     21 	}
     22 
     23 	public List<Change<T>> getHistory() {
     24 		return stack.subList(0, index);
     25 	}
     26 
     27 	public List<Change<T>> getFuture() {
     28 		return stack.subList(index, stack.size());
     29 	}
     30 
     31 	public void add(T player, Map<Vector2D<Integer, Integer>, T> changes) {
     32 		for (int i = stack.size(); i > index; i--)
     33 			stack.pop();
     34 
     35 		Map<Vector2D<Integer, Integer>, Move<T>> moves = new HashMap<>();
     36 		for (Map.Entry<Vector2D<Integer, Integer>, T> entry : changes.entrySet()) {
     37 			var vector = entry.getKey();
     38 			moves.put(entry.getKey(), new Move<>(entry.getValue(), get(vector)));
     39 		}
     40 
     41 		stack.push(new Change<>(player, moves));
     42 		index++;
     43 
     44 		for (var move : changes.entrySet()) {
     45 			var vector = move.getKey();
     46 			set(move.getValue(), vector);
     47 		}
     48 	}
     49 
     50 	public boolean canUndo() {
     51 		return index > 0;
     52 	}
     53 
     54 	public boolean canRedo() {
     55 		return index < stack.size();
     56 	}
     57 
     58 	public boolean undo() {
     59 		if (!canUndo())
     60 			return false;
     61 
     62 		index--;
     63 
     64 		for (var move : stack.get(index).moves.entrySet()) {
     65 			var vector = move.getKey();
     66 			set(move.getValue().previous, vector);
     67 		}
     68 
     69 		return true;
     70 	}
     71 
     72 	public boolean redo() {
     73 		if (!canRedo())
     74 			return false;
     75 
     76 		for (var move : stack.get(index).moves.entrySet()) {
     77 			var vector = move.getKey();
     78 			set(move.getValue().current, vector);
     79 		}
     80 
     81 		index++;
     82 		return true;
     83 	}
     84 
     85 	public void clear() {
     86 		super.clear();
     87 		stack.clear();
     88 		index = 0;
     89 	}
     90 }