-
Notifications
You must be signed in to change notification settings - Fork 166
[๐ ์ฌ์ดํด1 - ๋ฏธ์ (๋ณด๋ ์ด๊ธฐํ + ๊ธฐ๋ฌผ ์ด๋)] ํ ๋ฆฌ ๋ฏธ์ ์ ์ถํฉ๋๋ค. #243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: yeji-kim-erica
Are you sure you want to change the base?
Changes from all commits
0ceec3c
7f73e77
0be33b8
e8d6b4c
9c9605d
3f0af3a
381957c
c1c423e
b750b23
d699f78
8f0e517
748f714
4060f81
584b043
92c55ab
a9e05d2
ac68f60
6322b8c
f5f2291
356b578
c605c7b
0441baa
2ed703c
8e916fd
6aadc0b
5800252
b55d7fa
770eef2
1c43383
41c3287
dc92d78
f7db4f5
c8dc4e1
491cfac
b31fd46
ac709cd
89fc068
9508070
d394f53
b6e9e76
f031242
d9e038a
bc27b6b
3f25d1b
6bc5a0c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,67 @@ | ||
| # java-janggi | ||
|
|
||
| ์ฅ๊ธฐ ๋ฏธ์ ์ ์ฅ์ | ||
|
|
||
| --- | ||
|
|
||
| ## ๐ก ์ฃผ์ ๊ฒ์ ๊ท์น | ||
Chocochip101 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ### ๊ธฐ๋ฌผ ์ด๋ ๊ท์น | ||
|
|
||
| - **๊ถ, ์ฌ** | ||
| - ๊ถ๊ถ ์์์๋ง ๋ฐฉํฅ ์๊ด์์ด 1์นธ์ฉ ์ด๋ | ||
| - ๋ฐ์ด๋๊ธฐ ๋ถ๊ฐ | ||
| - ์์ ์์น ๊ณ ์ | ||
| - **์** | ||
| - ์/์/๋ค 1์นธ + ๋๊ฐ์ 2์นธ | ||
| - ๋ฐ์ด๋๊ธฐ ๋ถ๊ฐ | ||
| - ๋ง์ ์์น ๋ณ๊ฒฝ ๊ฐ๋ฅ | ||
| - **๋ง** | ||
| - ์/์/๋ค 1์นธ + ๋๊ฐ์ 1์นธ | ||
| - ๋ฐ์ด๋๊ธฐ ๋ถ๊ฐ | ||
| - ์๊ณผ ์์น ๋ณ๊ฒฝ ๊ฐ๋ฅ | ||
| - **์ฐจ** | ||
| - ์ง์ ์ผ๋ก ์ํ๋ ๋งํผ ์ด๋ | ||
| - ๋ฐ์ด๋๊ธฐ ๋ถ๊ฐ | ||
| - ์์ ์์น ๊ณ ์ | ||
| - **ํฌ** | ||
| - ์/์/๋ค ์ํ๋ ๋งํผ ์ด๋ | ||
| - ํฌ๋ฅผ ์ ์ธํ ๊ธฐ๋ฌผ์ 1๊ฐ ๋ฐ์ด๋์ด์ผ๋ง ์ด๋ | ||
| - ์์ ์์น ๊ณ ์ | ||
| - **์กธ/๋ณ** | ||
| - ์/์์ผ๋ก๋ง 1์นธ ์ ์ง | ||
| - ๋ฐ์ด๋๊ธฐ ๋ถ๊ฐ | ||
| - ์์ ์์น ๊ณ ์ | ||
|
|
||
| ## ๐ ๊ธฐ๋ฅ ์๊ตฌ ์ฌํญ | ||
|
|
||
| ### 1.1 **๋ณด๋ ์ด๊ธฐํ** | ||
|
|
||
| ๊ฒ์ ์์ ์ ์ฅ๊ธฐํ๊ณผ ์ ์ฒด ๊ธฐ๋ฌผ์ ์ฌ๋ฐ๋ฅธ ์์น์ ์ด๊ธฐํํ๋ค. | ||
|
|
||
| - [x] ์ฅ๊ธฐํ ์ด๊ธฐํ ์ ๋ต์ ๋ฒํธ๋ก ์ ๋ ฅ๋ฐ๋๋ค. | ||
| - ์๋ง๋ง์, ์๋ง์๋ง, ๋ง์๋ง์, ๋ง์์๋ง | ||
| - [x] ์ฌ์ฉ์ ์ ๋ ฅ๊ฐ ์ ํจ์ฑ ๊ฒ์ฌ | ||
| - [x] ๊ณต๋ฐฑ์ธ ๊ฒฝ์ฐ ์์ธ ์ฒ๋ฆฌ | ||
| - [x] ์ซ์๊ฐ ์๋ ๋ฌธ์์ผ ๊ฒฝ์ฐ ์์ธ ์ฒ๋ฆฌ | ||
| - [x] ์ ์ ๋ฒ์๋ฅผ ๋ฒ์ด๋ ๊ฒฝ์ฐ ์์ธ ์ฒ๋ฆฌ | ||
| - [x] ๋๋ฉ์ธ ๊ท์น ๊ฒ์ฆ | ||
| - [x] ์ ๋ ฅ๊ฐ์ด ์ ํ์ง ๋ฒ์์ ํฌํจ๋์ง ์๋ ๊ฒฝ์ฐ ์์ธ ์ฒ๋ฆฌ | ||
| - [x] ์ ๋ต์ด ๋ฐ์๋ ์ฅ๊ธฐํ ์ํ๋ฅผ ์ถ๋ ฅํ๋ค. | ||
|
|
||
| ### 1.2 ๊ธฐ๋ฌผ ์ด๋ | ||
|
|
||
| - [x] ์ด๋ํ ๊ธฐ๋ฌผ์ ์์น์ ์ด๋ํ ์์น๋ฅผ ์ฌ์ฉ์๋ก๋ถํฐ ์ ๋ ฅ๋ฐ๋๋ค. | ||
Chocochip101 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - [x] ์ฌ์ฉ์ ์ ๋ ฅ๊ฐ ์ ํจ์ฑ ๊ฒ์ฌ | ||
| - [x] ๊ณต๋ฐฑ์ธ ๊ฒฝ์ฐ ์์ธ ์ฒ๋ฆฌ | ||
| - [x] `,` ๋ก ๊ตฌ๋ถ๋ ์ขํ ํ์์ด ์๋ ๊ฒฝ์ฐ ์์ธ ์ฒ๋ฆฌ | ||
| - [x] ์ขํ๊ฐ์ด ์ซ์๊ฐ ์๋ ๊ฒฝ์ฐ ์์ธ ์ฒ๋ฆฌ | ||
| - [x] ์ขํ๊ฐ์ด ์ ์ ๋ฒ์๋ฅผ ๋ฒ์ด๋ ๊ฒฝ์ฐ ์์ธ ์ฒ๋ฆฌ | ||
| - [x] ๋๋ฉ์ธ ๊ท์น ๊ฒ์ฆ | ||
| - [x] ์ขํ๊ฐ์ด ๋ณด๋ํ์ ๋ฒ์๋ฅผ ๋ฒ์ด๋ ๊ฒฝ์ฐ ์์ธ ์ฒ๋ฆฌ | ||
| - [x] ํด๋น ์ขํ์ ์ด๋์ํค๊ณ ์ ํ๋ ๊ธฐ๋ฌผ์ด ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ ์์ธ ์ฒ๋ฆฌ | ||
| - [x] ๊ธฐ๋ฌผ์ ์ด๋์ํจ๋ค. | ||
| - [x] ๋๋ฉ์ธ ๊ท์น ๊ฒ์ฆ | ||
| - [x] ๊ธฐ๋ฌผ ๊ท์น์ ๋ฐ๋ผ ์ด๋ํ ์์น์ ๋๋ฌํ ์ ์๋ ๊ฒฝ์ฐ ์์ธ ์ฒ๋ฆฌ | ||
| - [x] ์ด๋ํ ์์น์ ๊ธฐ์กด ๊ธฐ๋ฌผ์ ์ ๊ฑฐ๋๋ค. | ||
| - [x] ์ด๋์ด ๋ฐ์๋ ์ฅ๊ธฐํ ์ํ๋ฅผ ์ถ๋ ฅํ๋ค. | ||
| 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(); | ||
| } | ||
| } |
| 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); | ||
| } | ||
| } |
| 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 { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Flow๋ ์ด๋ค ๊ฒ์ ์๋ฏธํ๋์? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ์ controller ํจํค์ง ์์ ์๋์? controller๋ ๋ฌด์์ ์๋ฏธํ๋์?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ํด๋์ค์ ์ญํ ๊ณผ ๋ค์ด๋ฐ์ ๋ํด ๋ณธ์ง์ ์ธ ๊ณ ๋ฏผ์ ๋์ ธ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค! 1. Controller๋ ๋ฌด์์ ์๋ฏธํ๊ณ , ์ ์ด ํจํค์ง์ ์๋์?์ ๊ฐ ์๊ฐํ 2. Flow๋ ์ด๋ค ๊ฒ์ ์๋ฏธํ๋์?'Flow'๋ผ๋ ์ด๋ฆ์ ์ด ์ปจํธ๋กค๋ฌ๊ฐ ์ฅ๊ธฐ ๊ฒ์์ ์ ์ฒด์ ์ธ ์งํ ํ๋ฆ์ ์ ์ดํ๋ค๋ ์๋ฏธ๋ก ์ง์์ต๋๋ค. ๋ค๋ง ์ง๋ฌธ์ ๋ฐ๊ณ ๋ค์ ์๊ฐํด ๋ณด๋, 'Flow'๋ผ๋ ๋จ์ด๋ ์ํ๋ ์ญํ ๋ณด๋ค๋ 'ํ์ ์์ฒด'์ ๊ฐ๊น์ด ์ถ์์ ์ธ ๋จ์ด๋ผ, |
||
|
|
||
| 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()) { | ||
Chocochip101 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 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()); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| 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) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ์ผ๋ฐ์ ์ผ๋ก x๋ ์ด, y๋ ํ์ ์๋ฏธํ์ง ์๋์?(์๊ณ ๋ฆฌ์ฆ ํ ๋ ๊ทธ๋ ๊ฒ ์ผ๋ ๊ธฐ์ต์ด ์๋ค์ ๐ค) |
||
|
|
||
| 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; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,28 @@ | ||||||||
| package janggi.domain; | ||||||||
|
|
||||||||
| public enum Side { | ||||||||
|
|
||||||||
| HAN("ํ"), | ||||||||
| CHO("์ด"), | ||||||||
| NONE("์์"); | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NONE์ด ํ์ฌ ์ฐ์ด๋์? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ์๋์ ๊ฐ์ด ์ฐ๋ฉด, ๋ค์ ์ฌ๋์ด ๋ค๋ฅธ Enum์ ์ถ๊ฐํ ๋ ๋ณ๊ฒฝ์ฌํญ์ ์ ์กํ๊ฒ ๋ฉ๋๋ค :)
Suggested change
|
||||||||
|
|
||||||||
| private final String name; | ||||||||
|
|
||||||||
| Side(String name) { | ||||||||
| this.name = name; | ||||||||
| } | ||||||||
|
|
||||||||
| public Side switchSide() { | ||||||||
Chocochip101 marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||||||||
| } | ||||||||
| } | ||||||||
Uh oh!
There was an error while loading. Please reload this page.