Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
0ceec3c
docs(README): ์‚ฌ์ดํด 1: 1๋‹จ๊ณ„ ๊ตฌํ˜„ ๊ธฐ๋Šฅ ๋ชฉ๋ก ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 25, 2026
7f73e77
feat: ์žฅ๊ธฐํŒ ์ดˆ๊ธฐํ™” ์ „๋žต ๋ฒˆํ˜ธ ์ž…๋ ฅ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 25, 2026
0be33b8
feat: ์žฅ๊ธฐํŒ ์ดˆ๊ธฐ ๋ฐฐ์น˜ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 25, 2026
e8d6b4c
refactor(BoardAssembler): ์ƒ์„ฑ ์‹œ์— ์ „๋žต์„ ์ฃผ์ž…๋ฐ›๋„๋ก ๋ณ€๊ฒฝ
Yeji-Kim-Erica Mar 26, 2026
9c9605d
feat(BoardAssembler): ๋น„์–ด์žˆ๋Š” ์œ„์น˜๋ฅผ EmptyPiece ๊ฐ์ฒด๋กœ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 26, 2026
3f0af3a
refactor(Piece): ๊ฐ™์€ ํŽธ์„ ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ์ˆ˜์ •
Yeji-Kim-Erica Mar 26, 2026
381957c
feat(Board): ์žฅ๊ธฐํŒ ์ƒ์„ฑ ๋ฐ ๋ฐ˜ํ™˜ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 26, 2026
c1c423e
feat: ์žฅ๊ธฐํŒ ์ถœ๋ ฅ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 26, 2026
b750b23
refactor(JolByeong): ํด๋ž˜์Šค๋ช…์„ ํฌ๊ด„์  ์˜๋ฏธ๋ฅผ ๊ฐ–๋„๋ก ์ˆ˜์ •
Yeji-Kim-Erica Mar 26, 2026
d699f78
style: ๊ฐœํ–‰ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 26, 2026
8f0e517
docs(README): ์‚ฌ์ดํด 1: 2๋‹จ๊ณ„ ๊ตฌํ˜„ ๊ธฐ๋Šฅ ๋ชฉ๋ก ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 26, 2026
748f714
refactor: ์ •์ˆ˜๋ฅผ ์ฝ์–ด์˜ค๋Š” ๋ฉ”์„œ๋“œ๋ช… ๋ณ€๊ฒฝ
Yeji-Kim-Erica Mar 26, 2026
4060f81
feat: ๊ธฐ๋ฌผ ์ด๋™์„ ์œ„ํ•œ ์ขŒํ‘œ ์ž…๋ ฅ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 26, 2026
584b043
refactor: ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค ํŒจํ‚ค์ง€ ์ •๋ฆฌ
Yeji-Kim-Erica Mar 27, 2026
92c55ab
feat: ์กธ๋ณ‘์˜ ๊ธฐ๋ฌผ ์ด๋™ ๊ฒฝ๋กœ ์ขŒํ‘œ ๋ชฉ๋ก ๊ณ„์‚ฐ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 27, 2026
a9e05d2
feat: ๋งˆ์˜ ๊ธฐ๋ฌผ ์ด๋™ ๊ฒฝ๋กœ ์ขŒํ‘œ ๋ชฉ๋ก ๊ณ„์‚ฐ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 27, 2026
ac68f60
feat: ์ƒ์˜ ๊ธฐ๋ฌผ ์ด๋™ ๊ฒฝ๋กœ ์ขŒํ‘œ ๋ชฉ๋ก ๊ณ„์‚ฐ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 27, 2026
6322b8c
refactor: ๊ธฐ๋ฌผ ๋งˆ์™€ ์ƒ์˜ ํ…Œ์ŠคํŠธ๋ช…์„ ํ…Œ์ŠคํŠธ ๋‚ด์šฉ์— ๋งž๊ฒŒ ์ˆ˜์ •
Yeji-Kim-Erica Mar 27, 2026
f5f2291
feat: ๊ถ, ์‚ฌ์˜ ๊ธฐ๋ฌผ ์ด๋™ ๊ฒฝ๋กœ ์ขŒํ‘œ ๋ชฉ๋ก ๊ณ„์‚ฐ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 27, 2026
356b578
feat: ์ฐจ, ์ƒ์˜ ๊ธฐ๋ฌผ ์ด๋™ ๊ฒฝ๋กœ ์ขŒํ‘œ ๋ชฉ๋ก ๊ณ„์‚ฐ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 28, 2026
c605c7b
refactor: ๊ธฐ๋ฌผ ์ด๋™ ๊ทœ์น™์— ๋”ฐ๋ฅธ ๊ฒฝ๋กœ ๋ฐ˜ํ™˜ ํด๋ž˜์Šค์˜ ์ธํ„ฐํŽ˜์ด์Šค, ํด๋ž˜์Šค๋ช… ๋ณ€๊ฒฝ
Yeji-Kim-Erica Mar 28, 2026
0441baa
refactor: ๊ธฐ๋ฌผ ์ด๋™ ๊ทœ์น™ ๊ด€๋ จ ํŒจํ‚ค์ง€๋ช… ๋ณ€๊ฒฝ
Yeji-Kim-Erica Mar 28, 2026
2ed703c
feat: ๊ธฐ๋ฌผ ์ด๋™ ์‹œ ์žฅ์• ๋ฌผ ์ถฉ๋Œ ๊ฐ์ง€ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 28, 2026
8e916fd
feat: ํฌ ์ด๋™ ์‹œ ์žฅ์• ๋ฌผ ์ถฉ๋Œ ๊ฐ์ง€ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 28, 2026
6aadc0b
refactor: ํ…Œ์ŠคํŠธ์šฉ ๊ตฌํ˜„ ํด๋ž˜์Šค ํŒจํ‚ค์ง€๋กœ ์ •๋ฆฌ
Yeji-Kim-Erica Mar 28, 2026
5800252
feat(Board): ๊ธฐ๋ฌผ ์ด๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 28, 2026
b55d7fa
feat: ์ด๋™์ด ๋ฐ˜์˜๋œ ์žฅ๊ธฐํŒ ์ƒํƒœ ์ถœ๋ ฅ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 28, 2026
770eef2
refactor(EmptyPiece): ๋นˆ ๊ธฐ๋ฌผ์— ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด ์ ์šฉ
Yeji-Kim-Erica Mar 28, 2026
1c43383
refactor(strategy): ์ „๋žต ๊ตฌํ˜„ ํด๋ž˜์Šค์— ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด ์ ์šฉ
Yeji-Kim-Erica Mar 28, 2026
41c3287
refactor(rule): ๊ธฐ๋ฌผ ์ด๋™ ๊ทœ์น™ ๊ตฌํ˜„ ํด๋ž˜์Šค์— ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด ์ ์šฉ
Yeji-Kim-Erica Mar 28, 2026
dc92d78
refactor(piece): ๊ธฐ๋ฌผ ํƒ€์ž…์„ ๊ฒฐ์ •ํ•˜๋Š” Enum ๋„์ž…
Yeji-Kim-Erica Mar 28, 2026
f7db4f5
refactor: ๊ธธ ์ฐพ๊ธฐ ๊ณตํ†ต ๋กœ์ง ์ถ”์ถœ ๋ฐ ๋„๋ฉ”์ธ ๋„ค์ด๋ฐ/๊ฒ€์ฆ ๋กœ์ง ๊ฐœ์„ 
Yeji-Kim-Erica Mar 28, 2026
c8dc4e1
refactor(strategy): ๊ธฐ๋ฌผ ๋ฐฐ์น˜ ์ฑ…์ž„ ๋ถ„๋ฆฌ
Yeji-Kim-Erica Mar 28, 2026
491cfac
feat(controller): ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ์žฌ์ž…๋ ฅ ๋กœ์ง ์ถ”๊ฐ€ ๋ฐ ์ถœ๋ ฅ ๊ฐœ์„ 
Yeji-Kim-Erica Mar 28, 2026
b31fd46
refactor: ์•„ํ‚คํ…์ฒ˜ ์˜์กด์„ฑ ํ•ด์†Œ ๋ฐ ์˜ˆ์™ธ ํ๋ฆ„ ์ œ์–ด ์ค‘์•™ํ™”
Yeji-Kim-Erica Mar 28, 2026
ac709cd
refactor: ๋ฉ”์„œ๋“œ ๋„ค์ด๋ฐ ๊ฐœ์„  ๋ฐ ๋ถˆํ•„์š”ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ œ๊ฑฐ
Yeji-Kim-Erica Mar 31, 2026
89fc068
refactor(Side): ์ง„์˜ ๋ฐ˜์ „ ๋กœ์ง์— ๋ฐฉ์–ด์  ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์ถ”๊ฐ€
Yeji-Kim-Erica Mar 31, 2026
9508070
refactor(strategy): ๊ธฐ๋ฌผ ๋ฐฐ์น˜ ์ „๋žต ๊ตฌ์กฐ ๊ฐœ์„  ๋ฐ Resolver ๋„์ž…
Yeji-Kim-Erica Apr 1, 2026
d394f53
refactor: ๊ธฐ๋ฌผ ์ƒ์† ๊ตฌ์กฐ๋ฅผ ์กฐํ•ฉ์œผ๋กœ ์ „๋ฉด ๊ฐœํŽธ ๋ฐ ๋„๋ฉ”์ธ ๋ฆฌํŒฉํ† ๋ง
Yeji-Kim-Erica Apr 3, 2026
b6e9e76
refactor: View์˜ ๋ถˆํ•„์š”ํ•œ ์˜ˆ์™ธ ๊ฐ์ฒด ์˜์กด์„ฑ ์ œ๊ฑฐ
Yeji-Kim-Erica Apr 3, 2026
f031242
refactor: 2์ฐจ์› ๋ฐฐ์—ด ๋„ˆ๋น„ ์กฐํšŒ๋ฅผ ์œ„ํ•œ ์ธ๋ฑ์Šค ๋งค์ง ๋„˜๋ฒ„๋ฅผ ์ƒ์ˆ˜๋กœ ์ถ”์ถœ
Yeji-Kim-Erica Apr 3, 2026
d9e038a
refactor: ์žฌ๊ท€ ํ˜ธ์ถœ๋กœ ๊ตฌํ˜„๋œ ์ž…๋ ฅ ์žฌ์‹œ๋„ ๋กœ์ง์„ ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๊ฐœ์„ 
Yeji-Kim-Erica Apr 3, 2026
bc27b6b
refactor: 2์ฐจ์› ๋ฐฐ์—ด ์ดˆ๊ธฐํ™” ๋กœ์ง ๊ฐœ์„  ๋ฐ ์ธ๋ดํŠธ ๊ฐ์†Œ
Yeji-Kim-Erica Apr 3, 2026
3f25d1b
refactor: 2์ฐจ์› ๋ฐฐ์—ด ์ˆœํšŒ ์‹œ ๋ฐœ์ƒํ•˜๋Š” 2์ค‘ for๋ฌธ indent ๊ฐœ์„ 
Yeji-Kim-Erica Apr 3, 2026
6bc5a0c
feat: ์žฅ๊ธฐํŒ ํ…Œ๋‘๋ฆฌ ์ขŒํ‘œ(ํ–‰, ์—ด) ์ถœ๋ ฅ ๋ฐ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๋งคํ•‘ ๊ตฌํ˜„
Yeji-Kim-Erica Apr 3, 2026
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
64 changes: 64 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,67 @@
# java-janggi

