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,498 @@
|
|
|
1
|
+
# PR #131 — [블랙잭 2단계] 다이스 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@moondev03](https://github.com/moondev03)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-blackjack/pull/131
|
|
5
|
+
- **단계:** 2단계 (베팅 / 수익률 / 블랙잭 1.5배)
|
|
6
|
+
- **리뷰어:** @Gyuil-Hwnag (두루)
|
|
7
|
+
- **라인 코멘트:** 22 스레드 / 32 코멘트 — 리뷰어 칭찬 다수 + 학생 자가 학습 답변 위주
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`BetAmount` value class + `operator fun times` 오버로딩** — `betAmount.toDouble()` 같이 *value 접근 없는 직관적 변환*. 학생 자가 인용: *"`betAmount.value.toDouble()` 대신 `betAmount.toDouble()`을 사용하면, `value`에 직접 접근할 필요 없이 더 직관적으로 값을 변환할 수 있다고 생각했습니다. 또한, `value`를 `private`으로 감추면서 캡슐화를 유지할 수 있어, 향후 내부 구현을 변경하더라도 외부 코드에 영향을 주지 않는 장점이 있다고 생각합니다!"*
|
|
12
|
+
- **`Score` private constructor + `Score.create(cards)` 팩토리** — *Ace 11 기본 + 21 초과 시 ace 카운트만큼 -10 반복* 패턴. *Ace 다수 (2장 이상) 정확 처리* — `repeat(aceCount) { if (total > 21) total -= 10 }` 로 *Ace 11→1 점진적 변환*. PR #128·#135·#114·#125 와 같은 결의 Ace 정공 패턴.
|
|
13
|
+
|
|
14
|
+
```kotlin
|
|
15
|
+
private fun adjustAceValues(sum: Int, cards: List<Card>): Int {
|
|
16
|
+
val aceCount = cards.count { it.number == CardNumber.ACE }
|
|
17
|
+
var total = sum
|
|
18
|
+
repeat(aceCount) { if (total > BLACKJACK_SCORE) total -= ACE_BASE_SCORE }
|
|
19
|
+
return total
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
*Ace 2장 이상 + 합 > 21* 일 때 *한 Ace씩 -10*. 21 ≤ 합 이면 종료.
|
|
24
|
+
- **`PersonState` enum + `isFinal` 부가속성** — *HIT/BUST/STAY/BLACKJACK* 4상태 + *`isFinal` boolean*. *상태 일급화* 시도. *`Person.isDrawable() = !state.isFinal`* 이 *상태로부터 의미 추출*.
|
|
25
|
+
- **`BlackJackInputView` / `BlackJackOutputView` interface** — DIP (Dependency Inversion Principle). 학생 PR 본문 자가 인용: *"BlackJackInputView / BlackJackOutputView => Interface. BlackJack Interface로 추가하여 어떤 컨트롤러든 BlackJackGame을 사용할 수 있도록 ..."*. 두루 코멘트: *"이전 코멘트에 남겨두었던 interface로 하셨군요💪 하시면서, 어떤 생각이 드셨을까요?"*. 학생 자가 답변: *"BlackJack View Interface를 작성하므로써 View 구현체에 따라 사용자가 원하는 다양한 형태의 뷰를 즐길 수 있을 것 같습니다."*
|
|
26
|
+
- **`PersonCards` → `Hand` 합치기 자가 반영 — *깊이 (Player → Hand → PersonCards)* 축소** — 학생이 *Score 객체 분리 후 Hand의 역할 늘어남*을 *PersonCards 추출*로 풀려 했으나, 두루의 *"`Player -> Hand -> PersonCards` 뎁스가 깊어진다"* 진단으로 *Hand 안에서 다시 합침* 자가 후퇴. 학생 자가 답변: *"다시 PersonCards를 제거하고 Hand에서 관리하도록 변경했습니다."* — *과도한 분리 vs 깊이* 트레이드오프 자가 학습.
|
|
27
|
+
- **콜백 → 인터페이스 주입 자가 반영 (DIP 자가 학습)** — 이전 콜백 형태에서 *`BlackJackGame.play()` 한 줄로 게임 진행*. 학생 자가 학습: *"콜백으로 인해 컨트롤러에 중복 코드가 제거되니 코드가 깔끔해진 것 같습니다! 추가로 의존성 역전 원칙(DIP) 개념에 대해 찾아볼 수 있는 기회가 된 것 같습니다!"*
|
|
28
|
+
- **`Deck` 카드 부족 리필** — 두루 자가 칭찬: *"덱이 다 떨어졌을 때, 리필을 하는 기능 추가 좋습니다👍"*. PR #108·#133 (시아) 와 같은 결의 *카지노 무한 게임* 메타포 반영.
|
|
29
|
+
- **수익률 계산 책임 분리** — `PlayerBetInfo.calculatePlayerPayout(dealer): Profit` + `GameResult` 컬렉션 + `Profit` 값 객체. *베팅 정보 + 결과 계산 책임 응집*. 두루 자가 칭찬: *"PlayerBetInfo 객체를 통해서, 플레이어가 이기고 졌을때 등에 대한 게임의 배팅 결과를 알려주는 군요👍"*.
|
|
30
|
+
- **테스트 다양화 — BetAmount/PlayerBetInfo/BlackJackGame Controller/UI** — 두루 다중 칭찬: *"BetAmount에 대한 테스트 좋습니다~👍"*, *"Controller 테스트 형태를 작성하셨군요👍"*, *"Ui 테스트 형태를 작성해보셨군요👍"*. *흑백 테스트 + 인터페이스 테스트 + 도메인 객체 테스트* 다양화.
|
|
31
|
+
- **`Player.changeToStay()` 만 state 변경 — 의도 제한** — `Player` 만 `STAY`로 변경 가능 + `Dealer`는 *자기 hit 룰 따라 자동 상태 전이*. *Player 의지에 의한 상태 변경* vs *Dealer 자동 룰* 의 구분. 다만 *protected var 의 자식 접근* 함정도 동반 (못한 점 §3).
|
|
32
|
+
- **기본 생성자 자가 제거** — 두루의 *"개인적으로 생성자에 기본 생성자가 있는건 지양을 하는편이긴 합니다. ... 기본 생성자로 되어 있다보면, 개발자가 자칫 잘못해서 생성시에 빠트리는 경우가 있습니다."* 권고에 *기본 생성자 제거* 자가 반영.
|
|
33
|
+
|
|
34
|
+
## 못한 점 (설계 관점)
|
|
35
|
+
|
|
36
|
+
### 1. `BlackJackGame` 의 `lateinit var deck/dealer/playerBetInfos` — *호출 순서 invariant*
|
|
37
|
+
|
|
38
|
+
```kotlin
|
|
39
|
+
class BlackJackGame(
|
|
40
|
+
private val inputView: BlackJackInputView,
|
|
41
|
+
private val outputView: BlackJackOutputView,
|
|
42
|
+
) {
|
|
43
|
+
private lateinit var deck: Deck
|
|
44
|
+
private lateinit var dealer: Dealer
|
|
45
|
+
private lateinit var playerBetInfos: List<PlayerBetInfo>
|
|
46
|
+
|
|
47
|
+
fun play() {
|
|
48
|
+
prepareGame() // 여기서 초기화
|
|
49
|
+
runGame() // 사용
|
|
50
|
+
finishGame() // 사용
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private fun prepareGame() {
|
|
54
|
+
deck = Deck()
|
|
55
|
+
dealer = Dealer()
|
|
56
|
+
playerBetInfos = generatePlayers()
|
|
57
|
+
}
|
|
58
|
+
...
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
→ **`lateinit var` 3개 + `prepareGame` 누락 시 `UninitializedPropertyAccessException`**. *play() 가 외부 진입점*이므로 *prepareGame → runGame → finishGame 순서가 보장*되긴 하나, *Kotlin lateinit 안티패턴*: *상태가 두 단계 (초기화 전/후) 로 나뉘어 invariant 가 암묵적*. *`init`에서 모두 초기화* 하거나 *생성자에 주입*이 자연.
|
|
63
|
+
|
|
64
|
+
*deck/dealer 가 매 `play()` 호출마다 새로 생성* 의도면 *`run()` 시작 부분에서 새 `BlackJackGame` 인스턴스* 가 더 명료. *재사용 가능 BlackJackGame* + *상태 가짐* 의 트레이드오프 — 현재 *재사용 가능 + lateinit 의존*. PR #28·#92·#65·#10·#124 와 같은 결.
|
|
65
|
+
|
|
66
|
+
### 2. `PersonState.from(person)` 정적 팩토리 + `Dealer` 타입 검사 — *안티 다형성*
|
|
67
|
+
|
|
68
|
+
```kotlin
|
|
69
|
+
enum class PersonState(val isFinal: Boolean) {
|
|
70
|
+
HIT(false), BUST(true), STAY(true), BLACKJACK(true);
|
|
71
|
+
|
|
72
|
+
companion object {
|
|
73
|
+
fun from(person: Person): PersonState {
|
|
74
|
+
val score = person.score()
|
|
75
|
+
val isDealer = person is Dealer // ⚠ 타입 검사
|
|
76
|
+
|
|
77
|
+
return when {
|
|
78
|
+
person.cards().size == 2 && score.isBlackJackScore() -> BLACKJACK
|
|
79
|
+
score.isBustScore() -> BUST
|
|
80
|
+
isDealer && score.isDealerStayScore() -> STAY
|
|
81
|
+
else -> HIT
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
→ **`person is Dealer` 타입 검사 = *Player/Dealer 다형성 부재 신호***. *Dealer는 *17 이상이면 STAY**, *Player는 *외부 입력 (`Player.changeToStay`)으로 STAY**. *룰 차이 = 다형성*. *Person.stateAfterDraw(): PersonState* abstract method 면 *Dealer는 17 이상 STAY 로직 / Player는 default HIT*. 현재는 *enum 안에 타입 검사* — *enum 이 Person 의 subtype 의식*.
|
|
89
|
+
|
|
90
|
+
또한 `PersonState.from(person)` 호출이 *`Person.draw(deck)` 에서 매번*:
|
|
91
|
+
|
|
92
|
+
```kotlin
|
|
93
|
+
fun draw(deck: Deck) {
|
|
94
|
+
hand.addCard(deck.draw())
|
|
95
|
+
state = PersonState.from(this) // ⚠ 매 카드마다 상태 재계산
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
*상태 = 카드들로부터 매번 derive* — *상태 자체가 데이터인지 캐시인지 모호*. *진짜 State 패턴 (PR #152·#133·#136 등)* 은 *상태 객체 = 다음 상태로 전이*. *enum + from* 은 *상태 = 일종의 derived snapshot*. *Tell-Don't-Ask 의 메시지 분배*는 *State 객체 다형성*이 더 자연.
|
|
100
|
+
|
|
101
|
+
### 3. `Person.protected var state` + `val gameState: PersonState get() = state` — *두 getter + 자식 접근*
|
|
102
|
+
|
|
103
|
+
```kotlin
|
|
104
|
+
abstract class Person {
|
|
105
|
+
protected var state: PersonState = PersonState.HIT
|
|
106
|
+
val gameState: PersonState get() = state // ⚠ 같은 상태 두 이름
|
|
107
|
+
|
|
108
|
+
fun isDrawable(): Boolean = !state.isFinal
|
|
109
|
+
fun draw(deck: Deck) {
|
|
110
|
+
hand.addCard(deck.draw())
|
|
111
|
+
state = PersonState.from(this)
|
|
112
|
+
}
|
|
113
|
+
...
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
class Player(...) : Person() {
|
|
117
|
+
fun changeToStay() {
|
|
118
|
+
state = PersonState.STAY // ⚠ 자식이 부모 protected var 직접 변경
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
두루 (Person.kt — 미해결): *"아래와 같이 사용을 하는 방법도 있습니다~ 다이스가 보시기에는 각 두방식은 어떤 차이점이 있을까요? `protected var state: PersonState = PersonState.HIT` `val gameState: PersonState get() = state` 예시 `var state: PersonState = PersonState.HIT; private set`"*
|
|
124
|
+
|
|
125
|
+
학생 자가 답변: *"Person을 상속받는 Player에서는 STAY 상태로의 전환을 허용해야 해서 해당 형태로 작성했습니다. 원래는 Person에서 상태를 변경하는 함수를 만들었지만, STAY 상태로 변경하는 기능은 Player에서만 필요했기 때문에 이런 구조가 된 것 같습니다."*
|
|
126
|
+
|
|
127
|
+
→ **`var state` (자식이 직접 변경) + `val gameState` (외부 노출 read-only) = *두 이름이 같은 상태***. *Kotlin `var state private set` + `protected fun stayed()` (자식이 호출)* 패턴이 *접근 통제* 정공. *`protected var` + 자식 직접 변경*은 *Player가 PersonState.STAY 만 set 한다는 invariant*가 *암묵적* — *Player.changeToBust() 같은 잘못된 변경*도 *컴파일러가 차단 안 함*.
|
|
128
|
+
|
|
129
|
+
*Dealer 자기 상태 = PersonState.from(this) 결정 (draw 안에서)*. *Player.changeToStay = 외부 의지*. 두 진입점이 *명시적 메서드*면 *invariant 강제*. *현재는 var state 직접 변경*이 *책임 분배 불명확*.
|
|
130
|
+
|
|
131
|
+
### 4. `PlayerBetInfo.calculatePlayerPayout` 의 *Player.gameState 분기 + ResultState 정적 호출*
|
|
132
|
+
|
|
133
|
+
```kotlin
|
|
134
|
+
class PlayerBetInfo(
|
|
135
|
+
val player: Player,
|
|
136
|
+
private val betAmount: BetAmount,
|
|
137
|
+
) {
|
|
138
|
+
fun calculatePlayerPayout(dealer: Dealer): Profit {
|
|
139
|
+
val resultState = ResultState.calculateWin(player, dealer) // ⚠ 정적 호출
|
|
140
|
+
val profit = when (resultState) {
|
|
141
|
+
ResultState.WIN -> calculateWinPayout()
|
|
142
|
+
ResultState.LOSE -> calculateLosePayout()
|
|
143
|
+
ResultState.DRAW -> calculateDrawPayout()
|
|
144
|
+
}
|
|
145
|
+
return Profit(profit)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private fun calculateWinPayout(): Double {
|
|
149
|
+
if (player.gameState == PersonState.BLACKJACK) { // ⚠ gameState 분기
|
|
150
|
+
return betAmount * BLACKJACK_PAYOUT_MULTIPLIER
|
|
151
|
+
}
|
|
152
|
+
return betAmount * WINNING_PAYOUT_MULTIPLIER
|
|
153
|
+
}
|
|
154
|
+
...
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
→ **`ResultState.calculateWin(player, dealer)` 정적 호출 + `player.gameState` 분기**. *Tell-Don't-Ask 의 양면 위반*:
|
|
159
|
+
|
|
160
|
+
1. **`ResultState.calculateWin(player, dealer)` 정적 헬퍼** — *Player.compete(other)* 메시지가 정공. PR #108·#133 (시아) 와 같은 결.
|
|
161
|
+
2. **`player.gameState == PersonState.BLACKJACK` 분기** — *PlayerBetInfo가 Player의 상태를 검사 + 분기*. *Player.isBlackjack(): Boolean* 메시지가 *Tell-Don't-Ask*. 또는 *resultState 자체가 *WinNormal* vs *WinBlackjack* 으로 분리*.
|
|
162
|
+
|
|
163
|
+
*수익률 룰* = *BLACKJACK = 1.5배, WIN = 1.0, DRAW = 0, LOSE = -1*. *ResultState* 가 *4 멤버 (WinBlackjack, Win, Draw, Lose)* 면 *gameState 분기 사라짐*. PR #132 (환노) 의 *`WinningResult.BlackjackWin`* 과 같은 결.
|
|
164
|
+
|
|
165
|
+
### 5. `BetAmount * Int = Int` / `BetAmount * Double = Double` — *반환 타입이 Money 가 아님*
|
|
166
|
+
|
|
167
|
+
```kotlin
|
|
168
|
+
class BetAmount(val value: Int) {
|
|
169
|
+
operator fun times(multiplier: Int): Int = value * multiplier
|
|
170
|
+
operator fun times(multiplier: Double): Double = value * multiplier
|
|
171
|
+
...
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// 사용처
|
|
175
|
+
return betAmount * BLACKJACK_PAYOUT_MULTIPLIER // Double 반환
|
|
176
|
+
return betAmount * LOSING_PAYOUT_MULTIPLIER // Int 반환 (LOSING = -1)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
→ **`BetAmount * multiplier` 반환 타입이 *원시 타입 (Int/Double)***. *수익 금액* 도메인 객체 (`Profit`/`Money`) 가 *없음*. *BetAmount * 1.5 = Double* 이 *Profit (Double 으로 표현)* 으로 *다음 단계에서 wrap*:
|
|
180
|
+
|
|
181
|
+
```kotlin
|
|
182
|
+
return Profit(profit)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
이 *3 단계 변환* — *value 추출 → 곱셈 → Profit wrap*. *`BetAmount * multiplier: Profit`* 직접 반환이 *도메인 어휘 + 변환 단계 감소*. PR #133 (시아 2단계) 의 *Money.multiplyMoney* 와 *반대 트레이드오프* (시아는 Money 도메인 객체 + 가변/연산자 함정, 다이스는 도메인 객체 없음 + 단순).
|
|
186
|
+
|
|
187
|
+
또한 `LOSING_PAYOUT_MULTIPLIER = -1 (Int)` 인데 `WINNING = 1.0 (Double)` — *타입 일관성 부재*. `LOSING = -1.0` 으로 통일이 자연.
|
|
188
|
+
|
|
189
|
+
### 6. `GameResult.calculateDealerProfit` — *`NEGATIVE_ZERO_PROFIT = -0.0` 우회 — Double 산술 정밀도 함정*
|
|
190
|
+
|
|
191
|
+
```kotlin
|
|
192
|
+
class GameResult(dealer: Dealer, playerBetInfos: List<PlayerBetInfo>) {
|
|
193
|
+
val playerPayouts: Map<Player, Profit> = playerBetInfos.associateBy(...)
|
|
194
|
+
val dealerProfit: Profit = calculateDealerProfit()
|
|
195
|
+
|
|
196
|
+
private fun calculateDealerProfit(): Profit {
|
|
197
|
+
val profit = playerPayouts.values.sumOf { it.value } * NEGATIVE_ONE
|
|
198
|
+
val result = if (profit == NEGATIVE_ZERO_PROFIT) ZERO_PROFIT else profit
|
|
199
|
+
return Profit(result)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
companion object {
|
|
203
|
+
const val ZERO_PROFIT = 0.0
|
|
204
|
+
const val NEGATIVE_ZERO_PROFIT = -0.0
|
|
205
|
+
const val NEGATIVE_ONE = -1
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
→ **`-0.0` 우회 = *Double IEEE 754 부호 있는 0 함정***. *0.0 * -1 = -0.0* 인데 *외부 노출 시 "-0" 으로 표시* 문제. *학생이 `-0.0`을 명시적으로 검사 + 0.0 으로 변환*. *현실 도메인 의미는 "딜러 수익 = 0"*. *우회 자체는 좋은 면* — *Double 산술 함정 자가 인식*.
|
|
211
|
+
|
|
212
|
+
다만 *근본 해결*은 *BigDecimal 또는 Long (cents 단위)* 으로 *부호 있는 0 자체 회피*. *금융 도메인 표준*이 *BigDecimal*. 현재 *Double + -0.0 우회* 는 *임시 해결*. PR #133 (시아 2단계) 의 *Money Double 정밀도* 와 같은 결.
|
|
213
|
+
|
|
214
|
+
또한 `playerPayouts.values.sumOf { it.value } * -1` 자체는 *총합의 부호 뒤집기*. *딜러 수익 = 플레이어 수익의 합 × -1* 룰 정확. *명시*. PR #133 의 *getDealerResult* 와 같은 결.
|
|
215
|
+
|
|
216
|
+
### 7. `PersonState.from(person)` 호출이 *State 다형성 vs enum 정적 분기* 의 경계
|
|
217
|
+
|
|
218
|
+
```kotlin
|
|
219
|
+
fun draw(deck: Deck) {
|
|
220
|
+
hand.addCard(deck.draw())
|
|
221
|
+
state = PersonState.from(this)
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
→ **State 다형성 vs enum + 정적 분기**:
|
|
226
|
+
|
|
227
|
+
- *PR #152 (모찌) 식 State 패턴* — `Hit.draw(card): State` 가 *다음 상태로 전이* — 다형성으로 분기 0.
|
|
228
|
+
- *PR #131 (다이스) PersonState enum* — `PersonState.from(person)` 가 *Person 정보로 상태 결정* — 정적 분기.
|
|
229
|
+
|
|
230
|
+
*트레이드오프*: enum + from = *변경 1곳 (from 함수)*, *Person.draw 호출자 분기 0*. State 패턴 = *상태별 클래스 분리*, *새 상태 추가 시 클래스 + 분기 추가*. *현재 4 상태 (HIT/BUST/STAY/BLACKJACK)* 면 *enum 으로 충분*. *상태별 행동 차이가 작으면 enum 정공*. *상태별 행동 차이가 크면 State 객체 정공*.
|
|
231
|
+
|
|
232
|
+
다이스의 enum 선택은 *행동 = isFinal boolean* 만 다르고 *나머지는 Person.draw/cards/score 공통* 이므로 *enum 정합*. PR #152·#133·#136 의 *State sealed* 와 *반대 트레이드오프 선택*.
|
|
233
|
+
|
|
234
|
+
### 8. `BlackJackGame.runGame()` god-object 변형
|
|
235
|
+
|
|
236
|
+
```kotlin
|
|
237
|
+
fun play() {
|
|
238
|
+
prepareGame()
|
|
239
|
+
runGame()
|
|
240
|
+
finishGame()
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
private fun runGame() {
|
|
244
|
+
dealCards()
|
|
245
|
+
playPlayersTurns()
|
|
246
|
+
playDealerTurns()
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
→ **`BlackJackGame` 이 *Controller 절차적 명령 + 도메인 진행 흡수*** — 1단계 *BlackJackController god-object → 2단계 BlackJackGame god-object* 의 *이름 변경 + 책임 흡수*. *play/prepareGame/runGame/finishGame/dealCards/playPlayersTurns/playDealerTurns/playPlayerTurn/playerPlayerTurns/...* 메서드 다수.
|
|
251
|
+
|
|
252
|
+
다만 *Controller 책임* 과 *Game 도메인 책임* 의 *경계가 모호한 채 한 클래스* — *InputView/OutputView 보유 + 도메인 객체 (Deck/Dealer/PlayerBetInfo) 생성 + 게임 진행*. PR #133 (시아 2단계) 의 *BlackjackEngine god-object* 와 같은 결.
|
|
253
|
+
|
|
254
|
+
두루 코멘트 (BlackJackController.kt:10 — 미해결): *"너무 잘해주셔서, 코멘트 내용이 많지 않을 것 같은데, 시간이 있는 만큼 콜백 형태로도 구현을 해봤으니, 함수의 파라미터로 받아서 처리를 하는 방법도 구현을 해보고 두개를 비교해보는 것 과정에서도 얻을 것이 있을 것 같다는 생각이 듭니다💪 Controller 에서 `BlackjackGame.play()` 하나로 블랙잭 게임을 할 수 있는 형태로요"*
|
|
255
|
+
|
|
256
|
+
→ ***Controller 가 BlackJackGame.play() 한 줄 호출*** 패턴 권고. *현재 BlackJackGame 가 Controller 역할까지 + InputView/OutputView 의존*. *Controller = main + BlackJackGame 생성 + play()* 만 호출이면 *완전한 분리*.
|
|
257
|
+
|
|
258
|
+
### 9. `playPlayerTurn(player)` — *if-return + else branch 분리 부재*
|
|
259
|
+
|
|
260
|
+
```kotlin
|
|
261
|
+
private fun playPlayerTurn(player: Player) {
|
|
262
|
+
if (isHit(player.name)) {
|
|
263
|
+
player.draw(deck)
|
|
264
|
+
outputView.printPlayerDrawStatus(player)
|
|
265
|
+
return
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
player.changeToStay()
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
→ **`isHit` 분기 후 if-return + else (`player.changeToStay()`)** — *Kotlin `when (isHit) { true → ..., false → ... }`* 또는 *`if-else`* 가 *대칭 분기* 표현. *if-return + 외부 else* 는 *Java 어휘*. Kotlin 어휘로 통일.
|
|
273
|
+
|
|
274
|
+
또한 *`isHit(player.name)` 이 매 turn 마다 외부 입력* 이고 *`while (player.isDrawable())` 외부 루프* — *if-return 으로 매 iteration 종료*. *false 시 changeToStay → state.isFinal == true → 루프 종료* — *암묵적 흐름*. *Player.act(action: ActionType) (HIT/STAY 입력 받아 자기 상태 변경)* 메시지가 정공.
|
|
275
|
+
|
|
276
|
+
### 10. `BlackJackGame` 이 *InputView 메서드를 직접 호출* — Controller 책임의 흡수
|
|
277
|
+
|
|
278
|
+
```kotlin
|
|
279
|
+
private fun generatePlayers(): List<PlayerBetInfo> {
|
|
280
|
+
val players = readPlayerNames()
|
|
281
|
+
return players.map { player ->
|
|
282
|
+
val betAmount = readPlayerBetAmount(player.name)
|
|
283
|
+
PlayerBetInfo(player, betAmount)
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
private fun readPlayerNames(): List<Player> =
|
|
288
|
+
retryWhenException {
|
|
289
|
+
inputView.getNames().map { name -> Player(name) }
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
→ **`BlackJackGame` 이 *InputView.getNames() + InputView.getBetAmount(name)* 직접 호출**. *도메인이 InputView 의존* — *InputView interface 추상화*는 했지만 *도메인이 의존*. *Controller 가 입력 받아 도메인에 전달* 패턴이 *MVC 의 정공*.
|
|
294
|
+
|
|
295
|
+
다만 *BlackJackGame interface* 추상화 의도면 *InputView 인터페이스 의존이 BlackJackGame interface 안에서 표현*. *학생 PR 본문 = "어떤 컨트롤러든 BlackJackGame을 사용할 수 있도록"* — *역방향 의존 (Controller → BlackJackGame)* 인데 *BlackJackGame → InputView* 도 의존. *DIP* 가 *완전히 도메인 → 인터페이스* 방향 — *InputView 가 도메인의 컨벤션을 따름*.
|
|
296
|
+
|
|
297
|
+
### 11. `Score.isDealerStayScore()` — *딜러 룰을 Score 객체가 알고 있음*
|
|
298
|
+
|
|
299
|
+
```kotlin
|
|
300
|
+
class Score private constructor(val value: Int) {
|
|
301
|
+
fun isBlackJackScore(): Boolean = value == BLACKJACK_SCORE
|
|
302
|
+
fun isBustScore(): Boolean = value > BLACKJACK_SCORE
|
|
303
|
+
fun isDealerStayScore(): Boolean = value > DEALER_ADDITIONAL_DRAW_BASE_SCORE
|
|
304
|
+
...
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
→ **`Score.isDealerStayScore` = *딜러 룰 (16점 초과면 STAY) 이 Score 안***. *Score 는 일반 점수 객체* 인데 *딜러 룰 의식*. *Dealer.canDraw() = score.value <= 16* 같은 *Dealer 안에서 직접*이 자연 — *Score는 *17 이상이 Dealer STAY*라는 룰 모름*.
|
|
309
|
+
|
|
310
|
+
또한 `isDealerStayScore` 는 *> 16* 검사. *Dealer.isDrawable() = !state.isFinal* 의존 + *PersonState.from* 에서 *isDealer && score.isDealerStayScore() -> STAY* 호출. *Score → PersonState → Person → Dealer 의 4 단계 의존*. *룰 위치가 분산*.
|
|
311
|
+
|
|
312
|
+
### 12. `Score.value` public — *Score 도메인 캡슐화 미달*
|
|
313
|
+
|
|
314
|
+
```kotlin
|
|
315
|
+
class Score private constructor(val value: Int) { ... }
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
→ **`Score.value` 가 *public*** — *Score 객체*의 *내부 표현 (Int)* 이 *외부 노출*. *Profit/PersonState/PlayerBetInfo* 등이 *score.value 직접 접근* 가능. *`Score.isXX()` 메시지가 외부 분기 대체*면 *value 직접 노출 불필요*. *value private + 메시지만 노출*이 *캡슐화 정공*.
|
|
319
|
+
|
|
320
|
+
다만 *value 가 외부에 표시 (OutputView)* 가 필요하면 *Score.toString() / .display()* 같은 *명시적 노출 메시지*가 자연. PR #136 (밀러 2단계) 의 *Score 캡슐화* 와 같은 결.
|
|
321
|
+
|
|
322
|
+
### 13. `Player.isFinal` 변수 미사용 의문 — 두루의 미세 진단
|
|
323
|
+
|
|
324
|
+
```kotlin
|
|
325
|
+
// PersonState.isFinal 사용처
|
|
326
|
+
fun isDrawable(): Boolean = !state.isFinal
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
두루 코멘트 (PersonState.kt:7 — 미해결): *"이제 isFinal 이라는 변수는 따로 사용이 안되고 있군요~"*
|
|
330
|
+
|
|
331
|
+
학생 자가 답변: *"Person에 있는 isDrawable()에서 사용하고 있습니다!"*
|
|
332
|
+
|
|
333
|
+
→ **isFinal = 상태가 종결 상태인지 boolean** — *isDrawable* 외 *추가 사용처 없음*. *isDrawable() = (state == HIT)* 와 동등 (4 상태 중 HIT만 not final). *enum 부가 속성이 단일 사용처* — *직접 검사*가 더 명료할 수도. 다만 *isFinal 표현이 더 의미 명시*면 OK. *코드 미세 다이어트* 여부의 트레이드오프.
|
|
334
|
+
|
|
335
|
+
### 14. `BetAmount.MIN_BET_AMOUNT = 0` — *최소 베팅 0원 허용?*
|
|
336
|
+
|
|
337
|
+
```kotlin
|
|
338
|
+
class BetAmount(val value: Int) {
|
|
339
|
+
init {
|
|
340
|
+
require(value >= MIN_BET_AMOUNT) { INVALID_BET_AMOUNT_MESSAGE }
|
|
341
|
+
}
|
|
342
|
+
...
|
|
343
|
+
companion object {
|
|
344
|
+
private const val MIN_BET_AMOUNT = 0
|
|
345
|
+
...
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
→ **`MIN_BET_AMOUNT = 0` 허용** — *0원 베팅이 도메인 의미 있는가*. *베팅 = 거는 금액*이면 *최소 1원 이상*. *0원 허용*은 *베팅 안 함*과 구분 불가. *MIN_BET_AMOUNT = 1* 또는 *최소 1000원*이 *카지노 룰 표준*. *도메인 invariant 미강제*.
|
|
351
|
+
|
|
352
|
+
### 15. `PersonCards` 분리/재합치 — 깊이 vs 책임의 균형 학습
|
|
353
|
+
|
|
354
|
+
학생 자가 답변 (PersonCards.kt): *"저도 고민했던 부분인데 기존 `Hand`는 카드만을 관리하기 위해 구현했으나, 리팩토링을 수행하면서 점수 객체가 포함되게 되었습니다. 이로 인해 `Hand`의 역할이 늘었났다고 판단해서 분리하고 싶었습니다. 책임을 분리한 후 각각의 모델은 다음과 같은 책임을 수행하게 되었습니다. - `PersonCards`는 단지 카드를 관리하는 객체로서, 카드 추가나 카드 목록을 조회하는 책임만 집니다. - `Hand`는 `PersonCards`가 제공하는 카드 목록을 사용하여 점수 계산과 같은 역할을 수행합니다. 이 구조로 변경하므로써 두 모델의 하나의 책임을 가지게 되었다고 생각합니다!"*
|
|
355
|
+
|
|
356
|
+
두루 후속: *"살짝 찜짬한 의문이 들었던 것은 아래와 같은 뎁스 형태로 구현이 되어 있어서 였습니다. `Player -> Hand -> PersonCards` 이렇게 객체간의 뎁스 형태로 되어 있다보면, 추후 요구사항이 변경되거나 뎁스 하단의 구조가 변경이 된다면, 자칫 잘못하면 전체 구조가 바뀔 수 있을 수 있겠다는 생각이 듭니다. 뎁스 구조에서 `점수 계산기 / 카드 관리`이렇게 분리를 해서 최 상단에서 계산을 해보도록 하는 것은 어떤가 라는 생각이 들었어요!"*
|
|
357
|
+
|
|
358
|
+
학생 자가 답변: *"다시 PersonCards를 제거하고 Hand에서 관리하도록 변경했습니다."*
|
|
359
|
+
|
|
360
|
+
→ **책임 분리 vs 객체 깊이 트레이드오프**. *Hand → PersonCards* 1 단계 더 깊어진 구조가 *변경 파급 ↑ + 디미터 위반 표면*. 학생이 *Score 객체 분리*로 *Hand의 점수 책임 이전* + *PersonCards 분리 불필요* 자가 결정. *책임 분리의 정공* = *수평 분리 (Hand + Score)* 가 *수직 분리 (Hand → PersonCards)* 보다 *디미터 안전*. 학습 가시화 모범.
|
|
361
|
+
|
|
362
|
+
### 16. `Person.cards()` 노출 — *Person 카드 외부 노출*
|
|
363
|
+
|
|
364
|
+
```kotlin
|
|
365
|
+
abstract class Person {
|
|
366
|
+
private val hand: Hand = Hand()
|
|
367
|
+
...
|
|
368
|
+
fun cards(): List<Card> = hand.cards
|
|
369
|
+
fun score(): Score = Score.create(hand.cards)
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
→ **`Person.cards()` 외부 노출 = *View 호환*** — *OutputView가 받은 카드 출력* 시 필요. 다만 *Person.cards()* 메시지 자체 가 *내부 hand 표현 노출*. *Person.score() / Person.isBlackjack() / Person.isBust()* 메시지가 *분기 미니멈*인 반면 *cards()* 는 *List 데이터 노출*. *View 가 카드 목록을 받음*은 *카드 자체가 노출 가능*. PR #133 (시아 2단계) 의 *EventListener.displayParticipantCards(name, cards)* 와 같은 결.
|
|
374
|
+
|
|
375
|
+
### 17. `GameResult` 가 *playerPayouts + dealerProfit* 두 필드 노출
|
|
376
|
+
|
|
377
|
+
```kotlin
|
|
378
|
+
class GameResult(dealer: Dealer, playerBetInfos: List<PlayerBetInfo>) {
|
|
379
|
+
val playerPayouts: Map<Player, Profit> = ...
|
|
380
|
+
val dealerProfit: Profit = ...
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
→ **`GameResult` 가 *플레이어 수익 Map + 딜러 수익* 외부 노출**. *데이터 클래스에 가까움* — *결과 보유 + 외부 조회*. *Tell-Don't-Ask 적용*은 *GameResult.displayTo(view)* 같은 *자기 출력 메시지*. 다만 *View 가 도메인 알면 안 됨* 이라면 *현재처럼 데이터만 노출 + Controller 변환* 도 합리. *데이터 노출 vs 메시지* 의 트레이드오프.
|
|
385
|
+
|
|
386
|
+
### 18. `runGame()` 의 흐름 = *dealCards → playPlayersTurns → playDealerTurns* 절차적
|
|
387
|
+
|
|
388
|
+
→ **`runGame()` 의 *3 단계 절차*가 *Controller 절차적 명령*과 정합 vs *도메인 객체의 흐름 자율성* 위배**. *Game.start() / Game.next() / Game.end()* 같은 *상태 머신*이 *도메인 객체 자율성*. 다만 *블랙잭 게임 = 라운드 단위 진행 + 외부 입력 의존*이라 *완전한 자율성 어려움*. *입력 콜백 + 도메인 자율 진행*이 PR #132 (환노) 같은 *고차함수 패턴*. PR #131 은 *명령형 절차*에 머묾.
|
|
389
|
+
|
|
390
|
+
### 19. 메서드 추출 + private 의 *Controller 의 함수 트리* 형성
|
|
391
|
+
|
|
392
|
+
```kotlin
|
|
393
|
+
fun play() { ... }
|
|
394
|
+
private fun prepareGame() { ... }
|
|
395
|
+
private fun runGame() { ... }
|
|
396
|
+
private fun finishGame() { ... }
|
|
397
|
+
private fun generatePlayers() { ... }
|
|
398
|
+
private fun dealCards() { ... }
|
|
399
|
+
private fun playPlayersTurns() { ... }
|
|
400
|
+
private fun playDealerTurns() { ... }
|
|
401
|
+
private fun showPersonFinalCardStatus() { ... }
|
|
402
|
+
private fun showGameResult() { ... }
|
|
403
|
+
private fun readPlayerNames() { ... }
|
|
404
|
+
private fun readPlayerBetAmount(name) { ... }
|
|
405
|
+
private fun playPlayerTurns(player) { ... }
|
|
406
|
+
private fun playPlayerTurn(player) { ... }
|
|
407
|
+
private fun isHit(name) { ... }
|
|
408
|
+
private fun <T> retryWhenException(...) { ... }
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
→ ***15+ 메서드 = 함수 분해 자체는 좋은 면 + Controller god-object 의 자기 표현***. *각 메서드 작아짐* (가독성 ↑). *책임 분배*는 *Controller가 모든 진행 흡수*. *Game 도메인 객체*가 *play(callback)* 같은 *콜백 노출 + 외부 입력 받음* 패턴이면 *Controller의 메서드 수 축소* 가능.
|
|
412
|
+
|
|
413
|
+
### 20. `Profit(profit)` — *Profit 값 객체 도입 좋은 면 + 정밀도 함정 잔존*
|
|
414
|
+
|
|
415
|
+
```kotlin
|
|
416
|
+
return Profit(profit) // profit = Double
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
→ **Profit 값 객체 도입** = *Double 의 도메인 의미 wrap*. *수익 = Profit (Double)* 명시. *BetAmount × multiplier = Profit* 직접 반환이면 *변환 단계 감소*. *현재 BetAmount × 1.5 = Double + Profit(Double)*. 두 단계.
|
|
420
|
+
|
|
421
|
+
또한 *Profit 가 Double 표현* — *BigDecimal 권고* (못한 점 §6) 의 연장. 학생이 *NEGATIVE_ZERO_PROFIT 우회*로 *Double 함정* 자가 인식.
|
|
422
|
+
|
|
423
|
+
## 리뷰어 의견 요지
|
|
424
|
+
|
|
425
|
+
- **뎁스 깊이 vs 책임 분리 — 수직 분리는 변경 파급 + 디미터 위험** — `Hand → PersonCards` 가 *깊이 분리*. *수평 분리 (Hand + Score)* 가 *디미터 안전 + 변경 격리*.
|
|
426
|
+
- **`BlackjackGame.play()` 하나로 게임 진행** — *Controller 가 도메인 진입점 한 줄* 호출. *현재 BlackJackGame이 InputView/OutputView 의존*이라 *완전 분리 미달*. *Controller가 콜백 주입*이 정공.
|
|
427
|
+
- **기본 생성자 지양 — 빠뜨림 위험** — *생성 시 자동완성 누락 위험*. *영향력이 큰 도메인 (가격 등)* 에서 *심각한 오류 가능성*. *명시적 인자 강제*.
|
|
428
|
+
- **`var state private set` < `protected var state` + `val gameState get()`** — *접근 통제 명료성*.
|
|
429
|
+
- **`isFinal` 단일 사용처** — *enum 부가 속성의 사용처 1개*면 *직접 검사 vs 추상화* 트레이드오프.
|
|
430
|
+
- **Score 객체 분리 = 점수 계산 응집** — *Hand 의 점수 책임 이전*. *수평 분리*.
|
|
431
|
+
- **DIP 자가 학습** — *콜백 → 인터페이스 주입* 으로 *의존성 역전 원칙 학습*.
|
|
432
|
+
|
|
433
|
+
## 대표 인용
|
|
434
|
+
|
|
435
|
+
**두루 (뎁스 vs 수평 분리, PersonCards.kt):**
|
|
436
|
+
> 살짝 찜짬한 의문이 들었던 것은 아래와 같은 뎁스 형태로 구현이 되어 있어서 였습니다.
|
|
437
|
+
> `Player -> Hand -> PersonCards`
|
|
438
|
+
> 이렇게 객체간의 뎁스 형태로 되어 있다보면, 추후 요구사항이 변경되거나 뎁스 하단의 구조가 변경이 된다면, 자칫 잘못하면 전체 구조가 바뀔 수 있을 수 있겠다는 생각이 듭니다.
|
|
439
|
+
> 뎁스 구조에서 `점수 계산기 / 카드 관리`이렇게 분리를 해서 최 상단에서 계산을 해보도록 하는 것은 어떤가 라는 생각이 들었어요!💪
|
|
440
|
+
|
|
441
|
+
**두루 (BlackjackGame.play() 한 줄, BlackJackController.kt:10):**
|
|
442
|
+
> 너무 잘해주셔서, 코멘트 내용이 많지 않을 것 같은데, 시간이 있는 만큼 콜백 형태로도 구현을 해봤으니, 함수의 파라미터로 받아서 처리를 하는 방법도 구현을 해보고 두개를 비교해보는 것 과정에서도 얻을 것이 있을 것 같다는 생각이 듭니다.
|
|
443
|
+
> Controller 에서 `BlackjackGame.play()` 하나로 블랙잭 게임을 할 수 있는 형태로요
|
|
444
|
+
|
|
445
|
+
**두루 (기본 생성자 지양, Player.kt):**
|
|
446
|
+
> 개인적으로 생성자에 기본 생성자가 있는건 지양을 하는편이긴 합니다.
|
|
447
|
+
> 얼마전에 회사 코드에서 기본생성자를 넣었다가 에러를 발생시켰던 일이 있어서 지양을 하게 되었던 것 같아요
|
|
448
|
+
> 기본 생성자로 되어 있다보면, 개발자가 자칫 잘못해서 생성시에 빠트리는 경우가 있습니다.
|
|
449
|
+
> 영향력이 적거나 없는 경우라면 괜찮겠지만, 예를 들어서 물건의 가격등이라면 아주 큰 문제가 발생할 수 있을 것 같네요🥲
|
|
450
|
+
|
|
451
|
+
**학생 자가 학습 (DIP 자가 학습, BlackJackGame.kt:14):**
|
|
452
|
+
> 콜백으로 인해 컨트롤러에 중복 코드가 제거되니 코드가 깔끔해진 것 같습니다!
|
|
453
|
+
> 추가로 의존성 역전 원칙(DIP) 개념에 대해 찾아볼 수 있는 기회가 된 것 같습니다!
|
|
454
|
+
|
|
455
|
+
**학생 자가 답변 (PersonCards → Hand 재합치, PersonCards.kt):**
|
|
456
|
+
> 책임을 분리한 후 각각의 모델은 다음과 같은 책임을 수행하게 되었습니다.
|
|
457
|
+
> - `PersonCards`는 단지 카드를 관리하는 객체로서, 카드 추가나 카드 목록을 조회하는 책임만 집니다.
|
|
458
|
+
> - `Hand`는 `PersonCards`가 제공하는 카드 목록을 사용하여 점수 계산과 같은 역할을 수행합니다.
|
|
459
|
+
> 이 구조로 변경하므로써 두 모델의 하나의 책임을 가지게 되었다고 생각합니다!
|
|
460
|
+
> ...
|
|
461
|
+
> 다시 PersonCards를 제거하고 Hand에서 관리하도록 변경했습니다.
|
|
462
|
+
|
|
463
|
+
**학생 자가 답변 (Player.changeToStay 의도, Person.kt):**
|
|
464
|
+
> Person을 상속받는 Player에서는 STAY 상태로의 전환을 허용해야 해서 해당 형태로 작성했습니다.
|
|
465
|
+
> 원래는 Person에서 상태를 변경하는 함수를 만들었지만,
|
|
466
|
+
> STAY 상태로 변경하는 기능은 Player에서만 필요했기 때문에 이런 구조가 된 것 같습니다.
|
|
467
|
+
|
|
468
|
+
## 얻은 교훈
|
|
469
|
+
|
|
470
|
+
1. ***수평 분리 (`Hand + Score`) > 수직 분리 (`Hand → PersonCards`)***. *수직 분리*는 *디미터 위반 + 변경 파급 ↑*. *수평 분리*는 *각 객체 독립 + 위임 메서드 한 단계*. 학생 자가 학습 모범 — *PersonCards 추출 → 두루 진단 → 다시 합침*. PR #128·#135·#125 와 같은 결의 책임 분리 균형.
|
|
471
|
+
|
|
472
|
+
2. ***`Ace 11 기본 + repeat(aceCount) { -10 if >21 }` 패턴은 Ace 다수 정확***. *while + 차감* 변형이지만 *aceCount 만큼만 차감 + 21 이하 도달 시 종료* 로 *Ace 3장+ 정확 처리*. PR #128·#135·#114·#125 와 같은 결의 Ace 정공.
|
|
473
|
+
|
|
474
|
+
3. ***DIP = 콜백 → 인터페이스 주입***. *Controller → BlackJackGame(InputView, OutputView)* 가 *도메인이 인터페이스 의존, 구현체 외부 주입* 패턴. *InputView/OutputView interface = 도메인의 추상화 의존*. *학생 자가 학습 모범*.
|
|
475
|
+
|
|
476
|
+
4. ***`lateinit var` 안티패턴 잔존 — 호출 순서 invariant***. `lateinit var deck/dealer/playerBetInfos` 가 *prepareGame 호출 전 접근 시 예외*. *play() 진입점 보장*되더라도 *재사용 시 invariant 깨질 위험*. *생성자 인자* 또는 *각 play() 마다 새 인스턴스*가 안전. PR #28·#92·#65·#10·#124·#152 와 같은 결.
|
|
477
|
+
|
|
478
|
+
5. ***`person is Dealer` 타입 검사 = Person 다형성 부재 신호***. *enum.from(person)* 의 *isDealer && score.isDealerStayScore() -> STAY* 분기는 *Dealer 자기 룰을 enum이 알고 있음*. *Person.stateAfterDraw(): PersonState* abstract method 다형성이 정공. PR #108·#133 (시아) 와 같은 결.
|
|
479
|
+
|
|
480
|
+
6. ***`protected var` + 자식 직접 변경 = invariant 부재***. *Player.changeToStay() { state = STAY }* 가 *자식이 부모 protected var 직접 변경* — *컴파일러가 잘못된 변경 차단 안 함*. *`var state private set` + protected method (`fun stayed()`)* 가 *접근 통제 강제*.
|
|
481
|
+
|
|
482
|
+
7. ***Score 객체 도입 = 점수 책임 응집***. *Hand 의 점수 계산을 Score 객체로 이전* 후 *Hand = 카드 관리 + Score = 점수 계산* 책임 분리. *Score private constructor + factory* 가 *불변 + 캡슐화* 정공.
|
|
483
|
+
|
|
484
|
+
8. ***`Score.isDealerStayScore()` = 딜러 룰 누수***. *Score 가 일반 점수* 인데 *Dealer 룰 (17 이상 STAY) 의식*. *Dealer.canDraw() = score.value <= 16* 같은 *Dealer 안에서 직접*이 자연. *룰 위치 분산*은 *룰 변경 시 여러 곳 수정 필요*.
|
|
485
|
+
|
|
486
|
+
9. ***BetAmount × multiplier = 원시 타입 vs 도메인 객체***. *BetAmount * 1.5 = Double + Profit(Double)* 가 *2단계 변환*. *BetAmount × multiplier: Profit* 직접 반환이 *도메인 어휘 + 변환 단계 감소*. PR #133 (시아 2단계) 의 *Money* 와 *반대 트레이드오프*.
|
|
487
|
+
|
|
488
|
+
10. ***Double `-0.0` 우회 = IEEE 754 함정***. *0.0 * -1 = -0.0* 가 *외부 표시 "-0"* 문제. *학생이 명시적 우회 검사*는 좋은 면. *근본 해결 = BigDecimal 또는 Long (cents)*. *금융 도메인 표준 어휘*.
|
|
489
|
+
|
|
490
|
+
11. ***Controller (BlackJackGame) god-object 변형***. 1단계 *BlackjackController god-object → 2단계 BlackJackGame 이름 변경 + 책임 흡수*. *play/prepareGame/runGame/finishGame/dealCards/playPlayersTurns/...* 15+ 메서드. *Controller = Game.play() 호출자* 분리가 정공.
|
|
491
|
+
|
|
492
|
+
12. ***기본 생성자 지양 — 영향력 큰 도메인 위험***. *물건 가격 등*에서 *생성 시 빠뜨림 위험*. *명시적 인자 강제*가 *컴파일러 보호*. *Kotlin default value* 는 *편의*이지만 *도메인 invariant 강제 부재*. 학생 자가 반영.
|
|
493
|
+
|
|
494
|
+
13. ***enum 부가 속성 (`isFinal`)은 단일 사용처 시 직접 검사와 트레이드오프***. *PersonState.isFinal = HIT 만 false* 일 때 *isDrawable() = state == HIT* 와 동등. *enum 멤버에 의미 묶기* vs *분기 직접 표현* 의 가독성 트레이드오프. *둘 다 합리*.
|
|
495
|
+
|
|
496
|
+
14. ***칭찬 위주 리뷰의 한계 — 학생 자가 학습 기회 풍부 + 깊은 진단 부족***. 두루의 *🥳/👍/💪* 다수 + *"고민해보면 좋을 주제"* 메타 질문 위주. *깊은 안티패턴 진단 < 자가 학습 기회 제공*. *학생 자가 답변 풍부*가 그 보상. PR #128·#135·#124·#152·#133·#136 의 *학생 자가 학습 모범*과 같은 결.
|
|
497
|
+
|
|
498
|
+
15. ***`var state` 직접 변경 vs `state = state.next()` 메시지***. *PersonState.from(this)* 가 *매 draw 마다 상태 재계산*. *State 객체 다형성 (PR #152·#136)* 은 *next() 메시지 + 다음 상태 객체 반환*. 두 표현의 트레이드오프 — *enum + from* 은 *간단 + 분기 변경 1곳*, *State 객체* 는 *상태별 행동 차이 표현*. *PR #131 은 행동 차이 작음 → enum 합리*.
|