hanze/game-client

src/main/java/nl/isygameclient/models/board/HistoryBoard.java in modern-design
Repositories | Summary | Log | Files

HistoryBoard.java (2181B) download


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