์žฅ๊ธฐ ๋ฏธ์…˜ ์ €์žฅ์†Œ

---

## ๐Ÿ’ก ์ฃผ์š” ๊ฒŒ์ž„ ๊ทœ์น™

### ๊ธฐ๋ฌผ ์ด๋™ ๊ทœ์น™

- **๊ถ, ์‚ฌ**
- ๊ถ๊ถ ์•ˆ์—์„œ๋งŒ ๋ฐฉํ–ฅ ์ƒ๊ด€์—†์ด 1์นธ์”ฉ ์ด๋™
- ๋›ฐ์–ด๋„˜๊ธฐ ๋ถˆ๊ฐ€
- ์‹œ์ž‘ ์œ„์น˜ ๊ณ ์ •
- **์ƒ**
- ์•ž/์˜†/๋’ค 1์นธ + ๋Œ€๊ฐ์„  2์นธ
- ๋›ฐ์–ด๋„˜๊ธฐ ๋ถˆ๊ฐ€
- ๋งˆ์™€ ์œ„์น˜ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ
- **๋งˆ**
- ์•ž/์˜†/๋’ค 1์นธ + ๋Œ€๊ฐ์„  1์นธ
- ๋›ฐ์–ด๋„˜๊ธฐ ๋ถˆ๊ฐ€
- ์ƒ๊ณผ ์œ„์น˜ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ
- **์ฐจ**
- ์ง์„ ์œผ๋กœ ์›ํ•˜๋Š” ๋งŒํผ ์ด๋™
- ๋›ฐ์–ด๋„˜๊ธฐ ๋ถˆ๊ฐ€
- ์‹œ์ž‘ ์œ„์น˜ ๊ณ ์ •
- **ํฌ**
- ์•ž/์˜†/๋’ค ์›ํ•˜๋Š” ๋งŒํผ ์ด๋™
- ํฌ๋ฅผ ์ œ์™ธํ•œ ๊ธฐ๋ฌผ์„ 1๊ฐœ ๋›ฐ์–ด๋„˜์–ด์•ผ๋งŒ ์ด๋™
- ์‹œ์ž‘ ์œ„์น˜ ๊ณ ์ •
- **์กธ/๋ณ‘**
- ์•ž/์˜†์œผ๋กœ๋งŒ 1์นธ ์ „์ง„
- ๋›ฐ์–ด๋„˜๊ธฐ ๋ถˆ๊ฐ€
- ์‹œ์ž‘ ์œ„์น˜ ๊ณ ์ •

