-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathChessPiece.m
136 lines (115 loc) · 4.67 KB
/
ChessPiece.m
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
classdef ChessPiece < handle
properties
Type % Must be PieceType
Player % Must be 1 or 2
Enigmas % Must be [EnigmaType, EnigmaType...]
FlagPure % Must be boolean; only used for if the piece hasn't moved yet — this actually neatly takes care of King castling and Pawn 2-hop.
FlagTemp % Must be boolean; only used for "just occurred flags" — all piece's flag2 are reset at the END of the entire turn (both black and white have moved)
end
methods
function obj = ChessPiece(Type, Player)
obj.Type = Type;
obj.Player = Player;
obj.Enigmas = [];
obj.FlagPure = 1;
obj.FlagTemp = 0;
end
% "Copy"
% Makes a copy of this object (just type and player).
function piece = cpy(obj)
piece = ChessPiece(obj.Type, obj.Player);
end
% "Full copy"
% Makes a full copy of this object (all attributes).
function piece = fcpy(obj)
piece = obj.cpy();
piece.Enigmas = obj.Enigmas;
piece.FlagPure = obj.FlagPure;
piece.FlagTemp = obj.FlagTemp;
end
% "Get rank"
% Gets the relative rank of this piece including +/- for player.
function r = rank(obj)
r = obj.Type.Rank;
% Flip polarity if black
if obj.Player == 2
r = -r;
end
end
% "Can add that enigma?"
% Checks if you can still add that enigma to this piece.
function result = cane(obj, enigmatype)
% If invalid enigma type, shortcircuit.
if ~has(EnigmaType.types(obj.Type), enigmatype)
result = 0;
else
if isempty(obj.Enigmas)
result = 1;
else
% Decompile enigmas.
edecomp = vdecomp(obj.Enigmas);
% Decomp index for enigma type.
eind = has(exti(edecomp, 1), enigmatype);
if enigmatype.Max == -1
result = ~has(obj.Enigmas, enigmatype);
elseif eind ~= 0
% Compare counts and set result whether over max or not
epair = edecomp{eind};
result = epair{2} < enigmatype.Max;
else
result = 1;
end
end
end
end
% "Can add any enigmas?"
% Checks if you can still add ANY enigmas to this piece.
% "pes" = potential enigmas.
function [pes] = canae(obj)
% Decompose into counts for each item for filter (to remove)
edecomp = vdecomp(obj.Enigmas);
% Get all possible enigmas.
pen = EnigmaType.types(obj.Type);
for i = length(edecomp):-1:1
% Extract cell
edi = edecomp{i};
% If is not permanent (-1) and not at max, remove from edecomp
% filter.
if edi{2} ~= -1 && edi{2} < edi{1}.Max
edecomp(i) = [];
end
end
% Check if any potential enigmas remain. We only need the first
% column as counts are irrelevant, and remove these.
pes = vfilt(pen, exti(edecomp, 1));
end
% Add enigma
% Throws error if invalid enigma added.
function egadd(obj, enigma)
if ~obj.cane(enigma)
error("Enigma %s cannot be added to a %s!", string(enigma), string(obj.Type));
end
obj.Enigmas = [ obj.Enigmas, enigma ];
end
% Remove enigma
% Returns nothing if no enigmas/that enigma not present.
function eg = egrem(obj, enigma)
eind = has(obj.Enigmas, enigma);
if ~eind
fprintf("Warning: a %s piece (enigmas %s) could not remove %s; returning empty.", string(obj.Type), mat2str(obj.Enigmas), string(enigma));
eg = [];
else
eg = obj.Enigmas(eind);
obj.Enigmas(eind) = [];
end
end
% Equals method
function result = eq(obj, other)
result = obj.Type == other.Type && obj.Player == other.Player;
end
% "Full" equals method
function result = feq(obj, other)
result = obj.Type == other.Type && obj.Player == other.Player && obj.FlagTemp == other.FlagTemp && obj.FlagPure == other.FlagPure && length(obj.Enigmas) == length(other.Enigmas) && all(obj.Enigmas == other.Enigmas);
end
end
end