아무도 앉지 않은 방은 마지막 사람이 [방 나가기]로 나가면 바로 닫기

- 컴퓨터가 있는 방에만 있던 '나가서 앉은 사람이 없으면 바로 닫기'를 모든 방에 적용
  (아무도 들어오지 않은 대기실을 만든 사람이 나가면 목록에서 바로 사라짐)
- 관전자가 남아 있으면 그대로 두고, 마지막 관전자가 나갈 때 닫음
- 사이트를 닫거나 다른 화면으로 간 경우(자리 유지)는 기존 규칙 그대로

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
EJClaw
2026-10-08 10:14:29 +09:00
parent f5671cda70
commit beaee4675d
3 changed files with 35 additions and 3 deletions

View File

@@ -312,6 +312,38 @@ describe('practice rooms close once nobody is there', () => {
expect(h.manager.get(room.code)).toBeUndefined();
});
test('a room nobody joined closes as soon as the host leaves it', () => {
const h = harness();
const room = h.create('A', 'omok', 'public');
room.join(h.conn('A'), 'player');
expect(h.manager.publicRooms('omok')).toHaveLength(1);
room.leave('A');
expect(h.manager.get(room.code)).toBeUndefined();
expect(h.store.openRooms()).toHaveLength(0);
expect(h.manager.publicRooms('omok')).toHaveLength(0);
// Taking a seat in another room frees the lobby seat: same thing.
const first = h.create('B');
const b = h.conn('B');
first.join(b, 'player');
first.disconnect(b);
h.manager.releaseOtherLobbySeats('B', 'other');
expect(h.manager.get(first.code)).toBeUndefined();
});
test('the last person leaving a game on purpose closes it; a spectator still watching keeps it', () => {
const h = harness();
const room = h.create('A');
room.join(h.conn('A'), 'player');
room.join(h.conn('B'), 'player');
room.join(h.conn('S'), 'spectator');
expect(room.start('A')).toBeNull();
room.leave('A');
room.leave('B');
expect(h.manager.get(room.code)).toBe(room); // S is still connected
room.leave('S');
expect(h.manager.get(room.code)).toBeUndefined();
});
test('rooms without computers keep the old timeouts; someone still connected keeps any room', () => {
const h = harness();
const room = h.create('A');

View File

@@ -50,8 +50,8 @@ export class RoomManager {
settings: this.deps.settings,
botDelay: this.deps.botDelay,
onEmpty: (room, why) => {
// Everyone left a room with computer players on purpose: nobody can come back to it, close it now.
if (why === 'leave' && this.byCode.get(room.code) === room && room.hasBots() && !room.hasPeopleSeated()) this.close(room);
// The last person left on purpose and nobody holds a seat (only computers, or nobody joined): close it now.
if (why === 'leave' && this.byCode.get(room.code) === room && !room.hasPeopleSeated()) this.close(room);
},
onSeatChange: (room, userId, seated) => {
if (isBotId(userId)) return;