## ๐Ÿš€ ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ

### 1.1 **๋ณด๋“œ ์ดˆ๊ธฐํ™”**

๊ฒŒ์ž„ ์‹œ์ž‘ ์‹œ ์žฅ๊ธฐํŒ๊ณผ ์ „์ฒด ๊ธฐ๋ฌผ์„ ์˜ฌ๋ฐ”๋ฅธ ์œ„์น˜์— ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.

- [x] ์žฅ๊ธฐํŒ ์ดˆ๊ธฐํ™” ์ „๋žต์„ ๋ฒˆํ˜ธ๋กœ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค.
- ์ƒ๋งˆ๋งˆ์ƒ, ์ƒ๋งˆ์ƒ๋งˆ, ๋งˆ์ƒ๋งˆ์ƒ, ๋งˆ์ƒ์ƒ๋งˆ
- [x] ์‚ฌ์šฉ์ž ์ž…๋ ฅ๊ฐ’ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
- [x] ๊ณต๋ฐฑ์ธ ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
- [x] ์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๋ฌธ์ž์ผ ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
- [x] ์ •์ˆ˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
- [x] ๋„๋ฉ”์ธ ๊ทœ์น™ ๊ฒ€์ฆ
- [x] ์ž…๋ ฅ๊ฐ’์ด ์„ ํƒ์ง€ ๋ฒ”์œ„์— ํฌํ•จ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
- [x] ์ „๋žต์ด ๋ฐ˜์˜๋œ ์žฅ๊ธฐํŒ ์ƒํƒœ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

