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,289 @@
|
|
|
1
|
+
# PR #34 — [블랙잭 2단계] 아크 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@re4rk](https://github.com/re4rk)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-blackjack/pull/34
|
|
5
|
+
- **단계:** 2단계 (베팅 + 수익률 + State 패턴 도입)
|
|
6
|
+
- **리뷰어:** @woowajames (제임스)
|
|
7
|
+
- **라인 코멘트:** 30 (리뷰어 24 / 리뷰이 6)
|
|
8
|
+
- **참고:** 같은 학생의 1단계 = PR #8
|
|
9
|
+
|
|
10
|
+
## 잘한 점 (설계 관점)
|
|
11
|
+
|
|
12
|
+
- **State 패턴 도입 — `State` sealed + `inTurn/Hit`, `endTurn/Bust`/`Stay`/`BlackJack`** — 상태 전이를 *타입*으로 표현. PR #78 패턴.
|
|
13
|
+
- **`Money @JvmInline value class` 원시값 포장** + 범위 invariant.
|
|
14
|
+
- **`Outcome` enum + `rate: Double`** — *WIN_WITH_BLACKJACK(0.5)* / *WIN(1.0)* / *LOSE(-1.0)* 수익률 직접 보유.
|
|
15
|
+
- **`blackJack { ... }` DSL** — `cardDeck`, `participants` 빌더로 게임 구성.
|
|
16
|
+
- **`BlackJackResult(participants)` 결과 객체 분리** + `BlackJackResultUser(name, rateOfReturn)` 사용자 단위 결과.
|
|
17
|
+
- **테스트 함수에 fixture (`CLOVER_KING`, `CLOVER_NINE` 등) 도입** — 테스트 가독성.
|
|
18
|
+
- **후속 반영 — score를 *상태 분리* + Score 클래스 단일화 + Outcome.rate 적용 + CardViewUtil → toString 토론 결정**.
|
|
19
|
+
|
|
20
|
+
## 못한 점 (설계 관점)
|
|
21
|
+
|
|
22
|
+
### 1. `BlackJackGame.getCommand: lateinit var` — 함수 참조 미주입 시 런타임 에러
|
|
23
|
+
|
|
24
|
+
```kotlin
|
|
25
|
+
class BlackJackGame {
|
|
26
|
+
lateinit var getCommand: (String) -> Boolean
|
|
27
|
+
// setUp에서 미주입 시 isInitialized false → 런타임 NPE
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
리뷰어: "*해당 함수를 넘겨주지 않아도 컴파일 에러는 없지만 런타임 에러가 발생하게 됩니다. 이 경우를 대비할 수 있는 방법을 고민*해보면 어떨까요?" — *lateinit var callback*. *생성자 인자*가 자연 (`BlackJackGame(getCommand: (String) -> Boolean)`). PR #92·#29·#114·#33과 같은 결.
|
|
32
|
+
|
|
33
|
+
또: "*해당 라인이 누락되는 경우 런타임 에러는 해결된 듯 보이지만 논리적 에러가 발생합니다. 당장의 문제를 해결하는 것도 좋지만 회귀 테스트 관점으로 충분히 고민*해보시는 것도 좋겠네요." — *방어 코드*가 *런타임 통과*하면 *논리 오류 은폐*.
|
|
34
|
+
|
|
35
|
+
### 2. `User.score()`, `isBlackJack()`, `isBust()`, `draw()` 모두 함수 — *상태와 행동 혼동*
|
|
36
|
+
|
|
37
|
+
```kotlin
|
|
38
|
+
abstract class User(name: String) {
|
|
39
|
+
fun score(): Int = cards.result.score() // 계산
|
|
40
|
+
fun isBlackJack(): Boolean = score() == BLACKJACK_NUMBER // 질의
|
|
41
|
+
fun isBust(): Boolean = score() > BLACKJACK_NUMBER // 질의
|
|
42
|
+
fun draw(card: Card) { cards += card } // 변경
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
리뷰어: "*score(), isBlackJack(), isBust(), draw() 모두 함수로 만드셨네요. 어떤 기준으로 만드신걸까요?* *행동은 상태를 변경시킵니다.* *상태와 행동을 구분하면 좋겠습니다.*" — **Kotlin val/fun 컨벤션**: *상태(질의)*는 `val` + custom getter / `data class` 프로퍼티, *행동(변경)*은 `fun`. *score*는 *카드의 합 = 파생 상태* → `val score: Int`, *draw*는 *상태 변경* → `fun`. PR #135·#10·#33과 같은 결.
|
|
47
|
+
|
|
48
|
+
### 3. `Card.isACE()` 함수명 대문자 — 카멜 케이스 위반
|
|
49
|
+
|
|
50
|
+
```kotlin
|
|
51
|
+
data class Card(val mark: CardMark, val value: CardValue) {
|
|
52
|
+
fun isACE(): Boolean = value == CardValue.ACE
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
리뷰어: "*외부의 요청에 응답하기 위한 함수(=행동)네요. 다만 상태를 변경하는 역할을 하지는 않네요. 그리고 코틀린 코딩 컨벤션에 따른 함수명은 카멜 케이스로 작성하기*입니다." — `isAce()` 카멜 케이스. *상수처럼 보이는 약자도 카멜*. + *질의는 `val`이 더 자연* (위 §2와 같은 맥락).
|
|
57
|
+
|
|
58
|
+
### 4. `Score` 클래스에 *`BLACKJACK_NUMBER` 상수가 여러 곳에서 참조*
|
|
59
|
+
|
|
60
|
+
```kotlin
|
|
61
|
+
class Score(cards: Cards) {
|
|
62
|
+
companion object {
|
|
63
|
+
const val BLACKJACK_NUMBER = 21 // ⚠ 외부 import (Score.Companion)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
리뷰어: "*여러 곳에서 참조하고 있네요. 그렇다는 것은 여러 곳에서 블랙잭인지 확인 하는 작업을 한다는 의미입니다.* *그런 작업을 하는 클래스가 존재하면 해당 상수를 그 클래스에서만 사용하는 것으로 변경 할 수 있습니다.*" — **상수의 *외부 노출*은 *기능이 분산*된 신호**. `isBlackJack()` / `isBust()` 같은 *Score 내부 질의*만 노출하면 *상수 비공개*가능. PR #128·#92와 같은 결.
|
|
69
|
+
|
|
70
|
+
### 5. `Money.toInt()` — 외부 노출 함수
|
|
71
|
+
|
|
72
|
+
```kotlin
|
|
73
|
+
@JvmInline
|
|
74
|
+
value class Money(private val money: Int) {
|
|
75
|
+
fun toInt(): Int = money
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
리뷰어: "*val 타입으로 외부에 노출해도 문제가 없을 것 같아요. 그러면 toInt() 함수도 제거할 수 있을 것 같은데 특별히 이렇게 한 이유가 있을까요?*" — `value class Money(val value: Int)`로 *프로퍼티 노출*이 자연. `toInt()` 같은 *Java 어휘 변환자*는 불필요. 학생 후속: `val value: Int` 채택.
|
|
80
|
+
|
|
81
|
+
### 6. `Money` 범위 검증 — 예외 vs 재입력
|
|
82
|
+
|
|
83
|
+
```kotlin
|
|
84
|
+
@JvmInline
|
|
85
|
+
value class Money(val value: Int) {
|
|
86
|
+
init { require(value in MIN_MONEY..MAX_MONEY) { ERROR_MONEY_RANGE } }
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
리뷰어: "*범위를 벗어난 값을 입력했을 때 다시 입력 받을 수 있도록 처리해보면 어떨까요?*" — *invariant 검증 = require → throw*. *재입력 루프*는 *Controller* 책임. *도메인 invariant 보호*와 *UI 재입력*은 다른 레이어. PR #146 (lotto)와 같은 결.
|
|
91
|
+
|
|
92
|
+
### 7. `CardViewUtil` 유틸 클래스 — 토론 후 학생 유지 결정
|
|
93
|
+
|
|
94
|
+
```kotlin
|
|
95
|
+
// blackjack/view/CardViewUtil.kt
|
|
96
|
+
fun Card.toText(): String = "${value.pattern()}${mark.name()}"
|
|
97
|
+
private fun CardMark.name(): String = when (this) { ... }
|
|
98
|
+
private fun CardValue.pattern(): String = when (this) { ... }
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
리뷰어: "*Util형 클래스를 두면 해당 클래스에 결합도가 높아지게 됩니다. CardMark, CardValue 각 클래스에 toString()을 오버라이딩 해보면 어떨까요?*"
|
|
102
|
+
|
|
103
|
+
학생 자가 토론: "*해당 기능은 리뷰어님들께서도 많이 의견이 갈리시는 방향이라 고민을 많이 해보았습니다.* *View의 영역에 있어야 한다는 리뷰어님들께서는 toString()를 오버라이딩을 한다면 domain에서 맡을 역할이 아니라고 조언*해주셨습니다. 다음으로 *domain의 영역에 있어야 하신 리뷰어님들 께서는 제임스와 같이 결합도가 높아진다고 조언*을 주셨습니다. 그래서 저의 선택은 앞에서 리뷰해주신 *when문을 exhaustive하게 작성*하시라고 하셔서 *이를 적용한다면 해당 구조가 괜찮지 않을까 생각*합니다."
|
|
104
|
+
|
|
105
|
+
리뷰어: "*정답이 없는 문제이기 때문에 사람마다 다르게 생각할 수 있다고 봐요.* 모든 리뷰에 대해 *수정할 필요도 없고 아크 생각에 이게 낫다고 판단되면 그대로 두셔도 됩니다!* *지금처럼 아크만의 생각을 정립하는 게 이러한 리뷰 시간에서 얻어가는 것*이라고 생각합니다."
|
|
106
|
+
|
|
107
|
+
→ **트레이드오프 명확히 인식 + 학생 결정 존중**. *toString = 도메인 + 결합도*, *유틸 = View + 결합도*. 학생의 *exhaustive when*은 *추가 변경 발견 가능*하지만 *수정 회피 수단은 아님* (리뷰어 추가 코멘트).
|
|
108
|
+
|
|
109
|
+
### 8. CardMark/CardValue *when 표현 + 한국어 UI*
|
|
110
|
+
|
|
111
|
+
```kotlin
|
|
112
|
+
private fun CardMark.name(): String = when (this) {
|
|
113
|
+
CardMark.CLOVER -> "클로버"
|
|
114
|
+
CardMark.DIA -> "다이아몬드"
|
|
115
|
+
CardMark.HEART -> "하트"
|
|
116
|
+
CardMark.SPADE -> "스페이드"
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
리뷰어: "*when 문은 exhaustive 한 것이 좋습니다.* 만약 *새로운 값이 추가 되었을 때 이 부분에 추가하는 것을 놓치면 논리적 오류가 발생할 가능성이 높겠죠?*" — **else 분기 없이 모든 case 명시 = exhaustive**. 새 enum 값 추가 시 *컴파일 에러*가 *추가 누락 방지*. PR #34만의 특이점.
|
|
121
|
+
|
|
122
|
+
### 9. `CardDeck.size: Int` — 함수명이 *변수명 형태*
|
|
123
|
+
|
|
124
|
+
```kotlin
|
|
125
|
+
class CardDeck(cards: List<Card>) {
|
|
126
|
+
val size: Int // 좋음 (속성)
|
|
127
|
+
fun nextCard(): Card // 좋음 (동작)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// 별도 함수: 함수명이 변수명 형태 (지목된 위치 모름)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
리뷰어: "*함수명이 변수명의 형태 같아요. 좀 더 어울리는 네이밍이 없을까요?*" — `size`/`nextCard` 같은 *상태 vs 동작* 명명 차이.
|
|
134
|
+
|
|
135
|
+
### 10. `Guest.isContinue` — *영문 형용사 vs 명사 동사 혼동*
|
|
136
|
+
|
|
137
|
+
```kotlin
|
|
138
|
+
abstract class User(name: String) {
|
|
139
|
+
abstract val isContinue: Boolean
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
리뷰어: "*isContinuable 이란 변수명이면 더 자연스러울 것 같아요.*" — `isContinue`는 *동사 continue를 형용사처럼*. `isContinuable` 형용사 형태. *영문법 정확성*. 학생 후속 반영.
|
|
144
|
+
|
|
145
|
+
### 11. `Participants.all()` — 함수 vs 프로퍼티
|
|
146
|
+
|
|
147
|
+
리뷰어: "*이건 상태일까요 행동일까요?* 🤔" — *all*은 *컬렉션 노출 = 상태*. `val all: List<User>` (custom getter). 학생 후속: `all`로 변경.
|
|
148
|
+
|
|
149
|
+
### 12. `Outcome enum`에 *블랙잭 승*이 enum 값으로
|
|
150
|
+
|
|
151
|
+
```kotlin
|
|
152
|
+
enum class Outcome(val rate: Double) {
|
|
153
|
+
WIN_WITH_BLACKJACK(0.5),
|
|
154
|
+
WIN(1.0),
|
|
155
|
+
DRAW(0.0),
|
|
156
|
+
LOSE(-1.0),
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
리뷰어: "*정리하면 좀 더 보기 좋을 것 같아요.*" — *Outcome*에 *블랙잭으로 승*까지 enum 값. *결과 + 수익률* 결합. *결과 = 승/무/패* 만 두고 *블랙잭 보너스*는 *별도 계산*이 분리. (학생 후속에 `rate` 속성 추가.)
|
|
161
|
+
|
|
162
|
+
### 13. `Stay.matchWith(otherState)`에서 *Hit 케이스 누락*
|
|
163
|
+
|
|
164
|
+
```kotlin
|
|
165
|
+
class Stay(cards: Cards) : EndTurn(cards) {
|
|
166
|
+
override fun matchWith(otherState: State): Outcome {
|
|
167
|
+
return when (otherState) {
|
|
168
|
+
is Bust -> WIN
|
|
169
|
+
is BlackJack -> compareBlackJack()
|
|
170
|
+
is Stay -> compareScore(otherState.score)
|
|
171
|
+
else -> throw IllegalStateException(ERROR_INVALID_STATE) // ⚠ Hit 케이스
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
리뷰어: "*현재 구조에서 Hit에서도 Stay의 matchWith()를 타고 들어오는데요.* 이 경우엔 *무조건 else 문으로 처리되어 프로그램이 정상적인 동작을 할 수 없습니다*. 간단하게는 *Stay와 동일하게 Hit를 처리*하면 되겠네요. 혹은 *Hit에서 Stay로 가는 로직을 추가*하면 되구요." — **State 패턴의 *상태 전이 빠짐*** = *런타임 에러*. *Hit → 종료 전이*가 누락. 학생 자가 인정. 후속 반영.
|
|
178
|
+
|
|
179
|
+
### 14. `HitTest`에서 *Hit → BlackJack 누락*
|
|
180
|
+
|
|
181
|
+
리뷰어: "*히트에서 블랙잭으로 가는 경우입니다.* 예를 들어 *16(히트)에서 스테이로 갈 수 있는 상황에 대한 로직 추가 및 테스트도 필요*할 것 같아요." — *상태 전이 그래프*의 *모든 경로*를 *테스트로 검증*해야 *State 패턴 완전*. 학생 후속: *Hit → Stay* 테스트 추가.
|
|
182
|
+
|
|
183
|
+
### 15. `Cards`가 *Score 관련 기능 보유*
|
|
184
|
+
|
|
185
|
+
```kotlin
|
|
186
|
+
class Cards(private val cards: Set<Card> = setOf()) {
|
|
187
|
+
val result = Score(this)
|
|
188
|
+
val size: Int = cards.size
|
|
189
|
+
val isContainsAce: Boolean
|
|
190
|
+
val hardScore: Score
|
|
191
|
+
val softScore: Score
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
리뷰어: "*이 프로퍼티를 포함하여 스코어 관련 기능은 스코어 클래스로 이동해보면 어떨까요?*" — `Cards`가 *카드 컬렉션 + 점수 계산* 둘. `Score(cards)`가 *점수 단일 책임*. *Cards = 카드 보유*, *Score = 합산 + 보정* 분리. 학생 후속 반영.
|
|
196
|
+
|
|
197
|
+
### 16. `DealerTest`가 *ACE 11 검사도 포함*
|
|
198
|
+
|
|
199
|
+
```kotlin
|
|
200
|
+
@Test fun `ACE를 11로 둘 때 17이상이면 뽑을 수 없다`() {
|
|
201
|
+
val dealer = Dealer()
|
|
202
|
+
dealer.draw(Card(CardMark.CLOVER, CardValue.ACE))
|
|
203
|
+
dealer.draw(Card(CardMark.CLOVER, CardValue.SIX))
|
|
204
|
+
assertThat(dealer.isContinue).isFalse
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
리뷰어: "*17이상일 때에 대한 테스트이기 때문에 물론 지금도 좋지만 ACE가 11인지에 대한 것은 Dealer 테스트가 굳이 알 필요는 없는 것 같아요.*" — *Dealer.isContinue 책임 = 17 이상 안 뽑기*. *ACE 보정 책임 = Cards/Score*. *DealerTest*에 *ACE 룰까지* 검증하면 *복합 책임 테스트*. PR #28·#116과 같은 결.
|
|
209
|
+
|
|
210
|
+
또: 함수명 *오타*: "*점수가 17이상이면 카드를 뽑을 수 없다*가 자연스러운 문장이겠네요" — *카드를* 누락.
|
|
211
|
+
|
|
212
|
+
### 17. `GuestTest` *오타*: `'아지 않고'` / `'아니면'`
|
|
213
|
+
|
|
214
|
+
```kotlin
|
|
215
|
+
@Test fun `버스트가 아지 않고 블랙잭이아니면 카드를 뽑을 수 있다`() { ... }
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
리뷰어: "*사546한 오타가 있습니다.* 😵💫" — *테스트 이름 = 사양서*. 오타가 *사양 신뢰도* ↓.
|
|
219
|
+
|
|
220
|
+
### 18. `OutputView`가 `print()` 여러 번 호출
|
|
221
|
+
|
|
222
|
+
리뷰어: "*[print() 호출]보다는 [StringBuilder]를 사용하면 성능에 도움이 됩니다.* 여기서는 *많은 데이터를 다루지 않아 큰차이가 없겠지만 한 번 개선해보는 것은 어떨까요?* 💪" — *Kotlin: `buildString { ... }` 또는 `joinToString`*. PR #24와 같은 결.
|
|
223
|
+
|
|
224
|
+
### 19. `outputResult` "최종 승패" 오타 (2단계는 "최종 수익")
|
|
225
|
+
|
|
226
|
+
리뷰어: "*사소한 오타 : '최종 승패'가 아닌 '최종 수익'입니다.*" — 1단계 표현이 2단계로 *그대로 남음*. *요구사항 차이*가 *코드 반영 누락*. PR #146 (lotto) *기존 요구사항 누락*과 같은 결.
|
|
227
|
+
|
|
228
|
+
### 20. `Cards.containsACE()` 함수 (UI 표시) vs `isContainsACE` 프로퍼티
|
|
229
|
+
|
|
230
|
+
```kotlin
|
|
231
|
+
class Cards { fun containsACE(): Boolean = ... }
|
|
232
|
+
// 후속
|
|
233
|
+
class Cards { val isContainsAce: Boolean = ... }
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
리뷰어: "*if else 구문은 한 줄 작성보다는 괄호를 추가해주는 게 좋을거 같아요.*" — 가독성 권고. 또 함수명 카멜 케이스 (`containsACE → isContainsAce`).
|
|
237
|
+
|
|
238
|
+
## 리뷰어 의견 요지
|
|
239
|
+
|
|
240
|
+
- ***`lateinit var` callback = 런타임 에러 위험*** — 생성자 주입.
|
|
241
|
+
- ***`val 상태 / fun 행동` 명확히 구분*** — score는 val.
|
|
242
|
+
- ***함수명 카멜 케이스*** (`isACE → isAce`).
|
|
243
|
+
- ***상수 외부 노출 = 기능 분산 신호*** — 단일 클래스 내부로.
|
|
244
|
+
- ***`Money.toInt()`보다 `val value: Int` 직접 노출***.
|
|
245
|
+
- ***require 검증 + Controller 재입력 = 레이어 분리***.
|
|
246
|
+
- ***Util 클래스 vs toString = 트레이드오프, 학생 결정 존중***.
|
|
247
|
+
- ***exhaustive when = 새 case 추가 누락 방지***.
|
|
248
|
+
- ***`size: val` / `nextCard: fun` 명명 차이 = 상태 vs 동작***.
|
|
249
|
+
- ***`isContinue` 영문 형용사 → `isContinuable`***.
|
|
250
|
+
- ***Outcome에 rate 결합 = 결과 + 수익률 결합***.
|
|
251
|
+
- ***State.matchWith의 상태 전이 누락 = 런타임 에러*** — 모든 전이 테스트.
|
|
252
|
+
- ***Cards → Score 책임 분리***.
|
|
253
|
+
- ***`DealerTest`에 ACE 룰 검증 = 복합 책임 테스트***.
|
|
254
|
+
- ***테스트 이름 오타 = 사양 신뢰도 ↓***.
|
|
255
|
+
- ***`print` 여러 번 < `buildString`***.
|
|
256
|
+
- ***1단계 표현 잔존 = 요구사항 변화 반영 누락***.
|
|
257
|
+
|
|
258
|
+
## 대표 인용
|
|
259
|
+
|
|
260
|
+
> *해당 함수를 넘겨주지 않아도 컴파일 에러는 없지만 런타임 에러가 발생*하게 됩니다. 이 경우를 대비할 수 있는 방법을 고민해보면 어떨까요?
|
|
261
|
+
> — @woowajames on `BlackJackGame.kt`
|
|
262
|
+
|
|
263
|
+
> score(), isBlackJack(), isBust(), draw() 모두 함수로 만드셨네요. *어떤 기준으로 만드신걸까요?* *행동은 상태를 변경시킵니다.* *상태와 행동을 구분*하면 좋겠습니다.
|
|
264
|
+
> — @woowajames on `User.kt`
|
|
265
|
+
|
|
266
|
+
> 정답이 없는 문제이기 때문에 *사람마다 다르게 생각할 수 있다고 봐요.* 모든 리뷰에 대해 *수정할 필요도 없고 아크 생각에 이게 낫다고 판단되면 그대로 두셔도 됩니다!* 지금처럼 *아크만의 생각을 정립하는 게 이러한 리뷰 시간에서 얻어가는 것*이라고 생각합니다.
|
|
267
|
+
> — @woowajames on `CardViewUtil.kt`
|
|
268
|
+
|
|
269
|
+
> 현재 구조에서 *Hit에서도 Stay의 matchWith()를 타고 들어오는데요*. 이 경우엔 *무조건 else 문으로 처리되어 프로그램이 정상적인 동작을 할 수 없습니다*.
|
|
270
|
+
> — @woowajames on `Stay.kt`
|
|
271
|
+
|
|
272
|
+
## 얻은 교훈
|
|
273
|
+
|
|
274
|
+
- ***`lateinit var callback` = 런타임 에러 잠재*** — 생성자 인자 주입이 자연. PR #92·#29·#114·#33과 같은 결.
|
|
275
|
+
- ***`val 상태 / fun 행동` Kotlin 컨벤션*** — score는 *카드 합 = 파생 상태* → `val score: Int`. *draw는 변경 → fun*. PR #135·#10·#33과 같은 결.
|
|
276
|
+
- ***함수명 카멜 케이스 (`isACE → isAce`)***.
|
|
277
|
+
- ***상수 외부 노출 = 기능 분산 신호*** — *단일 클래스 내부 사용*이 자연.
|
|
278
|
+
- ***`value class`에 `val 노출`이 자연*** — `toInt()` 같은 Java 어휘 변환자 불필요.
|
|
279
|
+
- ***require 도메인 invariant + Controller 재입력 = 레이어 분리*** — 도메인은 *예외 throw만*, 재입력 루프는 *Controller*.
|
|
280
|
+
- ***Util 클래스 vs toString 오버라이딩 = 정답 없는 트레이드오프*** — *유틸 결합도 vs 도메인 결합도*. 학생 *판단 정립이 학습 목적*.
|
|
281
|
+
- ***exhaustive when = 새 enum 값 추가 시 컴파일 에러 = 누락 방지*** — *else 분기*는 *방어*지만 *추가 알림 기능*은 없음.
|
|
282
|
+
- ***`size: val` / `nextCard: fun` 명명 차이 = 상태 vs 동작 시그널***.
|
|
283
|
+
- ***`isContinue` 영문 형용사 부재*** — `isContinuable`이 자연.
|
|
284
|
+
- ***Outcome enum에 rate 결합 = 결과 + 수익률 의미 혼합*** — *결과만 enum, 수익률은 별도 계산*도 옵션.
|
|
285
|
+
- ***State.matchWith의 상태 전이 누락 = 런타임 에러*** — *모든 상태 전이 그래프*를 *테스트로 검증*. State 패턴 도입 시 *전이 누락이 가장 흔한 버그*.
|
|
286
|
+
- ***Cards → Score 책임 분리*** — *Cards = 카드 보유*, *Score = 합산 + 보정*. PR #92와 같은 결.
|
|
287
|
+
- ***`DealerTest`에 ACE 룰 검증 = 복합 책임*** — *대상 클래스의 책임만* 테스트.
|
|
288
|
+
- ***테스트 이름 오타 = 사양 신뢰도 ↓*** — *테스트 = 사양서* 원칙.
|
|
289
|
+
- ***1단계 표현 (`최종 승패`)이 2단계 (`최종 수익`)에 잔존 = 요구사항 변화 반영 누락*** — *체크리스트 또는 grep 도구*로 변경 누락 점검.
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# PR #8 — [블랙잭 1단계] 아크 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@re4rk](https://github.com/re4rk)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-blackjack/pull/8
|
|
5
|
+
- **단계:** 1단계 (DSL Builder 시도)
|
|
6
|
+
- **리뷰어:** @woowajames (제임스)
|
|
7
|
+
- **라인 코멘트:** 30 (리뷰어 22 / 리뷰이 8)
|
|
8
|
+
- **참고:** 같은 학생의 2단계 = [PR #34](./34-2단계-블랙잭.md)
|
|
9
|
+
|
|
10
|
+
## 잘한 점 (설계 관점)
|
|
11
|
+
|
|
12
|
+
- **`BlackJackBuilder + cardDeck + participants` DSL** + `BlackJack data class` 구성.
|
|
13
|
+
- **`abstract User` + `Dealer`/`Guest`** + `isContinue` 추상.
|
|
14
|
+
- **`Score(cards: Cards)` 점수 계산 객체** + `minScore`/`maxScore` (Ace 보정).
|
|
15
|
+
- **`Cards` 일급 컬렉션 + `operator fun plus` immutable 패턴**.
|
|
16
|
+
- **`Name` value class 원시값 포장**.
|
|
17
|
+
- **DSL 학습 적용 — `study/PersonBuilder` + `SkillsBuilder` + `LanguagesBuilder`**.
|
|
18
|
+
- **후속 반영 — `CardValueTest` ParameterizedTest + CsvSource 적용**.
|
|
19
|
+
|
|
20
|
+
## 못한 점 (설계 관점)
|
|
21
|
+
|
|
22
|
+
### 1. `study/Test.kt` 학생 코드에 페어 닉네임 (`로피`) — 본인 닉네임 (`아크`) 미사용
|
|
23
|
+
|
|
24
|
+
리뷰어: "*정말 사소한 것이지만 페어가 아닌 본인 닉네임을 사용하면 좋았을 것 같아요.*" — *페어 코드를 그대로 가져옴* 신호. *학생 자신의 흔적*이 *학습 과정 가시화*.
|
|
25
|
+
|
|
26
|
+
### 2. `LanguagesBuilder` *Korean/English 하드코딩*
|
|
27
|
+
|
|
28
|
+
```kotlin
|
|
29
|
+
class LanguagesBuilder {
|
|
30
|
+
var korean = 0; var english = 0
|
|
31
|
+
infix fun String.level(grade: Int) {
|
|
32
|
+
when (this) {
|
|
33
|
+
"Korean" -> korean = grade
|
|
34
|
+
"English" -> english = grade
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
data class Languages(val korean: Int, val english: Int)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
리뷰어: "*Korean, English 외 언어에 관한 입력은 처리가 불가능한 형태입니다. Skills를 참고하여 변경*해보면 좋겠네요." — **확장성 부재**. *Skills처럼 `Map<String, Int>`* 또는 *List<Language>*로. *enum 또는 값 객체*로 *언어 추가 가능*.
|
|
42
|
+
|
|
43
|
+
### 3. `Test`가 *오류 케이스 검증 X*
|
|
44
|
+
|
|
45
|
+
리뷰어: "*hard 스킬에 kotlin을 넣으려고 의도했지만 오류로 결과적으로 java라는 값이 들어갈 수도 있다면 이 테스트 코드가 그걸 검증해 줄 수 있나요?* *개인적으로는 심리적 안정감에 도움이 되지 않는 테스트 코드라고 생각합니다.*" — **테스트가 *의도와 다른 동작*을 못 잡으면 *안전감 X***. *정상 입력*만 검증하면 *오류 경로*는 무방비. *입력 검증 + 의도 위반 케이스*가 *진짜 테스트*.
|
|
46
|
+
|
|
47
|
+
### 4. `BlackJackBuilder` + `lateinit` + DSL — 학생의 *DSL 적용 욕구*
|
|
48
|
+
|
|
49
|
+
```kotlin
|
|
50
|
+
private fun setBlackJack(): BlackJack = BlackJackBuilder.init {
|
|
51
|
+
cardDeck(Card.all().shuffled())
|
|
52
|
+
participants {
|
|
53
|
+
dealer("딜러")
|
|
54
|
+
guests(inputView.inputParticipants())
|
|
55
|
+
}
|
|
56
|
+
draw()
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
→ **PR #29 (tmdgh1592) Builder + DSL과 같은 패턴**. *수업에서 배운 기능 적용 욕구*가 *과잉 적용*을 만드는 점. (다만 PR #34에서는 학생이 *DSL을 유지*하고 *Builder 자체*는 *수업 학습 결과로 인정*받음.)
|
|
61
|
+
|
|
62
|
+
### 5. `BlackJackGame`의 *멤버 확장 함수 + `lateinit var input`*
|
|
63
|
+
|
|
64
|
+
```kotlin
|
|
65
|
+
class BlackJackGame {
|
|
66
|
+
private lateinit var input: (String) -> String
|
|
67
|
+
fun input(func: (String) -> String) { input = func }
|
|
68
|
+
|
|
69
|
+
fun BlackJack.guestsTurn(output: (User) -> Unit) =
|
|
70
|
+
guests.forEach { guest -> guestTurn(guest, output) }
|
|
71
|
+
|
|
72
|
+
fun BlackJack.dealerTurn(output: () -> Unit) { ... }
|
|
73
|
+
private fun BlackJack.guestTurn(guest: Guest, output: (User) -> Unit) { ... }
|
|
74
|
+
private fun Guest.getCommand() = input(this.name.toString())
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
리뷰어: "*멤버 확장 함수의 사용은 지양하는 것이 좋습니다. 현재 꼭 필요한지 모르겠고 개인적으로는 코드의 가독성이 매우 떨어진다고 생각*됩니다." — **`class BlackJackGame { fun BlackJack.foo() }` 멤버 확장 함수**는 *BlackJack의 메서드인 듯 보이지만 실제로는 BlackJackGame 안에서만 호출 가능*. *수신자 + 컨텍스트* 두 가지가 호출 사이트에서 *모호*. Kotlin 권고: *최상위 확장 함수* 또는 *일반 메서드*.
|
|
79
|
+
|
|
80
|
+
또: `lateinit var input` + `fun input(func)` setter 패턴 = PR #34와 동일 안티패턴.
|
|
81
|
+
|
|
82
|
+
### 6. `BlackJack`이 *3개 이상의 인스턴스 변수* — 요구사항 위반
|
|
83
|
+
|
|
84
|
+
```kotlin
|
|
85
|
+
data class BlackJack(val cardDeck: CardDeck, val participants: Participants, ...)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
리뷰어: "*3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다.* 위 요구 사항을 지켜보면 어떨까요?" — **요구사항 (3변수 제한)** PR #92·#135와 같은 결. 학생이 *3변수 위반*. *형식 규칙은 강제*. 단 *PR #92·#135처럼 인공 객체 만들지 않게*도 주의.
|
|
89
|
+
|
|
90
|
+
### 7. `Score`도 *3개 이상의 인스턴스 변수* 위반
|
|
91
|
+
|
|
92
|
+
```kotlin
|
|
93
|
+
class Score(val cards: Cards) {
|
|
94
|
+
val score: Int; val isNotBust: Boolean; val checkDealerScore: Boolean
|
|
95
|
+
private val minScore: Int; private val maxScore: Int
|
|
96
|
+
private val validateAceCondition: Boolean; private val isMaxScoreInRange: Boolean
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
리뷰어: 동일 코멘트 반복. — *Score 안에 여러 파생 프로퍼티*. *get() 함수*로 계산하면 *멤버 변수 아님*. 그러나 *backing val*로 보유하면 *멤버 카운트*. **`get()` vs `val` 선택의 *요구사항 충족 여부* 영향**.
|
|
101
|
+
|
|
102
|
+
### 8. `Score`가 *외부 상수 참조* (`BlackJackGame.BLACKJACK_NUMBER`)
|
|
103
|
+
|
|
104
|
+
```kotlin
|
|
105
|
+
class Score(val cards: Cards) {
|
|
106
|
+
val isNotBust: Boolean get() = minScore <= BlackJackGame.BLACKJACK_NUMBER
|
|
107
|
+
val checkDealerScore: Boolean get() = maxScore < DEALER_MIN_NUMBER
|
|
108
|
+
private val validateAceCondition: Boolean get() = minScore + ACE_OTHER_NUMBER_DIFF <= BlackJackGame.BLACKJACK_NUMBER
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
리뷰어: "*BlackJackGame에 있는 상수를 직접 참조하지 않는 방향을 고민해보세요.* 그리고 *Score라는 클래스에 버스트 상태 확인하는 것이 적절한지 모르겠*습니다." / 후속: "*변수명에도 DEALER라고 명확히 적혀있다는 것은 딜러가 가져야할 역할과 관련*되어 있다는 의미가 아닐까요?" / "*`BLACKJACK_NUMBER = 21` 같은 상수가 여러 곳에서 사용중*입니다. 만약 *해당 값에 변경이 발생한다면 모두 찾아서 변경*해줘야 하며 *실수로 빠뜨리면 버그가 발생*할 수 있습니다. *하나의 상수로 해결 할 수 있는 구조에 대해 고민*해보세요." — **상수의 단일 정의**. `Score` 외부에서 *BLACKJACK_NUMBER* 참조 = *Score가 BlackJackGame의 상수 알아야 함* = *역방향 의존*. *DEALER_MIN_NUMBER*는 *Dealer의 룰*인데 *Score에 있음* = *책임 누수*.
|
|
113
|
+
|
|
114
|
+
### 9. `Score.checkDealerScore` — 변수명 vs Boolean 컨벤션
|
|
115
|
+
|
|
116
|
+
```kotlin
|
|
117
|
+
val checkDealerScore: Boolean get() = maxScore < DEALER_MIN_NUMBER
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
리뷰어: "*보통 Boolean 타입은 is로 시작*하죠. 네이밍에 일관성을 맞추면 더 좋겠어요." — Kotlin/Java 컨벤션: `is`/`has`/`can` 접두사. `checkDealerScore`는 *명사 동사형 X*. `isDealerScoreInsufficient` 또는 `canDealerDraw`.
|
|
121
|
+
|
|
122
|
+
### 10. `Guest`에 *불필요한 주석* + dealer 오타
|
|
123
|
+
|
|
124
|
+
```kotlin
|
|
125
|
+
class Guest(name: String) : User(name) {
|
|
126
|
+
override val isContinue: Boolean // dealer // ⚠ Guest인데 dealer 주석
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
리뷰어: "*불필요한 주석인 것 같고 dealer가 아니라 guest네요.*" — **복사-붙여넣기 흔적**. 학생이 *Dealer 코드를 베이스로 Guest 작성*. *주석이 코드의 진실보다 늦게 갱신* = *주석 ≠ 코드 룰*. *주석 자체를 지우는 게 더 안전*.
|
|
131
|
+
|
|
132
|
+
### 11. `OutcomeTest` 함수명 모호 — *누가 지는가*
|
|
133
|
+
|
|
134
|
+
```kotlin
|
|
135
|
+
@Test fun `딜러와 유저의 점수가 둘 다 21점 이상이면 비긴다`() { ... }
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
리뷰어: "*누가 지는건가요? 단순히 테스트명이 문제가 아니라 Outcome의 of 함수부터 애매모호*합니다." — **`Outcome.of(dealer, guest)` 자체가 주어 부재**. *누구의 결과인가*. `Outcome.of(player, opponent)` 또는 `player.match(opponent)`. PR #28·#10·#125·#63·#34와 같은 결.
|
|
139
|
+
|
|
140
|
+
### 12. `CardDeckTest` *애매한 함수명* "잘 있는지"
|
|
141
|
+
|
|
142
|
+
```kotlin
|
|
143
|
+
@Test fun `카드덱 잘 있는지 확인`() { ... }
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
리뷰어: "*잘 있는게 뭔가요? 어떤 상태가 잘 있는거죠? 무엇을 테스트하는 것인지 좀 더 상세하고 명확하게 작성*해주세요.(이하 동일)" — **테스트 함수명 = 사양서**. "잘 있는"은 *입력/결과 명시 부재*. *카드덱이 52장이다*, *중복 카드가 없다* 같은 *구체 시나리오*.
|
|
147
|
+
|
|
148
|
+
### 13. `Outcome.of(dealer, guest)` — 정적 비교자
|
|
149
|
+
|
|
150
|
+
```kotlin
|
|
151
|
+
enum class Outcome { WIN, DRAW, LOSE; companion object { fun of(dealer: Dealer, guest: Guest): Outcome { ... } } }
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
→ `dealer.match(guest)`가 자연. PR #28·#63·#125·#10·#33·#24·#116·#29·#17·#81·#119 권고와 동일.
|
|
155
|
+
|
|
156
|
+
### 14. `Cards.containsACE()` vs `isContainsAce()` 명명
|
|
157
|
+
|
|
158
|
+
```kotlin
|
|
159
|
+
fun containsACE(): Boolean = ...
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
리뷰어: "*isContainsAce()라는 네이밍이 좀 더 어울리지 않을까요?*" — *동사 contains*가 *함수명에 적합*하나 *Kotlin Boolean 관례는 `is*` 접두*. 또 `ACE` 대문자가 *카멜 위반*(PR #34 후속과 같은 결).
|
|
163
|
+
|
|
164
|
+
### 15. `Score.kt`에 *Score 테스트 부재*
|
|
165
|
+
|
|
166
|
+
리뷰어: "*Score에 대한 테스트 코드도 작성해보시죠!*" — *블랙잭의 핵심 = 점수 계산*. *Ace 보정 + Bust + 비교*가 모두 Score 안. *테스트 부재 = 룰 검증 부재*.
|
|
167
|
+
|
|
168
|
+
### 16. `CardDeck` Kotlin 컨벤션 순서
|
|
169
|
+
|
|
170
|
+
```kotlin
|
|
171
|
+
class CardDeck(cards: List<Card>) {
|
|
172
|
+
private val cards: MutableList<Card> = cards.toMutableList()
|
|
173
|
+
init { ... }
|
|
174
|
+
val size: Int get() = cards.size // ⚠ init 후 val 선언
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
리뷰어: "*[코틀린 컨벤션]에 따라 위치를 조정하면 좋을 것 같아요.* 1. *Property declarations and initializer blocks* 2. *Secondary constructors* 3. *Method declarations* 4. *Companion object*" — Kotlin Class Layout 권고: *property → init → constructor → method → companion*. *`val size`는 property*인데 *init 후*에 위치 = 순서 위반.
|
|
179
|
+
|
|
180
|
+
### 17. `InputView` *(예는 y, 아니오는 n) 안내 누락*
|
|
181
|
+
|
|
182
|
+
리뷰어: "*(예는 y, 아니오는 n) 에 대한 안내가 없습니다.*" — **사용자에게 입력 가이드 제공 = UI 책임**.
|
|
183
|
+
|
|
184
|
+
### 18. `InputView.inputParticipants` 빈 이름 처리 — 원시값 포장 미적용
|
|
185
|
+
|
|
186
|
+
```kotlin
|
|
187
|
+
fun inputParticipants(): List<String> {
|
|
188
|
+
println(...)
|
|
189
|
+
return readln().split(",").map { it.trim() } // ⚠ 빈 이름 무방비
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
리뷰어: "*모든 원시 값과 문자열을 포장한다* *이름을 공백으로 여러명을 넣어도 동작*을 하네요. *원시 값 포장을 통해서 예외 처리*를 하면 어떨까요?" — *Name value class*에서 `init { require(value.isNotBlank()) }`. PR #28·#24·#10과 같은 결.
|
|
194
|
+
|
|
195
|
+
### 19. `Controller`가 `Card.all().shuffled()`를 *직접 호출* — Deck이 자체 셔플 X
|
|
196
|
+
|
|
197
|
+
```kotlin
|
|
198
|
+
private fun setBlackJack(): BlackJack = BlackJackBuilder.init {
|
|
199
|
+
cardDeck(Card.all().shuffled()) // ⚠ Controller가 셔플 후 전달
|
|
200
|
+
...
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
리뷰어: "*현재 Card 클래스는 단순히 Card를 넘어서 Cards의 역할까지 하는 것 같습니다*. *CardDeck에 Cards를 주입하는 것은 좋습니다!* 그런데 *Card와 CardDeck의 차이는 뭘까요?* CardDeck 내부에도 cards 프로퍼티가 있는데 *외부에서 셔플을 해서 넘겨주기 보다 내부에서 그 역할을 할 수 있는 방법*을 고민해보면 어떨까요?" — **`Card.all() + shuffled()`이 Controller에 = Deck의 자체 책임 누수**. *Deck = 52장 + 셔플 + 뽑기*가 단일 책임. PR #111의 *Controller에서 미리 셔플*은 *테스터빌리티 이유*였으나 여기는 *그냥 외부 호출*.
|
|
205
|
+
|
|
206
|
+
### 20. `BlackJackController`가 *y에만 응답 처리* — 그 외는 No
|
|
207
|
+
|
|
208
|
+
```kotlin
|
|
209
|
+
// y만 처리, 그 외는 카드 안 받음 (n이 아니어도)
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
리뷰어: "*y에 대한 처리만 있고 그 외에는 n이 아니더라도 아무 값을 입력하면 카드를 받지 않는 것으로 되어 있네요.*" — **입력 검증 부재**. *yY/nN* 외 입력 시 *명확한 안내*가 *UI 책임*.
|
|
213
|
+
|
|
214
|
+
### 21. `Dealer.default value`
|
|
215
|
+
|
|
216
|
+
```kotlin
|
|
217
|
+
class BlackJackController(... 딜러 inject ...) { ... }
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
리뷰어: "*딜러는 변경될 가능성이 적으니 굳이 현재 시점에서 주입 받기보다 default value를 사용*해보는 것은 어떨까요?" — **DI 과잉**. *변경 가능성 낮은 의존*은 *기본값으로 단순화*. *테스트에서 교체 필요*하면 *기본값 + 명시 주입* 둘 다 가능.
|
|
221
|
+
|
|
222
|
+
### 22. `OutputView` *,로 구분*
|
|
223
|
+
|
|
224
|
+
리뷰어: "*미션 실행 결과에는 ,로 구분되는데 적용해보면 어떨까요?*" — **요구사항 미충족** (출력 형식). PR #146 (lotto)와 같은 *요구사항 충실*.
|
|
225
|
+
|
|
226
|
+
### 23. `OutputView` private 메서드
|
|
227
|
+
|
|
228
|
+
리뷰어: "*private으로 해도 되겠네요.*" — *내부 사용 메서드*는 *최소 가시성*.
|
|
229
|
+
|
|
230
|
+
### 24. `docs/README.md` 기능 요구사항 미충족
|
|
231
|
+
|
|
232
|
+
리뷰어: "*다음 사항에 관한 구현 여부를 확인해보세요. 기본적인 기능 요구 사항을 만족하지 않고 있습니다.* - *딜러는 처음에 받은 2장의 합계가 16이하이면 반드시 1장의 카드를 추가로 받아야 하고, 17점 이상이면 추가로 받을 수 없다.* - *플레이어는 21을 넘지 않을 경우 원한다면 얼마든지 카드를 계속 뽑을 수 있다.* (현재 *플레이어 카드가 K, ACE 일 때도 카드를 더 받을 것인지 묻고* 있습니다. *Ace를 언제 1 또는 11로 계산할지 좀 더 고민*이 필요해보여요.)" — **블랙잭 룰 누락 + Ace 처리 미흡**. PR #10·#92·#116·#119와 같은 결.
|
|
233
|
+
|
|
234
|
+
## 리뷰어 의견 요지
|
|
235
|
+
|
|
236
|
+
- ***페어 닉네임 그대로 사용 = 학습 흔적 없음***.
|
|
237
|
+
- ***DSL이 *Korean/English 하드코딩* = 확장성 부재***.
|
|
238
|
+
- ***정상 입력만 테스트 = 오류 경로 무방비***.
|
|
239
|
+
- ***멤버 확장 함수 = 호출 사이트 모호***.
|
|
240
|
+
- ***`lateinit var input + fun input(func) setter` 패턴***.
|
|
241
|
+
- ***3변수 제한 요구사항 충족 vs 인공 객체*** — 트레이드오프.
|
|
242
|
+
- ***외부 상수(`BlackJackGame.BLACKJACK_NUMBER`) 참조 = 역방향 의존***.
|
|
243
|
+
- ***`Score.checkDealerScore`가 Score 안 = 책임 누수***.
|
|
244
|
+
- ***Boolean 함수명 `is*` 접두사***.
|
|
245
|
+
- ***불필요 주석 + 잘못된 주석 (`// dealer`)***.
|
|
246
|
+
- ***테스트 함수명 *누가 지는가* 명시 부재***.
|
|
247
|
+
- ***Cards.containsACE 카멜 + Boolean 접두사***.
|
|
248
|
+
- ***Score 테스트 부재 = 핵심 룰 검증 부재***.
|
|
249
|
+
- ***Kotlin Class Layout 순서***.
|
|
250
|
+
- ***`(예는 y, 아니오는 n)` 안내 누락***.
|
|
251
|
+
- ***Name 원시값 포장 + 빈 이름 검증***.
|
|
252
|
+
- ***Deck 외부 셔플 = Deck 책임 누수***.
|
|
253
|
+
- ***y만 처리 + 그 외 No = 입력 검증 부재***.
|
|
254
|
+
- ***Dealer 기본값 vs DI = 변경 가능성에 따라***.
|
|
255
|
+
- ***출력 형식 *,로 구분* 요구사항 미충족***.
|
|
256
|
+
- ***딜러 16 이하 추가 + ACE 1/11 결정 룰 누락***.
|
|
257
|
+
|
|
258
|
+
## 대표 인용
|
|
259
|
+
|
|
260
|
+
> hard 스킬에 kotlin을 넣으려고 의도했지만 *오류로 결과적으로 java라는 값이 들어갈 수도 있다면 이 테스트 코드가 그걸 검증해 줄 수 있나요?* 개인적으로는 *심리적 안정감에 도움이 되지 않는 테스트 코드*라고 생각합니다.
|
|
261
|
+
> — @woowajames on `Test.kt`
|
|
262
|
+
|
|
263
|
+
> 멤버 확장 함수의 사용은 *지양*하는 것이 좋습니다. 현재 꼭 필요한지 모르겠고 *개인적으로는 코드의 가독성이 매우 떨어진다*고 생각됩니다.
|
|
264
|
+
> — @woowajames on `BlackJackGame.kt`
|
|
265
|
+
|
|
266
|
+
> `BLACKJACK_NUMBER = 21` 같은 상수가 *여러 곳에서 사용중*입니다. 만약 *해당 값에 변경이 발생한다면 모두 찾아서 변경*해줘야 하며 *실수로 빠뜨리면 버그가 발생*할 수 있습니다.
|
|
267
|
+
> — @woowajames on `Score.kt`
|
|
268
|
+
|
|
269
|
+
> 현재 Card 클래스는 *단순히 Card를 넘어서 Cards의 역할*까지 하는 것 같습니다. [...] *외부에서 셔플을 해서 넘겨주기 보다 내부에서 그 역할을 할 수 있는 방법*을 고민해보면 어떨까요?
|
|
270
|
+
> — @woowajames on `BlackJackController.kt`
|
|
271
|
+
|
|
272
|
+
> 다음 사항에 관한 구현 여부를 확인해보세요. *기본적인 기능 요구 사항을 만족하지 않고 있습니다.*
|
|
273
|
+
> — @woowajames on `docs/README.md`
|
|
274
|
+
|
|
275
|
+
## 얻은 교훈
|
|
276
|
+
|
|
277
|
+
- ***페어 닉네임 그대로 사용 = 학습 흔적 부재*** — 본인 닉네임으로 자기 사고 명시.
|
|
278
|
+
- ***DSL Builder의 하드코딩은 확장성 부재*** — *enum 또는 Map*으로 *추가 가능*.
|
|
279
|
+
- ***정상 입력만 테스트 = 의도와 다른 동작 못 잡음*** — *오류 경로*도 *심리적 안정감*의 일부.
|
|
280
|
+
- ***멤버 확장 함수 `class Foo { fun Bar.baz() }` = 호출 사이트 모호*** — *수신자 + 컨텍스트* 두 가지가 호출 시 *명시 X*. Kotlin 권고: *최상위 확장* 또는 *일반 메서드*.
|
|
281
|
+
- ***`lateinit var callback + fun setter` = PR #34와 동일 패턴*** — 생성자 주입.
|
|
282
|
+
- ***3변수 제한 = 요구사항 충실 vs 인공 객체 = 트레이드오프*** — PR #92·#135와 같은 결.
|
|
283
|
+
- ***외부 클래스 상수 참조 = 역방향 의존*** — *Score가 BlackJackGame.BLACKJACK_NUMBER*를 알면 *Score → BlackJackGame 의존*. 상수 단일 정의 + 의존 방향 정리.
|
|
284
|
+
- ***`Score.checkDealerScore` = 책임 누수*** — *DEALER 룰*은 *Dealer*. *Score는 점수만*. *변수명에 DEALER가 박혀있으면 책임 잘못 배치 신호*.
|
|
285
|
+
- ***Boolean 함수명 `is`/`has`/`can` 접두사*** — `checkDealerScore`처럼 *동사 명사형*은 *Boolean의 의미*를 흐림.
|
|
286
|
+
- ***주석은 코드보다 늦게 갱신 = 거짓말 위험*** — `// dealer` 같은 *잘못 남은 주석*. *주석 제거가 안전*.
|
|
287
|
+
- ***`Outcome.of(dealer, guest)` 정적 비교자 = 주어 부재*** — *누구의 결과인가*가 *함수 시그니처에서 명시*되지 않음. `player.match(opponent)`. 14개+ PR 연속 권고.
|
|
288
|
+
- ***테스트 함수명 "잘 있는지" 같은 모호 표현 = 사양서로 거짓*** — *입력 + 결과* 명시.
|
|
289
|
+
- ***Score 테스트 부재 = 핵심 룰 검증 부재*** — *블랙잭 = 점수 계산*이 가장 중요한 도메인 룰.
|
|
290
|
+
- ***Kotlin Class Layout 순서*** — property → init → constructor → method → companion.
|
|
291
|
+
- ***`(예는 y, 아니오는 n)` 안내 = UI 책임*** — *사용자 가이드 표시*.
|
|
292
|
+
- ***Name value class에 `require(isNotBlank())` invariant*** — *원시값 포장 + 검증*. PR #28·#24·#10과 같은 결.
|
|
293
|
+
- ***Deck 외부 셔플 = Deck 책임 누수*** — *52장 + 셔플 + 뽑기*가 단일 책임.
|
|
294
|
+
- ***`y만 처리` 입력 검증 부재 = 사용자 경험 ↓*** — *yY/nN 외 입력 시 명시 안내*.
|
|
295
|
+
- ***Dealer 기본값 vs DI*** — *변경 가능성 낮은 의존*은 *기본값*, *테스트 교체 필요*하면 *기본값 + 명시 주입*. **변경 가능성에 따른 DI 결정**.
|
|
296
|
+
- ***출력 `,로 구분` 같은 형식 요구사항 충실*** — *요구사항 = 도메인의 일부*.
|
|
297
|
+
- ***딜러 16 이하 추가 + ACE 1/11 결정 룰 누락 = 블랙잭 룰 미반영*** — 14개+ PR 연속 *블랙잭 룰 정확 이해* 권고.
|