forked from woowacourse/java-janggi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBoard.java
153 lines (129 loc) · 4.69 KB
/
Board.java
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package domain.board;
import domain.piece.Piece;
import domain.piece.PieceType;
import domain.piece.Team;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class Board {
private final Map<Point, Piece> pieceByPoint;
private final PointNodeMapper pointNodeMapper;
public Board(final Map<Point, Piece> pieceByPoint, final PointNodeMapper pointNodeMapper) {
this.pieceByPoint = pieceByPoint;
this.pointNodeMapper = pointNodeMapper;
}
public boolean isEnd() {
return !isTwoWangsAlive();
}
private boolean isTwoWangsAlive() {
return findTeamsOfWang().containsAll(List.of(Team.CHO, Team.HAN));
}
public Team findWinTeam() {
if (!isEnd()) {
throw new IllegalStateException("아직 게임이 끝나지 않았습니다.");
}
Set<Team> foundTeam = findTeamsOfWang();
if (foundTeam.contains(Team.CHO)) {
return Team.CHO;
}
return Team.HAN;
}
private Set<Team> findTeamsOfWang() {
return pieceByPoint.values().stream()
.filter(piece -> piece.type() == PieceType.WANG)
.map(Piece::team)
.collect(Collectors.toSet());
}
public boolean canMove(final Point source, final Point destination) {
if (!existsPiece(source)) {
return false;
}
Piece piece = getPieceByPoint(source);
return piece.canMove(source, destination, this);
}
public void movePiece(final Point source, final Point destination) {
Piece sourcePiece = getPieceByPoint(source);
if (!sourcePiece.canMove(source, destination, this)) {
throw new IllegalArgumentException(source + " -> " + destination + " [ERROR] 이동할 수 없는 경로입니다.");
}
pieceByPoint.put(destination, sourcePiece);
removePiece(source);
}
public boolean existsPiece(final Point point) {
if (!existsPoint(point)) {
return false;
}
return pieceByPoint.containsKey(point);
}
private boolean existsPoint(final Point point) {
return pointNodeMapper.existsPoint(point);
}
public boolean existsPo(final Point point) {
if (!existsPiece(point)) {
return false;
}
Piece piece = getPieceByPoint(point);
return piece.type() == PieceType.PO;
}
public void removePiece(final Point point) {
if (!existsPiece(point)) {
return;
}
Piece piece = getPieceByPoint(point);
pieceByPoint.remove(point, piece);
}
public boolean matchTeam(final Point point, final Team team) {
if (!existsPiece(point)) {
return false;
}
Piece piece = getPieceByPoint(point);
return piece.team() == team;
}
public boolean hasPieceType(final Point point, final PieceType pieceType) {
if (!existsPiece(point)) {
return false;
}
Piece piece = getPieceByPoint(point);
return piece.type() == pieceType;
}
private Piece getPieceByPoint(final Point point) {
if (!existsPiece(point)) {
throw new IllegalArgumentException(point + ": [ERROR] 해당 좌표에 기물이 존재하지 않습니다.");
}
return pieceByPoint.get(point);
}
public boolean existsNextPoint(final Point point, final Direction direction) {
if (!existsPoint(point)) {
return false;
}
Node node = pointNodeMapper.getNodeByPoint(point);
return node.hasNextNode(direction);
}
public Point getNextPoint(final Point point, final Direction direction) {
validateExistPoint(point);
Node node = pointNodeMapper.getNodeByPoint(point);
Node nextNode = node.getNextNodeByDirection(direction);
return pointNodeMapper.getPointByNode(nextNode);
}
public boolean canMoveByPath(final Point point, final Path path) {
if (!existsPoint(point)) {
return false;
}
Node node = pointNodeMapper.getNodeByPoint(point);
return node.canMoveByPath(path);
}
public Point getPointMovedByPath(final Point point, final Path path) {
validateExistPoint(point);
Node node = pointNodeMapper.getNodeByPoint(point);
return pointNodeMapper.getPointByNode(node.moveByPath(path));
}
private void validateExistPoint(final Point point) {
if (!existsPoint(point)) {
throw new IllegalArgumentException(point.row() + ", " + point.column() + ": 존재하지 않는 좌표입니다.");
}
}
public Map<Point, Piece> getPieceByPoint() {
return pieceByPoint;
}
}