### 1.2 ๊ธฐ๋ฌผ ์ด๋™

- [x] ์ด๋™ํ•  ๊ธฐ๋ฌผ์˜ ์œ„์น˜์™€ ์ด๋™ํ•  ์œ„์น˜๋ฅผ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค.
- [x] ์‚ฌ์šฉ์ž ์ž…๋ ฅ๊ฐ’ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
- [x] ๊ณต๋ฐฑ์ธ ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
- [x] `,` ๋กœ ๊ตฌ๋ถ„๋œ ์ขŒํ‘œ ํ˜•์‹์ด ์•„๋‹Œ ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
- [x] ์ขŒํ‘œ๊ฐ’์ด ์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
- [x] ์ขŒํ‘œ๊ฐ’์ด ์ •์ˆ˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
- [x] ๋„๋ฉ”์ธ ๊ทœ์น™ ๊ฒ€์ฆ
- [x] ์ขŒํ‘œ๊ฐ’์ด ๋ณด๋“œํŒ์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
- [x] ํ•ด๋‹น ์ขŒํ‘œ์— ์ด๋™์‹œํ‚ค๊ณ ์ž ํ•˜๋Š” ๊ธฐ๋ฌผ์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
- [x] ๊ธฐ๋ฌผ์„ ์ด๋™์‹œํ‚จ๋‹ค.
- [x] ๋„๋ฉ”์ธ ๊ทœ์น™ ๊ฒ€์ฆ
- [x] ๊ธฐ๋ฌผ ๊ทœ์น™์— ๋”ฐ๋ผ ์ด๋™ํ•  ์œ„์น˜์— ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
- [x] ์ด๋™ํ•  ์œ„์น˜์˜ ๊ธฐ์กด ๊ธฐ๋ฌผ์€ ์ œ๊ฑฐ๋œ๋‹ค.
- [x] ์ด๋™์ด ๋ฐ˜์˜๋œ ์žฅ๊ธฐํŒ ์ƒํƒœ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.
Empty file removed src/main/java/.gitkeep
Empty file.
16 changes: 16 additions & 0 deletions src/main/java/janggi/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package janggi;

