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,573 @@
|
|
|
1
|
+
# PR #132 — [블랙잭 2단계] 환노 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@hwannow](https://github.com/hwannow)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-blackjack/pull/132
|
|
5
|
+
- **단계:** 2단계 (베팅 / 수익률 / 블랙잭 1.5배)
|
|
6
|
+
- **리뷰어:** @laco-dev (페로로)
|
|
7
|
+
- **라인 코멘트:** 24 스레드 / 42 코멘트 — *ActionType 위치 (View vs Controller vs Domain)* 깊은 토론 + 학생 자가 답변 풍부
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Participants` abstract class + Player/Dealer 다형성 (`canHit`, `getInitCard`, `compareScores`)** — 1단계 *open class Player/Dealer : Player* 의 모순을 *Participants 추상화*로 완전 해소 + *abstract method 3개* 로 *진짜 다형성*. `Player.canHit() = !isBust()`, `Dealer.canHit() = sumCardNumber <= 16` 로 *룰 차이 = 메서드 구현 차이*. `Player.getInitCard() = cards.take(2)`, `Dealer.getInitCard() = cards.take(1)` 로 **블랙잭 공개 규칙 = 다형성 메시지** — *플레이어 2장 공개 / 딜러 1장 공개*. 1단계 페로로 *"최초에 딜러는 1장, 플레이어는 2장 공개 규칙은 명확한 비즈니스 로직 → 추상화 관점에서 접근"* 의 완전 반영.
|
|
12
|
+
- **`Participants.compareScores(participant): GameResult` 메시지 — Tell-Don't-Ask** — `Player.compareScores(dealer)` 가 *플레이어가 자기 입장 결과를 알려줌*. *블랙잭 / 버스트 / 점수 비교* 4 분기 + *fallback compareNumber*. 1단계 *`GameResult.of(score, score)` 정적 호출* (페로로 진단) 의 완전한 후속 반영.
|
|
13
|
+
- **`GameResult` enum + `earningRate: Double`** — *WIN(1.0) / LOSE(-1.0) / DRAW(0.0) / BlackjackWin(1.5)* 4 멤버 + *수익률 enum 부가 속성*. 페로로의 *"승패여부, 블랙잭 상관 없이 배율(earningRate)이라는 개념을 넘겨주는 방식은 어떨까요? > 블랙잭은 1.5배, 버스트는 -1배"* 진단의 완전 반영. *enum 멤버 = 결과 + 배율*이 한 자리에 응집.
|
|
14
|
+
- **`Proceed` value class** — `@JvmInline value class Proceed(val amount: Int)` 로 *수익 = 도메인 타입 wrap*. 페로로의 *"Int값이 뭔지 사용하는 사람이 알 수 있나요? 자연스럽게 수익률이라고 했지만 이게 승리 수일수도 있고 아무도 모르는 거지 않나요?"* 진단의 후속 반영. *value class*로 *Int 박싱 없이 타입 안전*.
|
|
15
|
+
- **`Hand.isBlackjack()` 룰 정확 — `_cards.size == 2 && getSumNumber() == BUST_STANDARD`** — *2장 + 21*만 진짜 블랙잭. PR #124·#128·#135·#114·#125 와 같은 결의 블랙잭 룰 정확성.
|
|
16
|
+
- **`BlackjackResult` 책임 분리 — `calculatePlayersProceed` + `calculateDealerProceed`** — 페로로의 *"`Map<X, X>` 타입을 지양하라는 말이었습니다. 만약, 이전과 같이 승패 여부도 같이 반환해야 된다면 이렇게 만들건지? 되묻고 싶어요. `Map<Player, Pair<GameResult, Proceed>>` 나아가서 사용해야 하는 타입이 4개, 5개 넘어가면? `Quadruple<A, B, C, D>`?"* 진단 + *학생 후속 반영*. *결과 객체 `BlackjackResult`* + *ProceedStatus 리스트*로 *명시적 도메인 표현*.
|
|
17
|
+
- **`PlayerGroup` 일급 컬렉션 + 카드 부족 회피 검증** — `require(players.size <= MAX_PLAYERS_SIZE)` 로 *최대 7명 검증*. 페로로의 *"한편.... 한명의 참가자는 몰래 조커 카드를 들고 게임을 시작하게 되는데"* 마이너 우려에 *카드 부족 회피용 명시적 검증*. 학생 자가 답변: *"카드가 모자라지 않도록 PlayerGroup 에서 참여자 인원수를 제한해 줬습니다!"*.
|
|
18
|
+
- **`Blackjack` 도메인 서비스 객체 + `Controller → blackjack.endGame(betStatus)` 메시지** — 1단계 *Controller god-object* 진단의 부분 후속 반영. *`Blackjack` 이 deck + playerGroup 보유 + 게임 진행 책임*. *Controller가 직접 Player 접근* 대신 *Blackjack 메시지* 활용.
|
|
19
|
+
- **`Hand` 가 자기 점수/Bust/Blackjack 판단** — *Tell-Don't-Ask* — `Hand.getSumNumber()`, `Hand.isBust()`, `Hand.isBlackjack()` 자기 메시지. 1단계 *Player.getScore()* (Cards 책임 누수) 진단의 완전 반영.
|
|
20
|
+
- **`ActionType` enum → Controller 변환 → InputView 직접 반환 자가 학습 후속 반영** — 학생이 초기에 *"View는 멍청해야 한다 → ActionType 변환은 Controller 책임"* 주장 → 페로로의 *InputView interface 다형성 예시 (ConsoleInputView / GraphicsInputView)* 로 *"View가 사용자 입력 = 사용자 의도 표현"* 자가 학습 + 후속 반영 (커밋 `072010d`). **학생 자가 답변 변동의 학습 모범 사례**.
|
|
21
|
+
- **테스트 픽스처 + `Player.copy(hand = Hand(...))` 같은 손패 주입 후속 반영** — 페로로의 *"플레이어가 카드를 받을 수 있는 방법이 receiveCard() 밖에 없다보니 만약 카드를 10장 이런식으로 받는다고 가정하면 테스트가 엄청 번거로워지기도 해요. 플레이어의 생성자로 Hand를 받을 수 있다면 달라질까요?"* 진단에 학생이 *deck.spreadCard(INITIAL_CARD_COUNT)* 로 *list 형태 카드 분배* 자가 반영. 학생 자가 표현: *"기존의 `repeat(2)`으로 처리해 주던 초기 카드 분배 로직도 `player.receiveCard(deck.spreadCard(INITIAL_CARD_COUNT))` 위처럼 더 명확하게 바꿀 수 있었습니다!"*
|
|
22
|
+
|
|
23
|
+
## 못한 점 (설계 관점)
|
|
24
|
+
|
|
25
|
+
### 1. `Hand.operator plus(cards: List<Card>)` = `Unit` + 가변 변경 — *연산자 오버로딩 안티패턴*
|
|
26
|
+
|
|
27
|
+
```kotlin
|
|
28
|
+
class Hand(cards: MutableList<Card>) {
|
|
29
|
+
private val _cards: MutableList<Card> = cards
|
|
30
|
+
val cards: List<Card> get() = _cards.deepCopy()
|
|
31
|
+
...
|
|
32
|
+
operator fun plus(cards: List<Card>) {
|
|
33
|
+
_cards.addAll(cards) // ⚠ Unit 반환 + 자기 변경
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
→ **`hand + cards` = Unit + 자기 가변 변경** — PR #133 (시아 2단계) 의 *Money.plus(money) Unit + 가변* 과 같은 결. *Kotlin operator plus 표준 = 새 객체 반환*. *자기 변경* 은 *`+=` (operator plusAssign)*. *`a + b` 표현식 의미 위반*.
|
|
39
|
+
|
|
40
|
+
사용처:
|
|
41
|
+
```kotlin
|
|
42
|
+
fun receiveCard(cards: List<Card>) {
|
|
43
|
+
hand + cards // ⚠ 의미 모호 — 결과 무시?
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
*`hand + cards`* 한 줄이 *NoOp* 으로 읽힘 — *Hand.plus 가변 구현* 알아야 의미 파악. *`hand.add(cards)` 같은 명시적 동사* 가 자연. *연산자 오버로딩 잘못된 사용*.
|
|
48
|
+
|
|
49
|
+
### 2. `Hand.cards.deepCopy()` — *불변 Card 에 대한 무용 deepCopy*
|
|
50
|
+
|
|
51
|
+
```kotlin
|
|
52
|
+
class Hand(cards: MutableList<Card>) {
|
|
53
|
+
private val _cards: MutableList<Card> = cards
|
|
54
|
+
val cards: List<Card> get() = _cards.deepCopy()
|
|
55
|
+
...
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private fun MutableList<Card>.deepCopy(): List<Card> = map { it.copy() }.toList()
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
→ **매 `cards` 호출마다 *N장 카드 모두 새 객체***. PR #124 (모찌 1단계) 의 `Card.copy()` 딥카피 강박과 같은 결. *Card가 불변 객체*면 *참조 노출 안전*. *deepCopy 비용 + invariant 흉내*. *`_cards.toList()`* 면 *immutable view + 사본 1회*.
|
|
62
|
+
|
|
63
|
+
또한 `compareScores`, `sumCardNumber`, `cardDeck` 모두 `cards` getter 호출 → *매 호출마다 N장 copy*. 한 비교 사이클에 *수십~수백 copy*. *성능 + 무용한 방어*.
|
|
64
|
+
|
|
65
|
+
### 3. `Participants.cardDeck` naming 모순 — *Hand.cards 인데 *cardDeck**
|
|
66
|
+
|
|
67
|
+
```kotlin
|
|
68
|
+
abstract class Participants() {
|
|
69
|
+
abstract val name: String
|
|
70
|
+
abstract val hand: Hand
|
|
71
|
+
|
|
72
|
+
val sumCardNumber: Int get() = hand.getSumNumber()
|
|
73
|
+
val cardDeck get() = hand.cards.toList() // ⚠ "Deck"? 사실은 hand
|
|
74
|
+
...
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
→ **`cardDeck` = *카드 덱***. *Deck = 셔플된 52장 카드 더미*. *Hand.cards = 참가자 손패*. *이름 모순*. *`hand` 또는 `cards`* 가 자연. *Deck* 어휘는 *전체 카드 풀*에 한정.
|
|
79
|
+
|
|
80
|
+
사용처:
|
|
81
|
+
```kotlin
|
|
82
|
+
// Blackjack
|
|
83
|
+
fun getParticipantCardSize(participant: Participants): Int {
|
|
84
|
+
return participant.cardDeck.size
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
→ *Participants 가 자기 cardDeck 노출 → Blackjack 이 size 추출* = *Demeter 위반 + naming 모순* 동시. *`Participants.handSize: Int`* 메시지가 자연.
|
|
89
|
+
|
|
90
|
+
### 4. `Blackjack.canHit(participant)` = `participant.canHit()` 단순 위임 — *Blackjack 역할 모호*
|
|
91
|
+
|
|
92
|
+
```kotlin
|
|
93
|
+
class Blackjack(
|
|
94
|
+
private val deck: PlayingCard,
|
|
95
|
+
val playerGroup: PlayerGroup,
|
|
96
|
+
) {
|
|
97
|
+
...
|
|
98
|
+
fun canHit(participant: Participants): Boolean {
|
|
99
|
+
return participant.canHit()
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
fun getParticipantCardSize(participant: Participants): Int {
|
|
103
|
+
return participant.cardDeck.size
|
|
104
|
+
}
|
|
105
|
+
...
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
→ **Blackjack 의 메서드가 *Participants 메시지 단순 위임***. *Blackjack 자기 책임 = ?* *단순 위임 wrapper* 는 *Demeter 우회 흉내* — *호출자가 Blackjack 통해 Participants 호출*. *진짜 Blackjack 책임 = deck 관리 + 게임 룰 정책 결정* 이면 *canHit 검사는 Participants 자율*. *Blackjack 통과 의의 부재*.
|
|
110
|
+
|
|
111
|
+
페로로 (BlackjackController.kt — 미해결 + 토론): *"아직은 블랙잭외에도 컨트롤러가 플레이어에 직접 접근하는 등 블랙잭 혼자서는 게임이 불가능한 상태인데요. 지금까지 해온 것 처럼 블랙잭에게 필요한 메시지를 전달하도록 해볼까요? `player.canHit() → blackjack.canHit(player)`"*
|
|
112
|
+
|
|
113
|
+
→ **페로로 의도 = Blackjack 객체가 단일 진입점**. *Controller → Player 직접 의존 제거*. *현재 Blackjack.canHit(participant) → participant.canHit()* 위임으로 *형태는 통과*. 다만 *Blackjack 책임이 위임 wrapper 만이면 클래스의 의의 부재*. *진짜 진입점 = `blackjack.playRound(callback)` 같은 한 줄*. PR #131 (다이스) 의 *BlackJackGame.play()* 와 같은 결의 콜백 패턴.
|
|
114
|
+
|
|
115
|
+
학생 자가 답변 (시도 후 좌절): *"위 피드백을 보고 `view의 입출력 함수`들을 블랙잭 메소드의 인자로 넘겨 ( 고차함수 사용 ) 게임을 진행하는 전체 로직을 `Blackjack`으로 옮겨 주려 했습니다... 🥲 그러다 보니 `depth` 가 너무 깊어져서 테스트가 불가능한 상황이 발생하더군요 🤔. `플레이어가 (버스트가 아닌 경우) 원할 때까지 카드를 받는다` <- 이 로직은 블랙잭에 있어야 한다고 생각했는데, 중간중간 입출력이 필요하기 때문에 블랙잭 도메인에서 처리가 불가능합니다."*
|
|
116
|
+
|
|
117
|
+
페로로 답변: *"협력을 위한 인터페이스보다 고차함수가 먼저 나온것에 대해 우선.... 놀라봅니다! 말씀하신 대로 콜백 개념 없이는 블랙잭 게임 함수 하나로 모든 게임 진행을 하는 것은 어렵습니다. 그렇기에 컨트롤러의 게임 진행 로직을 최대한 간결하게 하고 인터페이스 다운 느낌을 주도록 챙겨봅시다"*
|
|
118
|
+
|
|
119
|
+
→ **고차함수 vs 인터페이스 = 트레이드오프 자가 학습**. *고차함수 = 한번에 콜백 주입*, *인터페이스 = 명시적 의존 + 다양한 구현*. *둘 다 정공*. *학생이 고차함수 시도 → 깊이 문제 → 콜백 부분 분리* 흐름이 학습 가시화 모범.
|
|
120
|
+
|
|
121
|
+
### 5. `Participants.compareScores` — *상대 입장 결과 처리 비대칭 + 마이너 룰 오류*
|
|
122
|
+
|
|
123
|
+
```kotlin
|
|
124
|
+
fun compareScores(participant: Participants): GameResult =
|
|
125
|
+
when {
|
|
126
|
+
hand.isBust() -> GameResult.Lose
|
|
127
|
+
!participant.hand.isBlackjack() && hand.isBlackjack() -> GameResult.BlackjackWin
|
|
128
|
+
participant.hand.isBlackjack() && !hand.isBlackjack() -> GameResult.Lose
|
|
129
|
+
participant.hand.isBust() -> GameResult.Win
|
|
130
|
+
else -> compareNumber(sumCardNumber, participant.sumCardNumber)
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
페로로 (Participants.kt:21 — 미해결): *"음 마이너하지만, 본인이 블랙잭이어도 상대가 버스트면 나는 블랙잭이 아닌 그냥 이긴게 되겠네요."*
|
|
135
|
+
|
|
136
|
+
학생 자가 답변 (커밋 `d6cab2a`): 후속 반영.
|
|
137
|
+
|
|
138
|
+
→ **분기 순서가 *블랙잭 vs 버스트* 우선순위 의미 결정**:
|
|
139
|
+
|
|
140
|
+
1. `hand.isBust() -> Lose` — *내가 Bust면 무조건 Lose* (정확)
|
|
141
|
+
2. *!상대 블랙잭 && 내가 블랙잭 → BlackjackWin* — *상대가 일반 패 + 내가 블랙잭*
|
|
142
|
+
3. *상대 블랙잭 && !내 블랙잭 → Lose*
|
|
143
|
+
4. *상대 Bust → Win*
|
|
144
|
+
5. *fallback: 점수 비교*
|
|
145
|
+
|
|
146
|
+
페로로 진단: *"본인이 블랙잭 + 상대가 버스트"* 케이스. *조건 2 의 *!참가자 블랙잭** 검사가 *상대 Bust 도 !블랙잭이라 통과* → *BlackjackWin* 반환. 다만 *블랙잭 룰 = "상대 Bust 시 모든 살아남은 플레이어 Win"* 이지 *BlackjackWin 1.5배는 아님*. *내 블랙잭은 그저 Win (1.0배)*. *현재 코드 = BlackjackWin (1.5배)* — *룰 위반*.
|
|
147
|
+
|
|
148
|
+
학생 후속 반영 (커밋 `d6cab2a`) 으로 *조건 순서 변경* 또는 *조건 4 (상대 Bust → Win) 를 상위로* 등 수정.
|
|
149
|
+
|
|
150
|
+
### 6. `Hand` 의 `Ace 단일 +10` 패턴 — *Ace 2장 이상 처리 불충분 신호*
|
|
151
|
+
|
|
152
|
+
```kotlin
|
|
153
|
+
fun getSumNumber(): Int {
|
|
154
|
+
var sum = cards.sumOf { it.cardNumber.number }
|
|
155
|
+
val haveAce: Boolean = Denomination.Ace in cards.map { it.cardNumber }
|
|
156
|
+
|
|
157
|
+
if (haveAce && sum + Denomination.BONUS_SCORE <= BUST_STANDARD) {
|
|
158
|
+
sum += Denomination.BONUS_SCORE
|
|
159
|
+
}
|
|
160
|
+
return sum
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
→ **Ace 보너스 +10 한 번만 적용** — *Ace 2장 (A♠ A♥)* 케이스. *base sum = 2 (1+1)*, *+10 if ≤21* → *12*. 정확 (둘 다 11 = 22 > 21 이므로 한 Ace만 11 + 나머지는 1 → 12).
|
|
165
|
+
|
|
166
|
+
*Ace 3장* 케이스: *base = 3*, *+10 = 13*. 정확 (한 Ace만 11). *Ace 4장 + 17* 같은 *극단 케이스도 정확*. PR #128·#135·#114·#125·#131 와 같은 결의 Ace 정공 패턴 (Ace 1 기본 + 단일 +10).
|
|
167
|
+
|
|
168
|
+
다만 *cards.map { it.cardNumber }* 가 *List 새 생성* — 매 호출 비용. *cards.any { it.cardNumber == Denomination.Ace }* 가 *short-circuit*. 미세 비효율.
|
|
169
|
+
|
|
170
|
+
### 7. `BetAmount.times(dividend: Double): Int` — *Int 반환 = 도메인 타입 미보존*
|
|
171
|
+
|
|
172
|
+
```kotlin
|
|
173
|
+
class BetAmount(private val money: Int) {
|
|
174
|
+
init { require(money >= 0) { ... } }
|
|
175
|
+
|
|
176
|
+
operator fun times(dividend: Double): Int {
|
|
177
|
+
return (money * dividend).toInt()
|
|
178
|
+
}
|
|
179
|
+
...
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// 사용처
|
|
183
|
+
ProceedStatus(betInfo.player, Proceed(betInfo.betAmount * result.earningRate))
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
→ **`BetAmount × Double = Int`** + *외부에서 `Proceed(int)` wrap*. *BetAmount × earningRate = Proceed* 직접 반환이면 *변환 단계 감소 + 도메인 타입 유지*. PR #131 (다이스) / #133 (시아) 와 같은 결.
|
|
187
|
+
|
|
188
|
+
또한 *`(money * dividend).toInt()` 정밀도 손실* — *`1000 * 1.5 = 1500.0 → 1500`* OK. *`1000 * 0.9999 = 999.9 → 999`* (1원 손실). *금융 도메인 정밀도 함정*.
|
|
189
|
+
|
|
190
|
+
### 8. `BetAmount.MINIMUM_BET_AMOUNT = 0` — *0원 베팅 허용*
|
|
191
|
+
|
|
192
|
+
```kotlin
|
|
193
|
+
companion object {
|
|
194
|
+
private const val MINIMUM_BET_AMOUNT: Int = 0
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
→ PR #131 와 같은 결. *0원 베팅 = 베팅 안 함* 과 구분 불가. *카지노 도메인 = 최소 1원 이상*.
|
|
199
|
+
|
|
200
|
+
### 9. `BetStatus` + `ProceedStatus` 가 *Pair 우회 클래스*
|
|
201
|
+
|
|
202
|
+
```kotlin
|
|
203
|
+
class BetStatus(val player: Player, val betAmount: BetAmount)
|
|
204
|
+
class ProceedStatus(val participant: Participants, val proceed: Proceed)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
페로로 (마지막 미해결 코멘트): *"한편으로는 인스턴스 변수 3개에 너무 얽매인 것은 아닐까 싶네요. 제약사항이기는 했지만 무조건 이것을 지키기 위해서 너무 손해볼게 많아지기도 하니까요. 굳이 만든다면 이런 느낌이 되었으려나요? `class BlackjackResult(val dealerResult: DealerResult, val playerResults: List<PlayerResult>); class PlayerResult(val player: Player, val profit: Profit); class DealerResult(val dealer: Dealer, val profit: Profit)`"*
|
|
208
|
+
|
|
209
|
+
→ **`BetStatus` + `ProceedStatus` 두 클래스 = *Player와 (BetAmount/Proceed) 의 묶음**. *Pair<Player, BetAmount>* / *Pair<Participants, Proceed>* 회피용. *3 변수 제약 = 연습 도구 (PR #133 말리빈 진단)* 의 부산물.
|
|
210
|
+
|
|
211
|
+
또한 *Player 와 Participants* 의 비대칭 — *BetStatus 는 Player만 (베팅은 Player 만 함)*, *ProceedStatus 는 Participants 일반 (딜러도 수익 받음)*. *타입 정확*하나 *클래스 두 개로 표현*. *PlayerResult / DealerResult 처럼 *분리된 의미 클래스* 가 *도메인 어휘 더 명료*.
|
|
212
|
+
|
|
213
|
+
### 10. `data class Player(name: String)` vs `class Dealer(name: String)` — *비대칭*
|
|
214
|
+
|
|
215
|
+
```kotlin
|
|
216
|
+
data class Player(override val name: String) : Participants() {
|
|
217
|
+
override val hand: Hand = Hand(mutableListOf())
|
|
218
|
+
...
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
class Dealer(override val name: String = DEALER_NAME) : Participants() {
|
|
222
|
+
override val hand: Hand = Hand(mutableListOf())
|
|
223
|
+
...
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
→ **`Player` 는 `data class` + `Dealer` 는 `class`** — *equals/hashCode/copy 자동* vs *기본*. *Player 동등성 (이름 같으면 같은 사람)* 의도면 *equals override*. *Dealer 도 동등성 의미*면 일관성 위해 *data class*. *현재 비대칭은 의도 부재*.
|
|
228
|
+
|
|
229
|
+
또한 `Participants` `abstract` 인데 *`hand` override val = Hand(mutableListOf())* 둘 다 동일 — *Participants 안에 디폴트 hand 초기화* 도 가능. *반복 표현*.
|
|
230
|
+
|
|
231
|
+
### 11. `PlayerGroup` `dealer = participants.filterIsInstance<Dealer>().first()` — *암묵 invariant + 안티 다형성*
|
|
232
|
+
|
|
233
|
+
```kotlin
|
|
234
|
+
class PlayerGroup(val participants: List<Participants>) {
|
|
235
|
+
val dealer = participants.filterIsInstance<Dealer>().first()
|
|
236
|
+
val players = participants.filterIsInstance<Player>()
|
|
237
|
+
...
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
→ **`first()` = *딜러가 무조건 있다는 암묵 invariant***. *participants 에 Dealer 없으면 `NoSuchElementException`*. *참여자에 Dealer 가 있다*는 *명시적 invariant 강제*는 *생성자 인자 분리*:
|
|
242
|
+
|
|
243
|
+
```kotlin
|
|
244
|
+
class PlayerGroup(val dealer: Dealer, val players: List<Player>) {
|
|
245
|
+
val participants: List<Participants> = listOf(dealer) + players
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
이 *컴파일 타임 보장 + 의도 명시*. *현재 `filterIsInstance<Dealer>().first()`* 는 *런타임 발견 + 예외 가능성*.
|
|
250
|
+
|
|
251
|
+
또한 *Player 중복 검사 (`require(players.toSet().size == players.size)`)* 는 *Player data class 의 equals 기반*. *동등성 의미 = 이름* 인지 *전체 속성* 인지 *암묵*. *이름만 동등*이면 *`players.map { it.name }.toSet().size`* 가 명시적.
|
|
252
|
+
|
|
253
|
+
### 12. `Blackjack.initGame` 가 *모든 참여자 2장 분배* — *Dealer 1장 / Player 2장 룰은 getInitCard 로 *공개 단계*에서만 분기*
|
|
254
|
+
|
|
255
|
+
```kotlin
|
|
256
|
+
fun initGame() {
|
|
257
|
+
playerGroup.participants.forEach { player ->
|
|
258
|
+
hitAction(player, INITIAL_CARD_COUNT) // ⚠ 모든 참여자 2장
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
→ **`initGame` = *Dealer/Player 모두 2장 받음***. *공개 룰* 은 *`Player.getInitCard().take(2)` / `Dealer.getInitCard().take(1)`* 로 *View 표시 시 분리*. *룰 분리 = 분배 룰 (모두 2장) + 공개 룰 (Dealer 1 / Player 2)*.
|
|
264
|
+
|
|
265
|
+
이 분리 자체는 *카지노 도메인 정합* — *Dealer 도 2장 받지만 1장만 공개*. *현재 모든 참여자 2장 분배 + 공개 1/2 분리*는 *룰 표현 정확*. 1단계 *카드 분배가 곧 공개* 의 안티패턴 해소.
|
|
266
|
+
|
|
267
|
+
다만 `playerGroup.participants.forEach` 가 *Dealer 포함 모든 참가자* — *Dealer 도 Hit 메시지로 카드 받음*. *Participants 다형성* 이 *Player 와 Dealer 의 분배 차이 없음* 의 정합.
|
|
268
|
+
|
|
269
|
+
### 13. `BlackjackResult.calculateDealerProceed` — *Player Proceed 합 × -1*
|
|
270
|
+
|
|
271
|
+
```kotlin
|
|
272
|
+
fun calculateDealerProceed(playerProceedStatus: List<ProceedStatus>): ProceedStatus {
|
|
273
|
+
val playersProceedSum = playerProceedStatus.sumOf { it.proceed.amount }
|
|
274
|
+
val dealerProceed = Proceed(playersProceedSum * -1)
|
|
275
|
+
return ProceedStatus(dealer, dealerProceed)
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
→ **딜러 수익 = 플레이어 수익 합 × -1** — *총합 0 게임* 룰. *Proceed.amount Int* 라 *부호 있는 0 함정 없음* (PR #131 다이스 *NEGATIVE_ZERO_PROFIT* 우회 불필요). *Int 표현의 단순성 이점*. 다만 *cents 단위 vs 원화 단위 + 1.5배 곱셈 정밀도* 는 미해결.
|
|
280
|
+
|
|
281
|
+
또한 `calculateDealerProceed` 가 *플레이어 결과를 인자로 받음* = *순차적 의존*. *BlackjackResult 한 객체 안에서 두 단계 계산*. *블랙잭 비즈니스 로직 = 플레이어 결과가 딜러 결과의 입력* 이라는 *시간 흐름 응집*.
|
|
282
|
+
|
|
283
|
+
### 14. `ActionType` 위치 토론 — *View vs Controller vs Domain*
|
|
284
|
+
|
|
285
|
+
학생 초기: *"저는 기존에 `View는 최대한 멍청해야 한다`라고 생각했습니다. 따라서 View가 `y -> Hit, n -> Stay` 의 관계를 몰라야 한다고 생각합니다. View의 역할은 `형식에 맞는 값을 받는다`로 끝나야 하지 않을까요? 형식에 맞는 값을 받아서 그것을 행동으로 변환시키는 건 controller 혹은 domain의 역할이라고 생각합니다 !!"*
|
|
286
|
+
|
|
287
|
+
페로로 (BlackjackController.kt 미해결 + 추가 다중 코멘트):
|
|
288
|
+
> 저는 View가 단순히 raw 데이터를 받는 것이 아닌 사용자의 입력을 표현하는 역할을 한다고 생각합니다.
|
|
289
|
+
> 컨트롤러가 UI와 강하게 결합하면 이후 View의 자유도가 떨어지며 어떤 View를 사용하더라도 무조건 "y" 아니면 "n"을 반환해야만 합니다.
|
|
290
|
+
>
|
|
291
|
+
> 만약, InputView를 여러개로 바꿔가면서 실행해본다고 가정해보세요.
|
|
292
|
+
> ```kotlin
|
|
293
|
+
> interface InputView { fun getRawActionType(): String }
|
|
294
|
+
> class ConsoleInputView: InputView { override fun getRawActionType() = readln() }
|
|
295
|
+
> class GraphicsInputView: InputView {
|
|
296
|
+
> override fun getActionType() = runBlocking {
|
|
297
|
+
> 유저 입력을 받을때까지 쓰레드를 블로킹한다
|
|
298
|
+
> If (InputSource is YesButton) return "Y" else if (InputSource is NoButton) return "N" else throw
|
|
299
|
+
> }
|
|
300
|
+
> }
|
|
301
|
+
> ```
|
|
302
|
+
> 이제 또 다른 InputView를 만든다고 생각해보세요.
|
|
303
|
+
> InputView 객체에게 사용자의 의도(ActionType)를 달라고 메시지를 요청했을 뿐인데 강제로 "Y" "N"이 아니면 터지는 프로그램이 좋은 프로그램인가요..?
|
|
304
|
+
|
|
305
|
+
학생 자가 학습 답변 (커밋 `072010d`): *"`사용자의 입력을 표현하는 역할` 이 부분이 마음에 와닿네요...! `안드로이드 플랫폼에서 버튼을 클릭해도 컨트롤러에게 String 타입으로 반환해 줄 것인가?` 에 대해 고민해 보니 제 논리가 잘못됐던 것 같네요! `사용자가 하려는 행동을 표현해 준다` 이렇게 InputView의 행동을 정의하는 것이 더 자연스러운 것 같습니다."*
|
|
306
|
+
|
|
307
|
+
→ **View 의 역할 = 사용자 의도 표현 (ActionType 반환), raw String 반환 X**. *학생의 "View는 멍청해야"* 사고가 *콘솔 UI 가정*에서 옴. *Multi-platform UI* (Console / Graphics / Mobile) 에선 *각 View가 자기 입력 방식 → ActionType 변환* 이 *Controller의 변환 일관성 vs View 다형성* 의 트레이드오프. **페로로의 GraphicsInputView 예시가 결정적**.
|
|
308
|
+
|
|
309
|
+
페로로 추가 진단: *"이미 InputView에서 "Y" "N"을 처리하고 있는데 컨트롤러에 중복해서 만들어지면서 한쪽이 바뀌면 한쪽은 그대로 고장납니다"* — *컨트롤러에서 또 변환하면 변환 로직 중복*. **MCP 룰 후보 — `view-as-raw-input-converter`**. PR #133 (시아 2단계) 의 *EventListener/EventProvider* 와 같은 결.
|
|
310
|
+
|
|
311
|
+
### 15. `BlackjackResult.calculatePlayersProceed` — *static-like 정적 호출 잔존*
|
|
312
|
+
|
|
313
|
+
```kotlin
|
|
314
|
+
class BlackjackResult(private val dealer: Dealer) {
|
|
315
|
+
fun calculatePlayersProceed(betStatus: List<BetStatus>): List<ProceedStatus> {
|
|
316
|
+
return betStatus.map { betInfo ->
|
|
317
|
+
val result = betInfo.player.compareScores(dealer) // Player 메시지 ✓
|
|
318
|
+
ProceedStatus(betInfo.player, Proceed(betInfo.betAmount * result.earningRate))
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
→ **`Player.compareScores(dealer)` 메시지 사용 + Proceed(...) wrap 한 줄**. 이건 OK — *Player 자기 결과 알림*. *BlackjackResult 의 책임 = 결과 컬렉션 변환*. 책임 응집.
|
|
325
|
+
|
|
326
|
+
다만 *Proceed 계산 (`betAmount * earningRate`) 위치*가 *BlackjackResult 내부*. *Player.calculateProceed(dealer, betAmount)* 메시지가 *Tell-Don't-Ask* 더 적용. *현재는 BlackjackResult가 외부 계산*. 트레이드오프 — *결과 책임이 Player 분산 vs 결과 객체 응집*.
|
|
327
|
+
|
|
328
|
+
### 16. `Hand` 의 `cards: MutableList<Card>` 생성자 인자 — *외부 가변 참조*
|
|
329
|
+
|
|
330
|
+
```kotlin
|
|
331
|
+
class Hand(cards: MutableList<Card>) {
|
|
332
|
+
private val _cards: MutableList<Card> = cards
|
|
333
|
+
...
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
→ **`MutableList` 외부 인자 → `_cards` 가 동일 참조** — *외부 List 변경 = Hand 내부 변경*. *deepCopy 매 cards getter*는 *읽기 방어*. *쓰기 방어 0* — *외부 list 가 hand 의 _cards 변경 가능*.
|
|
338
|
+
|
|
339
|
+
`Hand(cards.toMutableList())` 처럼 *생성자에서 사본* 이 정공. 또는 *`Hand(cards: List<Card>)` immutable 인자 + 내부에서 mutable list 생성*. *PR #108·#133 (시아) 의 lotto empty-object-external-fill* 변형.
|
|
340
|
+
|
|
341
|
+
또한 *Player.hand: Hand = Hand(mutableListOf())* 가 *빈 list 로 시작 → receiveCard 로 채움* — 1단계 *Hand 초기값 미주입* 안티패턴 일부 잔존. *초기 카드 받기 전 hand 가 빈 상태로 존재*.
|
|
342
|
+
|
|
343
|
+
### 17. `Hand.cards: List<Card> get() = _cards.deepCopy()` — *List 매 호출 새 생성*
|
|
344
|
+
|
|
345
|
+
```kotlin
|
|
346
|
+
val cards: List<Card>
|
|
347
|
+
get() = _cards.deepCopy()
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
→ **매 `cards` getter 호출마다 *deepCopy + toList* 2회 사본 + N장 Card.copy()**. PR #124 와 같은 결의 강박. *cards.size*, *cards.sumOf*, *cards.map* 등 각 호출이 *N copies*. 한 게임 1라운드에 *수십~수백 copies*. *성능 + 무용한 방어*. *Card 불변* 보장 시 *toList() (immutable view)* 만으로 충분.
|
|
351
|
+
|
|
352
|
+
### 18. `Blackjack.drawUntilDealerStands(): Int` — *카운트 반환 = 콘솔 영향*
|
|
353
|
+
|
|
354
|
+
```kotlin
|
|
355
|
+
fun drawUntilDealerStands(): Int {
|
|
356
|
+
var count: Int = 0
|
|
357
|
+
while (canHit(playerGroup.dealer)) {
|
|
358
|
+
hitAction(playerGroup.dealer)
|
|
359
|
+
count++
|
|
360
|
+
}
|
|
361
|
+
return count
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
→ **`Int` 반환 = *딜러 추가 뽑은 카드 수* — 출력용**. PR #133 (시아) 의 *displayDealerDrawInfo(name, count)* 와 같은 결. *도메인 메시지가 아니라 출력 카운터*. *Dealer 가 뽑은 카드 수 노출 메시지*는 *`Dealer.additionalCardCount: Int`* 같은 *상태 메시지*가 자연. *함수 시그니처에 카운터 반환*은 *콘솔 출력 의존*.
|
|
366
|
+
|
|
367
|
+
말리빈 (1단계 진단) 와 같은 결: *"반환 값인 Int가 어떤 값을 의미하는지 유추하기는 어려워보여요. 나아가서, 어떠한 플랫폼의 (콘솔)의 영향으로 이렇게 구성했다는 느낌이 강하게 드네요. 도메인에서 이러한 것을 알아야할지 고민해보세요"*
|
|
368
|
+
|
|
369
|
+
### 19. `BetAmount.money` private — *getter 미노출 + 외부 곱셈만 가능*
|
|
370
|
+
|
|
371
|
+
```kotlin
|
|
372
|
+
class BetAmount(private val money: Int) {
|
|
373
|
+
operator fun times(dividend: Double): Int { return (money * dividend).toInt() }
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
→ **`money` private = 외부 read 불가 + `times` 메시지만 노출**. *캡슐화 정공*. 다만 *`betAmount * 0`* 같은 *0 곱셈* 도 *Int 반환 0* — *Draw 시 0 수익*은 *enum.DRAW.earningRate = 0.0* 으로 표현. *호출 정합*.
|
|
378
|
+
|
|
379
|
+
또한 *`BetAmount + BetAmount` 같은 합산 메서드 미정의* — *베팅금 누적 / 분할* 도메인 미고려. *현재 라운드 단일 베팅* 만 표현. *확장 시 추가 필요*.
|
|
380
|
+
|
|
381
|
+
### 20. `Dealer.canHit() = sumCardNumber <= 16` — *Dealer 룰을 Dealer 안 자체*
|
|
382
|
+
|
|
383
|
+
```kotlin
|
|
384
|
+
override fun canHit(): Boolean {
|
|
385
|
+
return sumCardNumber <= THRESHOLD
|
|
386
|
+
}
|
|
387
|
+
companion object {
|
|
388
|
+
private const val THRESHOLD: Int = 16
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
→ **`THRESHOLD = 16` Dealer companion 상수**. *Dealer 자기 룰 = Dealer 안*. *Tell-Don't-Ask 정공*. 다만 *Bust 시 canHit = false* 도 *sumCardNumber 가 17~21 일 때만 false* — *Bust 분기 별도* 필요할 수 있음 (현재 Hand.isBust = sumNumber > 21 이면 canHit = false (≤16 위반)). 정합.
|
|
393
|
+
|
|
394
|
+
### 21. `Blackjack.deck: PlayingCard` — *PlayingCard naming 의문*
|
|
395
|
+
|
|
396
|
+
```kotlin
|
|
397
|
+
class Blackjack(
|
|
398
|
+
private val deck: PlayingCard, // ⚠ "PlayingCard"? = deck인데
|
|
399
|
+
val playerGroup: PlayerGroup,
|
|
400
|
+
)
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
→ **`PlayingCard` 가 *Deck 의미*** — naming 모순. *PlayingCard = 1장 카드* 어휘. *현재 코드는 Deck 책임* 이라면 *Deck 또는 CardDeck* 이 자연. *코드 어휘 정합 부재*.
|
|
404
|
+
|
|
405
|
+
페로로 미해결 코멘트도 없으나 *Hand.cards = List<Card> + Blackjack.deck = PlayingCard* 가 *각 객체 어휘 불일치* 신호.
|
|
406
|
+
|
|
407
|
+
### 22. `playPlayersTurns` `forEach` 외부 입력 의존 — *블랙잭 진행 흐름의 입출력 분리 미완*
|
|
408
|
+
|
|
409
|
+
→ 학생의 *Blackjack 으로 전체 진행 이전 시도 → 깊이 문제* 자가 인식 + 페로로의 *"콜백 개념 없이는 블랙잭 게임 함수 하나로 모든 게임 진행을 하는 것은 어렵습니다. 그렇기에 컨트롤러의 게임 진행 로직을 최대한 간결하게 하고 인터페이스 다운 느낌을 주도록"* 메타 답변. *완전한 분리는 콜백 / 인터페이스 주입* — *현재 절충*.
|
|
410
|
+
|
|
411
|
+
### 23. `BetStatus.player: Player` + `ProceedStatus.participant: Participants` — *타입 비대칭*
|
|
412
|
+
|
|
413
|
+
```kotlin
|
|
414
|
+
class BetStatus(val player: Player, val betAmount: BetAmount)
|
|
415
|
+
class ProceedStatus(val participant: Participants, val proceed: Proceed)
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
→ **`BetStatus.player: Player` (Player 만) + `ProceedStatus.participant: Participants` (일반)** — *베팅은 Player 만 함*, *수익은 Player + Dealer 모두*. *타입 표현 정확*. 다만 *클래스 이름 비대칭* (Status 공통) 이 *어휘 어색*. *Bet vs Proceed* 가 *베팅 정보 vs 수익 정보* 의 *명사 표현*이 더 자연.
|
|
419
|
+
|
|
420
|
+
### 24. `Hand` 의 `BUST_STANDARD = 21` — *Bust 와 Blackjack 둘 다 21에 묶인 상수 이름*
|
|
421
|
+
|
|
422
|
+
```kotlin
|
|
423
|
+
companion object {
|
|
424
|
+
const val BUST_STANDARD: Int = 21
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
fun isBust(): Boolean { return getSumNumber() > BUST_STANDARD }
|
|
428
|
+
fun isBlackjack(): Boolean { return _cards.size == 2 && getSumNumber() == BUST_STANDARD }
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
→ **`BUST_STANDARD = 21` 이름 = *Bust 기준***. 다만 *Blackjack 도 21* 의미. *MAX_SCORE 또는 BLACKJACK_SCORE* 가 *이름 더 명료*. *Bust 는 > 21*, *Blackjack 은 == 21 + 2장*. *이름이 Bust 만 표현*은 *룰 일부만 노출*.
|
|
432
|
+
|
|
433
|
+
## 리뷰어 의견 요지
|
|
434
|
+
|
|
435
|
+
- **View 의 역할 = 사용자 의도 표현 (ActionType 반환), raw String X** — *멀티 플랫폼 View 시 *각 View 가 자기 입력 방식 → 도메인 어휘 변환** = *Controller 변환 일관성보다 View 다형성*. 학생의 *"View는 멍청해야"* 사고가 *콘솔 가정* 에서 옴.
|
|
436
|
+
- **Controller 변환 = 변환 로직 중복** — *InputView에서 "Y"/"N" 처리 + Controller에서 또 변환* = *한쪽 변경 시 한쪽 고장*.
|
|
437
|
+
- **`Map<X, X>` 지양 — 게임 결과 객체 도입** — *4-5 개 타입 묶음을 익명 Pair/Triple/Quadruple* 로 표현하지 말 것. *명시적 도메인 클래스*.
|
|
438
|
+
- **`compareScores` 의 블랙잭 vs Bust 우선순위 마이너 룰**: *블랙잭 + 상대 Bust*는 *그냥 Win, BlackjackWin 아님*. 학생 후속 반영.
|
|
439
|
+
- **`Blackjack` 도메인 객체에 게임 진행 로직 + Controller 콜백/인터페이스 의존** — *완전한 분리*는 *콜백 또는 인터페이스 주입*. *고차함수* 시도는 *깊이 문제*. 학생이 *고차함수 → 인터페이스* 자가 학습.
|
|
440
|
+
- **3 변수 제약 = 연습 도구, 너무 얽매이지 말 것** — `BetStatus`, `ProceedStatus` 같은 *Pair 우회 클래스* 가 *연습 부산물*. *PlayerResult/DealerResult* 처럼 *분리된 의미 클래스* 가 자연. PR #133 의 *Items* 와 같은 결.
|
|
441
|
+
- **테스트 편의성 — `Player(name, Hand(cards))` 생성자 카드 주입 가능성** — 학생 자가 답변: *"플레이어는 카드를 받음과 동시에 게임장에 착석한다 로 어색"* → *list 형태 분배 (`deck.spreadCard(2)`) → receiveCard*. 다른 표현 트레이드오프.
|
|
442
|
+
- **`drawUntilThreshold` naming 모호 — 동사 + 의미 명시 부재** — *Dealer 카드 뽑는 차례* 가 *함수명에서 안 드러남*. *`dealerHitUntilStands` 같은 의미 명시* 가 자연.
|
|
443
|
+
|
|
444
|
+
## 대표 인용
|
|
445
|
+
|
|
446
|
+
**페로로 (View = 사용자 의도 표현, BlackjackController.kt):**
|
|
447
|
+
> 저는 View가 단순히 raw 데이터를 받는 것이 아닌 사용자의 입력을 표현하는 역할을 한다고 생각합니다.
|
|
448
|
+
> 컨트롤러가 UI와 강하게 결합하면 이후 View의 자유도가 떨어지며 어떤 View를 사용하더라도 무조건 "y" 아니면 "n"을 반환해야만 합니다.
|
|
449
|
+
>
|
|
450
|
+
> 만약, InputView를 여러개로 바꿔가면서 실행해본다고 가정해보세요.
|
|
451
|
+
> InputView 객체에게 사용자의 의도(ActionType)를 달라고 메시지를 요청했을 뿐인데 강제로 "Y" "N"이 아니면 터지는 프로그램이 좋은 프로그램인가요..?
|
|
452
|
+
|
|
453
|
+
**페로로 (Map<X, X> 지양, Blackjack.kt):**
|
|
454
|
+
> 제가 앞서부터 드린 질문의 의도는 `Map<X, X>` 타입을 지양하라는 말이었습니다.
|
|
455
|
+
> 지금은 단순히 Map으로 하나의 타입만 반환하도록 되어 있지만 만약, 이전과 같이 승패 여부도 같이 반환해야 된다면 이렇게 만들건지? 되묻고 싶어요
|
|
456
|
+
>
|
|
457
|
+
> ```kotlin
|
|
458
|
+
> fun endGame(...): Map<Player, Pair<GameResult, Proceed>>
|
|
459
|
+
> ```
|
|
460
|
+
>
|
|
461
|
+
> 나아가서 사용해야 하는 타입이 4개, 5개 넘어가면?? `Quadruple<A, B, C, D>` ?
|
|
462
|
+
> 게임의 결과 객체를 만들고 결과 객체로 하여금 수익률을 계산할 수 있도록 역할을 연습해보면 좋겠어요
|
|
463
|
+
|
|
464
|
+
**페로로 (Blackjack 메시지 + canHit, BlackjackController.kt):**
|
|
465
|
+
> 아직은 블랙잭외에도 컨트롤러가 플레이어에 직접 접근하는 등 블랙잭 혼자서는 게임이 불가능한 상태인데요.
|
|
466
|
+
> 지금까지 해온 것 처럼 블랙잭에게 필요한 메시지를 전달하도록 해볼까요?
|
|
467
|
+
> ```kotlin
|
|
468
|
+
> // as-is
|
|
469
|
+
> player.canHit()
|
|
470
|
+
> // to-be
|
|
471
|
+
> blackjack.canHit(player)
|
|
472
|
+
> ```
|
|
473
|
+
|
|
474
|
+
**페로로 (배율 = earningRate, BetAmount.kt):**
|
|
475
|
+
> 넵, 제가 보기에는 적절한 것 같습니다.
|
|
476
|
+
> 다만 블랙잭 여부를 알고 있는데 이후 다른 조건이 들어가게 되면 함수가 비대해질 수 있는 문제는 있는데요.
|
|
477
|
+
> 이 로직은 참가자에서도 비슷하게 하고있는데 요기서 또 하는 듯 한 느낌이 드니까요
|
|
478
|
+
>
|
|
479
|
+
> 승패여부, 블랙잭 상관 없이 배율(earningRate)이라는 개념을 넘겨주는 방식은 어떨까요?
|
|
480
|
+
> > 블랙잭은 1.5배, 버스트는 -1배
|
|
481
|
+
|
|
482
|
+
**페로로 (3 변수 제약 너무 얽매이지 말 것, OutputView.kt):**
|
|
483
|
+
> 한편으로는 인스턴스 변수 3개에 너무 얽매인 것은 아닐까 싶네요.
|
|
484
|
+
> 제약사항이기는 했지만 무조건 이것을 지키기 위해서 너무 손해볼게 많아지기도 하니까요.
|
|
485
|
+
> 굳이 만든다면 이런 느낌이 되었으려나요?
|
|
486
|
+
|
|
487
|
+
**페로로 (콜백 + 인터페이스 정공, BlackjackController.kt:26):**
|
|
488
|
+
> 협력을 위한 인터페이스보다 고차함수가 먼저 나온것에 대해 우선.... 놀라봅니다!
|
|
489
|
+
> 말씀하신 대로 콜백 개념 없이는 블랙잭 게임 함수 하나로 모든 게임 진행을 하는 것은 어렵습니다.
|
|
490
|
+
> 그렇기에 컨트롤러의 게임 진행 로직을 최대한 간결하게 하고 인터페이스 다운 느낌을 주도록 챙겨봅시다
|
|
491
|
+
|
|
492
|
+
**학생 자가 학습 (View 역할 자가 변동, ActionType.kt):**
|
|
493
|
+
> 저는 기존에 `View는 최대한 멍청해야 한다`라고 생각했습니다
|
|
494
|
+
> 따라서 View가 `y -> Hit, n -> Stay` 의 관계를 몰라야 한다고 생각합니다
|
|
495
|
+
> View의 역할은 `형식에 맞는 값을 받는다`로 끝나야 하지 않을까요?
|
|
496
|
+
> ...
|
|
497
|
+
> (페로로 GraphicsInputView 예시 후)
|
|
498
|
+
> `사용자의 입력을 표현하는 역할`
|
|
499
|
+
> 이 부분이 마음에 와닿네요 ... !
|
|
500
|
+
> `안드로이드 플랫폼에서 버튼을 클릭해도 컨트롤러에게 String 타입으로 반환해 줄 것인가?`
|
|
501
|
+
> 에 대해 고민해 보니 제 논리가 잘못됐던 것 같네요!
|
|
502
|
+
|
|
503
|
+
**학생 자가 답변 (Player 생성자 Hand 인자 어색, PlayingCard.kt:5):**
|
|
504
|
+
> Player("환노", Hand(mutableListOf(Card1, Card2)))
|
|
505
|
+
> 개인적으로 플레이어의 생성자로 Hand를 받으면
|
|
506
|
+
> `플레이어는 카드를 받음과 동시에 게임장에 착석한다` 로 어색하게 느껴집니다 🥲
|
|
507
|
+
>
|
|
508
|
+
> 따라서 애초에 카드를 list 형태로 뽑고, list 형태로 받으면 테스트 코드에서 번거로움이 사라질 것 같습니다!
|
|
509
|
+
>
|
|
510
|
+
> 기존의 `repeat(2)`으로 처리해 주던 초기 카드 분배 로직도
|
|
511
|
+
> ```kotlin
|
|
512
|
+
> player.receiveCard(deck.spreadCard(INITIAL_CARD_COUNT))
|
|
513
|
+
> ```
|
|
514
|
+
> 위처럼 더 명확하게 바꿀 수 있었습니다!
|
|
515
|
+
|
|
516
|
+
**학생 자가 답변 (Blackjack 게임 흐름 분리 시도 + 좌절, BlackjackController.kt):**
|
|
517
|
+
> 위 피드백을 보고 `view의 입출력 함수`들을 블랙잭 메소드의 인자로 넘겨 ( 고차함수 사용 )
|
|
518
|
+
> 게임을 진행하는 전체 로직을 `Blackjack`으로 옮겨 주려 했습니다... 🥲
|
|
519
|
+
>
|
|
520
|
+
> 그러다 보니 `depth` 가 너무 깊어져서 테스트가 불가능한 상황이 발생하더군요 🤔
|
|
521
|
+
>
|
|
522
|
+
> `플레이어가 (버스트가 아닌 경우) 원할 때까지 카드를 받는다` <- 이 로직은 블랙잭에 있어야 한다고 생각했는데,
|
|
523
|
+
> 중간중간 입출력이 필요하기 때문에 블랙잭 도메인에서 처리가 불가능합니다 🥲
|
|
524
|
+
>
|
|
525
|
+
> 결국 UI 로직 처리를 위해 컨트롤러의 도움이 필요해서, 컨트롤러의 로직으로 두고,
|
|
526
|
+
> 컨트롤러가 직접적으로 플레이어에게 접근하는 부분 (`canHit`, `cards.size`) 만 `Blackjack`에서 처리하도록 바꾸었는데,
|
|
527
|
+
> 페로로는 이에 대해 어떻게 생각하시나요? 😵💫
|
|
528
|
+
|
|
529
|
+
**학생 자가 답변 (Pair 우회 클래스 + 한계 인식, OutputView.kt):**
|
|
530
|
+
> 당장엔 인스턴스 변수를 3개 이상 사용하지 못하므로
|
|
531
|
+
> (플레이어, 승패 여부)를 묶는 클래스를 또 만드는 게 최선일 것 같습니다 🥲
|
|
532
|
+
|
|
533
|
+
## 얻은 교훈
|
|
534
|
+
|
|
535
|
+
1. ***View의 역할 = 사용자 의도 표현, raw 데이터 변환 X***. *멀티 플랫폼 UI (Console/Graphics/Mobile)* 시 *각 View 가 자기 입력 방식 → 도메인 어휘 (ActionType) 변환*. *Controller 변환 = 변환 로직 중복 = 한쪽 변경 시 한쪽 고장*. 학생의 *"View는 멍청해야"* 사고가 *콘솔 가정*에서 옴. **MCP 룰 후보 — `view-as-raw-input-converter`**. PR #133 (시아 2단계) 의 *EventListener/EventProvider* 와 같은 결.
|
|
536
|
+
|
|
537
|
+
2. ***`Map<X, X>` 지양 — 도메인 결과 객체 도입***. *Pair/Triple/Quadruple* 같은 *익명 묶음* 은 *3-4 개 데이터에서 한계*. *명시적 도메인 클래스 (BlackjackResult, PlayerResult)*가 *어휘 명시 + 확장 안전*. PR #131 (다이스 2단계) 의 *GameResult 분리* 와 같은 결.
|
|
538
|
+
|
|
539
|
+
3. ***`Participants` 추상화 = 진짜 다형성***. *abstract method 3개 (`canHit`, `getInitCard`, `compareScores`)* 가 *Player/Dealer 룰 차이를 다형성으로 표현*. **`Player.getInitCard() = take(2)`, `Dealer.getInitCard() = take(1)` 가 블랙잭 공개 룰을 메시지로 표현** — *외부 분기 0*. 1단계 *open class Player + Dealer : Player 모순* 의 완전 해소.
|
|
540
|
+
|
|
541
|
+
4. ***`operator plus` Unit 반환 + 가변 변경 = 안티패턴 정공***. PR #133 (시아 2단계) 의 *Money.plus* 와 같은 결. *Kotlin operator plus = 새 객체 반환* 표준. *자기 변경*은 *operator plusAssign (`+=`)*. *`hand + cards` = NoOp 표현* 가독성 0.
|
|
542
|
+
|
|
543
|
+
5. ***카드 분배 룰 = 모두 N장 받음 / 공개 룰 = 분기*** — *카지노 도메인 정합*. *initGame: 모든 참여자 2장 분배 + getInitCard: 공개 단계에서 Dealer 1장 / Player 2장 분기*. *룰 두 단계 분리* (분배 vs 공개) 가 *도메인 정확*.
|
|
544
|
+
|
|
545
|
+
6. ***`Blackjack.canHit(participant) = participant.canHit()` 단순 위임 wrapper 는 클래스 의의 부재 신호***. *Blackjack 객체의 책임 = ?* *Demeter 우회용 wrapper* 면 *Blackjack 의 진짜 역할이 무엇인가*. *진짜 진입점 = `blackjack.playRound(callback)` 같은 단일 함수*. PR #131 (다이스) 의 *BlackJackGame.play()* 와 같은 결.
|
|
546
|
+
|
|
547
|
+
7. ***고차함수 vs 인터페이스 트레이드오프 자가 학습***. *고차함수 = 한번에 콜백 주입 + 호출자 간결*. *인터페이스 = 명시적 의존 + 다양한 구현 + 테스트 용이*. *둘 다 정공*. 학생이 *고차함수 시도 → 깊이 문제 → 절충* 흐름이 학습 가시화 모범. 페로로의 *"협력을 위한 인터페이스보다 고차함수가 먼저 나온것에 대해 우선.... 놀라봅니다!"* 가 *인터페이스 우선* 가르침.
|
|
548
|
+
|
|
549
|
+
8. ***`compareScores` 의 분기 우선순위 = 도메인 룰 정확성***. *블랙잭 + 상대 Bust* 가 *BlackjackWin (1.5배) X, 그냥 Win (1.0배) O*. *분기 순서 신중* — *조건 1 (내 Bust → Lose), 조건 2 (상대 Bust → Win)* 을 *위로*. *그 다음 블랙잭 분기*. *블랙잭 룰의 정확성 = 분기 순서*.
|
|
550
|
+
|
|
551
|
+
9. ***`Ace 단일 +10 if (sum + 10 ≤ 21)` 패턴은 Ace 다수 정확***. PR #128·#135·#114·#125·#131·#108 와 같은 결의 Ace 정공.
|
|
552
|
+
|
|
553
|
+
10. ***`@JvmInline value class Proceed(amount: Int)` = 도메인 타입 wrap***. *Int = 의미 모호*. *Proceed = "수익" 명시*. *value class = 런타임 박싱 없음 + 타입 안전*. PR #131 (다이스) 의 *BetAmount value class* 와 같은 결.
|
|
554
|
+
|
|
555
|
+
11. ***`GameResult enum + earningRate: Double` = 룰 표를 enum 부가 속성으로 응집***. *블랙잭 1.5 / Win 1.0 / Draw 0 / Lose -1* 룰이 *enum 한 자리*. *수익 계산 = `betAmount * result.earningRate`* 한 줄. *룰 변경 시 enum 멤버 수정 1곳*.
|
|
556
|
+
|
|
557
|
+
12. ***`MutableList` 생성자 인자 = 외부 가변 참조 = 쓰기 방어 0***. *읽기 방어 (`get() = _cards.deepCopy()`)* + *쓰기 방어 0* 비대칭. *생성자에서 `cards.toMutableList()` 사본*이 *진짜 캡슐화*.
|
|
558
|
+
|
|
559
|
+
13. ***`Hand.cards` 매 호출 deepCopy = 불변 객체에 무용 비용***. PR #124 (모찌 1단계) 와 같은 결. *Card 불변 보장* 시 *toList() (immutable view)* 만으로 충분. *deepCopy* 는 *Card가 가변* 일 때만 필요.
|
|
560
|
+
|
|
561
|
+
14. ***`drawUntilDealerStands(): Int` 반환 카운트 = 콘솔 영향 흔적***. *도메인 메시지가 아니라 출력용 카운터*. *Dealer 추가 카드 수 = 출력 표시 룰* 인데 *함수 반환에 들어가면 도메인 누수*. PR #133·#108 의 *getAdditionalDrawCount* 와 같은 결.
|
|
562
|
+
|
|
563
|
+
15. ***3 변수 제약 = 연습 도구, 너무 얽매이지 말 것***. 페로로의 *"무조건 이것을 지키기 위해서 너무 손해볼게 많아지기도 하니까요"* 가 *제약의 의도 = 분리 능력 키우기*. *완전히 정당한 도메인 객체*만 *제약의 부산물 X*. PR #133 (시아) 의 *Items* 와 같은 결.
|
|
564
|
+
|
|
565
|
+
16. ***`PlayerGroup.filterIsInstance<Dealer>().first()` = 런타임 발견 + 암묵 invariant***. *Dealer가 무조건 있다* 는 *컴파일 타임 보장 X*. *생성자 분리 (`PlayerGroup(dealer: Dealer, players: List<Player>)`)* 가 *invariant 강제*. *팩토리 함수*로 *List<Participants> → (Dealer, List<Player>) 변환* 가능.
|
|
566
|
+
|
|
567
|
+
17. ***`data class Player` vs `class Dealer` 비대칭 = 동등성 의미 부재***. *Player 동등성 의미 (이름) vs 전체 속성* 의 *명시 부재*. *Dealer 도 동등성 의미*면 *둘 다 data class*. *비대칭은 의도 부재 신호*.
|
|
568
|
+
|
|
569
|
+
18. ***V는 사용자 의도 표현 (ActionType 반환) → 학생 자가 학습 변동 = 모범***. *학생이 처음 "View 멍청, Controller 변환" 주장 → 페로로의 GraphicsInputView 예시로 자가 변동 → 후속 반영* 흐름이 *학습 가시화 모범*. *외부 다형성 예시 → 자가 사고 변동* 패턴. PR #128·#135·#111·#120·#124·#133 와 같은 결.
|
|
570
|
+
|
|
571
|
+
19. ***`PlayingCard` naming = Deck 책임을 가진 클래스가 이름은 "1장 카드"*** — *어휘 정합 부재*. *코드 어휘 = 도메인 어휘* 가 *읽기 비용 ↓*. *naming 불일치*는 *호출자가 의미 추측*. PR #108·#133 의 *naming 부조화* 잔존.
|
|
572
|
+
|
|
573
|
+
20. ***`Blackjack` 도메인 객체의 게임 진행 흡수 + 입출력 의존의 균형 = 콜백/인터페이스 주입***. *완전한 도메인 자율 = 입력 콜백 인자*. *입출력 분리 = View 인터페이스 의존*. *둘 다 정공*. *현재 절충 (Blackjack에 게임 일부 + Controller에 입출력 일부)* 은 *깊이 vs 분리* 의 트레이드오프.
|