Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.idea
.gradle
.gradle-home
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
Expand Down
2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 13 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.5.3'
id 'io.spring.dependency-management' version '1.1.4'
}

group = 'com.yourssu'
version = '1.0-SNAPSHOT'
version = '1.0.0'

java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
developmentOnly 'org.springframework.boot:spring-boot-devtools'

testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.0'
Expand Down
70 changes: 70 additions & 0 deletions docs/api-specs/endpoints/create-game.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# createGame (POST /api/v1/games)

새로운 오목 게임을 생성합니다.

## Request

### Request Header

| Name | Type | Required | Description |
|------------|--------|----------|--------------------|
| `X-Player` | string | Yes | `BLACK` or `WHITE` |

### Request Body

| Name | Type | Required | Constraint | Description |
|--------|---------|----------|---------------|-----------------|
| `size` | integer | No | 5 ≤ size ≤ 15 | 보드 크기 (기본값: 15) |

### Example Request

```json
{
"size": 15
}
```

## Reply

### Response Body

| Name | Type | Nullable | Description |
|---------------|----------|----------|--------------------------------------------|
| `gameId` | string | No | 게임 고유 식별자 (생성 방식은 구현자가 선택) |
| `size` | integer | No | 보드 크기 |
| `status` | string | No | 게임 상태 (`IN_PROGRESS`, `COMPLETED`, `DRAW`) |
| `currentTurn` | string | No | 현재 차례 플레이어 (`BLACK`, `WHITE`) |
| `board` | string[] | No | 보드 상태 (각 행을 문자열로 표현) |
| `createdAt` | string | No | 게임 생성 시각 (ISO-8601 UTC) |

### Example Response

```json
{
"timestamp": "2025-11-14T15:09:00Z",
"result": {
"gameId": "game-001",
"size": 15,
"status": "IN_PROGRESS",
"currentTurn": "BLACK",
"board": [
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############"
],
"createdAt": "2025-11-14T15:09:00Z"
}
}
```
92 changes: 92 additions & 0 deletions docs/api-specs/endpoints/get-game-status.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# getGameStatus (GET /api/v1/games/{gameId})

지정한 게임의 상태를 조회합니다.

## Path Parameters

| Name | Type | Required | Description |
|----------|--------|----------|-------------|
| `gameId` | string | Yes | 게임 고유 식별자 |

## Request

### Request Header

| Name | Type | Required | Description |
|------------|--------|----------|--------------------|
| `X-Player` | string | Yes | `BLACK` or `WHITE` |

## Reply

### Response Body

| Name | Type | Nullable | Description |
|---------------|----------|----------|-----------------------------------|
| `gameId` | string | No | 게임 고유 식별자 (생성 방식은 구현자가 선택) |
| `size` | integer | No | 보드 크기 |
| `status` | string | No | 게임 상태 |
| `currentTurn` | string | Yes | 현재 차례 플레이어 (게임 종료 시 null) |
| `winner` | string | Yes | 승리한 플레이어 (`BLACK`, `WHITE`, null) |
| `board` | string[] | No | 보드 상태 |
| `turnCount` | integer | No | 현재 턴 수 |
| `lastMove` | Move | Yes | 마지막으로 둔 수 |
| `createdAt` | string | No | 게임 생성 시각 |
| `updatedAt` | string | No | 마지막 업데이트 시각 |

### Move Object

| Name | Type | Nullable | Description |
|--------------|------------|----------|-------------------------|
| `player` | string | No | 플레이어 (`BLACK`, `WHITE`) |
| `coordinate` | Coordinate | No | 돌을 놓은 좌표 |
| `turnNumber` | integer | No | 턴 번호 |

### Coordinate Object

| Name | Type | Nullable | Description |
|----------|---------|----------|-------------|
| `column` | string | No | 열 (A~O) |
| `row` | integer | No | 행 (1~15) |

### Example Response