import janggi.controller.JanggiFlow;
import janggi.view.ApplicationView;
import janggi.view.ConsoleReader;
import janggi.view.ConsoleWriter;

public class Application {

public static void main(String[] args) {
ApplicationView view = new ApplicationView(new ConsoleWriter(), new ConsoleReader());
JanggiFlow janggi = new JanggiFlow(view);

janggi.process();
}
}
67 changes: 67 additions & 0 deletions src/main/java/janggi/controller/ArrangementOption.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package janggi.controller;

import static janggi.domain.piece.PieceType.MA;
import static janggi.domain.piece.PieceType.SANG;

import janggi.domain.Side;
import janggi.domain.piece.PieceType;
import janggi.strategy.ArrangementStrategy;
import janggi.strategy.MaSangArrangementStrategy;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public enum ArrangementOption {
MA_SANG_MA_SANG(1, "๋งˆ์ƒ๋งˆ์ƒ", List.of(MA, SANG, MA, SANG)),
SANG_MA_SANG_MA(2, "์ƒ๋งˆ์ƒ๋งˆ", List.of(SANG, MA, SANG, MA)),
SANG_MA_MA_SANG(3, "์ƒ๋งˆ๋งˆ์ƒ", List.of(SANG, MA, MA, SANG)),
MA_SANG_SANG_MA(4, "๋งˆ์ƒ์ƒ๋งˆ", List.of(MA, SANG, SANG, MA));

private static final Map<Integer, String> STRATEGY_OPTIONS =
Collections.unmodifiableMap(
Arrays.stream(values())
.collect(Collectors.toMap(
ArrangementOption::getOptionNumber,
ArrangementOption::getDisplayName,
(existing, replacement) -> existing,
LinkedHashMap::new
))
);

private final int optionNumber;
private final String displayName;
private final List<PieceType> arrangement;

ArrangementOption(int optionNumber, String displayName, List<PieceType> arrangement) {
this.optionNumber = optionNumber;
this.displayName = displayName;
this.arrangement = arrangement;
}

public static ArrangementStrategy createStrategyOf(Side side, int optionNumber) {
return Arrays.stream(values())
.filter(resolver -> resolver.optionNumber == optionNumber)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("์œ ํšจํ•˜์ง€ ์•Š์€ ๋ฐฐ์น˜ ์ „๋žต ๋ฒˆํ˜ธ์ž…๋‹ˆ๋‹ค."))
.toStrategy(side);
}

public static Map<Integer, String> getStrategyOptions() {
return STRATEGY_OPTIONS;
}

private int getOptionNumber() {
return optionNumber;
}

private String getDisplayName() {
return displayName;
}

private ArrangementStrategy toStrategy(Side side) {
return MaSangArrangementStrategy.of(side, arrangement);
}
}
106 changes: 106 additions & 0 deletions src/main/java/janggi/controller/JanggiFlow.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package janggi.controller;

