oh-my-oop 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MCP_STRUCTURE.md +301 -0
- package/README.md +167 -0
- package/SCOPE.md +27 -0
- package/dist/application/discovery.d.ts +133 -0
- package/dist/application/discovery.js +62 -0
- package/dist/application/discovery.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +80 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +16 -0
- package/dist/config.js +32 -0
- package/dist/config.js.map +1 -0
- package/dist/domain/collaborators.d.ts +2 -0
- package/dist/domain/collaborators.js +26 -0
- package/dist/domain/collaborators.js.map +1 -0
- package/dist/domain/ids.d.ts +4 -0
- package/dist/domain/ids.js +23 -0
- package/dist/domain/ids.js.map +1 -0
- package/dist/domain/model.d.ts +71 -0
- package/dist/domain/model.js +2 -0
- package/dist/domain/model.js.map +1 -0
- package/dist/domain/schemas.d.ts +213 -0
- package/dist/domain/schemas.js +79 -0
- package/dist/domain/schemas.js.map +1 -0
- package/dist/domain/stereotypes.d.ts +7 -0
- package/dist/domain/stereotypes.js +65 -0
- package/dist/domain/stereotypes.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/io/classStore.d.ts +9 -0
- package/dist/io/classStore.js +39 -0
- package/dist/io/classStore.js.map +1 -0
- package/dist/io/collaborationStore.d.ts +7 -0
- package/dist/io/collaborationStore.js +32 -0
- package/dist/io/collaborationStore.js.map +1 -0
- package/dist/io/design.d.ts +3 -0
- package/dist/io/design.js +22 -0
- package/dist/io/design.js.map +1 -0
- package/dist/io/designIndex.d.ts +6 -0
- package/dist/io/designIndex.js +49 -0
- package/dist/io/designIndex.js.map +1 -0
- package/dist/io/frontmatter.d.ts +8 -0
- package/dist/io/frontmatter.js +31 -0
- package/dist/io/frontmatter.js.map +1 -0
- package/dist/io/history.d.ts +10 -0
- package/dist/io/history.js +38 -0
- package/dist/io/history.js.map +1 -0
- package/dist/io/useCaseStore.d.ts +8 -0
- package/dist/io/useCaseStore.js +36 -0
- package/dist/io/useCaseStore.js.map +1 -0
- package/dist/io/workspace.d.ts +14 -0
- package/dist/io/workspace.js +82 -0
- package/dist/io/workspace.js.map +1 -0
- package/dist/oop/commands.d.ts +446 -0
- package/dist/oop/commands.js +319 -0
- package/dist/oop/commands.js.map +1 -0
- package/dist/oop/conformance.d.ts +16 -0
- package/dist/oop/conformance.js +30 -0
- package/dist/oop/conformance.js.map +1 -0
- package/dist/prompts/discovery.d.ts +2 -0
- package/dist/prompts/discovery.js +41 -0
- package/dist/prompts/discovery.js.map +1 -0
- package/dist/prompts/imagineWithoutController.d.ts +2 -0
- package/dist/prompts/imagineWithoutController.js +75 -0
- package/dist/prompts/imagineWithoutController.js.map +1 -0
- package/dist/prompts/index.d.ts +2 -0
- package/dist/prompts/index.js +17 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/phasePressureTest.d.ts +2 -0
- package/dist/prompts/phasePressureTest.js +69 -0
- package/dist/prompts/phasePressureTest.js.map +1 -0
- package/dist/prompts/rddIntro.d.ts +2 -0
- package/dist/prompts/rddIntro.js +53 -0
- package/dist/prompts/rddIntro.js.map +1 -0
- package/dist/prompts/review.d.ts +2 -0
- package/dist/prompts/review.js +45 -0
- package/dist/prompts/review.js.map +1 -0
- package/dist/prompts/stateMachineIntrospect.d.ts +2 -0
- package/dist/prompts/stateMachineIntrospect.js +80 -0
- package/dist/prompts/stateMachineIntrospect.js.map +1 -0
- package/dist/prompts/tellDontAskRephrase.d.ts +2 -0
- package/dist/prompts/tellDontAskRephrase.js +66 -0
- package/dist/prompts/tellDontAskRephrase.js.map +1 -0
- package/dist/render/diff.d.ts +21 -0
- package/dist/render/diff.js +84 -0
- package/dist/render/diff.js.map +1 -0
- package/dist/render/mermaid.d.ts +24 -0
- package/dist/render/mermaid.js +53 -0
- package/dist/render/mermaid.js.map +1 -0
- package/dist/render/sideBySide.d.ts +14 -0
- package/dist/render/sideBySide.js +91 -0
- package/dist/render/sideBySide.js.map +1 -0
- package/dist/resources/index.d.ts +2 -0
- package/dist/resources/index.js +349 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +22 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/alternatives.d.ts +2 -0
- package/dist/tools/alternatives.js +9 -0
- package/dist/tools/alternatives.js.map +1 -0
- package/dist/tools/classes.d.ts +2 -0
- package/dist/tools/classes.js +13 -0
- package/dist/tools/classes.js.map +1 -0
- package/dist/tools/collaborations.d.ts +2 -0
- package/dist/tools/collaborations.js +8 -0
- package/dist/tools/collaborations.js.map +1 -0
- package/dist/tools/compare.d.ts +2 -0
- package/dist/tools/compare.js +9 -0
- package/dist/tools/compare.js.map +1 -0
- package/dist/tools/conformance.d.ts +3 -0
- package/dist/tools/conformance.js +11 -0
- package/dist/tools/conformance.js.map +1 -0
- package/dist/tools/diagram.d.ts +2 -0
- package/dist/tools/diagram.js +9 -0
- package/dist/tools/diagram.js.map +1 -0
- package/dist/tools/discovery.d.ts +2 -0
- package/dist/tools/discovery.js +23 -0
- package/dist/tools/discovery.js.map +1 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.js +27 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/init.d.ts +2 -0
- package/dist/tools/init.js +9 -0
- package/dist/tools/init.js.map +1 -0
- package/dist/tools/oop.d.ts +9 -0
- package/dist/tools/oop.js +26 -0
- package/dist/tools/oop.js.map +1 -0
- package/dist/tools/responsibilities.d.ts +2 -0
- package/dist/tools/responsibilities.js +13 -0
- package/dist/tools/responsibilities.js.map +1 -0
- package/dist/tools/state.d.ts +2 -0
- package/dist/tools/state.js +8 -0
- package/dist/tools/state.js.map +1 -0
- package/dist/tools/useCases.d.ts +2 -0
- package/dist/tools/useCases.js +18 -0
- package/dist/tools/useCases.js.map +1 -0
- package/dist/tools/validate.d.ts +2 -0
- package/dist/tools/validate.js +9 -0
- package/dist/tools/validate.js.map +1 -0
- package/dist/tradeoff/engine.d.ts +61 -0
- package/dist/tradeoff/engine.js +171 -0
- package/dist/tradeoff/engine.js.map +1 -0
- package/dist/tradeoff/heuristics/classSplit.d.ts +3 -0
- package/dist/tradeoff/heuristics/classSplit.js +94 -0
- package/dist/tradeoff/heuristics/classSplit.js.map +1 -0
- package/dist/tradeoff/heuristics/collaborationShape.d.ts +2 -0
- package/dist/tradeoff/heuristics/collaborationShape.js +82 -0
- package/dist/tradeoff/heuristics/collaborationShape.js.map +1 -0
- package/dist/tradeoff/heuristics/collectionShape.d.ts +2 -0
- package/dist/tradeoff/heuristics/collectionShape.js +113 -0
- package/dist/tradeoff/heuristics/collectionShape.js.map +1 -0
- package/dist/tradeoff/heuristics/dualSubjectComparison.d.ts +2 -0
- package/dist/tradeoff/heuristics/dualSubjectComparison.js +114 -0
- package/dist/tradeoff/heuristics/dualSubjectComparison.js.map +1 -0
- package/dist/tradeoff/heuristics/errorHandling.d.ts +2 -0
- package/dist/tradeoff/heuristics/errorHandling.js +110 -0
- package/dist/tradeoff/heuristics/errorHandling.js.map +1 -0
- package/dist/tradeoff/heuristics/responsibilitySplit.d.ts +23 -0
- package/dist/tradeoff/heuristics/responsibilitySplit.js +183 -0
- package/dist/tradeoff/heuristics/responsibilitySplit.js.map +1 -0
- package/dist/tradeoff/heuristics/stereotypeChoice.d.ts +2 -0
- package/dist/tradeoff/heuristics/stereotypeChoice.js +23 -0
- package/dist/tradeoff/heuristics/stereotypeChoice.js.map +1 -0
- package/dist/tradeoff/heuristics/strategyOrPolicy.d.ts +2 -0
- package/dist/tradeoff/heuristics/strategyOrPolicy.js +110 -0
- package/dist/tradeoff/heuristics/strategyOrPolicy.js.map +1 -0
- package/dist/tradeoff/heuristics/valueObjectShape.d.ts +2 -0
- package/dist/tradeoff/heuristics/valueObjectShape.js +111 -0
- package/dist/tradeoff/heuristics/valueObjectShape.js.map +1 -0
- package/dist/tradeoff/templates.d.ts +2 -0
- package/dist/tradeoff/templates.js +33 -0
- package/dist/tradeoff/templates.js.map +1 -0
- package/dist/util/log.d.ts +1 -0
- package/dist/util/log.js +7 -0
- package/dist/util/log.js.map +1 -0
- package/dist/util/mcp.d.ts +4 -0
- package/dist/util/mcp.js +18 -0
- package/dist/util/mcp.js.map +1 -0
- package/dist/validate/cohesion.d.ts +3 -0
- package/dist/validate/cohesion.js +88 -0
- package/dist/validate/cohesion.js.map +1 -0
- package/dist/validate/collectionWrapper.d.ts +3 -0
- package/dist/validate/collectionWrapper.js +131 -0
- package/dist/validate/collectionWrapper.js.map +1 -0
- package/dist/validate/coupling.d.ts +3 -0
- package/dist/validate/coupling.js +47 -0
- package/dist/validate/coupling.js.map +1 -0
- package/dist/validate/cycle.d.ts +3 -0
- package/dist/validate/cycle.js +101 -0
- package/dist/validate/cycle.js.map +1 -0
- package/dist/validate/dataDuplication.d.ts +3 -0
- package/dist/validate/dataDuplication.js +150 -0
- package/dist/validate/dataDuplication.js.map +1 -0
- package/dist/validate/dependencyDirection.d.ts +3 -0
- package/dist/validate/dependencyDirection.js +106 -0
- package/dist/validate/dependencyDirection.js.map +1 -0
- package/dist/validate/dualUseKnowing.d.ts +3 -0
- package/dist/validate/dualUseKnowing.js +137 -0
- package/dist/validate/dualUseKnowing.js.map +1 -0
- package/dist/validate/emptyObjectFill.d.ts +3 -0
- package/dist/validate/emptyObjectFill.js +119 -0
- package/dist/validate/emptyObjectFill.js.map +1 -0
- package/dist/validate/findings.d.ts +22 -0
- package/dist/validate/findings.js +12 -0
- package/dist/validate/findings.js.map +1 -0
- package/dist/validate/functionDecompositionExcess.d.ts +3 -0
- package/dist/validate/functionDecompositionExcess.js +120 -0
- package/dist/validate/functionDecompositionExcess.js.map +1 -0
- package/dist/validate/functionNotObject.d.ts +3 -0
- package/dist/validate/functionNotObject.js +80 -0
- package/dist/validate/functionNotObject.js.map +1 -0
- package/dist/validate/godObject.d.ts +6 -0
- package/dist/validate/godObject.js +76 -0
- package/dist/validate/godObject.js.map +1 -0
- package/dist/validate/presentationInDomain.d.ts +3 -0
- package/dist/validate/presentationInDomain.js +57 -0
- package/dist/validate/presentationInDomain.js.map +1 -0
- package/dist/validate/primitiveWrapper.d.ts +3 -0
- package/dist/validate/primitiveWrapper.js +106 -0
- package/dist/validate/primitiveWrapper.js.map +1 -0
- package/dist/validate/rules.d.ts +24 -0
- package/dist/validate/rules.js +269 -0
- package/dist/validate/rules.js.map +1 -0
- package/dist/validate/singletonStatefulHolder.d.ts +3 -0
- package/dist/validate/singletonStatefulHolder.js +128 -0
- package/dist/validate/singletonStatefulHolder.js.map +1 -0
- package/dist/validate/strategyAsymmetry.d.ts +3 -0
- package/dist/validate/strategyAsymmetry.js +131 -0
- package/dist/validate/strategyAsymmetry.js.map +1 -0
- package/dist/validate/testability.d.ts +5 -0
- package/dist/validate/testability.js +157 -0
- package/dist/validate/testability.js.map +1 -0
- package/dist/validate/vagueName.d.ts +3 -0
- package/dist/validate/vagueName.js +136 -0
- package/dist/validate/vagueName.js.map +1 -0
- package/dist/validate/validationLocation.d.ts +3 -0
- package/dist/validate/validationLocation.js +120 -0
- package/dist/validate/validationLocation.js.map +1 -0
- package/lessons/STYLE_GUIDE.md +304 -0
- package/lessons/woowacourse-kotlin-blackjack/2chang5/33-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +293 -0
- package/lessons/woowacourse-kotlin-blackjack/Choisehyeon/52-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +106 -0
- package/lessons/woowacourse-kotlin-blackjack/Choisehyeon/9-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +282 -0
- package/lessons/woowacourse-kotlin-blackjack/DYGames/14-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +182 -0
- package/lessons/woowacourse-kotlin-blackjack/DYGames/37-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +122 -0
- package/lessons/woowacourse-kotlin-blackjack/EmilyCh0/12-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +117 -0
- package/lessons/woowacourse-kotlin-blackjack/EmilyCh0/38-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +291 -0
- package/lessons/woowacourse-kotlin-blackjack/HANDOVER.md +1475 -0
- package/lessons/woowacourse-kotlin-blackjack/HamBeomJoon/119-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +251 -0
- package/lessons/woowacourse-kotlin-blackjack/HamBeomJoon/137-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +459 -0
- package/lessons/woowacourse-kotlin-blackjack/Hevton/100-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +282 -0
- package/lessons/woowacourse-kotlin-blackjack/Hevton/82-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +303 -0
- package/lessons/woowacourse-kotlin-blackjack/Hogu59/71-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +134 -0
- package/lessons/woowacourse-kotlin-blackjack/Hogu59/96-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +323 -0
- package/lessons/woowacourse-kotlin-blackjack/JoYehyun99/66-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +210 -0
- package/lessons/woowacourse-kotlin-blackjack/Junyoung-WON/101-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +191 -0
- package/lessons/woowacourse-kotlin-blackjack/Junyoung-WON/80-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +253 -0
- package/lessons/woowacourse-kotlin-blackjack/Leeyerin0210/108-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +516 -0
- package/lessons/woowacourse-kotlin-blackjack/Leeyerin0210/133-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +541 -0
- package/lessons/woowacourse-kotlin-blackjack/RightHennessy/22-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +278 -0
- package/lessons/woowacourse-kotlin-blackjack/RightHennessy/48-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +188 -0
- package/lessons/woowacourse-kotlin-blackjack/SeongHoonC/16-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +228 -0
- package/lessons/woowacourse-kotlin-blackjack/SeongHoonC/54-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +227 -0
- package/lessons/woowacourse-kotlin-blackjack/Yunseok-Nam/76-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +279 -0
- package/lessons/woowacourse-kotlin-blackjack/Yunseok-Nam/86-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +203 -0
- package/lessons/woowacourse-kotlin-blackjack/aprilgom/105-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +162 -0
- package/lessons/woowacourse-kotlin-blackjack/aprilgom/64-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +279 -0
- package/lessons/woowacourse-kotlin-blackjack/boogi-woogi/18-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +188 -0
- package/lessons/woowacourse-kotlin-blackjack/boogi-woogi/36-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +769 -0
- package/lessons/woowacourse-kotlin-blackjack/briandr97/19-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +226 -0
- package/lessons/woowacourse-kotlin-blackjack/briandr97/59-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +193 -0
- package/lessons/woowacourse-kotlin-blackjack/chaehyuns/70-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +175 -0
- package/lessons/woowacourse-kotlin-blackjack/chaehyuns/98-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +206 -0
- package/lessons/woowacourse-kotlin-blackjack/chanho0908/123-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +277 -0
- package/lessons/woowacourse-kotlin-blackjack/chanho0908/150-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +219 -0
- package/lessons/woowacourse-kotlin-blackjack/chws0508/26-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +259 -0
- package/lessons/woowacourse-kotlin-blackjack/chws0508/43-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +189 -0
- package/lessons/woowacourse-kotlin-blackjack/cucumber99/109-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +351 -0
- package/lessons/woowacourse-kotlin-blackjack/cucumber99/149-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +147 -0
- package/lessons/woowacourse-kotlin-blackjack/devfeijoa/121-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +168 -0
- package/lessons/woowacourse-kotlin-blackjack/devfeijoa/153-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +116 -0
- package/lessons/woowacourse-kotlin-blackjack/doabletuple/126-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +680 -0
- package/lessons/woowacourse-kotlin-blackjack/doabletuple/142-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +739 -0
- package/lessons/woowacourse-kotlin-blackjack/donghyun81/116-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +297 -0
- package/lessons/woowacourse-kotlin-blackjack/donghyun81/147-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +244 -0
- package/lessons/woowacourse-kotlin-blackjack/dpcks0509/78-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +232 -0
- package/lessons/woowacourse-kotlin-blackjack/dpcks0509/88-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +137 -0
- package/lessons/woowacourse-kotlin-blackjack/etama123/112-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +269 -0
- package/lessons/woowacourse-kotlin-blackjack/etama123/148-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +240 -0
- package/lessons/woowacourse-kotlin-blackjack/gaeun5744/102-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +146 -0
- package/lessons/woowacourse-kotlin-blackjack/gaeun5744/69-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +224 -0
- package/lessons/woowacourse-kotlin-blackjack/gahyunkim/118-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +397 -0
- package/lessons/woowacourse-kotlin-blackjack/gahyunkim/141-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +215 -0
- package/lessons/woowacourse-kotlin-blackjack/giovannijunseokim/106-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +395 -0
- package/lessons/woowacourse-kotlin-blackjack/giovannijunseokim/134-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +219 -0
- package/lessons/woowacourse-kotlin-blackjack/haeum808/62-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +230 -0
- package/lessons/woowacourse-kotlin-blackjack/haeum808/89-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +169 -0
- package/lessons/woowacourse-kotlin-blackjack/hwannow/110-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +221 -0
- package/lessons/woowacourse-kotlin-blackjack/hwannow/132-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +573 -0
- package/lessons/woowacourse-kotlin-blackjack/hxeyexn/103-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +188 -0
- package/lessons/woowacourse-kotlin-blackjack/hxeyexn/81-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +301 -0
- package/lessons/woowacourse-kotlin-blackjack/hyemdooly/21-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +613 -0
- package/lessons/woowacourse-kotlin-blackjack/hyemdooly/35-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +691 -0
- package/lessons/woowacourse-kotlin-blackjack/hyunji1203/13-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +206 -0
- package/lessons/woowacourse-kotlin-blackjack/ii2001/79-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +153 -0
- package/lessons/woowacourse-kotlin-blackjack/ii2001/85-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +318 -0
- package/lessons/woowacourse-kotlin-blackjack/ijh1298/128-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +250 -0
- package/lessons/woowacourse-kotlin-blackjack/ijh1298/135-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +269 -0
- package/lessons/woowacourse-kotlin-blackjack/inseonyun/28-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +346 -0
- package/lessons/woowacourse-kotlin-blackjack/inseonyun/49-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +360 -0
- package/lessons/woowacourse-kotlin-blackjack/ippnsj/30-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +152 -0
- package/lessons/woowacourse-kotlin-blackjack/ippnsj/42-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +213 -0
- package/lessons/woowacourse-kotlin-blackjack/jaeyeongjo/73-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +247 -0
- package/lessons/woowacourse-kotlin-blackjack/jaeyeongjo/87-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +900 -0
- package/lessons/woowacourse-kotlin-blackjack/jerry8282/125-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +248 -0
- package/lessons/woowacourse-kotlin-blackjack/jerry8282/151-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +243 -0
- package/lessons/woowacourse-kotlin-blackjack/jinuemong/63-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +281 -0
- package/lessons/woowacourse-kotlin-blackjack/jinuemong/92-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +283 -0
- package/lessons/woowacourse-kotlin-blackjack/jiyuneel/113-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +348 -0
- package/lessons/woowacourse-kotlin-blackjack/jiyuneel/140-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +265 -0
- package/lessons/woowacourse-kotlin-blackjack/junjange/61-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +270 -0
- package/lessons/woowacourse-kotlin-blackjack/junjange/93-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +465 -0
- package/lessons/woowacourse-kotlin-blackjack/junseo511/107-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +296 -0
- package/lessons/woowacourse-kotlin-blackjack/junseo511/145-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +316 -0
- package/lessons/woowacourse-kotlin-blackjack/ki960213/11-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +175 -0
- package/lessons/woowacourse-kotlin-blackjack/kimhm0728/72-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +458 -0
- package/lessons/woowacourse-kotlin-blackjack/kimhm0728/97-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +225 -0
- package/lessons/woowacourse-kotlin-blackjack/kkosang/68-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +221 -0
- package/lessons/woowacourse-kotlin-blackjack/kkosang/94-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +158 -0
- package/lessons/woowacourse-kotlin-blackjack/kmkim2689/65-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +252 -0
- package/lessons/woowacourse-kotlin-blackjack/kmkim2689/90-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +460 -0
- package/lessons/woowacourse-kotlin-blackjack/krrong/32-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +216 -0
- package/lessons/woowacourse-kotlin-blackjack/krrong/46-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +285 -0
- package/lessons/woowacourse-kotlin-blackjack/m6z1/122-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +177 -0
- package/lessons/woowacourse-kotlin-blackjack/m6z1/144-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +155 -0
- package/lessons/woowacourse-kotlin-blackjack/medAndro/130-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +683 -0
- package/lessons/woowacourse-kotlin-blackjack/medAndro/143-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +678 -0
- package/lessons/woowacourse-kotlin-blackjack/moondev03/114-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +262 -0
- package/lessons/woowacourse-kotlin-blackjack/moondev03/131-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +498 -0
- package/lessons/woowacourse-kotlin-blackjack/murjune/77-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +287 -0
- package/lessons/woowacourse-kotlin-blackjack/murjune/91-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +280 -0
- package/lessons/woowacourse-kotlin-blackjack/no1msh/31-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +250 -0
- package/lessons/woowacourse-kotlin-blackjack/otter66/24-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +302 -0
- package/lessons/woowacourse-kotlin-blackjack/otter66/58-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +391 -0
- package/lessons/woowacourse-kotlin-blackjack/oungsi2000/111-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +253 -0
- package/lessons/woowacourse-kotlin-blackjack/oungsi2000/136-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +540 -0
- package/lessons/woowacourse-kotlin-blackjack/parkjiminnnn/117-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +819 -0
- package/lessons/woowacourse-kotlin-blackjack/parkjiminnnn/139-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +683 -0
- package/lessons/woowacourse-kotlin-blackjack/pingu244/20-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +258 -0
- package/lessons/woowacourse-kotlin-blackjack/pingu244/41-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +171 -0
- package/lessons/woowacourse-kotlin-blackjack/re4rk/34-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +289 -0
- package/lessons/woowacourse-kotlin-blackjack/re4rk/8-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +297 -0
- package/lessons/woowacourse-kotlin-blackjack/rhkrwngud445/17-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +279 -0
- package/lessons/woowacourse-kotlin-blackjack/rhkrwngud445/50-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +145 -0
- package/lessons/woowacourse-kotlin-blackjack/rhthrhrl0/23-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +253 -0
- package/lessons/woowacourse-kotlin-blackjack/rhthrhrl0/39-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +238 -0
- package/lessons/woowacourse-kotlin-blackjack/rosemin928/129-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +726 -0
- package/lessons/woowacourse-kotlin-blackjack/rosemin928/138-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +845 -0
- package/lessons/woowacourse-kotlin-blackjack/s6m1n/67-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +220 -0
- package/lessons/woowacourse-kotlin-blackjack/s6m1n/99-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +229 -0
- package/lessons/woowacourse-kotlin-blackjack/s9hn/10-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +284 -0
- package/lessons/woowacourse-kotlin-blackjack/sh1mj1/75-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +224 -0
- package/lessons/woowacourse-kotlin-blackjack/songpink/74-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +238 -0
- package/lessons/woowacourse-kotlin-blackjack/songpink/95-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +216 -0
- package/lessons/woowacourse-kotlin-blackjack/sujin9/15-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +132 -0
- package/lessons/woowacourse-kotlin-blackjack/sujin9/47-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +265 -0
- package/lessons/woowacourse-kotlin-blackjack/tmdgh1592/29-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +305 -0
- package/lessons/woowacourse-kotlin-blackjack/tmdgh1592/51-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +278 -0
- package/lessons/woowacourse-kotlin-blackjack/tobae-time/115-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +305 -0
- package/lessons/woowacourse-kotlin-blackjack/tobae-time/154-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +298 -0
- package/lessons/woowacourse-kotlin-blackjack/whk06061/25-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +235 -0
- package/lessons/woowacourse-kotlin-blackjack/whk06061/53-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +130 -0
- package/lessons/woowacourse-kotlin-blackjack/wondroid-world/124-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +486 -0
- package/lessons/woowacourse-kotlin-blackjack/wondroid-world/152-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +482 -0
- package/lessons/woowacourse-kotlin-blackjack/yrsel/120-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +194 -0
- package/lessons/woowacourse-kotlin-blackjack/yrsel/146-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +444 -0
- package/lessons/woowacourse-kotlin-lotto/2chang5/27-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
- package/lessons/woowacourse-kotlin-lotto/2chang5/52-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +187 -0
- package/lessons/woowacourse-kotlin-lotto/Choisehyeon/14-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +206 -0
- package/lessons/woowacourse-kotlin-lotto/Choisehyeon/47-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +119 -0
- package/lessons/woowacourse-kotlin-lotto/DYGames/2-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +83 -0
- package/lessons/woowacourse-kotlin-lotto/DYGames/34-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +88 -0
- package/lessons/woowacourse-kotlin-lotto/EmilyCh0/12-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
- package/lessons/woowacourse-kotlin-lotto/EmilyCh0/40-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +135 -0
- package/lessons/woowacourse-kotlin-lotto/HANDOVER.md +217 -0
- package/lessons/woowacourse-kotlin-lotto/HamBeomJoon/121-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
- package/lessons/woowacourse-kotlin-lotto/HamBeomJoon/139-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +75 -0
- package/lessons/woowacourse-kotlin-lotto/Hevton/76-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
- package/lessons/woowacourse-kotlin-lotto/Hevton/92-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +122 -0
- package/lessons/woowacourse-kotlin-lotto/Hogu59/100-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +110 -0
- package/lessons/woowacourse-kotlin-lotto/Hogu59/68-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +84 -0
- package/lessons/woowacourse-kotlin-lotto/JoYehyun99/60-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +176 -0
- package/lessons/woowacourse-kotlin-lotto/JoYehyun99/96-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +71 -0
- package/lessons/woowacourse-kotlin-lotto/Junyoung-WON/61-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
- package/lessons/woowacourse-kotlin-lotto/Junyoung-WON/93-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +16 -0
- package/lessons/woowacourse-kotlin-lotto/Leeyerin0210/109-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +57 -0
- package/lessons/woowacourse-kotlin-lotto/Leeyerin0210/135-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +115 -0
- package/lessons/woowacourse-kotlin-lotto/PROGRESS.md +160 -0
- package/lessons/woowacourse-kotlin-lotto/README.md +77 -0
- package/lessons/woowacourse-kotlin-lotto/RightHennessy/32-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
- package/lessons/woowacourse-kotlin-lotto/RightHennessy/5-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
- package/lessons/woowacourse-kotlin-lotto/SUMMARY.md +369 -0
- package/lessons/woowacourse-kotlin-lotto/SeongHoonC/25-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
- package/lessons/woowacourse-kotlin-lotto/SeongHoonC/37-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +27 -0
- package/lessons/woowacourse-kotlin-lotto/Yunseok-Nam/72-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +137 -0
- package/lessons/woowacourse-kotlin-lotto/Yunseok-Nam/86-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +17 -0
- package/lessons/woowacourse-kotlin-lotto/aprilgom/102-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +62 -0
- package/lessons/woowacourse-kotlin-lotto/aprilgom/64-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +146 -0
- package/lessons/woowacourse-kotlin-lotto/boogi-woogi/11-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
- package/lessons/woowacourse-kotlin-lotto/boogi-woogi/29-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
- package/lessons/woowacourse-kotlin-lotto/briandr97/26-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
- package/lessons/woowacourse-kotlin-lotto/briandr97/51-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +123 -0
- package/lessons/woowacourse-kotlin-lotto/chaehyuns/71-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +115 -0
- package/lessons/woowacourse-kotlin-lotto/chaehyuns/97-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
- package/lessons/woowacourse-kotlin-lotto/chanho0908/124-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +51 -0
- package/lessons/woowacourse-kotlin-lotto/chanho0908/129-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
- package/lessons/woowacourse-kotlin-lotto/chws0508/24-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +117 -0
- package/lessons/woowacourse-kotlin-lotto/chws0508/50-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +167 -0
- package/lessons/woowacourse-kotlin-lotto/cucumber99/116-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
- package/lessons/woowacourse-kotlin-lotto/cucumber99/147-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +223 -0
- package/lessons/woowacourse-kotlin-lotto/devfeijoa/125-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +68 -0
- package/lessons/woowacourse-kotlin-lotto/devfeijoa/153-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
- package/lessons/woowacourse-kotlin-lotto/doabletuple/119-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +157 -0
- package/lessons/woowacourse-kotlin-lotto/doabletuple/138-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +77 -0
- package/lessons/woowacourse-kotlin-lotto/donghyun81/111-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +67 -0
- package/lessons/woowacourse-kotlin-lotto/donghyun81/152-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
- package/lessons/woowacourse-kotlin-lotto/dpcks0509/80-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +141 -0
- package/lessons/woowacourse-kotlin-lotto/dpcks0509/87-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +134 -0
- package/lessons/woowacourse-kotlin-lotto/etama123/112-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +170 -0
- package/lessons/woowacourse-kotlin-lotto/etama123/148-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +183 -0
- package/lessons/woowacourse-kotlin-lotto/gaeun5744/101-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
- package/lessons/woowacourse-kotlin-lotto/gaeun5744/78-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +158 -0
- package/lessons/woowacourse-kotlin-lotto/gahyunkim/107-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +83 -0
- package/lessons/woowacourse-kotlin-lotto/gahyunkim/136-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +51 -0
- package/lessons/woowacourse-kotlin-lotto/giovannijunseokim/106-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +171 -0
- package/lessons/woowacourse-kotlin-lotto/giovannijunseokim/137-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +111 -0
- package/lessons/woowacourse-kotlin-lotto/haeum808/67-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
- package/lessons/woowacourse-kotlin-lotto/haeum808/95-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
- package/lessons/woowacourse-kotlin-lotto/hwannow/113-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +235 -0
- package/lessons/woowacourse-kotlin-lotto/hwannow/132-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
- package/lessons/woowacourse-kotlin-lotto/hxeyexn/77-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +141 -0
- package/lessons/woowacourse-kotlin-lotto/hxeyexn/98-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +162 -0
- package/lessons/woowacourse-kotlin-lotto/hyemdooly/17-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +19 -0
- package/lessons/woowacourse-kotlin-lotto/hyemdooly/28-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +23 -0
- package/lessons/woowacourse-kotlin-lotto/hyunji1203/15-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +171 -0
- package/lessons/woowacourse-kotlin-lotto/hyunji1203/48-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +150 -0
- package/lessons/woowacourse-kotlin-lotto/ii2001/62-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
- package/lessons/woowacourse-kotlin-lotto/ii2001/88-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
- package/lessons/woowacourse-kotlin-lotto/ijh1298/122-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +179 -0
- package/lessons/woowacourse-kotlin-lotto/ijh1298/133-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +153 -0
- package/lessons/woowacourse-kotlin-lotto/inseonyun/3-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +222 -0
- package/lessons/woowacourse-kotlin-lotto/inseonyun/49-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +166 -0
- package/lessons/woowacourse-kotlin-lotto/ippnsj/16-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +154 -0
- package/lessons/woowacourse-kotlin-lotto/ippnsj/55-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
- package/lessons/woowacourse-kotlin-lotto/jaeyeongjo/59-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +68 -0
- package/lessons/woowacourse-kotlin-lotto/jaeyeongjo/83-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +53 -0
- package/lessons/woowacourse-kotlin-lotto/jerry8282/115-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
- package/lessons/woowacourse-kotlin-lotto/jerry8282/134-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
- package/lessons/woowacourse-kotlin-lotto/jinuemong/63-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +144 -0
- package/lessons/woowacourse-kotlin-lotto/jinuemong/89-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +148 -0
- package/lessons/woowacourse-kotlin-lotto/jiyuneel/128-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
- package/lessons/woowacourse-kotlin-lotto/jiyuneel/144-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
- package/lessons/woowacourse-kotlin-lotto/junjange/58-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +148 -0
- package/lessons/woowacourse-kotlin-lotto/junjange/81-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
- package/lessons/woowacourse-kotlin-lotto/junseo511/120-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +153 -0
- package/lessons/woowacourse-kotlin-lotto/junseo511/131-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +188 -0
- package/lessons/woowacourse-kotlin-lotto/ki960213/43-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +24 -0
- package/lessons/woowacourse-kotlin-lotto/ki960213/8-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +159 -0
- package/lessons/woowacourse-kotlin-lotto/kimhm0728/74-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +50 -0
- package/lessons/woowacourse-kotlin-lotto/kimhm0728/94-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +176 -0
- package/lessons/woowacourse-kotlin-lotto/kkosang/85-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
- package/lessons/woowacourse-kotlin-lotto/kmkim2689/70-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
- package/lessons/woowacourse-kotlin-lotto/kmkim2689/82-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +157 -0
- package/lessons/woowacourse-kotlin-lotto/krrong/19-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +161 -0
- package/lessons/woowacourse-kotlin-lotto/krrong/41-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +73 -0
- package/lessons/woowacourse-kotlin-lotto/m6z1/105-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +67 -0
- package/lessons/woowacourse-kotlin-lotto/m6z1/151-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
- package/lessons/woowacourse-kotlin-lotto/medAndro/127-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +186 -0
- package/lessons/woowacourse-kotlin-lotto/medAndro/130-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +132 -0
- package/lessons/woowacourse-kotlin-lotto/moondev03/110-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
- package/lessons/woowacourse-kotlin-lotto/moondev03/141-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
- package/lessons/woowacourse-kotlin-lotto/murjune/69-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
- package/lessons/woowacourse-kotlin-lotto/murjune/90-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +177 -0
- package/lessons/woowacourse-kotlin-lotto/no1msh/20-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +69 -0
- package/lessons/woowacourse-kotlin-lotto/no1msh/46-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
- package/lessons/woowacourse-kotlin-lotto/otter66/13-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
- package/lessons/woowacourse-kotlin-lotto/otter66/53-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +160 -0
- package/lessons/woowacourse-kotlin-lotto/oungsi2000/126-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +71 -0
- package/lessons/woowacourse-kotlin-lotto/oungsi2000/149-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +56 -0
- package/lessons/woowacourse-kotlin-lotto/parkjiminnnn/117-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
- package/lessons/woowacourse-kotlin-lotto/parkjiminnnn/146-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +173 -0
- package/lessons/woowacourse-kotlin-lotto/pingu244/33-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
- package/lessons/woowacourse-kotlin-lotto/pingu244/54-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +30 -0
- package/lessons/woowacourse-kotlin-lotto/pingu244/7-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +19 -0
- package/lessons/woowacourse-kotlin-lotto/re4rk/31-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
- package/lessons/woowacourse-kotlin-lotto/re4rk/4-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
- package/lessons/woowacourse-kotlin-lotto/rhkrwngud445/23-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
- package/lessons/woowacourse-kotlin-lotto/rhkrwngud445/38-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
- package/lessons/woowacourse-kotlin-lotto/rhthrhrl0/21-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +146 -0
- package/lessons/woowacourse-kotlin-lotto/rhthrhrl0/36-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +150 -0
- package/lessons/woowacourse-kotlin-lotto/rosemin928/123-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +179 -0
- package/lessons/woowacourse-kotlin-lotto/rosemin928/140-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +126 -0
- package/lessons/woowacourse-kotlin-lotto/s6m1n/103-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +119 -0
- package/lessons/woowacourse-kotlin-lotto/s6m1n/66-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +118 -0
- package/lessons/woowacourse-kotlin-lotto/s9hn/18-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +112 -0
- package/lessons/woowacourse-kotlin-lotto/sh1mj1/75-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
- package/lessons/woowacourse-kotlin-lotto/sh1mj1/91-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +140 -0
- package/lessons/woowacourse-kotlin-lotto/songpink/65-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +96 -0
- package/lessons/woowacourse-kotlin-lotto/songpink/99-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +64 -0
- package/lessons/woowacourse-kotlin-lotto/sujin9/10-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
- package/lessons/woowacourse-kotlin-lotto/sujin9/35-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
- package/lessons/woowacourse-kotlin-lotto/tmdgh1592/22-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +30 -0
- package/lessons/woowacourse-kotlin-lotto/tmdgh1592/30-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
- package/lessons/woowacourse-kotlin-lotto/tobae-time/114-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +158 -0
- package/lessons/woowacourse-kotlin-lotto/tobae-time/145-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +120 -0
- package/lessons/woowacourse-kotlin-lotto/whk06061/42-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
- package/lessons/woowacourse-kotlin-lotto/whk06061/9-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +89 -0
- package/lessons/woowacourse-kotlin-lotto/wondroid-world/118-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +100 -0
- package/lessons/woowacourse-kotlin-lotto/wondroid-world/150-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +142 -0
- package/lessons/woowacourse-kotlin-lotto/yrsel/108-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
- package/lessons/woowacourse-kotlin-lotto/yrsel/143-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +108 -0
- package/lessons/woowacourse-racingcar/2chang5/33-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
- package/lessons/woowacourse-racingcar/2chang5/75-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/CFalws/85-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
- package/lessons/woowacourse-racingcar/Choisehyeon/46-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
- package/lessons/woowacourse-racingcar/DYGames/49-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +62 -0
- package/lessons/woowacourse-racingcar/EmilyCh0/40-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +64 -0
- package/lessons/woowacourse-racingcar/EmilyCh0/57-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/HamBeomJoon/137-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/HamBeomJoon/170-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
- package/lessons/woowacourse-racingcar/Hevton/106-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/Hevton/118-/353/246/254/355/214/251/355/204/260/353/247/201.md +51 -0
- package/lessons/woowacourse-racingcar/Hogu59/108-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
- package/lessons/woowacourse-racingcar/Hogu59/125-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
- package/lessons/woowacourse-racingcar/JoYehyun99/111-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/JoYehyun99/88-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +45 -0
- package/lessons/woowacourse-racingcar/Junyoung-WON/127-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
- package/lessons/woowacourse-racingcar/Junyoung-WON/90-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
- package/lessons/woowacourse-racingcar/Leeyerin0210/133-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
- package/lessons/woowacourse-racingcar/Leeyerin0210/159-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/PROGRESS.md +94 -0
- package/lessons/woowacourse-racingcar/README.md +69 -0
- package/lessons/woowacourse-racingcar/RightHennessy/51-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/RightHennessy/58-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/RunaNam/81-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +44 -0
- package/lessons/woowacourse-racingcar/SUMMARY.md +339 -0
- package/lessons/woowacourse-racingcar/SeongHoonC/37-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/SeongHoonC/66-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
- package/lessons/woowacourse-racingcar/Songusika/84-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
- package/lessons/woowacourse-racingcar/Yunseok-Nam/114-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
- package/lessons/woowacourse-racingcar/Yunseok-Nam/96-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/aprilgom/130-/353/246/254/355/214/251/355/204/260/353/247/201.md +52 -0
- package/lessons/woowacourse-racingcar/aprilgom/97-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
- package/lessons/woowacourse-racingcar/awesomeo184/23-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
- package/lessons/woowacourse-racingcar/boogi-woogi/35-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +62 -0
- package/lessons/woowacourse-racingcar/boogi-woogi/59-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/briandr97/54-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/chaehyuns/131-/353/246/254/355/214/251/355/204/260/353/247/201.md +49 -0
- package/lessons/woowacourse-racingcar/chaehyuns/99-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
- package/lessons/woowacourse-racingcar/chanho0908/147-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/chanho0908/160-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
- package/lessons/woowacourse-racingcar/chws0508/45-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
- package/lessons/woowacourse-racingcar/chws0508/73-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +46 -0
- package/lessons/woowacourse-racingcar/cucumber99/132-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/cucumber99/177-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/devfeijoa/146-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/doabletuple/149-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/doabletuple/175-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/donghyun81/154-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
- package/lessons/woowacourse-racingcar/dpcks0509/103-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
- package/lessons/woowacourse-racingcar/dpcks0509/112-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
- package/lessons/woowacourse-racingcar/drunkenhw/82-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
- package/lessons/woowacourse-racingcar/etama123/145-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
- package/lessons/woowacourse-racingcar/gaeun5744/124-/353/246/254/355/214/251/355/204/260/353/247/201.md +53 -0
- package/lessons/woowacourse-racingcar/gaeun5744/93-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
- package/lessons/woowacourse-racingcar/gahyunkim/134-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/gahyunkim/164-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/giovannijunseokim/140-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/haeum808/101-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/haeum808/129-/353/246/254/355/214/251/355/204/260/353/247/201.md +46 -0
- package/lessons/woowacourse-racingcar/hwannow/141-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
- package/lessons/woowacourse-racingcar/hwannow/157-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +45 -0
- package/lessons/woowacourse-racingcar/hxeyexn/109-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
- package/lessons/woowacourse-racingcar/hxeyexn/128-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
- package/lessons/woowacourse-racingcar/hyemdooly/50-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
- package/lessons/woowacourse-racingcar/hyemdooly/68-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/hyunji1203/29-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/hyunji1203/60-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
- package/lessons/woowacourse-racingcar/ii2001/102-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +42 -0
- package/lessons/woowacourse-racingcar/ii2001/122-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
- package/lessons/woowacourse-racingcar/ijh1298/144-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/injoon2019/24-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
- package/lessons/woowacourse-racingcar/inseonyun/44-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
- package/lessons/woowacourse-racingcar/inseonyun/76-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/ippnsj/36-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/ippnsj/67-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/jaeyeongjo/110-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +39 -0
- package/lessons/woowacourse-racingcar/jaeyeongjo/89-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +46 -0
- package/lessons/woowacourse-racingcar/jinuemong/104-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
- package/lessons/woowacourse-racingcar/jinuemong/117-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +42 -0
- package/lessons/woowacourse-racingcar/jiyuneel/142-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
- package/lessons/woowacourse-racingcar/junjange/113-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +41 -0
- package/lessons/woowacourse-racingcar/junjange/87-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +39 -0
- package/lessons/woowacourse-racingcar/junseo511/148-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
- package/lessons/woowacourse-racingcar/junseo511/165-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
- package/lessons/woowacourse-racingcar/ki960213/32-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/ki960213/63-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
- package/lessons/woowacourse-racingcar/kimhm0728/100-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
- package/lessons/woowacourse-racingcar/kimhm0728/116-/353/246/254/355/214/251/355/204/260/353/247/201.md +54 -0
- package/lessons/woowacourse-racingcar/kkosang/105-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/kkosang/126-/353/246/254/355/214/251/355/204/260/353/247/201.md +53 -0
- package/lessons/woowacourse-racingcar/kmkim2689/123-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
- package/lessons/woowacourse-racingcar/kmkim2689/92-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/krrong/34-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +63 -0
- package/lessons/woowacourse-racingcar/m6z1/150-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/m6z1/156-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +40 -0
- package/lessons/woowacourse-racingcar/medAndro/153-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/moondev03/135-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/moondev03/161-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
- package/lessons/woowacourse-racingcar/murjune/121-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
- package/lessons/woowacourse-racingcar/murjune/95-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/no1msh/43-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/no1msh/69-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
- package/lessons/woowacourse-racingcar/otter66/48-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/otter66/77-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
- package/lessons/woowacourse-racingcar/oungsi2000/152-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
- package/lessons/woowacourse-racingcar/oungsi2000/187-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/parkjiminnnn/143-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
- package/lessons/woowacourse-racingcar/parkjiminnnn/158-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/pingu244/38-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
- package/lessons/woowacourse-racingcar/pingu244/62-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
- package/lessons/woowacourse-racingcar/re4rk/28-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
- package/lessons/woowacourse-racingcar/re4rk/55-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/rhkrwngud445/42-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/rhkrwngud445/74-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +47 -0
- package/lessons/woowacourse-racingcar/rhthrhrl0/31-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
- package/lessons/woowacourse-racingcar/rosemin928/138-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/rosemin928/171-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +38 -0
- package/lessons/woowacourse-racingcar/s6m1n/120-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/s6m1n/91-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +62 -0
- package/lessons/woowacourse-racingcar/s9hn/53-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +44 -0
- package/lessons/woowacourse-racingcar/s9hn/78-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
- package/lessons/woowacourse-racingcar/sh1mj1/107-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/sh1mj1/115-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
- package/lessons/woowacourse-racingcar/songpink/119-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
- package/lessons/woowacourse-racingcar/songpink/98-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/sujin9/52-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
- package/lessons/woowacourse-racingcar/sujin9/61-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +47 -0
- package/lessons/woowacourse-racingcar/tmdgh1592/47-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
- package/lessons/woowacourse-racingcar/tmdgh1592/64-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/tobae-time/151-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
- package/lessons/woowacourse-racingcar/tobae-time/167-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
- package/lessons/woowacourse-racingcar/whk06061/41-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
- package/lessons/woowacourse-racingcar/wondroid-world/136-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
- package/lessons/woowacourse-racingcar/wondroid-world/166-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
- package/lessons/woowacourse-racingcar/yrsel/139-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/yujamint/83-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
- package/package.json +46 -0
- package/skills/oh-my-oop/SKILL.md +39 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# PR #31 — [블랙잭 1단계] 반달 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@no1msh](https://github.com/no1msh) (**반달 = 본 MCP `oh-my-oop` 프로젝트 저자**)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-blackjack/pull/31
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @vagabond95
|
|
7
|
+
- **라인 코멘트:** 19 스레드 — *학생 자가 PR 본문 의문 2개 (DTO 위치 + 상수화) + Dealer is-a Player 자가 의문 + Builder 패턴 자가 인정 + 일급 컬렉션 칭찬*
|
|
8
|
+
- **신규 reviewee** + **메타 케이스: reviewee 가 본 MCP `oh-my-oop` 저자** — *학생 시절 코드 + reviewer 메타 어휘 양가 활용 사례*.
|
|
9
|
+
|
|
10
|
+
## 잘한 점 (설계 관점)
|
|
11
|
+
|
|
12
|
+
- **PR 본문 자가 의문 2개 + 자가 후회 + 자가 어려움 명시** — *"미션 시간이 얼마남지 않아 바쁘게 하다보니 완벽하게 하진 못했던 것 같습니다ㅜㅜ"* + *(1) DTO 위치 (Controller vs Domain)* + *(2) 에러 메시지 상수화 vs 직접 작성*. **PR 본문 자가 의문 모범**. PR #128·#135·#108·#136·#137·#148·#151·#98·#95·#99·#46·#77·#91 결.
|
|
13
|
+
- **`Command` 도메인 분리 칭찬** — vagabond95: *"코멘드를 따로 도메인으로 분리해주신 시도 좋습니다 👍"*. **Command 패턴 자가 도입** — *Hit/Stay 명령을 별도 도메인 객체로*. PR #88·#90·#147 의 *Action enum* 결.
|
|
14
|
+
- **`View` 비즈니스 로직 X 칭찬** — vagabond95: *"View 의 역할에 맞게, 비즈니스 로직이 포함되지 않고 간결하게 잘 구현해주신 것 같습니다 👍"*. **View 책임 명확 분리** — PR #28·#79·#16·#26·#9 의 *View 로직 누수* 와 반대 결.
|
|
15
|
+
- **일급 컬렉션 활용 칭찬** — vagabond95: *"일급 컬렉션 활용 👍"* (Cards 클래스).
|
|
16
|
+
- **Controller 단순 중계 칭찬** — vagabond95: *"컨트롤러의 구현이 단순히 중계해주는 형태로 단순해졌네요 👍"* — *피드백 반영 후 칭찬*. PR #99·#95·#28·#78·#112·#125·#147·#43·#77·#46 의 *Controller god-object* 와 반대 결.
|
|
17
|
+
|
|
18
|
+
## 못한 점 (설계 관점)
|
|
19
|
+
|
|
20
|
+
### 1. PR 본문 자가 의문 1: `DTO 위치 = Controller vs Domain`
|
|
21
|
+
|
|
22
|
+
PR 본문: *"우선, 이번 프로젝트를 진행하면서 Domain에서 DTO로 감싸서 전달하도록 하였습니다. 하지만 테스트 코드를 작성하는 것이 너무 힘들어진다는 문제가 발생하였는데, 이런 구조여도 괜찮은지 궁금합니다!"*
|
|
23
|
+
|
|
24
|
+
→ **DTO 위치 양가성**:
|
|
25
|
+
|
|
26
|
+
- **Domain 이 DTO 반환** (학생 선택):
|
|
27
|
+
- 장점: Domain 이 외부 표현 정확히 통제.
|
|
28
|
+
- **단점 (학생 자가 명시): 테스트 어려움** — *Domain 메서드가 DTO 반환 = 테스트 시 도메인 객체 직접 검증 X + DTO 변환 결과만 검증*.
|
|
29
|
+
|
|
30
|
+
- **Controller 가 Domain → DTO 변환** (정공):
|
|
31
|
+
- Domain 은 자기 객체만 반환 → Controller 가 DTO 변환.
|
|
32
|
+
- 장점: *Domain 테스트는 도메인 객체로 결정적 검증*. *Controller 가 변환 책임*.
|
|
33
|
+
- 단점: Controller 의 변환 책임 추가 (작은 비용).
|
|
34
|
+
|
|
35
|
+
- **별도 Mapper / Assembler 객체**:
|
|
36
|
+
- 변환 책임을 별도 객체로 응집.
|
|
37
|
+
|
|
38
|
+
**MCP 룰 후보 — `dto-conversion-locus`** = *Domain 이 DTO 반환 = 테스트 어려움 시그널*. PR #99 (s6m1n *Hand 클래스*) / PR #91 (murjune *UiModel*) / PR #88·#131 (view-by-stage-split) 결.
|
|
39
|
+
|
|
40
|
+
학생 자가 명시 *"테스트 코드를 작성하는 것이 너무 힘들어진다는 문제"* — **테스트 어려움 = 책임 잘못 배치 시그널 자가 학습**. PR #99 (s6m1n *Controller + View 없이 가능?*) 와 같은 결의 *역방향* (학생측 자가 진단).
|
|
41
|
+
|
|
42
|
+
### 2. PR 본문 자가 의문 2: `에러 메시지 상수화 vs 직접 작성`
|
|
43
|
+
|
|
44
|
+
학생 자가 의문: *"에러 메시지와 같은 String도 const val 키워드를 통해 상수화를 해주는 것이 가독성이 높은지, 아니면 문자 그대로 작성하는 것이 높은지 궁금합니다!"*
|
|
45
|
+
|
|
46
|
+
→ **에러 메시지 상수화 양가성**:
|
|
47
|
+
|
|
48
|
+
- **상수화 (`const val ERROR_MESSAGE = "..."`)**:
|
|
49
|
+
- 장점: 메시지 변경 시 한 곳 수정.
|
|
50
|
+
- 장점: 다국어 / i18n 시 분리 용이.
|
|
51
|
+
- 단점: 호출 위치에서 메시지 내용 즉시 알기 어려움 (가독성 ↓).
|
|
52
|
+
|
|
53
|
+
- **직접 작성 (`throw IllegalArgumentException("...")`)**:
|
|
54
|
+
- 장점: 호출 위치에서 메시지 즉시 가독.
|
|
55
|
+
- 단점: 동일 메시지 N 곳 = 변경 시 N 곳 수정.
|
|
56
|
+
|
|
57
|
+
- **하이브리드** — *컴파일 시점 보간 (Kotlin string templates)* + *상수 prefix + 동적 인자*.
|
|
58
|
+
|
|
59
|
+
**학생 자가 의문 모범**. *vagabond95 미답변* — *PR 본문 의문 답변 누락 가능성*. PR #46 (말리빈 *minusFrom 권고*) 의 *에러 메시지에 입력값 포함* 결.
|
|
60
|
+
|
|
61
|
+
### 3. `Dealer is-a Player` 상속 의문
|
|
62
|
+
|
|
63
|
+
vagabond95: *"딜러가 플레이어를 상속하는 구조로 구현해주셨는데, 블랙잭 도메인에서 `Dealer is a Player` 의 논리가 성립할까요?"*
|
|
64
|
+
|
|
65
|
+
→ **3 가지 학습**:
|
|
66
|
+
|
|
67
|
+
#### 3.1. *LSP (Liskov Substitution Principle) + is-a 논리*
|
|
68
|
+
|
|
69
|
+
- *Dealer extends Player* = *모든 Dealer 는 Player* (LSP).
|
|
70
|
+
- *블랙잭 룰*: *Dealer 는 베팅 X, 자동 hit ≤16, 1.5배 배당 분기* — *Player 와 행동 다름*.
|
|
71
|
+
- *`Dealer is a Player` 가 의미적으로 성립 X* — *LSP 위반 위험*.
|
|
72
|
+
|
|
73
|
+
#### 3.2. *Dealer extends Player vs 공통 부모 추상화*
|
|
74
|
+
|
|
75
|
+
- **(A) `Dealer extends Player`** = 학생 선택. *PR #95 (말리빈 *Dealer 는 Player 의 변종?*) / PR #16 (BeokBeok *Dealer.name override?*) 의 *학생 자가 결정* 결*.
|
|
76
|
+
- **(B) `abstract Participant` + `Player` / `Dealer extends Participant`** = *공통 부모 추상화*. PR #74·#108·#133·#132·#136·#49·#46 의 *추상 클래스 + Participant 통합* 결.
|
|
77
|
+
- **(C) `interface Participant` + 다중 구현** = *상속 X + 인터페이스*.
|
|
78
|
+
- **(D) `Dealer` / `Player` 무관계 + 협력자 위임** = *컴포지션*.
|
|
79
|
+
|
|
80
|
+
**MCP 룰 후보 — `dealer-extends-player-lsp-violation`**. PR #95·#23·#46·#148·#151·#49·#132·#77 결.
|
|
81
|
+
|
|
82
|
+
#### 3.3. *vagabond95 의 *"논리가 성립할까요?"* 메타 질문*
|
|
83
|
+
|
|
84
|
+
학생 자가 답변 권유. PR #95 (말리빈 *Dealer 는 Player 의 변종?*) 와 *동일 메타 질문* — *2023년 3월 코호트 reviewer 공통 패턴*.
|
|
85
|
+
|
|
86
|
+
### 4. `ParticipantsBuilder` + `BlackJackBuilder` — Builder 패턴 의문
|
|
87
|
+
|
|
88
|
+
vagabond95 1차: *"빌더를 따로 두신 이유가 있으실까요? 현재 구현상, 빌더를 별도로 두었을때의 이점이 잘 보이지 않는 것 같습니다."*
|
|
89
|
+
|
|
90
|
+
vagabond95 2차: *"빌더 패턴을 염두하여 만드신 것이라면, 현재구조는 빌더 패턴과는 거리가 멀어보입니다. 빌더 패턴의 구조에 대해 학습해보셔도 좋을 것 같아요."*
|
|
91
|
+
|
|
92
|
+
vagabond95 3차 (BlackJackBuilder): *"Participants 빌더와 같은 맥락으로 꼭 필요한 클래스일지 검토 부탁드릴게요!"*
|
|
93
|
+
|
|
94
|
+
→ **2 가지 학습**:
|
|
95
|
+
|
|
96
|
+
#### 4.1. *Builder 패턴 = 복잡 객체 단계별 생성*
|
|
97
|
+
|
|
98
|
+
- *Builder = 호출 순서 무관 + build() 시점 invariant 검증* (PR #9 BeokBeok 결).
|
|
99
|
+
- *Participants 가 단순 List<Participant> = 빌더 불필요* — *생성자 + 팩토리 함수 충분*.
|
|
100
|
+
|
|
101
|
+
#### 4.2. *YAGNI (You Aren't Gonna Need It)*
|
|
102
|
+
|
|
103
|
+
- *현재 요구사항이 *복잡 생성 단계 X* + 학생이 *Builder 도입* = *과한 추상화*.
|
|
104
|
+
- **PR #146 (yrsel YAGNI 자가 인정)** 결.
|
|
105
|
+
|
|
106
|
+
**MCP 룰 후보 — `unnecessary-builder-pattern`** = *YAGNI 위반 + 책임 모호*. PR #9 (BeokBeok *Builder 호출 순서*) 결의 *Builder 도입 자체 불필요* 시점.
|
|
107
|
+
|
|
108
|
+
### 5. `한글 변수명` — 코딩 컨벤션 위반
|
|
109
|
+
|
|
110
|
+
vagabond95: *"변수명을 한글로 지으면 안되는 이유가 있다면 무엇일까요?"* + *"전반적으로 한글 변수가 사용된 케이스가 보이는데, 코멘트 참고하여 같이 검토 부탁드려요!"*
|
|
111
|
+
|
|
112
|
+
→ **PR #26 (chws0508 *한글 컨벤션 외부 글 자가 학습*) 와 같은 결**. *비 ASCII 문자 = 다른 개발자 혼란 + 컨벤션 위반*.
|
|
113
|
+
|
|
114
|
+
### 6. `enum 명명 구체화` + `CardNumber` enum 도입 권유
|
|
115
|
+
|
|
116
|
+
vagabond95 1차: *"enum 클래스 네이밍이 좀 더 구체적으로 지어지면 좋을 것 같아요."* (Shape)
|
|
117
|
+
|
|
118
|
+
vagabond95 2차: *"enum 으로 선언할 경우 좀 더 구현이 단순해질 것 같은데, 장/단점 비교 후 검토 부탁드려요." (CardNumber)*
|
|
119
|
+
|
|
120
|
+
→ **enum 어휘 + 명명 구체성**:
|
|
121
|
+
- *`Shape`* (추상) < *`CardShape`* / *`CardSuit`* (구체).
|
|
122
|
+
- *CardNumber* = *class 보다 enum 정공* (1~10, J, Q, K, A = 닫힌 집합).
|
|
123
|
+
|
|
124
|
+
**MCP 기존 룰 `vagueName` + enum 도입 권유**. PR #99·#26·#23·#39·#46·#16·#9 결.
|
|
125
|
+
|
|
126
|
+
### 7. `동일 도메인 상태 분산` — `CardGenerator` vs `CardDeck` 양쪽 cards
|
|
127
|
+
|
|
128
|
+
vagabond95 1차: *"generator 도 cards 를 가지고 있고, CardDeck 도 cards 를 가지고 있는데 각각 따로 관리되어야할 이유가 있을까요?"*
|
|
129
|
+
|
|
130
|
+
vagabond95 2차 (메타 질문): *"동일한 도메인 상태가 여러곳에 분산되면 어떠한 문제점이 생길 수 있을까요?"*
|
|
131
|
+
|
|
132
|
+
→ **도메인 상태 분산 = 동기화 문제**:
|
|
133
|
+
- *동일 cards 가 generator + CardDeck 양쪽 보유* → *변경 시 양쪽 동기화 필요*.
|
|
134
|
+
- *원본 단일 위치 (Single Source of Truth)* 정공.
|
|
135
|
+
|
|
136
|
+
**MCP 룰 후보 — `domain-state-duplication`** = *동일 상태 다중 객체 보유*. PR #39 (rhthrhrl0 *redundant-state*) 결.
|
|
137
|
+
|
|
138
|
+
### 8. `2번 draw 호출` — Controller vs Domain
|
|
139
|
+
|
|
140
|
+
vagabond95: *"꼭 2번 draw 를 해주는게 도메인의 비즈니스 로직이라면, 2번 호출해주는 부분은 domain 이 담당해보는 것은 어떨까요? 현재 drawAll 호출에 대한 제약사항이 없는 상태애서, 횟수에 대한 context 가 부족한 개발자의 경우 여러번 호출하게될 가능성이 있을 것 같아요. (+ 여러번 호출했을 떄의 안전장치도 없는 것 같구요!)"*
|
|
141
|
+
|
|
142
|
+
vagabond95 별도 (메타 질문): *"BlackJack 내부에서 수행 가능하지 않을까요? 컨트롤러가 도메인의 세부사항을 어디까지 알아야할지, 많이 알수록 or 적게알수록 장/단점은 무엇일지 고민해보면 좋겠어요!"*
|
|
143
|
+
|
|
144
|
+
→ **Controller 도메인 세부 침투 양가성**:
|
|
145
|
+
|
|
146
|
+
- *Controller 많이 알기*: *세부 제어 가능 + 도메인 변경 시 Controller 도 영향*.
|
|
147
|
+
- *Controller 적게 알기*: *도메인 응집 + Controller 단순 + 도메인 변경 영향 차단*.
|
|
148
|
+
|
|
149
|
+
**MCP 룰 후보 — `controller-domain-coupling-depth`**. PR #99·#95·#28·#78·#112·#125·#147·#43·#77·#46 결.
|
|
150
|
+
|
|
151
|
+
PR #46 (krrong *drawCard() 두 번 호출 → 한 메서드 2장 반환*) 와 동일 결.
|
|
152
|
+
|
|
153
|
+
### 9. `extension function` 활용 권유
|
|
154
|
+
|
|
155
|
+
vagabond95: *"`승, 무, 패` 도 extension function 으로 변환하도록 구현해볼수도 있겠네요!"*
|
|
156
|
+
|
|
157
|
+
→ **PR #9 (BeokBeok *winTo 확장 함수 vs 멤버 함수 학생 자가 4 분면*) 결**. *확장 함수 = 외부 변환 응집*.
|
|
158
|
+
|
|
159
|
+
### 10. `상수 vs 함수` 제공 의문
|
|
160
|
+
|
|
161
|
+
vagabond95: *"상수가 아닌 함수로 제공하시는 이유가 있을까요~?"*
|
|
162
|
+
|
|
163
|
+
→ **상수 (val) vs 함수 (fun) 양가성**:
|
|
164
|
+
- *상수* = *불변 + 계산 비용 X*.
|
|
165
|
+
- *함수* = *호출 시점 계산 + 외부 의존 가능*.
|
|
166
|
+
- *`fun blackJackNumber() = 21`* (상수임에도 함수) = *불필요한 함수 호출 비용 + 의도 모호*.
|
|
167
|
+
|
|
168
|
+
PR #91·#43 (프로퍼티 vs 함수) 결.
|
|
169
|
+
|
|
170
|
+
### 11. `getPlayerMatchResults()` 중복 통합
|
|
171
|
+
|
|
172
|
+
vagabond95: *"getPlayerMatchResults() 와 구현이 거의 비슷해보이는데, 재사용하거나 통합해보는 것이 가능할까요?"*
|
|
173
|
+
|
|
174
|
+
→ **DRY (Don't Repeat Yourself)**. PR #9 (BeokBeok *introduce vs companion init 중복*) 결.
|
|
175
|
+
|
|
176
|
+
### 12. `draw() 계속 호출 시 예외 처리`
|
|
177
|
+
|
|
178
|
+
vagabond95: *"draw() 를 계속 호출 했을때, 예외처리가 필요하지 않을까요?"*
|
|
179
|
+
|
|
180
|
+
→ **카드 부족 시 도메인 룰**:
|
|
181
|
+
- *예외 발생* (1 벌 한정 모델) vs *덱 리필* (카지노 6덱 메타포) vs *Optional 반환*.
|
|
182
|
+
|
|
183
|
+
PR #46 (krrong *53번 뽑으면 오류?*) / PR #26 (chws0508 *6덱 메타포*) / PR #58·#74·#108·#133·#136·#41 결.
|
|
184
|
+
|
|
185
|
+
### 13. `테스트 코드 비어있음`
|
|
186
|
+
|
|
187
|
+
vagabond95: *"테스트 코드가 채워지지 않은 것 같아요!"*
|
|
188
|
+
|
|
189
|
+
→ **TDD 요구사항 미준수**. PR #16·#33·#9 결.
|
|
190
|
+
|
|
191
|
+
## 리뷰어 의견 요지 (vagabond95)
|
|
192
|
+
|
|
193
|
+
19 코멘트 특징:
|
|
194
|
+
|
|
195
|
+
- **간결 + 메타 질문 위주** — *"이유가 있을까요?"*, *"논리가 성립할까요?"*, *"어떠한 문제점이 생길 수 있을까요?"* — 학생 자가 답변 유도.
|
|
196
|
+
- **장단점 비교 권유** — *"장/단점 비교 후 검토 부탁드려요"*, *"많이 알수록 or 적게알수록 장/단점은 무엇일지 고민해보면 좋겠어요"* — **MCP `oh-my-oop` 의 *N 안 + 트레이드오프* 어휘 합류**.
|
|
197
|
+
- **빌더 패턴 학습 권유** — *"빌더 패턴의 구조에 대해 학습해보셔도 좋을 것 같아요"* — *학생 자가 학습 채널 권유*.
|
|
198
|
+
- **`👍` 칭찬 분포** — *View 분리, Command 분리, 일급 컬렉션, Controller 단순화* 4회 칭찬. **균형 잡힌 분포**.
|
|
199
|
+
|
|
200
|
+
## 학생/Reviewee 메타 케이스: no1msh = MCP `oh-my-oop` 저자
|
|
201
|
+
|
|
202
|
+
본 PR의 학생 *no1msh = 반달* 은 이 분석 코퍼스가 사용되는 **MCP `oh-my-oop` 서버의 저자**.
|
|
203
|
+
|
|
204
|
+
→ **메타 학습 케이스**:
|
|
205
|
+
|
|
206
|
+
1. **2023년 3월 학생 시기 코드** = *Dealer extends Player + Builder 패턴 도입 + 한글 변수* 등 *현재 MCP 룰이 진단할만한 안티패턴 다수*.
|
|
207
|
+
2. **현재 MCP `oh-my-oop`** = *학생 시기 자가 학습이 *룰화* + *N 안 + 트레이드오프* 어휘로 진화*.
|
|
208
|
+
3. **vagabond95 의 reviewer 어휘** (장단점 비교, 메타 질문) = **MCP `oh-my-oop` 핵심 어휘와 일치**.
|
|
209
|
+
|
|
210
|
+
PR #46 (krrong 학생 + reviewer 메타 케이스) 와 *같은 결의 *1 년 학생 → 도구 저자* 진화 케이스*. **학생 시기 자가 의문 → 도구화** 패턴.
|
|
211
|
+
|
|
212
|
+
## 대표 인용
|
|
213
|
+
|
|
214
|
+
> *"미션 시간이 얼마남지 않아 바쁘게 하다보니 완벽하게 하진 못했던 것 같습니다ㅜㅜ"* — no1msh (학생 자가 완성도 인정)
|
|
215
|
+
|
|
216
|
+
> *"우선, 이번 프로젝트를 진행하면서 Domain에서 DTO로 감싸서 전달하도록 하였습니다. 하지만 테스트 코드를 작성하는 것이 너무 힘들어진다는 문제가 발생하였는데, 이런 구조여도 괜찮은지 궁금합니다!"* — no1msh (DTO 위치 + 테스트 어려움 자가 시그널)
|
|
217
|
+
|
|
218
|
+
> *"에러 메시지와 같은 String도 const val 키워드를 통해 상수화를 해주는 것이 가독성이 높은지, 아니면 문자 그대로 작성하는 것이 높은지 궁금합니다!"* — no1msh (상수화 양가성 자가 의문)
|
|
219
|
+
|
|
220
|
+
> *"블랙잭 도메인에서 `Dealer is a Player` 의 논리가 성립할까요?"* — vagabond95 (LSP + is-a 논리 메타 질문)
|
|
221
|
+
|
|
222
|
+
> *"동일한 도메인 상태가 여러곳에 분산되면 어떠한 문제점이 생길 수 있을까요?"* — vagabond95 (도메인 상태 분산 메타 질문)
|
|
223
|
+
|
|
224
|
+
> *"컨트롤러가 도메인의 세부사항을 어디까지 알아야할지, 많이 알수록 or 적게알수록 장/단점은 무엇일지 고민해보면 좋겠어요!"* — vagabond95 (Controller-Domain 결합 깊이 양가성)
|
|
225
|
+
|
|
226
|
+
## 얻은 교훈
|
|
227
|
+
|
|
228
|
+
1. **`DTO 위치 = Controller vs Domain` 양가성** — *Domain 이 DTO 반환 = 테스트 어려움 시그널*. *Controller 변환 정공 + Domain 은 자기 객체*. **MCP 룰 후보 `dto-conversion-locus`**. *학생 자가 테스트 어려움 명시 = 책임 잘못 배치 자가 진단 모범*.
|
|
229
|
+
|
|
230
|
+
2. **`Dealer is-a Player` LSP 위반** — *블랙잭 룰의 Dealer ≠ Player 차이 (베팅 X, 자동 hit, 1.5배)* = *상속 시 LSP 위반*. **MCP 룰 후보 `dealer-extends-player-lsp-violation`**. PR #95·#23·#46·#148·#151·#49·#132·#77 결.
|
|
231
|
+
|
|
232
|
+
3. **`불필요한 Builder 패턴`** — *YAGNI 위반 + Builder 정의 (호출 순서 무관 + build() invariant) 미준수*. **MCP 룰 후보 `unnecessary-builder-pattern`**. PR #9 (BeokBeok *Builder 호출 순서*) / PR #146 (yrsel *YAGNI 자가 인정*) 결.
|
|
233
|
+
|
|
234
|
+
4. **`동일 도메인 상태 분산` = Single Source of Truth 위반** — *동일 cards 가 generator + CardDeck 양쪽 보유 = 동기화 문제*. **MCP 룰 후보 `domain-state-duplication`**. PR #39 (rhthrhrl0 *redundant-state*) 결.
|
|
235
|
+
|
|
236
|
+
5. **`Controller-Domain 결합 깊이`** — *Controller 많이 알기 = 세부 제어 + 변경 영향* vs *적게 알기 = 도메인 응집 + 변경 차단*. **MCP 룰 후보 `controller-domain-coupling-depth`**. PR #99·#95·#46·#77 결.
|
|
237
|
+
|
|
238
|
+
6. **`상수화 vs 직접 작성` 학생 자가 의문** — *상수 (한 곳 수정) vs 직접 (즉시 가독)* — **MCP 룰 후보 `string-constant-locus`**. *학생 자가 의문 가시화 모범*.
|
|
239
|
+
|
|
240
|
+
7. **`reviewer 메타 어휘 = MCP `oh-my-oop` 핵심과 일치`** — *vagabond95 의 *"많이 알수록 or 적게알수록 장/단점"*, *"장/단점 비교 후 검토"*. **MCP `oh-my-oop` 의 *N 안 + 트레이드오프* 어휘 합류**. PR #23·#26·#43·#46·#91·#95 의 *9 reviewer 모두 공통 어휘* 결.
|
|
241
|
+
|
|
242
|
+
8. **`no1msh = MCP `oh-my-oop` 저자` 메타 학습 케이스** — *2023년 3월 학생 시기 자가 의문 → 1 년 후 도구 저자*. *학생 시기 자가 학습이 *룰화 + 어휘 진화*. PR #46 (krrong 학생 + reviewer) 결의 *학생 → 도구* 변형.
|
|
243
|
+
|
|
244
|
+
9. **`테스트 어려움 = 책임 잘못 배치 시그널`** — *학생이 *DTO 변환을 Domain 에 둔 후 테스트 어려움 자가 발견*. **테스트 어려움 = 설계 시그널** 자가 학습 모범. PR #99·#91·#46·#23·#74 결.
|
|
245
|
+
|
|
246
|
+
10. **`Command 도메인 분리`** — *Hit/Stay 명령을 별도 도메인 객체로*. PR #88·#90·#147 의 *Action enum* 결의 *Command 패턴*.
|
|
247
|
+
|
|
248
|
+
11. **`한글 변수명` 컨벤션 위반** — *비 ASCII = 다른 개발자 혼란*. PR #26 (chws0508 *한글 컨벤션 외부 글 자가 학습*) 결의 *학생측 미인식 케이스*.
|
|
249
|
+
|
|
250
|
+
12. **`vagabond95 reviewer 패턴`** — *간결 + 메타 질문 위주 + 장단점 비교 권유*. *batch 12 신규 reviewer 로 등장한 reviewer 의 *2023년 3월 코호트* 활동 진단*.
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# PR #24 — [블랙잭 1단계] 수달 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@otter66](https://github.com/otter66)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-blackjack/pull/24
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @laco-dev
|
|
7
|
+
- **라인 코멘트:** 30 (리뷰어 21 / 리뷰이 9)
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Cards` 일급 컬렉션 + `sumCardsNumber()` + Ace 보정 분리** — 점수 계산을 Cards에.
|
|
12
|
+
- **`CardGenerator(randomGenerator: Generator)` Strategy** — 테스터빌리티 (후속에 `Deck` 클래스로 단순화).
|
|
13
|
+
- **`Result` enum (WIN/LOSE/DRAW) + `Result.valueOf(dealerSum, participantSum)` 분리**.
|
|
14
|
+
- **`Participants` 일급 컬렉션 + `values: List<Participant>` 접근자**.
|
|
15
|
+
- **후속 반영 — `Cards` 방어적 복사 + Deck 도입 + 함수 순서(stepdown) + Participant 추상화 + match 메시지 분리**.
|
|
16
|
+
|
|
17
|
+
## 못한 점 (설계 관점)
|
|
18
|
+
|
|
19
|
+
### 1. `CardShape.word` / `Result.word` — UI 문자열 도메인 보유
|
|
20
|
+
|
|
21
|
+
```kotlin
|
|
22
|
+
enum class CardShape(val word: String) { SPADE("스페이드"), DIAMOND("다이아몬드"), HEART("하트"), CLOVER("클로버") }
|
|
23
|
+
enum class Result(val word: String) { WIN("승"), LOSE("패"), DRAW("무"); }
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
리뷰어: "*word는 UI의 관심사*이지 않을까요? 가령 스페이드를 *"spade" "♤"* 이렇게 출력할 수도 있습니다." / "마찬가지로 *"승", "패", "무"는 UI의 관심사로 보입니다*." — PR #28·#78·#112·#125·#128·#135와 동일한 *enum의 UI 표현 보유* 패턴. **6개 PR 연속 등장하는 안티패턴**.
|
|
27
|
+
|
|
28
|
+
### 2. `Cards.isBlackjack()` — *2장 + ACE + JQK*인지 *직접 비교*
|
|
29
|
+
|
|
30
|
+
```kotlin
|
|
31
|
+
private fun isBlackjack(): Boolean {
|
|
32
|
+
if (_cards.size != 2) return false
|
|
33
|
+
val condition1 = _cards.filter { it.number == CardNumber.ONE }.size
|
|
34
|
+
val condition2 = _cards.filter {
|
|
35
|
+
it.number == CardNumber.KING || it.number == CardNumber.QUEEN || it.number == CardNumber.JACK
|
|
36
|
+
}.size
|
|
37
|
+
if (condition1 == 1 && condition2 == 1) return true
|
|
38
|
+
return false
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
리뷰어: "*점수를 계산할 때에는 간단하게 아래처럼 생각해볼 수 있습니다.* ``` 1. 카드 점수를 합산한다 2. 에이스 카드가 있다면, 보너스 점수 10점을 더한 결과가 21 이하라면, 그 값을 반환한다. ```" — *블랙잭 = ACE + JQK 2장*이라는 *특별 케이스*가 *별도 메서드*. *합산 후 21 이하면 +10 보너스*가 *단일 룰*로 더 단순. + `condition1` / `condition2` 같은 *변수명*은 *의미 부재*.
|
|
43
|
+
|
|
44
|
+
### 3. `open class Player` + `Dealer : Player` 상속
|
|
45
|
+
|
|
46
|
+
```kotlin
|
|
47
|
+
open class Player(val name: String, ...) {
|
|
48
|
+
fun checkMustGenerateCard(): Boolean = ...
|
|
49
|
+
fun isGenerateCardPossible(): Boolean = ...
|
|
50
|
+
}
|
|
51
|
+
class Dealer(name: String = "딜러") : Player(name) {
|
|
52
|
+
fun checkMustGenerateCard(): Boolean = cards.sumCardsNumber() <= MIN_SUM_NUMBER
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
리뷰어: "*플레이어와 딜러 에게는 각자 카드를 더 뽑을 수 있는지 방법이 다릅니다.* 즉 *딜러인지 플레이어인지 상관 없이 카드를 더 뽑을 수 있는지? 에 대해서만 요청을 할 수 있다고 볼 수 있겠습니다.* open class를 이용한 상속 구조가 아닌, *다형성을 이용한 추상 클래스*를 고려해보면 어떨까요? ```kotlin abstract class Player { abstract fun canDraw(): Boolean }``` `dealer.checkMustGenerateCard() // (X)` / `participant.isGenerateCardPossible() // (X)` / `player.canDraw() // (O) 딜러인지 참가자인지 관심없음, 더 뽑을 수 있니?`" — PR #29와 같은 결. *`canDraw()` 단일 메서드*가 *Liskov 호환*.
|
|
57
|
+
|
|
58
|
+
또: 함수명 `checkMustGenerateCard` / `isGenerateCardPossible` 둘 다 *동작 동사*가 아닌 *상태 질의의 우회 표현*. `canDraw()` 한 줄.
|
|
59
|
+
|
|
60
|
+
### 4. `Player.generateCard()` — 카드를 *생성*?
|
|
61
|
+
|
|
62
|
+
```kotlin
|
|
63
|
+
open class Player(
|
|
64
|
+
val name: String,
|
|
65
|
+
private val generator: CardGenerator = CardGenerator(RandomGenerator())
|
|
66
|
+
) {
|
|
67
|
+
fun generateCard() { cards.addCard(generator.generateCard()) }
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
리뷰어: "*카드를 뽑는다 라는 개념은 addCard(card)를 이용해서 전달되는것에 반해 카드를 생성한다라는 개념은 플레이어에게 어떤 의미를 가지는 것일까요?* *카드 뭉치(Deck)에서 카드를 한장 뽑는다 라는 기능*을 구현할 수도 있지 않을까요? ```kotlin class Player { fun draw(deck: Deck) { ... } }```"
|
|
72
|
+
|
|
73
|
+
학생 자가 인정: "*말씀해주신 것처럼 카드를 발행하는 것(뽑는 것)은 플레이어가 아닌 덱에서 진행한 후 플레이어의 카드에 더하는 것이 더 좋은 방법인 것 같아 그렇게 수정*하였습니다!" — *Player가 generator를 보유 + 카드 생성 책임*은 *카드 출처 책임이 Player에*. *덱에서 한 장 뽑기*가 자연.
|
|
74
|
+
|
|
75
|
+
### 5. `Player(name, generator = CardGenerator(RandomGenerator()))` — 깊은 기본값 의존
|
|
76
|
+
|
|
77
|
+
```kotlin
|
|
78
|
+
open class Player(
|
|
79
|
+
val name: String,
|
|
80
|
+
private val generator: CardGenerator = CardGenerator(RandomGenerator())
|
|
81
|
+
) {...}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
*Player가 생성자 기본값에 RandomGenerator 의존*. *기본 생성 비용*에 *Random 인스턴스 매번* + *테스터빌리티 ↓*. *생성자 주입은 호출자가 명시*가 자연.
|
|
85
|
+
|
|
86
|
+
### 6. `Player.name`의 `require(name.length in 2..10)` — 이름 검증이 Player에 박힘
|
|
87
|
+
|
|
88
|
+
```kotlin
|
|
89
|
+
init { require(name.length in 2..10) { ERROR_NAME_LENGTH } }
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
리뷰어: "*플레이어 이름에 대해 도메인 로직을 분리*해보세요"
|
|
93
|
+
|
|
94
|
+
학생 변호: "*플레이어의 이름에 대해 "Name"등과 같이 분리를 할까 생각하였지만 이름의 길이를 검사하는 것 외에는 로직이 없고, 요구사항 외의 불필요한 로직이라 생각하여 해당 로직을 제거하는 방향으로 결정*하였습니다!!" — *Name 도메인 분리* 대신 *검증 제거*. **Trade-off**: *분리하면 객체 1개 더 + 검증 보유*, *제거하면 invariant 손실*. 학생은 *요구사항 외*라며 *후자 선택*. 리뷰어 의도는 *분리* 권고였으나 학생 *YAGNI 적용*. 합리적 결정 가능.
|
|
95
|
+
|
|
96
|
+
### 7. `OutputView`에 *String + 연산자 누적*
|
|
97
|
+
|
|
98
|
+
```kotlin
|
|
99
|
+
fun printFinalResult(dealer: Dealer, participants: Participants) {
|
|
100
|
+
var dealerResultMessage = FINAL_DEALER_RESULT_MENT
|
|
101
|
+
if (dealer.results[Result.WIN] != 0) dealerResultMessage += "${dealer.results[Result.WIN]}${Result.WIN.word} "
|
|
102
|
+
if (dealer.results[Result.LOSE] != 0) dealerResultMessage += "${dealer.results[Result.LOSE]}${Result.LOSE.word} "
|
|
103
|
+
if (dealer.results[Result.DRAW] != 0) dealerResultMessage += "${dealer.results[Result.DRAW]}${Result.DRAW.word} "
|
|
104
|
+
println(dealerResultMessage)
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
리뷰어: "*코틀린에서는 String 을 + 연산으로 이어나가는 방식은 지양*합니다. *buildString과 같은 문자열 Builder 함수를 사용* 해보세요" — `+=`로 *불변 String을 매번 새 인스턴스*. `buildString { ... }` 또는 `joinToString` 등 *전용 빌더*.
|
|
109
|
+
|
|
110
|
+
### 8. `CardGenerator + RandomGenerator + Generator` — 명사 중복
|
|
111
|
+
|
|
112
|
+
```kotlin
|
|
113
|
+
class CardGenerator(private val randomGenerator: Generator) {
|
|
114
|
+
fun generateCard(): Card = Card(generateCardNumber(), generateCardShape())
|
|
115
|
+
fun generateCardNumber(): CardNumber = randomGenerator.generateCardNumber()
|
|
116
|
+
fun generateCardShape(): CardShape = randomGenerator.generateCardShape()
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
리뷰어: "*제너레이터, 카드 제너레이터, 랜덤 제너레이터 등 여러가지 비슷한 개념이 뒤섞여 있는 느낌*이 듭니다. 로또 미션에서 *45개 라는 변하지 않는 숫자라는 개념*을 사용한 것과 같이 *카드 뭉치에는 최대 52개의 카드가 존재할 수 있습니다.* `끗수(13개) * 모양(4개) = 52` 이러한 개념을 모델로 풀어내보면 어떨까요? `class Deck(private val cards: Cards) { ... }` 마찬가지로 *하나의 블랙잭 게임에서는 무한대로 카드를 뽑을 수 있는 개념이 아니겠죠?*"
|
|
121
|
+
|
|
122
|
+
학생 자가 인정: "*테스트를 위해 제품코드에 인터페이스를 두고 구현하는 방법을 선택*하였는데 이 과정에서 *불필요한 코드가 여럿 생긴 것 같습니다*. 말씀해주신 것처럼 *덱 클래스를 두고 덱에서 카드를 뽑아줄 수 있도록 변경*하였습니다!!" — **테스터빌리티 위해 추상화 폭증 → 도메인 어휘 흐려짐**. *덱 = 52장 한정 자료구조*가 더 자연. PR #29와 같은 결.
|
|
123
|
+
|
|
124
|
+
### 9. `Result.valueOf(dealerSum, participantSum): Result` — 정적 + Int 비교
|
|
125
|
+
|
|
126
|
+
```kotlin
|
|
127
|
+
enum class Result {
|
|
128
|
+
companion object {
|
|
129
|
+
fun valueOf(dealerSum: Int, participantSum: Int): Result {
|
|
130
|
+
when {
|
|
131
|
+
((dealerSum > Cards.MAX_SUM_NUMBER) and (participantSum > Cards.MAX_SUM_NUMBER)) -> return DRAW
|
|
132
|
+
...
|
|
133
|
+
}
|
|
134
|
+
return WIN
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
리뷰어: "*승부를 결정짓는 것은 딜러와 상관없이 참가자가 다른 참가자와 판단할 요소이지 않을까요?* ```kotlin abstract class Player { fun decideResult(otherPlayer: Player): Result { ... } } ```" / 후속 댓글: "*승부를 판단하는 것은 참가자가 스스로 해야 하지 않을까요?* [...] 마찬가지로 *참가자는 다른 참가자와 점수를 비교할 수 있다는 의미*입니다. *가령 딜러 vs 플레이어가 아닌 플레이어 vs 플레이어의 승부가 되도 전혀 문제가 없어야* 합니다. ```kotlin abstract class Player { fun match(other: Player): Result { ... } } ```" / 또: "*한사람이 여러 사람과 승부를 벌이는 입장*에서도 마찬가지로 참가자의 역할로 만들어 볼 수 있겠습니다. ```kotlin abstract class Player { fun match(others: List<Player>): GameResult } class GameResult(val participant: Participant, val winCount: Int, val loseCount: Int, val drawCount: Int) ```"
|
|
141
|
+
|
|
142
|
+
→ **세 번의 리뷰**로 *상대 무관 비교 + 1대다 확장*까지 모델 제시. PR #28·#63·#125·#128·#29와 동일 주제 — *match는 참가자 메시지*가 핵심.
|
|
143
|
+
|
|
144
|
+
### 10. `Cards(_cards: MutableList<Card> = mutableListOf())` — 방어적 복사 누락
|
|
145
|
+
|
|
146
|
+
```kotlin
|
|
147
|
+
class Cards(private val _cards: MutableList<Card> = mutableListOf())
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
리뷰어: "*방어적 복사가 이루어질 수 있도록 해주세요* ```val cards = mutableListOf<Card>(); Cards(cards); cards.add(Card()); cards.add(Card()); cards.add(Card())```" — *외부 참조 보유*하면 *외부에서 추가 가능*. 학생 자가 인정: "*방어적 복사...!!! 수업시간에 배웠던 내용인데 무심코 지나쳐버렸네요...ㅠㅠ 방어적 복사를 적용하여 외부에서 전달한 리스트와 다른 주소의 리스트를 사용하도록 변경*하였습니다!! 감사합니다!!" — PR #79 (ii2001)·#65 (kmkim2689)와 같은 *Hand 외부 참조 누수*.
|
|
151
|
+
|
|
152
|
+
### 11. `BlackjackController`가 *카드 발급 직접 호출* — Participants 메시지 없음
|
|
153
|
+
|
|
154
|
+
```kotlin
|
|
155
|
+
private fun settingPlayersCards(dealer: Dealer, participants: Participants) {
|
|
156
|
+
repeat(CARD_SETTING_COUNT) { dealer.addCard(cardGenerator.generateCard()) }
|
|
157
|
+
participants.values.forEach { participant ->
|
|
158
|
+
repeat(CARD_SETTING_COUNT) { participant.addCard(cardGenerator.generateCard()) }
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
리뷰어: "*카드를 뽑는 동작을 참가자들(Participants) 객체에게 메시지를 전달해서 동작하도록* 해주세요. 다른 비슷한 곳도 같이 개선이 되면 좋겠습니다" — Controller가 *Dealer + Participants 각각 직접 호출*. `participants.drawInitial(deck)` 한 줄이 자연. *일급 컬렉션이 비즈니스 동작 제공*하는 패턴.
|
|
164
|
+
|
|
165
|
+
### 12. `readParticipantMoreCard` 깊은 중첩 + 불필요 분기
|
|
166
|
+
|
|
167
|
+
```kotlin
|
|
168
|
+
private fun readParticipantMoreCard(participant: Participant) {
|
|
169
|
+
while (true) {
|
|
170
|
+
val check = participant.isGenerateCardPossible()
|
|
171
|
+
if (check) {
|
|
172
|
+
val answer = inputView.readMoreCard(participant.name)
|
|
173
|
+
if (answer == ANSWER_MORE_CARD) { participant.addCard(cardGenerator.generateCard()) }
|
|
174
|
+
outputView.printParticipantCards(participant)
|
|
175
|
+
if (answer == ANSWER_NOT_MORE_CARD) break
|
|
176
|
+
}
|
|
177
|
+
if (!check) break // ⚠ check 변수를 if 두 번 검사
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
리뷰어: "*불필요한 괄호와 조건식이 같이 사용*되었습니다. 위 코드의 *가독성을 개선* 해 볼 수 있지 않을까요?" — `check`를 *if 두 번 + while true* 조합으로 *복잡*. `while (participant.isGenerateCardPossible())`로 *Boolean 결과를 while 조건에*.
|
|
183
|
+
|
|
184
|
+
### 13. `Cards.MAX_SUM_NUMBER = 21` — *Result enum이 외부 Cards 상수 참조*
|
|
185
|
+
|
|
186
|
+
```kotlin
|
|
187
|
+
enum class Result {
|
|
188
|
+
companion object {
|
|
189
|
+
fun valueOf(dealerSum: Int, participantSum: Int): Result {
|
|
190
|
+
when {
|
|
191
|
+
(dealerSum > Cards.MAX_SUM_NUMBER) ... -> return DRAW
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
`Result.valueOf` → `Cards.MAX_SUM_NUMBER` 의존. *Result가 Cards의 상수* 참조 = *역방향 의존*. PR #29의 `Cards`가 `BlackJack.blackjackScore()` 참조와 같은 결.
|
|
199
|
+
|
|
200
|
+
### 14. `Dealer.results: MutableMap<Result, Int>` public + Controller가 변경
|
|
201
|
+
|
|
202
|
+
```kotlin
|
|
203
|
+
class Dealer(...) : Player(...) {
|
|
204
|
+
val results: MutableMap<Result, Int> = Result.values().associateWith { 0 }.toMutableMap()
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Controller에서
|
|
208
|
+
dealer.decideParticipantsResult(participants)
|
|
209
|
+
dealer.decideDealerResult(participants)
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
*공개 mutable Map*. *invariant 무방비*. PR #125 (jerry8282) `Participants.cards/status` 와 같은 결.
|
|
213
|
+
|
|
214
|
+
### 15. `Participants(values: List<Participant>)` — values 명명 모호
|
|
215
|
+
|
|
216
|
+
```kotlin
|
|
217
|
+
class Participants(val values: List<Participant>)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
리뷰어: "*참가자들을 생성하기 위한 values가 무엇인지 사용하는 측에서 알기 어렵지 않을까요?*"
|
|
221
|
+
|
|
222
|
+
학생 변호: "*참가자 리스트라는 것을 직관적으로 나타낼 수 있는 participants라는 변수명을 사용*하려고 하였으나 외부에서 사용시 ``Participants.participants``로 사용하게 되어 *가독성이 좋지 않다고 판단*하였습니다. 따라서 *`mapOf<Int, String>().valu...`*" (cut) — *클래스 == 속성 동어반복* 회피 의도는 좋으나 `values`는 *Map.values* 연상. `items` 또는 *공개 자체를 안 함*(메서드로 노출).
|
|
223
|
+
|
|
224
|
+
### 16. `Cards.getFirstCard()` 류 누락 + Dealer 1장 vs Player 2장 공개 비대칭 (다른 PR 패턴 — 이 PR엔 명시 안 됨)
|
|
225
|
+
|
|
226
|
+
생략.
|
|
227
|
+
|
|
228
|
+
### 17. `Deck.??` 무슨 동작 함수인지 불명
|
|
229
|
+
|
|
230
|
+
리뷰어: "*무슨 동작을 하는 함수인지 이해가 잘 되지 않아요. 덱이 가지고 있는 카드들을 생성자 혹은 정적 팩토리 메소드로 만들어 볼 수 있지는 않을까요?*"
|
|
231
|
+
|
|
232
|
+
→ Deck의 메서드명이 *동작 모호*. *카드 미리 보유 + 생성자/팩토리*가 자연.
|
|
233
|
+
|
|
234
|
+
### 18. `DealerTest` 함수명 — *상태 질의*
|
|
235
|
+
|
|
236
|
+
```kotlin
|
|
237
|
+
@Test fun `카드를 더 받아야 하는 상태인지 확인한다`() { ... }
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
리뷰어: "*카드를 더 받아야 하는 상태가 무엇일까요?* *테스트 코드는 프로그램의 사양서*라고 부르기도 합니다. 즉 *테스트 코드만 봐도 어떻게 동작하는지 예측이 될 수 있도록 구체적으로 작성*하는 것이 중요합니다. 위 테스트로 예를 들어 보면, 아래처럼 작성이 가능합니다. *"카드의 합계가 16점보다 높다면 더 뽑을 수 없다"* / *"카드의 합계가 16점보다 낮다면 더 뽑을 수 있다"*" — *상태 라벨* 대신 *시나리오 + 결과*.
|
|
241
|
+
|
|
242
|
+
### 19. `DeckTest`가 *모든 요구사항을 한 테스트에*
|
|
243
|
+
|
|
244
|
+
```kotlin
|
|
245
|
+
@Test fun `덱은 52장 카드를 가지며 무작위로 1장씩 카드를 뽑을 수 있다`() {
|
|
246
|
+
// 52장 검증 + 셔플 검증 + 1장 뽑기 검증
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
리뷰어: "*한번에 모든 요구사항을 가지는 테스트를 하려고 하지 않아도* 됩니다. *덱이 가지는 특징을 테스트 할 수 있는 정도로 환경을 준비하는 것으로 충분*합니다. ```kotlin fun `카드 덱에 'A 하트' '3 스페이드'가 있을 때, 1장을 뽑으면 ...````" — *한 시나리오 한 테스트*. *모든 요구사항 검증* 의도는 *통합 테스트*에 가까움 + *실패 원인 추적 어려움*.
|
|
251
|
+
|
|
252
|
+
## 리뷰어 의견 요지
|
|
253
|
+
|
|
254
|
+
- ***enum의 UI 문자열 보유는 6개 PR 연속 안티패턴***.
|
|
255
|
+
- ***블랙잭 = ACE+JQK 2장* 특별 처리보다 *합산 + 보너스 10*** 단일 룰.
|
|
256
|
+
- ***open class < abstract Participant + canDraw()*** — PR #29와 같은 결.
|
|
257
|
+
- ***Player.generateCard() = 카드 출처 책임이 Player*** — `draw(deck: Deck)` 권고. 학생 자가 반영.
|
|
258
|
+
- ***String += < buildString***.
|
|
259
|
+
- ***Generator/CardGenerator/RandomGenerator 명사 중복 = 도메인 어휘 흐려짐*** — *Deck 52장 한정* 모델.
|
|
260
|
+
- ***match는 참가자 메시지 (Tell-Don't-Ask)*** — 세 번의 리뷰로 1대1, 1대다 확장 제시.
|
|
261
|
+
- ***Cards 외부 참조 = 방어적 복사 필요*** (학생 자가 반영).
|
|
262
|
+
- ***Controller가 직접 호출 < Participants 메시지***.
|
|
263
|
+
- ***Dealer.results MutableMap public = invariant 무방비***.
|
|
264
|
+
- ***Participants.values 명명 모호***.
|
|
265
|
+
- ***Deck 메서드 동작 모호***.
|
|
266
|
+
- ***DealerTest 함수명 = 상태 라벨 < 시나리오 + 결과***.
|
|
267
|
+
- ***DeckTest 한 테스트에 모든 요구사항 X*** — 한 시나리오 한 테스트.
|
|
268
|
+
|
|
269
|
+
## 대표 인용
|
|
270
|
+
|
|
271
|
+
> word는 *UI의 관심사*이지 않을까요? / "승", "패", "무"는 *UI의 관심사로 보입니다*.
|
|
272
|
+
> — @laco-dev on `CardShape.kt` / `Result.kt`
|
|
273
|
+
|
|
274
|
+
> 카드를 뽑는다 라는 개념은 addCard(card)를 이용해서 전달되는것에 반해 *카드를 생성한다라는 개념은 플레이어에게 어떤 의미를 가지는 것일까요?* 카드 뭉치(Deck)에서 *카드를 한장 뽑는다 라는 기능*을 구현할 수도 있지 않을까요?
|
|
275
|
+
> — @laco-dev on `Player.kt`
|
|
276
|
+
|
|
277
|
+
> 제너레이터, 카드 제너레이터, 랜덤 제너레이터 등 *여러가지 비슷한 개념이 뒤섞여 있는 느낌*이 듭니다. [...] *카드 뭉치에는 최대 52개의 카드가 존재할 수 있습니다.* 끗수(13개) * 모양(4개) = 52
|
|
278
|
+
> — @laco-dev on `CardGenerator.kt`
|
|
279
|
+
|
|
280
|
+
> 한사람이 여러 사람과 승부를 벌이는 입장에서도 마찬가지로 참가자의 역할로 만들어 볼 수 있겠습니다. `abstract class Player { fun match(others: List<Player>): GameResult }`
|
|
281
|
+
> — @laco-dev on `Score.kt`
|
|
282
|
+
|
|
283
|
+
> 한번에 모든 요구사항을 가지는 테스트를 하려고 하지 않아도 됩니다. *덱이 가지는 특징을 테스트 할 수 있는 정도로 환경을 준비*하는 것으로 충분합니다.
|
|
284
|
+
> — @laco-dev on `DeckTest.kt`
|
|
285
|
+
|
|
286
|
+
## 얻은 교훈
|
|
287
|
+
|
|
288
|
+
- ***enum의 UI 문자열(`word`, `koreanText` 등)은 7개+ PR 연속 안티패턴 = MCP 룰 후보로 매우 강력*** — *변경 비용이 도메인-뷰 경계 붕괴*.
|
|
289
|
+
- ***블랙잭 = ACE+JQK 2장* 같은 *특별 케이스 분기*보다 *합산 + 보너스 10* 단일 룰*** — *룰을 자료구조에 위임*하면 분기 폭증 회피.
|
|
290
|
+
- ***open class 상속 < abstract Participant + canDraw()*** — PR #29와 같은 결. *현실 비유 자율성*보다 *Liskov 호환*.
|
|
291
|
+
- ***Player가 generator를 보유 = 카드 출처 책임이 Player*** — *덱에서 뽑기*가 자연. 학생 자가 반영.
|
|
292
|
+
- ***Player.name의 invariant = 도메인 객체 분리 vs 검증 제거 트레이드오프*** — 학생이 *YAGNI 선택*도 합리적. 다만 *invariant 손실*은 *기록*해두기.
|
|
293
|
+
- ***String += < buildString/joinToString*** — Kotlin 컨벤션.
|
|
294
|
+
- ***`Generator + CardGenerator + RandomGenerator` 명사 중복 = 추상화 폭증*** — *테스터빌리티 위해 인터페이스* 시도가 *도메인 어휘 흐림*. *Deck 52장 한정 자료구조* 모델이 더 자연.
|
|
295
|
+
- ***match는 참가자 메시지 (1대1 → 1대다 확장 가능)*** — `GameResult(participant, winCount, loseCount, drawCount)` 형태로 *참가자 단위 집계*.
|
|
296
|
+
- ***`Cards(_cards: MutableList<Card>)` 외부 참조 = 방어적 복사 필요*** — `_cards.toMutableList()` 또는 `cards.toList()`.
|
|
297
|
+
- ***Controller가 직접 호출 < Participants 메시지*** — `participants.drawInitial(deck)` 한 줄.
|
|
298
|
+
- ***`MutableMap<Result, Int>` public = invariant 무방비*** — *count by result*는 *외부에서 변경 불가*하게.
|
|
299
|
+
- ***`Participants.values` 명명 모호 = Map.values 연상*** — `items` 또는 *공개 자체 안 함*(메서드만).
|
|
300
|
+
- ***Deck 메서드명이 동작 모호 = 카드 미리 보유 + 생성자/팩토리가 자연***.
|
|
301
|
+
- ***DealerTest 함수명 = "상태 라벨"보다 "시나리오 + 결과"*** — *테스트 = 사양서*.
|
|
302
|
+
- ***DeckTest 한 테스트에 모든 요구사항 X*** — *덱이 가지는 특징을 테스트할 수 있는 정도 환경 준비*. 통합 테스트 ≠ 단위 테스트.
|