```json
{
"timestamp": "2025-11-14T15:10:30Z",
"result": {
"gameId": "game-001",
"size": 15,
"status": "IN_PROGRESS",
"currentTurn": "WHITE",
"winner": null,
"board": [
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"#O#############",
"X##############"
],
"turnCount": 2,
"lastMove": {
"player": "WHITE",
"coordinate": {
"column": "B",
"row": 2
},
"turnNumber": 2
},
"createdAt": "2025-11-14T15:09:00Z",
"updatedAt": "2025-11-14T15:10:30Z"
}
}
```
186 changes: 186 additions & 0 deletions docs/api-specs/endpoints/place-stone.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# placeStone (POST /api/v1/games/{gameId}/stones)

지정한 게임의 좌표에 돌을 놓습니다.

## Path Parameters

| Name | Type | Required | Description |
|----------|--------|----------|-------------|
| `gameId` | string | Yes | 게임 고유 식별자 |

## Request

### Request Header

| Name | Type | Required | Description |
|------------|--------|----------|--------------------|
| `X-Player` | string | Yes | `BLACK` or `WHITE` |

### Request Body

| Name | Type | Required | Description |
|--------------|------------|----------|-------------|
| `coordinate` | Coordinate | Yes | 돌을 놓을 좌표 |

### Coordinate Object

| Name | Type | Required | Constraint | Description |
|----------|---------|----------|------------|-------------|
| `column` | string | Yes | A~O | 열 |
| `row` | integer | Yes | 1~15 | 행 |

### Example Request

```json
{
"coordinate": {
"column": "A",
"row": 1
}
}
```

## Reply

### Response Body

| Name | Type | Nullable | Description |
|--------|------|----------|-------------|
| `move` | Move | No | 방금 둔 수 정보 |
| `game` | Game | No | 업데이트된 게임 상태 |

### Move Object

| Name | Type | Nullable | Description |
|--------------|------------|----------|-------------|
| `player` | string | No | 플레이어 |
| `coordinate` | Coordinate | No | 좌표 |
| `turnNumber` | integer | No | 턴 번호 |
| `placedAt` | string | No | 수를 둔 시각 |

### Game Object

| Name | Type | Nullable | Description |
|---------------|--------------|----------|----------------------------|
| `gameId` | string | No | 게임 고유 식별자 (생성 방식은 구현자가 선택) |
| `size` | integer | No | 보드 크기 |
| `status` | string | No | 게임 상태 |
| `currentTurn` | string | Yes | 다음 차례 플레이어 |
| `winner` | string | Yes | 승리자 |
| `winningLine` | Coordinate[] | Yes | 승리한 5개 돌의 좌표 |
| `board` | string[] | No | 보드 상태 |
| `turnCount` | integer | No | 턴 수 |
| `updatedAt` | string | No | 업데이트 시각 |

### Example Response (게임 진행 중)

```json
{
"timestamp": "2025-11-14T15:11:00Z",
"result": {
"move": {
"player": "BLACK",
"coordinate": {
"column": "C",
"row": 3
},
"turnNumber": 3,
"placedAt": "2025-11-14T15:11:00Z"
},
"game": {
"gameId": "game-001",
"size": 15,
"status": "IN_PROGRESS",
"currentTurn": "WHITE",
"winner": null,
"winningLine": null,
"board": [
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"##X############",
"#O#############",
"X##############"
],
"turnCount": 3,
"updatedAt": "2025-11-14T15:11:00Z"
}
}
}
```

### Example Response (게임 종료 - 승리)

```json
{
"timestamp": "2025-11-14T15:15:00Z",
"result": {
"move": {
"player": "BLACK",
"coordinate": {
"column": "E",
"row": 5
},
"turnNumber": 9,
"placedAt": "2025-11-14T15:15:00Z"
},
"game": {
"gameId": "game-001",
"size": 15,
"status": "COMPLETED",
"currentTurn": null,
"winner": "BLACK",
"winningLine": [
{
"column": "A",
"row": 1
},
{
"column": "B",
"row": 2
},
{
"column": "C",
"row": 3
},
{
"column": "D",
"row": 4
},
{
"column": "E",
"row": 5
}
],
"board": [
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"###############",
"####X##########",
"###X###########",
"##X############",
"#XOO###########",
"XOOO###########"
],
"turnCount": 9,
"updatedAt": "2025-11-14T15:15:00Z"
}
}
}
```
Loading