import janggi.domain.Location;
import janggi.domain.Side;
import janggi.domain.board.Board;
import janggi.domain.piece.Piece;
import janggi.domain.piece.PieceType;
import janggi.strategy.ArrangementStrategy;
import janggi.strategy.BoardAssembler;
import janggi.view.ApplicationView;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

public class JanggiFlow {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flow๋Š” ์–ด๋–ค ๊ฒƒ์„ ์˜๋ฏธํ•˜๋‚˜์š”?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์™œ controller ํŒจํ‚ค์ง€ ์•ˆ์— ์žˆ๋‚˜์š”? controller๋Š” ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋‚˜์š”?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ํด๋ž˜์Šค์˜ ์—ญํ• ๊ณผ ๋„ค์ด๋ฐ์— ๋Œ€ํ•ด ๋ณธ์งˆ์ ์ธ ๊ณ ๋ฏผ์„ ๋˜์ ธ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!
๋‘ ์งˆ๋ฌธ์ด ๊ฒฐ๊ตญ '์ด ํด๋ž˜์Šค์˜ ์ •์ฒด์„ฑ'์„ ํ–ฅํ•˜๊ณ  ์žˆ์–ด์„œ ํ•จ๊ป˜ ๋ฌถ์–ด์„œ ๋‹ต๋ณ€์„ ๋‚จ๊ฒจ๋ด…๋‹ˆ๋‹ค.

1. Controller๋Š” ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๊ณ , ์™œ ์ด ํŒจํ‚ค์ง€์— ์žˆ๋‚˜์š”?

์ œ๊ฐ€ ์ƒ๊ฐํ•œ Controller๋Š” Model๊ณผ View ์‚ฌ์ด๋ฅผ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ์ค‘์žฌ์ž์ž…๋‹ˆ๋‹ค. Board, Piece ๋“ฑ์˜ ๋„๋ฉ”์ธ์€ ์ฝ˜์†” ์ž…๋ ฅ/์ถœ๋ ฅ์„ ์ „ํ˜€ ๋ชจ๋ฅธ ์ฑ„ ์ˆœ์ˆ˜ ์žฅ๊ธฐ ๊ทœ์น™๋งŒ ์ฒ˜๋ฆฌํ•˜๊ณ , View๋Š” ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์กฐ์ž‘ํ•˜์ง€ ์•Š๊ณ  ๋ฐ์ดํ„ฐ๋งŒ ๋ฟŒ๋ฆฌ๋„๋ก ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์˜€์Šต๋‹ˆ๋‹ค.
ํ˜„์žฌ ์ด ํด๋ž˜์Šค๋Š” View๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๋ฐ›๊ณ , ๋„๋ฉ”์ธ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด ๋ช…๋ น์„ ๋‚ด๋ฆฌ๋ฉฐ, ๋‹ค์‹œ ๋„๋ฉ”์ธ์˜ ์ƒํƒœ๋ฅผ View๋กœ ์ „๋‹ฌํ•˜๋Š” ๋‹ค๋ฆฌ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— controller ํŒจํ‚ค์ง€์— ๋ฐฐ์น˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

2. Flow๋Š” ์–ด๋–ค ๊ฒƒ์„ ์˜๋ฏธํ•˜๋‚˜์š”?

'Flow'๋ผ๋Š” ์ด๋ฆ„์€ ์ด ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์žฅ๊ธฐ ๊ฒŒ์ž„์˜ ์ „์ฒด์ ์ธ ์ง„ํ–‰ ํ๋ฆ„์„ ์ œ์–ดํ•œ๋‹ค๋Š” ์˜๋ฏธ๋กœ ์ง€์—ˆ์Šต๋‹ˆ๋‹ค.
(๋ฐฐ์น˜ ์ „๋žต ๋ฌป๊ธฐ -> ์ดˆ๊ธฐ ์„ธํŒ… -> ์ŠนํŒจ๊ฐ€ ๋‚  ๋•Œ๊นŒ์ง€ ํ„ด์„ ๋ฐ˜๋ณตํ•˜๋ฉฐ ๊ธฐ๋ฌผ ์ด๋™ํ•˜๊ธฐ)

๋‹ค๋งŒ ์งˆ๋ฌธ์„ ๋ฐ›๊ณ  ๋‹ค์‹œ ์ƒ๊ฐํ•ด ๋ณด๋‹ˆ, 'Flow'๋ผ๋Š” ๋‹จ์–ด๋Š” ์ƒํƒœ๋‚˜ ์—ญํ• ๋ณด๋‹ค๋Š” 'ํ˜„์ƒ ์ž์ฒด'์— ๊ฐ€๊นŒ์šด ์ถ”์ƒ์ ์ธ ๋‹จ์–ด๋ผ,
์ฒ˜์Œ ์ฝ”๋“œ๋ฅผ ๋ณด๋Š” ์‚ฌ๋žŒ์—๊ฒŒ ์ด ํด๋ž˜์Šค๊ฐ€ MVC์˜ ์ปจํŠธ๋กค๋Ÿฌ๋ผ๋Š” ์ ์ด ์ง๊ด€์ ์œผ๋กœ ์™€๋‹ฟ์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.
์ด ํด๋ž˜์Šค์˜ ์ค‘์žฌ์ž ์—ญํ• ์ด ๋” ๋ช…ํ™•ํžˆ ๋“œ๋Ÿฌ๋‚˜๋„๋ก JanggiController ํ˜น์€ ๊ฒŒ์ž„์˜ ์ „์ฒด ํ๋ฆ„์„ ํ†ต์ œํ•œ๋‹ค๋Š” ์˜๋ฏธ์˜ GameController๋กœ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ ๋” ๊ถŒ์žฅํ•˜์‹œ๋Š”์ง€ ์ดˆ์ฝ”์นฉ์˜ ์˜๊ฒฌ์ด ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค! ๐Ÿ™‡โ€โ™‚๏ธ


private final ApplicationView view;

public JanggiFlow(ApplicationView view) {
this.view = view;
}

public void process() {
ArrangementStrategy hanStrategy = repeatAskStrategyUntilSuccess(Side.HAN);
ArrangementStrategy choStrategy = repeatAskStrategyUntilSuccess(Side.CHO);
Board board = Board.create(BoardAssembler.from(List.of(hanStrategy, choStrategy)));

Side current = Side.HAN;
while (board.isNotEmpty()) {
view.showBoardArray(convertBoardStatus(board));
view.showCurrentSide(current.getName());

final Side turnSide = current;
retryUntilPieceIsSuccessfullyMoved(() -> {
Location from = repeatAskLocationOfPieceUntilSuccess(turnSide, board);
Location to = repeatAskLocationToMoveUntilSuccess(from, board);
board.move(from, to);
});
current = current.switchSide();
}
}

private <T> T retry(Supplier<T> supplier) {
while (true) {
try {
return supplier.get();
} catch (IllegalArgumentException e) {
view.showErrorMessage(e.getMessage());
}
}
}

private List<List<String>> convertBoardStatus(Board board) {
List<List<Piece>> boardIn2D = board.to2DArray();
return boardIn2D.stream()
.map(
row -> row.stream()
.map(Piece::getPieceType)
.map(PieceType::getNameFormat)
.toList()
).toList();
}

private ArrangementStrategy repeatAskStrategyUntilSuccess(Side side) {
return retry(() -> askStrategy(side));
}

private ArrangementStrategy askStrategy(Side side) {
Map<Integer, String> strategyInfos = ArrangementOption.getStrategyOptions();
int decisionNumber = view.promptForArrangementStrategyDecision(side.getName(), strategyInfos);
return ArrangementOption.createStrategyOf(side, decisionNumber);
}

private Location repeatAskLocationOfPieceUntilSuccess(Side turnSide, Board board) {
return retry(() -> askLocationOfPiece(turnSide, board));
}

private Location askLocationOfPiece(Side current, Board board) {
List<Integer> locationOfPiece = view.promptForLocationOfPiece();
Location verifiedLocation = Location.from(locationOfPiece);
board.validateLocationOfPiece(current, verifiedLocation);
return verifiedLocation;
}

private Location repeatAskLocationToMoveUntilSuccess(Location from, Board board) {
return retry(() -> askLocationToMove(from, board));
}

private Location askLocationToMove(Location startingLocation, Board board) {
List<Integer> locationToMove = view.promptForLocationToMove();
Location verifiedLocation = Location.from(locationToMove);
board.validateLocationToMove(startingLocation, verifiedLocation);
return verifiedLocation;
}

private void retryUntilPieceIsSuccessfullyMoved(Runnable runnable) {
while (true) {
try {
runnable.run();
break;
} catch (IllegalArgumentException e) {
view.showErrorMessage(e.getMessage());
}
}
}
}
33 changes: 33 additions & 0 deletions src/main/java/janggi/domain/Location.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package janggi.domain;

