diff --git a/.idea/misc.xml b/.idea/misc.xml
index cc61dbb..dbff33b 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -16,7 +16,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index ccfd51a..b1ac391 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,6 +2,7 @@
+
diff --git a/.idea/modules/clubs.main.iml b/.idea/modules/clubs.main.iml
index afc1871..cc1e2ab 100644
--- a/.idea/modules/clubs.main.iml
+++ b/.idea/modules/clubs.main.iml
@@ -3,6 +3,7 @@
+
\ No newline at end of file
diff --git a/src/main/java/org/mmga/clubs/controller/ChessController.java b/src/main/java/org/mmga/clubs/controller/ChessController.java
index 2cf4cc4..0fd8c8d 100644
--- a/src/main/java/org/mmga/clubs/controller/ChessController.java
+++ b/src/main/java/org/mmga/clubs/controller/ChessController.java
@@ -16,10 +16,7 @@ import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.mmga.clubs.entities.chess.Room;
import org.mmga.clubs.entities.chess.packet.*;
-import org.mmga.clubs.entities.chess.packet.request.CreateRoomRequest;
-import org.mmga.clubs.entities.chess.packet.request.PlaceChessPieceRequest;
-import org.mmga.clubs.entities.chess.packet.request.PlayerJoinRequest;
-import org.mmga.clubs.entities.chess.packet.request.RoomListRequest;
+import org.mmga.clubs.entities.chess.packet.request.*;
import org.mmga.clubs.entities.user.User;
import org.mmga.clubs.service.UserService;
import org.mmga.clubs.utils.JwtUtils;
@@ -128,6 +125,23 @@ public class ChessController {
Optional s = roomByPlayer.downPiece(x, y, sessionId);
if (s.isPresent()) return new ErrorPacket(s.get());
roomByPlayer.broadcast(roomByPlayer.getRoomInfo(users));
+ Optional winInfo = roomByPlayer.isWin();
+ winInfo.ifPresent(info -> {
+ roomByPlayer.broadcast(new HasPlayerWinPacket(info));
+ if (info.isWhite()) {
+ WebSocketUtils.sendPacketIfPossible(new PlayerWinPacket(), roomByPlayer.getWhiteSession());
+ WebSocketUtils.sendPacketIfPossible(new PlayerLosePacket(), roomByPlayer.getBlackSession());
+ } else {
+ WebSocketUtils.sendPacketIfPossible(new PlayerWinPacket(), roomByPlayer.getBlackSession());
+ WebSocketUtils.sendPacketIfPossible(new PlayerLosePacket(), roomByPlayer.getWhiteSession());
+ }
+ });
+ }
+ if (payload instanceof ResetRoomRequest) {
+ Room roomByPlayer = getRoomByPlayer(sessionId);
+ if (roomByPlayer == null) return new ErrorPacket("你还没加入房间呢");
+ roomByPlayer.requestRestart(session);
+ roomByPlayer.broadcast(roomByPlayer.getRoomInfo(users));
}
} catch (ClassNotFoundException e) {
return new ErrorPacket("错误的请求类型");
diff --git a/src/main/java/org/mmga/clubs/entities/chess/Room.java b/src/main/java/org/mmga/clubs/entities/chess/Room.java
index fc6cecc..589f529 100644
--- a/src/main/java/org/mmga/clubs/entities/chess/Room.java
+++ b/src/main/java/org/mmga/clubs/entities/chess/Room.java
@@ -27,6 +27,9 @@ public class Room {
private Session blackSession;
@JSONField(serialize = false, deserialize = false)
private byte[][] pieces;
+ private boolean isWhiteAcceptRestart;
+ private boolean isBlackAcceptRestart;
+ private boolean canWhiteDown;
public Room() {
this.id = UUID.randomUUID();
@@ -35,12 +38,15 @@ public class Room {
}
public void resetPieces() {
+ this.canWhiteDown = false;
this.pieces = new byte[16][16];
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
this.pieces[i][j] = -1;
}
}
+ isWhiteAcceptRestart = false;
+ isBlackAcceptRestart = false;
}
public boolean isFull() {
@@ -105,17 +111,56 @@ public class Room {
byte originalValue = this.pieces[y][x];
if (originalValue != -1) return Optional.of("此位置已落子!");
if (whiteSession.getId().equals(sessionId)) {
+ if (!canWhiteDown) return Optional.of("请等待对手落子");
+ canWhiteDown = false;
this.pieces[y][x] = 1;
} else {
+ if (canWhiteDown) return Optional.of("请等待对手落子");
+ canWhiteDown = true;
this.pieces[y][x] = 0;
}
return Optional.empty();
}
public Optional isWin() {
+ for (int y = 0; y < 16; y++) {
+ for (int x = 0; x < 16; x++) {
+ byte startPointType = this.pieces[y][x];
+ if (startPointType == -1) continue;
+ for (Faces value : Faces.values()) {
+ boolean facePossible = true;
+ for (int i = 1; i < 5; i++) {
+ int totalXDelta = value.xDelta * i;
+ int totalYDelta = value.yDelta * i;
+ int fullyX = x + totalXDelta;
+ int fullyY = y + totalYDelta;
+ if (fullyX < 0 || fullyX > 15 || fullyY < 0 || fullyY > 15) {
+ facePossible = false;
+ break;
+ }
+ if (this.pieces[fullyY][fullyX] != startPointType) {
+ facePossible = false;
+ break;
+ }
+ }
+ if (!facePossible) continue;
+ return Optional.of(new WinInfo(value, x, y, startPointType == 1));
+ }
+ }
+ }
return Optional.empty();
}
+ public void requestRestart(Session session) {
+ String sessionId = session.getId();
+ if (sessionId.equals(whiteSession.getId())) {
+ isWhiteAcceptRestart = true;
+ }
+ if (sessionId.equals(blackSession.getId())) {
+ isBlackAcceptRestart = true;
+ }
+ }
+
public enum RoomState {
CREATED,
WAITING,
diff --git a/src/main/java/org/mmga/clubs/entities/chess/packet/HasPlayerWinPacket.java b/src/main/java/org/mmga/clubs/entities/chess/packet/HasPlayerWinPacket.java
new file mode 100644
index 0000000..eb2f235
--- /dev/null
+++ b/src/main/java/org/mmga/clubs/entities/chess/packet/HasPlayerWinPacket.java
@@ -0,0 +1,6 @@
+package org.mmga.clubs.entities.chess.packet;
+
+import org.mmga.clubs.entities.chess.Room;
+
+public record HasPlayerWinPacket(Room.WinInfo winInfo) {
+}
diff --git a/src/main/java/org/mmga/clubs/entities/chess/packet/request/ResetRoomRequest.java b/src/main/java/org/mmga/clubs/entities/chess/packet/request/ResetRoomRequest.java
new file mode 100644
index 0000000..4fd7d38
--- /dev/null
+++ b/src/main/java/org/mmga/clubs/entities/chess/packet/request/ResetRoomRequest.java
@@ -0,0 +1,4 @@
+package org.mmga.clubs.entities.chess.packet.request;
+
+public record ResetRoomRequest() {
+}