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,297 @@
|
|
|
1
|
+
# PR #116 — [블랙잭 1단계] 동전 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@donghyun81](https://github.com/donghyun81)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-blackjack/pull/116
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @laco-dev
|
|
7
|
+
- **라인 코멘트:** 30 (리뷰어 24 / 리뷰이 6)
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Cards` 추상 클래스 + `Deck`/`Hands` 구체 구현** — *덱과 손패가 같은 기본 동작 (`accept`, `cards.count()`)*을 공유하면서 *서로 다른 역할*. 후속 분리.
|
|
12
|
+
- **`Dealer(vararg card: Card) : this(Hands(*card))` 보조 생성자** — 테스트 친화.
|
|
13
|
+
- **`Verdict.reverse()` — *상대 결과로 자기 결과 도출*** (Tell-Don't-Ask 1.5단계).
|
|
14
|
+
- **`Verdict.determine(standardPlayer, comparePlayer)` 의 *bust 양측 처리*** + 학생 자가 인정 (못한 점 §10 참고).
|
|
15
|
+
- **후속 반영 — *학생이 "현실 기반 사고가 잘못"이라고 자가 분석* → 점수 = 카드 책임으로 이전 + 자료구조 *Stack/Deque* 결정**.
|
|
16
|
+
|
|
17
|
+
## 못한 점 (설계 관점)
|
|
18
|
+
|
|
19
|
+
### 1. `Suit.value` / `Verdict.value` UI 문자열 — **7개 PR 연속**
|
|
20
|
+
|
|
21
|
+
```kotlin
|
|
22
|
+
enum class Suit(val value: String) { HEART("하트"), SPADE("스페이드"), DIAMOND("다이아몬드"), CLUB("클로버") }
|
|
23
|
+
enum class Verdict(val value: String) { WIN("승"), LOSE("패"), DRAW("무") }
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
리뷰어 (Suit): "*하트, 스페이드, 다이아몬드, 클로버가 위와 같이 출력 될 것이라는 것은 UI의 역할로 보입니다.* 만약 하트를 ❤️ 이렇게 출력한다면, *이는 도메인에서 수정할 책임일까요?*"
|
|
27
|
+
리뷰어 (Verdict): "*요기도 동일한 것 같아요!* 만약 디자이너가 *WIN 처럼 출력해달라고 했는데 그때마다 도메인이 바뀌면 안되겠죠?*"
|
|
28
|
+
|
|
29
|
+
→ **8개 PR 연속(#28·#78·#112·#125·#128·#135·#24·#116) 등장하는 안티패턴. MCP 룰 후보 최강.**
|
|
30
|
+
|
|
31
|
+
### 2. `Choice("y"/"n")` 도메인 객체 — UI 형식 보유
|
|
32
|
+
|
|
33
|
+
```kotlin
|
|
34
|
+
class Choice(private val value: String) {
|
|
35
|
+
init { require(value == CHOICE_YES || value == CHOICE_NO) { ERROR_INVALID_CHOICE } }
|
|
36
|
+
fun isHit(): Boolean = value == CHOICE_YES
|
|
37
|
+
companion object {
|
|
38
|
+
private const val CHOICE_YES = "y"
|
|
39
|
+
private const val CHOICE_NO = "n"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
리뷰어: "*이어서 이 내용들도 모두 UI 관심사로 보입니다!* 도메인 입장에서 *굳이 value라는 것을 만들 필요가 있을까?* 라는 생각도 드네요." — `enum class Choice { YES, NO }`로 *도메인 어휘만*. `"y"/"n"` → `YES/NO` 매핑은 InputView.
|
|
45
|
+
|
|
46
|
+
### 3. `InputView`가 `OutputView`를 가지고 *출력 호출*
|
|
47
|
+
|
|
48
|
+
```kotlin
|
|
49
|
+
class InputView {
|
|
50
|
+
private val outputView = OutputView()
|
|
51
|
+
fun readPlayerNames(): List<String> {
|
|
52
|
+
outputView.requestPlayerNames() // ⚠ InputView → OutputView
|
|
53
|
+
val input: String = readln()
|
|
54
|
+
return input.split(...).map { ... }
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
리뷰어: "*InputView가 직접 콘솔에 찍으면 안되는걸까요?* 굳이 OutputView를 다시 호출하는 이유가 궁금합니다."
|
|
60
|
+
|
|
61
|
+
학생 자가 토론: "출력이라는 기능은 outputView이 관리하는 게 더 맞지 않나? 라는 의견에 *정확하게 반박하기 힘들*어서 *관점에 차이일 수 있다*고 생각이 되었습니다. 저는 *inputView랑 outputView가 화면이라고 생각*한다면 당연히 굳이 OutputView를 InputView가 전혀 의존할 필요가 없다고 생각하는데, *inputView와 outputView가 input과 output이라고 생각한다면 이렇게 받는 게 맞지 않나?*"
|
|
62
|
+
|
|
63
|
+
리뷰어: "*콘솔에 입력받는것도 콘솔에 "출력"하면서 입력을 받지 않나요?* 입력과 출력을 어떤 기준으로 나누냐일 것 같은데요. *이름을 입력해주세요* '동전' <-- *이것도 출력이 아닌가?* 결국 *View라는 관점에서 본다면 입력과 출력으로 나누는게 아닌 입력을 위한 기능, 출력을 위한 기능 관점으로 접근하는게 맞지 않을까* 싶어요."
|
|
64
|
+
|
|
65
|
+
→ **입력 vs 출력의 경계 = 기준 합의 필요**. *View 책임 자체*는 *입력을 위한 화면 + 출력을 위한 화면*. *InputView가 OutputView 호출*하는 구조는 *책임 분리가 아니라 책임 이전*.
|
|
66
|
+
|
|
67
|
+
### 4. `InputView.readPlayerAction(player: Player): String` 반환
|
|
68
|
+
|
|
69
|
+
```kotlin
|
|
70
|
+
fun readPlayerAction(player: Player): String {
|
|
71
|
+
outputView.requestPlayerAction(player)
|
|
72
|
+
val input: String = readln()
|
|
73
|
+
return input
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
리뷰어: "*InputView로부터 Choice를 반환 받으면 될 것 같은데 String을 반환한 이유가 있나요?* 도메인을 의존안한다고 하기에는 *이미 Player를 받기 때문에 앞뒤가 안맞습니다*. 또한 *만약 Y, N을 String으로 비교하는게 아닌 키오스크에서 버튼을 누를수도 있고 그림을 그릴수도 있다면 지금 구조는 불가능*하게 됩니다."
|
|
78
|
+
|
|
79
|
+
→ **일관성 신호 — Player를 받으면서 String을 반환은 모순**. `Choice` enum 반환이 자연. + *Y/N String 비교*는 *콘솔 가정*이라 *UI 변형 불가능*.
|
|
80
|
+
|
|
81
|
+
### 5. `Player.getScore()` — 점수 계산이 Player 책임
|
|
82
|
+
|
|
83
|
+
```kotlin
|
|
84
|
+
open class Player(val name: String, initCards: List<Card> = listOf()) {
|
|
85
|
+
fun getScore(): Int {
|
|
86
|
+
val score = this.cards.sumOf { it.rank.score }
|
|
87
|
+
return score + getBonusScore(totalScore = score)
|
|
88
|
+
}
|
|
89
|
+
private fun getBonusScore(totalScore: Int): Int { ... }
|
|
90
|
+
private fun hasAce(): Boolean = this.cards.any { it.rank == Rank.ACE }
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
리뷰어: "*점수를 계산하는 것은 플레이어가 결정하는게 맞을까요?* *카드들을 관리하고 로직을 수행하는 역할의 객체가 필요하지는 않을까요?*"
|
|
95
|
+
|
|
96
|
+
학생 자가 인정: "*제가 아직 현실을 기반으로 객체의 책임을 생각하는 부분이 많아서 잘못 생각 한 것 같습니다.* '플레이가 자기 점수를 계산하고 반환' 보다는 *'카드가 자기 점수를 반환'이 카드가 플레이어나 딜러가 아닌 다른 객체에 있더라도 자기 점수를 반환하는 것이 자율성이 더 높을 것 같습니다.*" — **PR #112·#114·#29·#24와 동일한 *점수 = 카드/Hand 책임* 결론**. 학생 자가 깨달음.
|
|
97
|
+
|
|
98
|
+
### 6. `Player` open class 상속 — Participant 추상화 미시도
|
|
99
|
+
|
|
100
|
+
```kotlin
|
|
101
|
+
open class Player(val name: String, initCards: List<Card> = listOf()) { ... }
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
리뷰어: "*open class, abstract class, interface의 차이점을 알고 계신가요?* 플레이어 그리고 딜러는 *어떤 관계로 나타내야 적절할까요?* 가령 *딜러와 플레이어는 동일한 로직을 가지지만 일부는 서로 다른 로직을 수행*하고는 합니다. 이를 표현하기 위한 적절한 방법은 무엇일까요? 아래 힌트를 참고해보세요 :) ```#1 Participant ⨽Player ⨽Dealer #2 Player ⨽Dealer```"
|
|
105
|
+
|
|
106
|
+
→ 두 가지 추상화 옵션 명시 (`Participant` 추상 + Player/Dealer / `Player` 기반 + Dealer 확장). PR #24·#29·#114와 동일 주제.
|
|
107
|
+
|
|
108
|
+
### 7. `Cards` 추상 클래스 + `Cards` *덱 표현인지 모호*
|
|
109
|
+
|
|
110
|
+
```kotlin
|
|
111
|
+
class Cards(initCards: List<Card> = deckCards.shuffled()) {
|
|
112
|
+
private val cards: MutableList<Card> = initCards.toMutableList()
|
|
113
|
+
fun draw(count: Int = DRAW_DEFAULT_COUNT): List<Card> {
|
|
114
|
+
if (cards.count() < count) cards.addAll(deckCards.shuffled()) // ⚠ 무한 재공급
|
|
115
|
+
return List(count.coerceAtMost(count)) { cards.removeFirst() }
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
리뷰어: "*카드들 생각하다가 흠칫했네요. 혹시 이 객체의 역할은 "덱"일까요?* 이 기능이 카드와 카드들의 관계로 *잘 어울리는지 앞서 피드백을 참고*해보시면 좋을 것 같아요. *`Card - Deck - Cards`*"
|
|
121
|
+
|
|
122
|
+
→ `Cards`라는 *광범위 명사*가 *덱 + 손패* 둘 다 흡수. `Card - Deck - Hands` 두 가지 *역할*로 분리. *카드들* → *어떤 카드들?* 모호.
|
|
123
|
+
|
|
124
|
+
또: "*덱을 표현하기에 또 다른 자료구조는 어떤게 있을까요?*"
|
|
125
|
+
학생: "*자연스러운 자료구조는 선입후출인 Stack이 제일 자연스러운 자료구조*라고 생각 됩니다!" — Stack/Deque/LinkedList. 학생 후속: `Deck(LinkedList<Card>)`.
|
|
126
|
+
|
|
127
|
+
### 8. `Deck.draw` *카드 모자라면 무한 재공급*
|
|
128
|
+
|
|
129
|
+
```kotlin
|
|
130
|
+
class Deck private constructor(override val cards: LinkedList<Card>) : Cards() {
|
|
131
|
+
fun draw(count: Int = DRAW_DEFAULT_COUNT): List<Card> {
|
|
132
|
+
if (cards.count() < count) accept(blackJackCards.shuffled()) // ⚠ 모자라면 52장 재공급
|
|
133
|
+
return List(count.coerceAtMost(blackJackCards.count())) { cards.pop() }
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
리뷰어: "*카드가 모자라면 52장을 반환하는게 논리적으로 적절한 흐름인가요?* 다른 개발자도 바로 이해할 수 있는 것인지 *고민해볼 필요*가 있습니다. 한편으로는 *준비한 덱이 모두 소진되면 어떤 식으로 게임 진행이 되는지도* 같이 생각해보면 좋을 것 같아요. 지금 구조라면 *계속 뽑으면 무한정으로 뽑았던 카드를 또 뽑을 수 있겠*어요." — PR #135 (ijh1298) `refill`과 같은 결. *자동 재공급*은 *호출자 모름* + *덱 소진 invariant 무시*.
|
|
139
|
+
|
|
140
|
+
### 9. `GameController`가 *Hand에 직접 끼워넣기* — accept 메서드의 어색함
|
|
141
|
+
|
|
142
|
+
```kotlin
|
|
143
|
+
private fun initialDeal(deck: Deck, participants: Participants) {
|
|
144
|
+
participants.players.forEach { player ->
|
|
145
|
+
player.hands.accept(deck.draw(START_CARD_COUNT)) // ⚠ player.hands에 직접 accept
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
리뷰어: "*최초에 Hand를 준비할 때, 2장을 가진 상태로 생성을 하면 안되는건가? 라는 생각이 드는데요* *역할을 위해 accept라는 메소드가 만들어졋다기 보다는, accept를 쓰기 위해 구조를 억지로 바꾼듯한 느낌*이 들어서요" / "*참가자의 카드에 직접 끼워넣는 것 보다는 참가자에게 카드를 주는 것이 자연스럽지 않을까요?*"
|
|
151
|
+
|
|
152
|
+
→ `player.hands.accept(cards)` 는 *Hand에 직접 접근*. `player.accept(cards)` 또는 *2장 보유 상태로 생성*이 자연. **메서드 등장 이유 = 호출자 편의면 안 됨**.
|
|
153
|
+
|
|
154
|
+
### 10. `Dealer.determine` — *둘 다 Bust = 내가 승리* 룰 오해
|
|
155
|
+
|
|
156
|
+
```kotlin
|
|
157
|
+
private fun determine(otherHands: Hands): Verdict {
|
|
158
|
+
return when {
|
|
159
|
+
hands.isBust() && otherHands.isBust() -> WIN // ⚠ 둘 다 Bust = 딜러 승
|
|
160
|
+
hands.isBust() -> LOSE
|
|
161
|
+
...
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
리뷰어: "*"둘다 버스트면 내가 항상 이긴다" 라는 규칙은 너무 불공평하지 않을까요?* 블랙잭 게임에서 *여러명이 버스트면 그 여러명은 그냥 패배*한겁니다." — *블랙잭 룰* 정확히 *각 플레이어 vs 딜러* 개별 판정. *딜러 Bust = 모든 안-Bust 플레이어 승*. *플레이어 Bust = 그 플레이어 패배*(딜러 상태 무관). **블랙잭 룰을 흐릿하게 이해**.
|
|
167
|
+
|
|
168
|
+
또: `Verdict.reverse()`로 *상대 결과 → 자기 결과*는 좋으나, *Dealer가 비교 주체*인 구조 자체가 PR #28·#63·#125·#29·#24의 *match는 참가자 메시지* 권고에 어긋남.
|
|
169
|
+
|
|
170
|
+
### 11. `Dealer.getPlayerVerdict` / `Dealer.getDealerVerdicts` — *플레이어 / 딜러 별도 호출*
|
|
171
|
+
|
|
172
|
+
```kotlin
|
|
173
|
+
fun getPlayerVerdict(players: List<Participant>): Map<Participant, Verdict> = ...
|
|
174
|
+
fun getDealerVerdicts(players: List<Participant>): Map<Verdict, Int> = ...
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
리뷰어: "*Verdict이라는 것을 객체로 만들어 보면 어떤 차이점이 있을까요?* `class Verdict(...)` 플레이어와의 승부나 *딜러의 승부를 따로 호출하는 구조가 어색하게 느껴지기도* 합니다. *딜러도 플레이어도 결국 승리 수 패배 수 무승부 수라는 개념을 가지는게아닐까?*" — *Verdict 객체*로 *winCount/loseCount/drawCount*를 가지면 *Dealer/Player 모두 동일 추상 결과*. PR #24의 *1대다 GameResult*와 같은 결.
|
|
178
|
+
|
|
179
|
+
### 12. `Hands`가 `Deck.START_CARD_COUNT`에 의존
|
|
180
|
+
|
|
181
|
+
```kotlin
|
|
182
|
+
class Hands private constructor(override val cards: MutableList<Card>) : Cards() {
|
|
183
|
+
fun isStartCardCount(): Boolean = cards.count() == START_CARD_COUNT // Deck의 상수 참조
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
리뷰어: "*시작할 때 뽑는 카드 수를 일부로 분리했는데 Hands에서 다시 의존하게 만든 이유가 있나요?*" — *Hands가 Deck의 룰을 안다*면 *공통 상수* 또는 *룰의 소유자*가 모호. PR #128 (ijh1298)의 *Dealer.Companion의 `ACE_EXTRACT_SCORE`*와 같은 결.
|
|
188
|
+
|
|
189
|
+
### 13. `ChoiceTest` — *enum 동작 자체 테스트*
|
|
190
|
+
|
|
191
|
+
```kotlin
|
|
192
|
+
class ChoiceTest {
|
|
193
|
+
@Test fun `y가 입력될 시 true를 반환한다`() { assertThat(Choice.YES.isYes()).isEqualTo(true) }
|
|
194
|
+
@Test fun `n이 입력될 시 true를 반환한다`() { assertThat(Choice.NO.isYes()).isEqualTo(false) } // ⚠ true? 함수명 오류
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
리뷰어: "*이 테스트는 더이상 의미가 있는 테스트가 아닙니다 :) 🗑️*" — `Choice` 자체가 *enum 두 값*이면 *isYes() = (value == YES)* 항상 true. *자동 보장되는 동작을 테스트*는 *코드 → 테스트 동어반복*. (또: 두 번째 테스트 함수명에 `true를 반환` 오타.)
|
|
199
|
+
|
|
200
|
+
### 14. `DeckTest` — *함수명 vs 실제 동작 불일치*
|
|
201
|
+
|
|
202
|
+
```kotlin
|
|
203
|
+
@Test fun `카드들에서 카드 2장을 반환한다`() {
|
|
204
|
+
val deck = Deck(listOf(Card(Suit.HEART, Rank.SIX), Card(Suit.HEART, Rank.SEVEN)))
|
|
205
|
+
assertThat(deck.draw(1)).isEqualTo(listOf(Card(Suit.HEART, Rank.SIX), Card(Suit.HEART, Rank.SEVEN))) // ⚠ draw(1)이 2장?
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
리뷰어: "*코드 라인은 줄이다보니 가독성이 현저히 떨어지게 된 것 같아요. 이 부분도 개선해주세요 그리고 2장을 반환한다는데 draw는 1입니다* 😓" — *테스트 함수명*과 *호출 인자 / assertion* 불일치 = 테스트가 *문서로서 거짓*.
|
|
210
|
+
|
|
211
|
+
### 15. `HandsTest`에 `Player` 등장
|
|
212
|
+
|
|
213
|
+
```kotlin
|
|
214
|
+
class HandsTest {
|
|
215
|
+
@Test fun `플레이어는 카드를 받는다`() {
|
|
216
|
+
val actual = Player("동전", Card(Suit.HEART, Rank.ACE), Card(Suit.HEART, Rank.KING), Card(Suit.HEART, Rank.SIX))
|
|
217
|
+
hands.accept(listOf(Card(Suit.HEART, Rank.SIX)))
|
|
218
|
+
assertThat(hands.showCards()).isEqualTo(actual.hands.showCards())
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
리뷰어: "*Hands를 테스트하는데 플레이어가 왜 나오는건가요?*" — *테스트 대상 ≠ 테스트 시나리오*. *Hands.accept*를 검증하려면 *Hands만 등장*.
|
|
224
|
+
|
|
225
|
+
또: "*이 테스트를 읽는 사람이 보너스 점수가 어떤 원리로 동작하는지 이해할 수 있을까요?* 즉 성공하면 *왜 성공했는지 실패하면 왜 실패하는지를 알 수 있는 코드인지* 궁금합니다." — *테스트 = 사양서*. *왜 21점이 되는지*가 *카드 조합*에서 드러나야.
|
|
226
|
+
|
|
227
|
+
### 16. `OutputView`가 *Dealer 1장 / Player 2장 공개* 결정 — 비즈니스 룰이 UI
|
|
228
|
+
|
|
229
|
+
리뷰어: "*최초 공개시 딜러는 1장, 플레이어는 2장을 노출한다.* *비즈니스 로직이 아닐까요?* 이것을 *UI에서 결정하는 것이 게임의 규칙인지? UI의 규칙인지? 고민할 필요*가 있습니다. 우리가 만든 *참가자라는 역할 아래 딜러와 플레이어가 다른 구현을 가지도록 하는 것이 추상화를 적용해볼 기회*라고 봅니다." — PR #135·#92와 동일한 *공개 카드 수 = 비즈니스 룰*. `Participant.showInitialCards()` 추상 메서드.
|
|
230
|
+
|
|
231
|
+
### 17. `GameController`가 *Dealer는 생성자 직접, Player는 이름만*
|
|
232
|
+
|
|
233
|
+
```kotlin
|
|
234
|
+
val participants = Participants(Dealer(), inputView.readPlayerNames())
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
리뷰어: "*참가자를 만드는데 딜러는 생성자로 직접 받고 플레이어는 이름만 받는게 일관성이 떨어지는 것 같습니다.*" — *Dealer 생성 (인스턴스)* vs *Player(이름)* 비대칭. `Participants.of(dealerName, playerNames)` 또는 *둘 다 이름 받기*.
|
|
238
|
+
|
|
239
|
+
## 리뷰어 의견 요지
|
|
240
|
+
|
|
241
|
+
- ***enum의 UI value = 8 PR 연속 안티패턴 (Suit.value, Verdict.value)***.
|
|
242
|
+
- ***`Choice("y"/"n")` 도메인이 UI 형식 보유***.
|
|
243
|
+
- ***InputView가 OutputView 호출 = 책임 이전*** — *입력을 위한 화면 / 출력을 위한 화면*.
|
|
244
|
+
- ***InputView 반환 = Choice enum, String X***.
|
|
245
|
+
- ***점수 계산 = 카드/Hand 책임*** (학생 자가 깨달음, *현실 기반 사고 자기 분석*).
|
|
246
|
+
- ***Open class < Participant 추상*** (2가지 옵션 제시).
|
|
247
|
+
- ***`Cards`는 광범위 명사, `Card - Deck - Hands`로 역할 분리***.
|
|
248
|
+
- ***Deck 자동 재공급 = 호출자 모름, 덱 소진 invariant 무시***.
|
|
249
|
+
- ***player.hands.accept(cards)는 메서드 등장 정당화가 호출자 편의*** — `player.accept(cards)` 또는 *2장 보유 상태 생성*.
|
|
250
|
+
- ***둘 다 Bust = 내가 승리 = 블랙잭 룰 오해*** — *각 플레이어 vs 딜러 개별 판정*.
|
|
251
|
+
- ***Verdict 객체로 winCount/loseCount/drawCount 통일*** — Dealer/Player 별도 호출 어색.
|
|
252
|
+
- ***Hands가 Deck.START_CARD_COUNT 의존 = 룰 소유자 모호***.
|
|
253
|
+
- ***`enum 동작 자체 테스트는 의미 없음***.
|
|
254
|
+
- ***테스트 함수명 ≠ 동작이면 사양서로 거짓***.
|
|
255
|
+
- ***테스트 대상 ≠ 테스트 시나리오*** (Hands 테스트에 Player 등장).
|
|
256
|
+
- ***Dealer 1장 / Player 2장 공개 = 비즈니스 룰***.
|
|
257
|
+
- ***참가자 생성에 Dealer 인스턴스 vs Player 이름은 비대칭***.
|
|
258
|
+
|
|
259
|
+
## 대표 인용
|
|
260
|
+
|
|
261
|
+
> 만약 하트를 ❤️ 이렇게 출력한다면, 이는 *도메인에서 수정할 책임일까요?*
|
|
262
|
+
> — @laco-dev on `Suit.kt`
|
|
263
|
+
|
|
264
|
+
> 객체지향 관점에서 *협력이라는 것과 자율성 측면에서 본다면, 승부를 벌이는 것은 누가 하는게 가장 적절*하다고 생각하시나요? 1. 플레이어와 플레이어 2. 플레이어와 딜러 3. 참가자와 참가자 4. 승패 / 한편으로는 *만약 승부를 결정하기 위해 플레이어의 정보를 계속해서 참견해야 한다면, 그것은 자율성이 깨진다*고 볼 수 있지 않을까요?
|
|
265
|
+
> — @laco-dev on `Verdict.kt`
|
|
266
|
+
|
|
267
|
+
> 결국 *View라는 관점에서 본다면 입력과 출력으로 나누는게 아닌 입력을 위한 기능, 출력을 위한 기능 관점으로 접근*하는게 맞지 않을까 싶어요.
|
|
268
|
+
> — @laco-dev on `InputView.kt`
|
|
269
|
+
|
|
270
|
+
> 카드가 모자라면 *52장을 반환하는게 논리적으로 적절한 흐름인가요?* [...] 지금 구조라면 *계속 뽑으면 무한정으로 뽑았던 카드를 또 뽑을 수 있겠*어요.
|
|
271
|
+
> — @laco-dev on `Deck.kt`
|
|
272
|
+
|
|
273
|
+
> "둘다 버스트면 내가 항상 이긴다" 라는 규칙은 *너무 불공평하지 않을까요?* 블랙잭 게임에서 *여러명이 버스트면 그 여러명은 그냥 패배*한겁니다.
|
|
274
|
+
> — @laco-dev on `Dealer.kt`
|
|
275
|
+
|
|
276
|
+
> 역할을 위해 accept라는 메소드가 만들어졋다기 보다는, *accept를 쓰기 위해 구조를 억지로 바꾼듯한 느낌*이 들어서요
|
|
277
|
+
> — @laco-dev on `GameController.kt`
|
|
278
|
+
|
|
279
|
+
## 얻은 교훈
|
|
280
|
+
|
|
281
|
+
- ***enum의 UI 문자열 보유 = 8개 PR 연속 등장 (MCP 룰 후보 최강)*** — *디자이너가 표현 변경 요청 = 도메인 수정* 비효율.
|
|
282
|
+
- ***Choice("y"/"n") = UI 형식이 도메인에*** — `enum Choice { YES, NO }`. 매핑은 InputView.
|
|
283
|
+
- ***InputView → OutputView 호출은 책임 이전*** — *View = 입력을 위한 화면 + 출력을 위한 화면*. *Input/Output 분리*는 기능 분류이지 역할 분리 X.
|
|
284
|
+
- ***InputView 반환 타입 = 도메인 어휘 (Choice)*** — String 반환은 *UI 형식이 호출자에 누수*. 키오스크/그림 같은 *대안 UI*에서 *재사용 불가*.
|
|
285
|
+
- ***점수 계산 = 카드/Hand 책임, Player X*** — 학생 자가 깨달음 명시: *현실 기반 사고가 잘못*. *카드가 다른 객체에 있어도 자기 점수 반환이 자율성 ↑*.
|
|
286
|
+
- ***open class < `abstract Participant`*** — 두 가지 추상화 옵션(`Participant`/`Player`) 모두 가능. *역할 차이가 일부면 추상 메서드*.
|
|
287
|
+
- ***`Cards`는 광범위 명사 → 덱/손패 흡수*** — `Card - Deck - Hands` 두 역할로. PR #29 `Rule`과 같은 *광범위 명사 = 책임 흡인기* 패턴.
|
|
288
|
+
- ***Deck 자동 재공급 = 호출자 모름 + invariant 무시*** — 덱 소진 시 *명시 신호*가 자연. (PR #135 ijh1298 refill + null + Elvis 결과 우수.)
|
|
289
|
+
- ***`player.hands.accept(cards)` = 메서드 등장 정당화가 호출자 편의*** — *Hand에 직접 접근*. *2장 보유 상태로 생성* 또는 `player.accept(cards)`.
|
|
290
|
+
- ***Bust 양측 = 무승부/딜러 승 모두 룰 오해*** — *플레이어 vs 딜러 개별 판정*이 정답. *블랙잭 룰 충실히 읽기* (PR #128 *점수 동률 = 무승부*와 같은 결).
|
|
291
|
+
- ***Verdict 객체화 → winCount/loseCount/drawCount***로 Dealer/Player 통일 — *별도 호출* 어색.
|
|
292
|
+
- ***Hands가 Deck.START_CARD_COUNT 의존 = 룰 소유자 모호*** — 도메인 룰 상수의 *소속 객체*는 *룰의 책임자*.
|
|
293
|
+
- ***enum 동작 자체를 테스트는 동어반복*** — *호출 결과가 정의로 자명*하면 테스트 가치 ↓.
|
|
294
|
+
- ***테스트 함수명 ≠ 동작이면 사양서로 거짓*** — `draw(1)이 2장 반환`은 사양 무력화.
|
|
295
|
+
- ***테스트 대상 ≠ 테스트 시나리오*** — *Hands 테스트에 Player 등장*은 격리 위반.
|
|
296
|
+
- ***Dealer 1장 / Player 2장 공개 = 비즈니스 룰*** — Participant 추상 메서드.
|
|
297
|
+
- ***참가자 생성 비대칭 (Dealer 인스턴스 vs Player 이름) = 일관성 ↓*** — `Participants.of(dealerName, playerNames)` 또는 *둘 다 이름*.
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# PR #147 — [블랙잭 2단계] 동전 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@donghyun81](https://github.com/donghyun81)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-blackjack/pull/147
|
|
5
|
+
- **단계:** 2단계 (베팅 / 수익률 / 블랙잭 1.5배)
|
|
6
|
+
- **리뷰어:** @laco-dev (페로로)
|
|
7
|
+
- **라인 코멘트:** 15 스레드 / 26 코멘트 — *상태 클래스 분리 과잉 + 서비스 분리 의문 + 다형성 학습 진행 중*
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **상태를 클래스로 나누려는 시도** — 페로로 자가 칭찬: *"상태를 클래스로 나누려는 시도가 좋아 보입니다."* — *State 패턴 도입 의도*. 다만 *과잉 분리* 함정 동반 (못한 점 §1).
|
|
12
|
+
- **`MatchResult.BLACKJACK_LOSE(-1.5)` 의도 명시 + 학생 자가 회고** — 학생 자가 답변: *"BLACKJACK_LOSE(-1.5)가 추가된 이유는 딜러도 각 플레이어와 수익을 계산할 수 있도록 MatchDealer가 matchResults를 가지고 구현하려고 추가했습니다. 하지만 구현하다 보니 matchPlayers에서 각 bettingPlayer들을 찾아서 다시 matchResults와 비교를 해야 하니 너무 복잡해져서 제거했는데, 이 부분을 제거를 안 했네요.. ㅎㅎ"*. **시도 → 복잡도 인식 → 후퇴 + 의도 명시 모범**.
|
|
13
|
+
- **`Score` 객체 도입 시도** — 점수 계산 응집 시도. 다만 *블랙잭 / 딜러 룰 누수* 함정 동반 (못한 점 §6).
|
|
14
|
+
- **`PlayingService` 고차함수 시도** — 학생 자가 답변: *"학습 내용에 고차함수에 관련된 내용이 있어서 반영 했는데, 기본적인 인터페이스를 통해서 사용 해보겠습니다!"*. **학습 진행 + reviewer 권고 흡수**. PR #132 (환노) / #137 (미플) 와 같은 결의 *고차함수 → interface*.
|
|
15
|
+
- **수정 의지 + 다형성 학습 진행 중 자가 표현** — 학생 자가 답변: *"1단계 미션에서 다형성에서 느낀 장점은 "추상화된 타입에서 구현체들이 다른 일을 처리 할 수 있다" 를 제일 큰 장점으로 느꼈습니다. 하지만 수업에서 상태에 따라 처리하는 부분에서 조건을 줄이는 방법을 보면서 다형성에 장점에 관해서 다르게 느끼는 부분도 많고, 오히려 다형성이 뭔지 더 모호해진 느낌을 받았습니다. 이번에 클래스로 상태를 다 나누어 보고 페로로 피드백도 받아보면서, 왜 카드를 상태에 따라 처리했는지, 카드와 플레이어 중 상태에 따라 나누는 게 누구여야 하는지 등등 조금씩 감을 잡아가는 것 같아서 그에 따라 구현해보겠습니다."*. **학생 자가 학습 진행 + 메타 인식 모범**.
|
|
16
|
+
|
|
17
|
+
## 못한 점 (설계 관점)
|
|
18
|
+
|
|
19
|
+
### 1. `InitialParticipant / PlayingDealer / PlayingPlayer / ...` — *상태 × 참가자 = N × M 클래스 폭증*
|
|
20
|
+
|
|
21
|
+
```kotlin
|
|
22
|
+
// 추정 구조
|
|
23
|
+
class InitialParticipant ...
|
|
24
|
+
class InitialDealer ...
|
|
25
|
+
class InitialPlayer ...
|
|
26
|
+
class PlayingDealer ...
|
|
27
|
+
class PlayingPlayer ...
|
|
28
|
+
class MatchDealer ...
|
|
29
|
+
class MatchPlayer ...
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
페로로 (InitialParticipant.kt — 미해결): *"상태를 클래스로 나누려는 시도가 좋아 보입니다. 다만, 상태마다 딜러 플레이어 참가자가 매번 쌍으로 만들어져 너무 많은 클래스가 필요합니다. 이외에 상태가 또 생길때마다 N개씩 반복해서 만들어지게 되는데 플레이어든 딜러가 매번 바뀌는게 맞는걸까요? 그렇지 않다면, 딜러와 플레이어가 가지고있는 \"카드패\"의 상태가 바뀌는 것으로 생각해보면 어떨까요? 딜러 - 카드패 : Initial -> Playing -> Finished. 플레이어 - 카드패 : Initial -> Playing -> Finished"*
|
|
33
|
+
|
|
34
|
+
→ **상태 × 참가자 = N × M 클래스 폭증 안티패턴**. *블랙잭 = 3 상태 (Initial/Playing/Finished) × 2 참가자 (Dealer/Player) = 6 클래스 + Match 추가 시 9 클래스*. *상태 클래스 분리 의도는 좋으나 객체 단위 잘못 선택*.
|
|
35
|
+
|
|
36
|
+
**진짜 분리 = "카드패" 의 상태 객체** — *Hand.Initial / Hand.Playing / Hand.Finished 3 클래스 + Dealer/Player 2 클래스 = 5*. *N + M*. 다만 *N × M = 6 → 9 → ...* 폭증. **MCP 룰 후보 — `state-times-actor-class-explosion`**. PR #131·#136·#152·#93 의 *State 객체 (5 클래스) + Participant 다형성 (2 클래스)* 와 *반대 트레이드오프*.
|
|
37
|
+
|
|
38
|
+
학생 자가 학습 인용: *"다형성이 뭔지 더 모호해진 느낌"* — *과잉 분리 후 자가 인식*.
|
|
39
|
+
|
|
40
|
+
### 2. `PlayingDealer.handState` — *Initial 상태도 HandState 만들 수 있음*
|
|
41
|
+
|
|
42
|
+
페로로 (PlayingDealer.kt — 미해결): *"이러한 HandState는 플레잉중이 아니더라도 항상 만들어낼 수 있는 개념이라고 생각해요. Initial이어도 HandState를 계산할 수 있고 Match여도 계산할 수 있습니다."*
|
|
43
|
+
|
|
44
|
+
→ **`HandState` 가 *Playing 상태에만 종속***. *Hand 의 점수/Bust/Blackjack 상태는 모든 시점 계산 가능*. *PlayingDealer 의존*은 *학생 의도와 실제 행동의 불일치*. PR #146·#131 의 *Score 도메인 객체* 와 같은 결의 *시점 무관 상태*.
|
|
45
|
+
|
|
46
|
+
### 3. `InitService / PlayingService / ...` 서비스 분리 — *책임 분배 모호*
|
|
47
|
+
|
|
48
|
+
페로로 (InitService.kt — 미해결): *"서비스를 두개로 쪼개면 어떤 이점이 있나요..? 게임의 준비 단계도 하나의 게임 시나리오중 하나인데 플레잉 참가자로 바꾸는건 또 개별적으로 하고 있고 Init 서비스가 무슨 일을 하기 위한 객체인지 잘 이해가 안되요"*
|
|
49
|
+
|
|
50
|
+
학생 자가 답변: *"각 관심사를 가진 플레이어 끼리 서비스를 처리하면, 누가 게임시나리오 흐름에서 뭘 하는지 명확히 할 수 있고 수정 사항이 있어도 각 서비스에서만 수정 할 수 있지 않을까 싶어서 나눠 봤습니다. init이랑 play를 하는 플레이어가 같은 관심사를 가지고 있어서 의미는 없어보이지만 ㅎㅎ.."*
|
|
51
|
+
|
|
52
|
+
→ **서비스 분리 = 단계별 책임 명시 의도** vs **실제로는 같은 관심사 분산**. *학생 자가 인식*: *"의미는 없어 보이지만"*. *YAGNI 위반*. PR #88·#136·#137 와 같은 결의 *추상화 과잉*.
|
|
53
|
+
|
|
54
|
+
### 4. `MatchResult.BLACKJACK_LOSE(-1.5)` — *플레이어 -1.5배 손실 = 도메인 룰 위반*
|
|
55
|
+
|
|
56
|
+
페로로 (MatchResult.kt:8 — 미해결): *"호앵... 딜러가 블랙잭이면 오히려 내가 돈을 더 뱉어야하나요?? 😱"*
|
|
57
|
+
|
|
58
|
+
학생 자가 답변: *"... 하고 싶었던 구현은 when문을 제거해서 계산하고 각 플레이어의 대결을 뒤집어서 딜러가 보관하고 딜러의 대결 결과를 통해 딜러의 수익을 정하고 싶었는데 반대로만 남겨놔서 이상한 구현이 되었네요 ㅎㅎ..\"*
|
|
59
|
+
|
|
60
|
+
→ **`BLACKJACK_LOSE(-1.5)` = 학생 의도 잔재**. *카지노 룰 = 플레이어 패배 시 -1배 (베팅금 손실)*. *-1.5 = 도메인 룰 위반*. *학생 자가 인식 + 제거 누락* — *구현 정리 부족 신호*. PR #128·#137 와 같은 결의 *수익률 룰 정확성*.
|
|
61
|
+
|
|
62
|
+
### 5. `BettingPlayer` 에 *when 절 의미 부재 (자가 인식)*
|
|
63
|
+
|
|
64
|
+
페로로 (BettingPlayer.kt — 미해결): *"이 로직에 when이 어떤 의미가 있나요?"*
|
|
65
|
+
|
|
66
|
+
학생 자가 답변: *"승패 결과에 profitRate를 추가하고 나서 when으로 처리했던 부분을 없애야 하는데 생각없이 값만 처리했네요.. ㅎㅎ"*
|
|
67
|
+
|
|
68
|
+
→ **`when` 절 잔재 = 리팩토링 누락**. *enum + profit: Double* 후속 반영 후 *when 절 dead*. *학생 자가 인식 + 후속 반영 모범*. PR #131·#132·#137 와 같은 결의 *enum 부가속성 응집*.
|
|
69
|
+
|
|
70
|
+
### 6. `Score` 가 *블랙잭 + 딜러 룰 모두 알기*
|
|
71
|
+
|
|
72
|
+
페로로 (Score.kt — 미해결): *"버스트나 최대 점수는 이해하겠는데 블랙잭이나 딜러 스테이가 점수랑 무슨 관련이 있나요? > 블랙잭을 판단하는 것, 딜러가 카드를 더 뽑을 수 있는지 판단하는 것. 위 비즈니스 로직을 Score가 책임지는게 적절한가요?"*
|
|
73
|
+
|
|
74
|
+
학생 자가 답변: *"부적절하다고 생각됩니다! 수정하겠습니다."*
|
|
75
|
+
|
|
76
|
+
→ **`Score` = *일반 점수 객체***. *블랙잭/딜러 룰 = Hand/Participant 책임*. *PR #146·#136·#131 와 같은 결의 *Score 룰 누수***. *학생 자가 인식 + 후속 반영 모범*.
|
|
77
|
+
|
|
78
|
+
### 7. `ProfitPlayer` 클래스명 — *기능 + 클래스 이름 이어붙이기*
|
|
79
|
+
|
|
80
|
+
페로로 (ProfitPlayer.kt — 미해결): *"게임 결과에 수익률 외에 다른 개념들도 필요하면 클래스 이름을 이어붙일건가요??? `class MatchResultProfitPlayerWithXXX()`"*
|
|
81
|
+
|
|
82
|
+
학생 자가 답변: *"수익을 가지고 있는 클래스 보다는 수익과 관련된 행동을 하는 Player클래스라고 생각하고 명칭했지만, 공감 받기 너무 어려운 작명이였던 것 같습니다. 페로로는 명칭할때 행동에 따른 명칭은 어떤 부분을 신경쓰면서 작성해야 공감이 간다고 생각하시나요?"*
|
|
83
|
+
|
|
84
|
+
페로로 후속: *"질문이 잘 이해가 안되네요. 근본적으로 `수익과 관련된 행동을 하는 Player`라는게 왜 있는지 모르겠어요. 플레이어에게 수익금을 계산하라는 요청을 하는게 먼저아닌가여?"*
|
|
85
|
+
|
|
86
|
+
학생 자가 답변: *"음.. 그러네요 구현할때는 수익과 관련된 행동을 하는 Player라고 생각하고 만들었는데, 정리하다보니 상태만 남았던 Player여서 행동에 의미가 전혀 없는 클래스가 되었군요, 수정하겠습니다!"*
|
|
87
|
+
|
|
88
|
+
→ **클래스명 = 기능 + 명사 이어붙이기 안티패턴**. *`ProfitPlayer / MatchResultProfitPlayerWithXXX`* 는 *기능 명사화 = 책임 분리 실패 신호*. *Player 자체에 수익 계산 메서드*가 정공. *Tell-Don't-Ask = `player.calculateProfit(dealer)`*. **MCP 룰 후보 — `feature-class-naming-explosion`**. PR #88·#125·#114·#146 의 *vagueName 변형*.
|
|
89
|
+
|
|
90
|
+
### 8. `BettingPlayers.findXX` naming — *Kotlin find 의미 (nullable)*
|
|
91
|
+
|
|
92
|
+
페로로 (BettingPlayers.kt — 미해결): *"흔히 find라는 의미는 코틀린에서 찾는다를 뜻해서 대부분 반환 타입이 nullable로만들어져요. `List.find { ... }`를 찾아보세요 비슷한 함수가 많습니다."*
|
|
93
|
+
|
|
94
|
+
→ **`find` = nullable 반환 표준 (Kotlin stdlib)**. *non-null 반환 = `first` / `single`* 이 *Kotlin 어휘*. PR #108·#133·#58 와 같은 결의 *naming 부조화*.
|
|
95
|
+
|
|
96
|
+
### 9. `DealerHit / PlayerHit / DoubleHit / ...` 분리 — *Hit 가 *주체별 다른 룰* 가정*
|
|
97
|
+
|
|
98
|
+
페로로 (DealerHit.kt — 미해결): *"Hit에 딜러인지 플레이어인지를 엮는 이점이 있을까요? 만약 다른 Hit를 판단하는 My라는 룰이 생기면 MyHit YouHit DoubleHit 이런거를 계속 만들건가요?"*
|
|
99
|
+
|
|
100
|
+
→ **`Hit` 에 *주체 엮기 = 폭증 안티패턴***. *`DealerHit`, `PlayerHit`* = *주체별 클래스*. *Hit = 행위*, *주체는 메서드 인자 또는 다형성*. PR #131·#136·#152·#93 와 같은 결의 *State 객체 분리* 와 *주체 분리* 의 차이.
|
|
101
|
+
|
|
102
|
+
### 10. `Finished` 가 *Initial 상속* — *상속 모순*
|
|
103
|
+
|
|
104
|
+
페로로 (Finished.kt — 미해결): *"Finished가 Initial을 상속하는게 엄청 모순적이지 않나요?"*
|
|
105
|
+
|
|
106
|
+
→ **상속 = is-a 관계**. *Finished is-a Initial?* — *Finished 가 *초기 상태의 하위* 인가*. *논리적 모순*. *상태 객체 분리* 시 *공통 인터페이스 (State) + Initial/Playing/Finished 형제 클래스*가 정공. *상속 계층 부정확 = 학생 다형성 학습 진행 신호*. PR #93·#136·#152 와 같은 결의 *sealed/abstract State 형제 분리*.
|
|
107
|
+
|
|
108
|
+
### 11. `Finished.draw` 가 *예외 던짐 = 자기 자신 반환 대안*
|
|
109
|
+
|
|
110
|
+
페로로 (Finished.kt — 미해결): *"오류를 발생시키는것도 나쁘지 않은 방법인데 자기 자신을 반환하는 방법도 있습니다."*
|
|
111
|
+
|
|
112
|
+
→ **`Finished.draw(card) = throw` vs `Finished.draw(card) = this`** 트레이드오프. *throw = 명시적 실패*. *self return = silent 무시*. *PR #152 (모찌) 의 Finish.draw throw IllegalStateException* 와 같은 결의 *throw 정공*. *PR #85 (하디) 의 Hand.draw stay → self return* 와 *반대 트레이드오프*.
|
|
113
|
+
|
|
114
|
+
### 12. `Hands.bonus` 점수 처리 미이전 — *구현 일관성 부재*
|
|
115
|
+
|
|
116
|
+
페로로 (Hands.kt — 미해결): *"점수로 다 옮겼는데 정작 보너스 점수는 안옮긴... 구현에 일관성이 떨어지는군요"*
|
|
117
|
+
|
|
118
|
+
→ **점수 계산 → Score 이전 + 보너스 점수 (Ace 11 보정) Hands 잔존** = *책임 분산*. *Ace 보너스 = 점수 계산의 일부* — *Score 응집*이 일관. *학생 리팩토링 미완성 신호*.
|
|
119
|
+
|
|
120
|
+
### 13. `PlayingService` 의 *초기 카드 시점 onPlayerState 호출* — *시점 모호*
|
|
121
|
+
|
|
122
|
+
페로로 (PlayingService.kt — 미해결): *"카드가 2장이면 onPlayerState가 호출되는 상관관계가 있나요? 어색하지 않나요?"*
|
|
123
|
+
|
|
124
|
+
학생 자가 답변: *"첫 초기화 상태일 경우에 호출 되도록 수정하겠습니다!"*
|
|
125
|
+
|
|
126
|
+
→ **`카드 2장 → onPlayerState 호출` = 초기 상태 메시지 시점 모호**. *카드 수로 *초기 상태* 판단 = *Hand 의 isInitial 메시지*가 정공. *호출자 (Service) 가 카드 수 직접 검사 = Demeter 위반 + 시점 모호*.
|
|
127
|
+
|
|
128
|
+
### 14. `BetTest` 미완성 주석 잔존 — *PR 위생*
|
|
129
|
+
|
|
130
|
+
페로로 (BetTest.kt — 미해결): *"모두 완료되지 않았더라도 주석을 그대로 남기고 올리지는 말아주세요 :)"*
|
|
131
|
+
|
|
132
|
+
학생 자가 답변: *"일이 있어서 피드백을 일요일 점심이후로 적용해볼려고 빨리 올리다보니 급하게 행동한 것 같습니다 ㅎㅎ... 주의하겠습니다"*
|
|
133
|
+
|
|
134
|
+
→ **PR 위생 = 완성된 코드 + 주석 정리**. *미완성 주석은 reviewer 부담*. *Draft PR* 활용이 정공. *학생 자가 인정*.
|
|
135
|
+
|
|
136
|
+
### 15. `PlayingService` 고차함수 vs 인터페이스 — 페로로 권고
|
|
137
|
+
|
|
138
|
+
페로로 (PlayingService.kt — 미해결): *"TMI : 일단 무작정 고차함수로 만든 시도는 좋지만 우리는 협력을 위한 가장 기본적인 \"인터페이스\" 라는 것을 사용 할 수도 있었어요."*
|
|
139
|
+
|
|
140
|
+
→ **고차함수 vs 인터페이스 트레이드오프**. *고차함수 = 함수 인자 = 간결 + 단일 동작*. *인터페이스 = 명시적 의존 + 다양한 구현 + 테스트 용이*. PR #132 (환노) 의 *고차함수 시도 → 인터페이스 권고* / PR #137 (미플) 의 *onXX 콜백 어휘* 와 같은 결.
|
|
141
|
+
|
|
142
|
+
## 리뷰어 의견 요지
|
|
143
|
+
|
|
144
|
+
- **상태 × 참가자 N×M 클래스 폭증 = "카드패" 의 상태 객체로 N+M 분리** — *Hand.Initial/Playing/Finished + Dealer/Player*.
|
|
145
|
+
- **HandState 시점 무관 계산 가능** — *Playing 상태 종속 X*.
|
|
146
|
+
- **서비스 분리 이점 모호 = 같은 관심사 분산** — 학생 자가 인식.
|
|
147
|
+
- **`Hit` 주체별 분리 = 폭증 = Hit + 주체 인자 또는 다형성*** — *DealerHit / PlayerHit / DoubleHit* 회피.
|
|
148
|
+
- **`Finished is-a Initial` 상속 모순** — 형제 클래스 + 공통 인터페이스.
|
|
149
|
+
- **Finished.draw = throw vs self return 트레이드오프**.
|
|
150
|
+
- **Score 가 블랙잭/딜러 룰 알기 = 누수** — 학생 자가 인식.
|
|
151
|
+
- **`ProfitPlayer` 기능 + 명사 이어붙이기 = 책임 분리 실패 신호** — *Player 자체 메서드*.
|
|
152
|
+
- **`find` = Kotlin nullable 반환 표준** — *non-null 은 first/single*.
|
|
153
|
+
- **고차함수 vs 인터페이스 트레이드오프** — *인터페이스 협력 정공*.
|
|
154
|
+
- **PR 위생 = 미완성 주석 X** — Draft PR 활용.
|
|
155
|
+
|
|
156
|
+
## 대표 인용
|
|
157
|
+
|
|
158
|
+
**페로로 (상태 × 참가자 폭증, InitialParticipant.kt):**
|
|
159
|
+
> 상태를 클래스로 나누려는 시도가 좋아 보입니다.
|
|
160
|
+
>
|
|
161
|
+
> 다만, 상태마다 딜러 플레이어 참가자가 매번 쌍으로 만들어져 너무 많은 클래스가 필요합니다.
|
|
162
|
+
> 이외에 상태가 또 생길때마다 N개씩 반복해서 만들어지게 되는데 플레이어든 딜러가 매번 바뀌는게 맞는걸까요?
|
|
163
|
+
>
|
|
164
|
+
> 그렇지 않다면,
|
|
165
|
+
> 딜러와 플레이어가 가지고있는 "카드패"의 상태가 바뀌는 것으로 생각해보면 어떨까요?
|
|
166
|
+
>
|
|
167
|
+
> 딜러
|
|
168
|
+
> - 카드패 : Initial -> Playing -> Finished
|
|
169
|
+
>
|
|
170
|
+
> 플레이어
|
|
171
|
+
> - 카드패 : Initial -> Playing -> Finished
|
|
172
|
+
|
|
173
|
+
**페로로 (Hit + 주체 폭증, DealerHit.kt):**
|
|
174
|
+
> Hit에 딜러인지 플레이어인지를 엮는 이점이 있을까요?
|
|
175
|
+
> 만약 다른 Hit를 판단하는 My라는 룰이 생기면 MyHit YouHit DoubleHit 이런거를 계속 만들건가요?
|
|
176
|
+
|
|
177
|
+
**페로로 (상속 모순, Finished.kt):**
|
|
178
|
+
> Finished가 Initial을 상속하는게 엄청 모순적이지 않나요?
|
|
179
|
+
|
|
180
|
+
**페로로 (기능 + 명사 이어붙이기, ProfitPlayer.kt):**
|
|
181
|
+
> 게임 결과에 수익률 외에 다른 개념들도 필요하면 클래스 이름을 이어붙일건가요???
|
|
182
|
+
> ```
|
|
183
|
+
> class MatchResultProfitPlayerWithXXX()
|
|
184
|
+
> ```
|
|
185
|
+
|
|
186
|
+
**페로로 (HandState 시점 무관, PlayingDealer.kt):**
|
|
187
|
+
> 이러한 HandState는 플레잉중이 아니더라도 항상 만들어낼 수 있는 개념이라고 생각해요.
|
|
188
|
+
> Initial이어도 HandState를 계산할 수 있고 Match여도 계산할 수 있습니다.
|
|
189
|
+
|
|
190
|
+
**페로로 (find = nullable, BettingPlayers.kt):**
|
|
191
|
+
> 흔히 find라는 의미는 코틀린에서 찾는다를 뜻해서 대부분 반환 타입이 nullable로만들어져요.
|
|
192
|
+
> `List.find { ... }`를 찾아보세요 비슷한 함수가 많습니다.
|
|
193
|
+
|
|
194
|
+
**학생 자가 학습 (다형성 학습 진행 중 메타 인식, InitialParticipant.kt):**
|
|
195
|
+
> 1단계 미션에서 다형성에서 느낀 장점은 "추상화된 타입에서 구현체들이 다른 일을 처리 할 수 있다" 를 제일 큰 장점으로 느꼈습니다.
|
|
196
|
+
> 하지만 수업에서 상태에 따라 처리하는 부분에서 조건을 줄이는 방법을 보면서 다형성에 장점에 관해서 다르게 느끼는 부분도 많고,
|
|
197
|
+
> 오히려 다형성이 뭔지 더 모호해진 느낌을 받았습니다.
|
|
198
|
+
> 이번에 클래스로 상태를 다 나누어 보고 페로로 피드백도 받아보면서, 왜 카드를 상태에 따라 처리했는지,
|
|
199
|
+
> 카드와 플레이어 중 상태에 따라 나누는 게 누구여야 하는지 등등 조금씩 감을 잡아가는 것 같아서 그에 따라 구현해보겠습니다.
|
|
200
|
+
|
|
201
|
+
**학생 자가 답변 (BLACKJACK_LOSE 의도 + 후퇴 누락, MatchResult.kt:8):**
|
|
202
|
+
> BLACKJACK_LOSE(-1.5)가 추가된 이유는 딜러도 각 플레이어와 수익을 계산할 수 있도록 MatchDealer가 matchResults를 가지고 구현하려고 추가했습니다.
|
|
203
|
+
> 하지만 구현하다 보니 matchPlayers에서 각 bettingPlayer들을 찾아서 다시 matchResults와 비교를 해야 하니 너무 복잡해져서 제거했는데, 이 부분을 제거를 안 했네요.. ㅎㅎ
|
|
204
|
+
|
|
205
|
+
**학생 자가 답변 (서비스 분리 의문 자가 인식, InitService.kt):**
|
|
206
|
+
> 각 관심사를 가진 플레이어 끼리 서비스를 처리하면, 누가 게임시나리오 흐름에서 뭘 하는지 명확히 할 수 있고 수정 사항이 있어도 각 서비스에서만 수정 할 수 있지 않을까 싶어서 나눠 봤습니다.
|
|
207
|
+
> init이랑 play를 하는 플레이어가 같은 관심사를 가지고 있어서 의미는 없어보이지만 ㅎㅎ..
|
|
208
|
+
> 역할 분리를 통한 재사용성에 관해서 솔직히 실질적으로 프로젝트를 만들고 확장하거나 수정해본적이 없어서 이론을 가지고 분리해야하는데 경험이 없으니 이론을 정립하거나 공감하기 어려워서 이것저것 해보는것이 좋다고 생각해서 해봤습니다!
|
|
209
|
+
|
|
210
|
+
**학생 자가 답변 (ProfitPlayer naming 자가 인식, ProfitPlayer.kt):**
|
|
211
|
+
> 음.. 그러네요 구현할때는 수익과 관련된 행동을 하는 Player라고 생각하고 만들었는데,
|
|
212
|
+
> 정리하다보니 상태만 남았던 Player여서 행동에 의미가 전혀 없는 클래스가 되었군요, 수정하겠습니다!
|
|
213
|
+
|
|
214
|
+
## 얻은 교훈
|
|
215
|
+
|
|
216
|
+
1. ***상태 × 참가자 N×M 클래스 폭증 = "카드패" 상태 분리로 N+M***. *상태 클래스 분리 의도는 좋으나 객체 단위 잘못*. *Hand.Initial/Playing/Finished + Dealer/Player = 5*. *N×M (Initial×Dealer, Initial×Player, ...) = 6 → 9 → ...* 폭증. **MCP 룰 후보 — `state-times-actor-class-explosion`**.
|
|
217
|
+
|
|
218
|
+
2. ***`Hit + 주체` 이름 폭증 = 행위 + 주체 인자 분리***. *DealerHit / PlayerHit / DoubleHit* 회피. *Hit = 행위* + *주체는 메서드 인자 (`compete(other)`) 또는 다형성*. PR #131·#136·#152·#93 와 같은 결.
|
|
219
|
+
|
|
220
|
+
3. ***`Finished is-a Initial` 상속 모순 = is-a 관계 위반***. *상태 객체 = 형제 클래스 + 공통 인터페이스 (sealed/abstract State)*. PR #93·#136·#152 와 같은 결의 *State 형제 분리*.
|
|
221
|
+
|
|
222
|
+
4. ***`ProfitPlayer / MatchResultProfitPlayerWithXXX` 기능 + 명사 이어붙이기 = 책임 분리 실패***. *Player 자체 메서드 (calculateProfit)* 가 정공. *기능 명사화 = naming 폭증*. **MCP 룰 후보 — `feature-class-naming-explosion`**. PR #88·#125·#114·#146 의 *vagueName 변형*.
|
|
223
|
+
|
|
224
|
+
5. ***`HandState` 시점 무관 = 모든 시점 계산 가능***. *Playing 상태 종속 X*. *Hand 의 점수/Bust/Blackjack 은 시점 무관*. *PR #146·#131 의 Score 도메인 객체* 와 같은 결의 *불변 derived 값*.
|
|
225
|
+
|
|
226
|
+
6. ***서비스 분리 = 같은 관심사 분산 시 의미 부재***. *학생 자가 인식 ("의미는 없어 보이지만")*. *YAGNI 위반*. *책임 분리 = 다른 책임 시*에만. PR #88·#136·#137 와 같은 결.
|
|
227
|
+
|
|
228
|
+
7. ***`Score` 가 블랙잭/딜러 룰 알기 = 누수***. *Score = 일반 점수 객체*. *룰 = Hand/Participant 책임*. *학생 자가 인식 + 후속 반영*. PR #146·#136·#131·#108·#137 와 같은 결.
|
|
229
|
+
|
|
230
|
+
8. ***`Finished.draw = throw` vs `self return` 트레이드오프***. *PR #152 throw (페로로) / PR #85 self return (페로로 같은 reviewer 다른 PR) 둘 다 합리*. *throw = 명시적 실패 vs self = silent*.
|
|
231
|
+
|
|
232
|
+
9. ***`find` Kotlin nullable 반환 = non-null 은 first/single***. *Kotlin 어휘 표준*. PR #108·#133·#58 와 같은 결.
|
|
233
|
+
|
|
234
|
+
10. ***고차함수 vs 인터페이스 트레이드오프 = 인터페이스 협력 정공***. *고차함수 = 함수 인자 간결 + 단일 동작*. *인터페이스 = 명시적 의존 + 다양한 구현*. PR #132·#137 와 같은 결.
|
|
235
|
+
|
|
236
|
+
11. ***PR 위생 = 미완성 주석 X***. *Draft PR 활용*. *완성 PR 만 리뷰 요청*. *학생 자가 인정 + 후속 권고 흡수*.
|
|
237
|
+
|
|
238
|
+
12. ***학생 다형성 학습 진행 중 메타 인식 = "다형성이 뭔지 더 모호해진 느낌"*** — *학생 자가 학습 진행 모범*. *상태 클래스 분리 → 폭증 → 페로로 진단 → 카드패 상태 객체 + Hand 다형성 학습 진행*. PR #128·#135·#108·#133·#137·#146·#41·#88 와 같은 결의 학생 자가 토론 풍부.
|
|
239
|
+
|
|
240
|
+
13. ***`BLACKJACK_LOSE(-1.5)` 룰 위반 = 도메인 룰 정확성 실패***. *학생 의도 (딜러 입장 -1.5배 mirror) → 구현 복잡도 → 제거 결정 → 제거 누락*. *PR 정리 부족 신호*. PR #128·#137·#136 와 같은 결의 *수익률 룰 정확성*.
|
|
241
|
+
|
|
242
|
+
14. ***`when` 절 리팩토링 후 잔재 dead code***. *enum + profit: Double 후속 반영 후 when 정리 누락*. *학생 자가 인식 모범*. PR #131·#132·#137·#88 와 같은 결.
|
|
243
|
+
|
|
244
|
+
15. ***`PlayingDealer` HandState 종속 = State 객체 책임 모호***. *HandState = 시점 무관 derived*. *Playing 상태 종속*은 *학생 다형성 학습 진행 중 신호*. PR #146·#131 의 *Score 시점 무관* 와 같은 결.
|