import java.util.List;

public record Location(int x, int y) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ผ๋ฐ˜์ ์œผ๋กœ x๋Š” ์—ด, y๋Š” ํ–‰์„ ์˜๋ฏธํ•˜์ง€ ์•Š๋‚˜์š”?(์•Œ๊ณ ๋ฆฌ์ฆ˜ ํ’€ ๋•Œ ๊ทธ๋ ‡๊ฒŒ ์ผ๋˜ ๊ธฐ์–ต์ด ์žˆ๋„ค์š” ๐Ÿค”)
์—ฌ๊ธฐ๋Š” ๋ฐ˜๋Œ€๋กœ ์“ฐ์ด๋Š” ๊ฒƒ ๊ฐ™๋„ค์š”. ์•„๋‹ˆ๋ฉด row, col๋กœ ๋” ๋ช…์‹œ์ ์œผ๋กœ ํ‘œํ˜„ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ค๊ฐ€์š”?


private static final int COORDINATION_COUNT = 2;

public static Location from(List<Integer> coordination) {
validateCount(coordination);
int row = coordination.get(0) - 1;
int col = coordination.get(1) - 1;
return new Location(row, col);
}

private static void validateCount(List<Integer> coordination) {
if (coordination.size() != COORDINATION_COUNT) {
throw new IllegalArgumentException("์ขŒํ‘œ์˜ ๊ฐœ์ˆ˜๋Š” " + COORDINATION_COUNT + "๊ฐœ ์ž…๋‹ˆ๋‹ค.");
}
}

public Location add(int dx, int dy) {
return new Location(x + dx, y + dy);
}

public int calculateHorizontalDiff(Location to) {
return to.y - this.y;
}

public int calculateVerticalDiff(Location to) {
return to.x - this.x;
}
}
28 changes: 28 additions & 0 deletions src/main/java/janggi/domain/Side.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package janggi.domain;

public enum Side {

HAN("ํ•œ"),
CHO("์ดˆ"),
NONE("์—†์Œ");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NONE์ด ํ˜„์žฌ ์“ฐ์ด๋‚˜์š”?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์•„๋ž˜์™€ ๊ฐ™์ด ์“ฐ๋ฉด, ๋‹ค์Œ ์‚ฌ๋žŒ์ด ๋‹ค๋ฅธ Enum์„ ์ถ”๊ฐ€ํ• ๋•Œ ๋ณ€๊ฒฝ์‚ฌํ•ญ์— ์•ˆ ์žกํžˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค :)

Suggested change
NONE("์—†์Œ");
NONE("์—†์Œ"),
;


private final String name;

Side(String name) {
this.name = name;
}

public Side switchSide() {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enum์ด ์ž์‹ ์˜ ๋‹ค์Œ ์ƒํƒœ๋ฅผ if/if๋กœ ํŒ๋‹จํ•˜๊ณ  ์žˆ๋„ค์š”.
์ƒ์ˆ˜๊ฐ€ ์ž์‹ ์˜ ๋‹ค์Œ ์ƒํƒœ๋ฅผ ์ง์ ‘ ์•Œ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์ง€ ์•Š์„๊นŒ์š”?

if (this == HAN) {
return CHO;
}
if (this == CHO) {
return HAN;
}
throw new UnsupportedOperationException("์ง„์˜์ด ์กด์žฌํ•˜์ง€ ์•Š์•„ ์ง„์˜์„ ๋ฐ˜์ „์‹œํ‚ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.");
}

public String getName() {
return name;
}
}
Loading