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.
Files changed (660) hide show
  1. package/MCP_STRUCTURE.md +301 -0
  2. package/README.md +167 -0
  3. package/SCOPE.md +27 -0
  4. package/dist/application/discovery.d.ts +133 -0
  5. package/dist/application/discovery.js +62 -0
  6. package/dist/application/discovery.js.map +1 -0
  7. package/dist/cli.d.ts +2 -0
  8. package/dist/cli.js +80 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/config.d.ts +16 -0
  11. package/dist/config.js +32 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/domain/collaborators.d.ts +2 -0
  14. package/dist/domain/collaborators.js +26 -0
  15. package/dist/domain/collaborators.js.map +1 -0
  16. package/dist/domain/ids.d.ts +4 -0
  17. package/dist/domain/ids.js +23 -0
  18. package/dist/domain/ids.js.map +1 -0
  19. package/dist/domain/model.d.ts +71 -0
  20. package/dist/domain/model.js +2 -0
  21. package/dist/domain/model.js.map +1 -0
  22. package/dist/domain/schemas.d.ts +213 -0
  23. package/dist/domain/schemas.js +79 -0
  24. package/dist/domain/schemas.js.map +1 -0
  25. package/dist/domain/stereotypes.d.ts +7 -0
  26. package/dist/domain/stereotypes.js +65 -0
  27. package/dist/domain/stereotypes.js.map +1 -0
  28. package/dist/index.d.ts +2 -0
  29. package/dist/index.js +21 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/io/classStore.d.ts +9 -0
  32. package/dist/io/classStore.js +39 -0
  33. package/dist/io/classStore.js.map +1 -0
  34. package/dist/io/collaborationStore.d.ts +7 -0
  35. package/dist/io/collaborationStore.js +32 -0
  36. package/dist/io/collaborationStore.js.map +1 -0
  37. package/dist/io/design.d.ts +3 -0
  38. package/dist/io/design.js +22 -0
  39. package/dist/io/design.js.map +1 -0
  40. package/dist/io/designIndex.d.ts +6 -0
  41. package/dist/io/designIndex.js +49 -0
  42. package/dist/io/designIndex.js.map +1 -0
  43. package/dist/io/frontmatter.d.ts +8 -0
  44. package/dist/io/frontmatter.js +31 -0
  45. package/dist/io/frontmatter.js.map +1 -0
  46. package/dist/io/history.d.ts +10 -0
  47. package/dist/io/history.js +38 -0
  48. package/dist/io/history.js.map +1 -0
  49. package/dist/io/useCaseStore.d.ts +8 -0
  50. package/dist/io/useCaseStore.js +36 -0
  51. package/dist/io/useCaseStore.js.map +1 -0
  52. package/dist/io/workspace.d.ts +14 -0
  53. package/dist/io/workspace.js +82 -0
  54. package/dist/io/workspace.js.map +1 -0
  55. package/dist/oop/commands.d.ts +446 -0
  56. package/dist/oop/commands.js +319 -0
  57. package/dist/oop/commands.js.map +1 -0
  58. package/dist/oop/conformance.d.ts +16 -0
  59. package/dist/oop/conformance.js +30 -0
  60. package/dist/oop/conformance.js.map +1 -0
  61. package/dist/prompts/discovery.d.ts +2 -0
  62. package/dist/prompts/discovery.js +41 -0
  63. package/dist/prompts/discovery.js.map +1 -0
  64. package/dist/prompts/imagineWithoutController.d.ts +2 -0
  65. package/dist/prompts/imagineWithoutController.js +75 -0
  66. package/dist/prompts/imagineWithoutController.js.map +1 -0
  67. package/dist/prompts/index.d.ts +2 -0
  68. package/dist/prompts/index.js +17 -0
  69. package/dist/prompts/index.js.map +1 -0
  70. package/dist/prompts/phasePressureTest.d.ts +2 -0
  71. package/dist/prompts/phasePressureTest.js +69 -0
  72. package/dist/prompts/phasePressureTest.js.map +1 -0
  73. package/dist/prompts/rddIntro.d.ts +2 -0
  74. package/dist/prompts/rddIntro.js +53 -0
  75. package/dist/prompts/rddIntro.js.map +1 -0
  76. package/dist/prompts/review.d.ts +2 -0
  77. package/dist/prompts/review.js +45 -0
  78. package/dist/prompts/review.js.map +1 -0
  79. package/dist/prompts/stateMachineIntrospect.d.ts +2 -0
  80. package/dist/prompts/stateMachineIntrospect.js +80 -0
  81. package/dist/prompts/stateMachineIntrospect.js.map +1 -0
  82. package/dist/prompts/tellDontAskRephrase.d.ts +2 -0
  83. package/dist/prompts/tellDontAskRephrase.js +66 -0
  84. package/dist/prompts/tellDontAskRephrase.js.map +1 -0
  85. package/dist/render/diff.d.ts +21 -0
  86. package/dist/render/diff.js +84 -0
  87. package/dist/render/diff.js.map +1 -0
  88. package/dist/render/mermaid.d.ts +24 -0
  89. package/dist/render/mermaid.js +53 -0
  90. package/dist/render/mermaid.js.map +1 -0
  91. package/dist/render/sideBySide.d.ts +14 -0
  92. package/dist/render/sideBySide.js +91 -0
  93. package/dist/render/sideBySide.js.map +1 -0
  94. package/dist/resources/index.d.ts +2 -0
  95. package/dist/resources/index.js +349 -0
  96. package/dist/resources/index.js.map +1 -0
  97. package/dist/server.d.ts +2 -0
  98. package/dist/server.js +22 -0
  99. package/dist/server.js.map +1 -0
  100. package/dist/tools/alternatives.d.ts +2 -0
  101. package/dist/tools/alternatives.js +9 -0
  102. package/dist/tools/alternatives.js.map +1 -0
  103. package/dist/tools/classes.d.ts +2 -0
  104. package/dist/tools/classes.js +13 -0
  105. package/dist/tools/classes.js.map +1 -0
  106. package/dist/tools/collaborations.d.ts +2 -0
  107. package/dist/tools/collaborations.js +8 -0
  108. package/dist/tools/collaborations.js.map +1 -0
  109. package/dist/tools/compare.d.ts +2 -0
  110. package/dist/tools/compare.js +9 -0
  111. package/dist/tools/compare.js.map +1 -0
  112. package/dist/tools/conformance.d.ts +3 -0
  113. package/dist/tools/conformance.js +11 -0
  114. package/dist/tools/conformance.js.map +1 -0
  115. package/dist/tools/diagram.d.ts +2 -0
  116. package/dist/tools/diagram.js +9 -0
  117. package/dist/tools/diagram.js.map +1 -0
  118. package/dist/tools/discovery.d.ts +2 -0
  119. package/dist/tools/discovery.js +23 -0
  120. package/dist/tools/discovery.js.map +1 -0
  121. package/dist/tools/index.d.ts +2 -0
  122. package/dist/tools/index.js +27 -0
  123. package/dist/tools/index.js.map +1 -0
  124. package/dist/tools/init.d.ts +2 -0
  125. package/dist/tools/init.js +9 -0
  126. package/dist/tools/init.js.map +1 -0
  127. package/dist/tools/oop.d.ts +9 -0
  128. package/dist/tools/oop.js +26 -0
  129. package/dist/tools/oop.js.map +1 -0
  130. package/dist/tools/responsibilities.d.ts +2 -0
  131. package/dist/tools/responsibilities.js +13 -0
  132. package/dist/tools/responsibilities.js.map +1 -0
  133. package/dist/tools/state.d.ts +2 -0
  134. package/dist/tools/state.js +8 -0
  135. package/dist/tools/state.js.map +1 -0
  136. package/dist/tools/useCases.d.ts +2 -0
  137. package/dist/tools/useCases.js +18 -0
  138. package/dist/tools/useCases.js.map +1 -0
  139. package/dist/tools/validate.d.ts +2 -0
  140. package/dist/tools/validate.js +9 -0
  141. package/dist/tools/validate.js.map +1 -0
  142. package/dist/tradeoff/engine.d.ts +61 -0
  143. package/dist/tradeoff/engine.js +171 -0
  144. package/dist/tradeoff/engine.js.map +1 -0
  145. package/dist/tradeoff/heuristics/classSplit.d.ts +3 -0
  146. package/dist/tradeoff/heuristics/classSplit.js +94 -0
  147. package/dist/tradeoff/heuristics/classSplit.js.map +1 -0
  148. package/dist/tradeoff/heuristics/collaborationShape.d.ts +2 -0
  149. package/dist/tradeoff/heuristics/collaborationShape.js +82 -0
  150. package/dist/tradeoff/heuristics/collaborationShape.js.map +1 -0
  151. package/dist/tradeoff/heuristics/collectionShape.d.ts +2 -0
  152. package/dist/tradeoff/heuristics/collectionShape.js +113 -0
  153. package/dist/tradeoff/heuristics/collectionShape.js.map +1 -0
  154. package/dist/tradeoff/heuristics/dualSubjectComparison.d.ts +2 -0
  155. package/dist/tradeoff/heuristics/dualSubjectComparison.js +114 -0
  156. package/dist/tradeoff/heuristics/dualSubjectComparison.js.map +1 -0
  157. package/dist/tradeoff/heuristics/errorHandling.d.ts +2 -0
  158. package/dist/tradeoff/heuristics/errorHandling.js +110 -0
  159. package/dist/tradeoff/heuristics/errorHandling.js.map +1 -0
  160. package/dist/tradeoff/heuristics/responsibilitySplit.d.ts +23 -0
  161. package/dist/tradeoff/heuristics/responsibilitySplit.js +183 -0
  162. package/dist/tradeoff/heuristics/responsibilitySplit.js.map +1 -0
  163. package/dist/tradeoff/heuristics/stereotypeChoice.d.ts +2 -0
  164. package/dist/tradeoff/heuristics/stereotypeChoice.js +23 -0
  165. package/dist/tradeoff/heuristics/stereotypeChoice.js.map +1 -0
  166. package/dist/tradeoff/heuristics/strategyOrPolicy.d.ts +2 -0
  167. package/dist/tradeoff/heuristics/strategyOrPolicy.js +110 -0
  168. package/dist/tradeoff/heuristics/strategyOrPolicy.js.map +1 -0
  169. package/dist/tradeoff/heuristics/valueObjectShape.d.ts +2 -0
  170. package/dist/tradeoff/heuristics/valueObjectShape.js +111 -0
  171. package/dist/tradeoff/heuristics/valueObjectShape.js.map +1 -0
  172. package/dist/tradeoff/templates.d.ts +2 -0
  173. package/dist/tradeoff/templates.js +33 -0
  174. package/dist/tradeoff/templates.js.map +1 -0
  175. package/dist/util/log.d.ts +1 -0
  176. package/dist/util/log.js +7 -0
  177. package/dist/util/log.js.map +1 -0
  178. package/dist/util/mcp.d.ts +4 -0
  179. package/dist/util/mcp.js +18 -0
  180. package/dist/util/mcp.js.map +1 -0
  181. package/dist/validate/cohesion.d.ts +3 -0
  182. package/dist/validate/cohesion.js +88 -0
  183. package/dist/validate/cohesion.js.map +1 -0
  184. package/dist/validate/collectionWrapper.d.ts +3 -0
  185. package/dist/validate/collectionWrapper.js +131 -0
  186. package/dist/validate/collectionWrapper.js.map +1 -0
  187. package/dist/validate/coupling.d.ts +3 -0
  188. package/dist/validate/coupling.js +47 -0
  189. package/dist/validate/coupling.js.map +1 -0
  190. package/dist/validate/cycle.d.ts +3 -0
  191. package/dist/validate/cycle.js +101 -0
  192. package/dist/validate/cycle.js.map +1 -0
  193. package/dist/validate/dataDuplication.d.ts +3 -0
  194. package/dist/validate/dataDuplication.js +150 -0
  195. package/dist/validate/dataDuplication.js.map +1 -0
  196. package/dist/validate/dependencyDirection.d.ts +3 -0
  197. package/dist/validate/dependencyDirection.js +106 -0
  198. package/dist/validate/dependencyDirection.js.map +1 -0
  199. package/dist/validate/dualUseKnowing.d.ts +3 -0
  200. package/dist/validate/dualUseKnowing.js +137 -0
  201. package/dist/validate/dualUseKnowing.js.map +1 -0
  202. package/dist/validate/emptyObjectFill.d.ts +3 -0
  203. package/dist/validate/emptyObjectFill.js +119 -0
  204. package/dist/validate/emptyObjectFill.js.map +1 -0
  205. package/dist/validate/findings.d.ts +22 -0
  206. package/dist/validate/findings.js +12 -0
  207. package/dist/validate/findings.js.map +1 -0
  208. package/dist/validate/functionDecompositionExcess.d.ts +3 -0
  209. package/dist/validate/functionDecompositionExcess.js +120 -0
  210. package/dist/validate/functionDecompositionExcess.js.map +1 -0
  211. package/dist/validate/functionNotObject.d.ts +3 -0
  212. package/dist/validate/functionNotObject.js +80 -0
  213. package/dist/validate/functionNotObject.js.map +1 -0
  214. package/dist/validate/godObject.d.ts +6 -0
  215. package/dist/validate/godObject.js +76 -0
  216. package/dist/validate/godObject.js.map +1 -0
  217. package/dist/validate/presentationInDomain.d.ts +3 -0
  218. package/dist/validate/presentationInDomain.js +57 -0
  219. package/dist/validate/presentationInDomain.js.map +1 -0
  220. package/dist/validate/primitiveWrapper.d.ts +3 -0
  221. package/dist/validate/primitiveWrapper.js +106 -0
  222. package/dist/validate/primitiveWrapper.js.map +1 -0
  223. package/dist/validate/rules.d.ts +24 -0
  224. package/dist/validate/rules.js +269 -0
  225. package/dist/validate/rules.js.map +1 -0
  226. package/dist/validate/singletonStatefulHolder.d.ts +3 -0
  227. package/dist/validate/singletonStatefulHolder.js +128 -0
  228. package/dist/validate/singletonStatefulHolder.js.map +1 -0
  229. package/dist/validate/strategyAsymmetry.d.ts +3 -0
  230. package/dist/validate/strategyAsymmetry.js +131 -0
  231. package/dist/validate/strategyAsymmetry.js.map +1 -0
  232. package/dist/validate/testability.d.ts +5 -0
  233. package/dist/validate/testability.js +157 -0
  234. package/dist/validate/testability.js.map +1 -0
  235. package/dist/validate/vagueName.d.ts +3 -0
  236. package/dist/validate/vagueName.js +136 -0
  237. package/dist/validate/vagueName.js.map +1 -0
  238. package/dist/validate/validationLocation.d.ts +3 -0
  239. package/dist/validate/validationLocation.js +120 -0
  240. package/dist/validate/validationLocation.js.map +1 -0
  241. package/lessons/STYLE_GUIDE.md +304 -0
  242. 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
  243. 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
  244. 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
  245. 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
  246. 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
  247. 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
  248. 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
  249. package/lessons/woowacourse-kotlin-blackjack/HANDOVER.md +1475 -0
  250. 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
  251. 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
  252. 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
  253. 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
  254. 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
  255. 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
  256. 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
  257. 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
  258. 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
  259. 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
  260. 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
  261. 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
  262. 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
  263. 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
  264. 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
  265. 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
  266. 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
  267. 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
  268. 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
  269. 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
  270. 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
  271. 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
  272. 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
  273. 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
  274. 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
  275. 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
  276. 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
  277. 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
  278. 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
  279. 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
  280. 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
  281. 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
  282. 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
  283. 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
  284. 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
  285. 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
  286. 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
  287. 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
  288. 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
  289. 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
  290. 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
  291. 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
  292. 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
  293. 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
  294. 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
  295. 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
  296. 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
  297. 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
  298. 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
  299. 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
  300. 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
  301. 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
  302. 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
  303. 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
  304. 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
  305. 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
  306. 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
  307. 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
  308. 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
  309. 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
  310. 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
  311. 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
  312. 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
  313. 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
  314. 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
  315. 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
  316. 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
  317. 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
  318. 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
  319. 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
  320. 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
  321. 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
  322. 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
  323. 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
  324. 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
  325. 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
  326. 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
  327. 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
  328. 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
  329. 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
  330. 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
  331. 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
  332. 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
  333. 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
  334. 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
  335. 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
  336. 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
  337. 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
  338. 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
  339. 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
  340. 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
  341. 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
  342. 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
  343. 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
  344. 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
  345. 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
  346. 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
  347. 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
  348. 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
  349. 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
  350. 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
  351. 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
  352. 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
  353. 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
  354. 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
  355. 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
  356. 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
  357. 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
  358. 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
  359. 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
  360. 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
  361. 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
  362. 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
  363. 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
  364. 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
  365. 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
  366. 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
  367. 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
  368. 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
  369. 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
  370. 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
  371. 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
  372. 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
  373. 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
  374. 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
  375. 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
  376. 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
  377. 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
  378. package/lessons/woowacourse-kotlin-lotto/2chang5/27-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
  379. package/lessons/woowacourse-kotlin-lotto/2chang5/52-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +187 -0
  380. package/lessons/woowacourse-kotlin-lotto/Choisehyeon/14-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +206 -0
  381. package/lessons/woowacourse-kotlin-lotto/Choisehyeon/47-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +119 -0
  382. package/lessons/woowacourse-kotlin-lotto/DYGames/2-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +83 -0
  383. package/lessons/woowacourse-kotlin-lotto/DYGames/34-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +88 -0
  384. package/lessons/woowacourse-kotlin-lotto/EmilyCh0/12-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
  385. package/lessons/woowacourse-kotlin-lotto/EmilyCh0/40-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +135 -0
  386. package/lessons/woowacourse-kotlin-lotto/HANDOVER.md +217 -0
  387. package/lessons/woowacourse-kotlin-lotto/HamBeomJoon/121-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
  388. package/lessons/woowacourse-kotlin-lotto/HamBeomJoon/139-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +75 -0
  389. package/lessons/woowacourse-kotlin-lotto/Hevton/76-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  390. package/lessons/woowacourse-kotlin-lotto/Hevton/92-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +122 -0
  391. package/lessons/woowacourse-kotlin-lotto/Hogu59/100-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +110 -0
  392. package/lessons/woowacourse-kotlin-lotto/Hogu59/68-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +84 -0
  393. package/lessons/woowacourse-kotlin-lotto/JoYehyun99/60-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +176 -0
  394. package/lessons/woowacourse-kotlin-lotto/JoYehyun99/96-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +71 -0
  395. package/lessons/woowacourse-kotlin-lotto/Junyoung-WON/61-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  396. package/lessons/woowacourse-kotlin-lotto/Junyoung-WON/93-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +16 -0
  397. package/lessons/woowacourse-kotlin-lotto/Leeyerin0210/109-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +57 -0
  398. package/lessons/woowacourse-kotlin-lotto/Leeyerin0210/135-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +115 -0
  399. package/lessons/woowacourse-kotlin-lotto/PROGRESS.md +160 -0
  400. package/lessons/woowacourse-kotlin-lotto/README.md +77 -0
  401. package/lessons/woowacourse-kotlin-lotto/RightHennessy/32-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
  402. package/lessons/woowacourse-kotlin-lotto/RightHennessy/5-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  403. package/lessons/woowacourse-kotlin-lotto/SUMMARY.md +369 -0
  404. package/lessons/woowacourse-kotlin-lotto/SeongHoonC/25-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
  405. package/lessons/woowacourse-kotlin-lotto/SeongHoonC/37-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +27 -0
  406. package/lessons/woowacourse-kotlin-lotto/Yunseok-Nam/72-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +137 -0
  407. package/lessons/woowacourse-kotlin-lotto/Yunseok-Nam/86-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +17 -0
  408. package/lessons/woowacourse-kotlin-lotto/aprilgom/102-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +62 -0
  409. package/lessons/woowacourse-kotlin-lotto/aprilgom/64-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +146 -0
  410. package/lessons/woowacourse-kotlin-lotto/boogi-woogi/11-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
  411. package/lessons/woowacourse-kotlin-lotto/boogi-woogi/29-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
  412. package/lessons/woowacourse-kotlin-lotto/briandr97/26-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
  413. package/lessons/woowacourse-kotlin-lotto/briandr97/51-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +123 -0
  414. package/lessons/woowacourse-kotlin-lotto/chaehyuns/71-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +115 -0
  415. package/lessons/woowacourse-kotlin-lotto/chaehyuns/97-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
  416. package/lessons/woowacourse-kotlin-lotto/chanho0908/124-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +51 -0
  417. package/lessons/woowacourse-kotlin-lotto/chanho0908/129-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  418. package/lessons/woowacourse-kotlin-lotto/chws0508/24-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +117 -0
  419. package/lessons/woowacourse-kotlin-lotto/chws0508/50-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +167 -0
  420. package/lessons/woowacourse-kotlin-lotto/cucumber99/116-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
  421. package/lessons/woowacourse-kotlin-lotto/cucumber99/147-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +223 -0
  422. package/lessons/woowacourse-kotlin-lotto/devfeijoa/125-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +68 -0
  423. package/lessons/woowacourse-kotlin-lotto/devfeijoa/153-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
  424. package/lessons/woowacourse-kotlin-lotto/doabletuple/119-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +157 -0
  425. package/lessons/woowacourse-kotlin-lotto/doabletuple/138-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +77 -0
  426. package/lessons/woowacourse-kotlin-lotto/donghyun81/111-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +67 -0
  427. package/lessons/woowacourse-kotlin-lotto/donghyun81/152-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
  428. package/lessons/woowacourse-kotlin-lotto/dpcks0509/80-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +141 -0
  429. package/lessons/woowacourse-kotlin-lotto/dpcks0509/87-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +134 -0
  430. package/lessons/woowacourse-kotlin-lotto/etama123/112-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +170 -0
  431. package/lessons/woowacourse-kotlin-lotto/etama123/148-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +183 -0
  432. package/lessons/woowacourse-kotlin-lotto/gaeun5744/101-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  433. package/lessons/woowacourse-kotlin-lotto/gaeun5744/78-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +158 -0
  434. package/lessons/woowacourse-kotlin-lotto/gahyunkim/107-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +83 -0
  435. package/lessons/woowacourse-kotlin-lotto/gahyunkim/136-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +51 -0
  436. package/lessons/woowacourse-kotlin-lotto/giovannijunseokim/106-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +171 -0
  437. package/lessons/woowacourse-kotlin-lotto/giovannijunseokim/137-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +111 -0
  438. package/lessons/woowacourse-kotlin-lotto/haeum808/67-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
  439. package/lessons/woowacourse-kotlin-lotto/haeum808/95-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
  440. package/lessons/woowacourse-kotlin-lotto/hwannow/113-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +235 -0
  441. package/lessons/woowacourse-kotlin-lotto/hwannow/132-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  442. package/lessons/woowacourse-kotlin-lotto/hxeyexn/77-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +141 -0
  443. package/lessons/woowacourse-kotlin-lotto/hxeyexn/98-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +162 -0
  444. package/lessons/woowacourse-kotlin-lotto/hyemdooly/17-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +19 -0
  445. package/lessons/woowacourse-kotlin-lotto/hyemdooly/28-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +23 -0
  446. package/lessons/woowacourse-kotlin-lotto/hyunji1203/15-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +171 -0
  447. package/lessons/woowacourse-kotlin-lotto/hyunji1203/48-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +150 -0
  448. package/lessons/woowacourse-kotlin-lotto/ii2001/62-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
  449. package/lessons/woowacourse-kotlin-lotto/ii2001/88-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
  450. package/lessons/woowacourse-kotlin-lotto/ijh1298/122-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +179 -0
  451. package/lessons/woowacourse-kotlin-lotto/ijh1298/133-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +153 -0
  452. package/lessons/woowacourse-kotlin-lotto/inseonyun/3-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +222 -0
  453. package/lessons/woowacourse-kotlin-lotto/inseonyun/49-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +166 -0
  454. package/lessons/woowacourse-kotlin-lotto/ippnsj/16-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +154 -0
  455. package/lessons/woowacourse-kotlin-lotto/ippnsj/55-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
  456. package/lessons/woowacourse-kotlin-lotto/jaeyeongjo/59-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +68 -0
  457. package/lessons/woowacourse-kotlin-lotto/jaeyeongjo/83-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +53 -0
  458. package/lessons/woowacourse-kotlin-lotto/jerry8282/115-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
  459. package/lessons/woowacourse-kotlin-lotto/jerry8282/134-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
  460. package/lessons/woowacourse-kotlin-lotto/jinuemong/63-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +144 -0
  461. package/lessons/woowacourse-kotlin-lotto/jinuemong/89-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +148 -0
  462. package/lessons/woowacourse-kotlin-lotto/jiyuneel/128-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
  463. package/lessons/woowacourse-kotlin-lotto/jiyuneel/144-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  464. package/lessons/woowacourse-kotlin-lotto/junjange/58-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +148 -0
  465. package/lessons/woowacourse-kotlin-lotto/junjange/81-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
  466. package/lessons/woowacourse-kotlin-lotto/junseo511/120-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +153 -0
  467. package/lessons/woowacourse-kotlin-lotto/junseo511/131-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +188 -0
  468. package/lessons/woowacourse-kotlin-lotto/ki960213/43-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +24 -0
  469. package/lessons/woowacourse-kotlin-lotto/ki960213/8-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +159 -0
  470. package/lessons/woowacourse-kotlin-lotto/kimhm0728/74-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +50 -0
  471. package/lessons/woowacourse-kotlin-lotto/kimhm0728/94-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +176 -0
  472. package/lessons/woowacourse-kotlin-lotto/kkosang/85-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
  473. package/lessons/woowacourse-kotlin-lotto/kmkim2689/70-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
  474. package/lessons/woowacourse-kotlin-lotto/kmkim2689/82-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +157 -0
  475. package/lessons/woowacourse-kotlin-lotto/krrong/19-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +161 -0
  476. package/lessons/woowacourse-kotlin-lotto/krrong/41-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +73 -0
  477. package/lessons/woowacourse-kotlin-lotto/m6z1/105-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +67 -0
  478. package/lessons/woowacourse-kotlin-lotto/m6z1/151-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
  479. package/lessons/woowacourse-kotlin-lotto/medAndro/127-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +186 -0
  480. package/lessons/woowacourse-kotlin-lotto/medAndro/130-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +132 -0
  481. package/lessons/woowacourse-kotlin-lotto/moondev03/110-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
  482. package/lessons/woowacourse-kotlin-lotto/moondev03/141-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
  483. package/lessons/woowacourse-kotlin-lotto/murjune/69-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  484. package/lessons/woowacourse-kotlin-lotto/murjune/90-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +177 -0
  485. package/lessons/woowacourse-kotlin-lotto/no1msh/20-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +69 -0
  486. package/lessons/woowacourse-kotlin-lotto/no1msh/46-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  487. package/lessons/woowacourse-kotlin-lotto/otter66/13-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
  488. package/lessons/woowacourse-kotlin-lotto/otter66/53-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +160 -0
  489. package/lessons/woowacourse-kotlin-lotto/oungsi2000/126-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +71 -0
  490. package/lessons/woowacourse-kotlin-lotto/oungsi2000/149-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +56 -0
  491. package/lessons/woowacourse-kotlin-lotto/parkjiminnnn/117-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
  492. package/lessons/woowacourse-kotlin-lotto/parkjiminnnn/146-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +173 -0
  493. package/lessons/woowacourse-kotlin-lotto/pingu244/33-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  494. package/lessons/woowacourse-kotlin-lotto/pingu244/54-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +30 -0
  495. package/lessons/woowacourse-kotlin-lotto/pingu244/7-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +19 -0
  496. package/lessons/woowacourse-kotlin-lotto/re4rk/31-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  497. package/lessons/woowacourse-kotlin-lotto/re4rk/4-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
  498. package/lessons/woowacourse-kotlin-lotto/rhkrwngud445/23-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
  499. package/lessons/woowacourse-kotlin-lotto/rhkrwngud445/38-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
  500. package/lessons/woowacourse-kotlin-lotto/rhthrhrl0/21-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +146 -0
  501. package/lessons/woowacourse-kotlin-lotto/rhthrhrl0/36-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +150 -0
  502. package/lessons/woowacourse-kotlin-lotto/rosemin928/123-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +179 -0
  503. package/lessons/woowacourse-kotlin-lotto/rosemin928/140-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +126 -0
  504. package/lessons/woowacourse-kotlin-lotto/s6m1n/103-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +119 -0
  505. package/lessons/woowacourse-kotlin-lotto/s6m1n/66-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +118 -0
  506. package/lessons/woowacourse-kotlin-lotto/s9hn/18-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +112 -0
  507. package/lessons/woowacourse-kotlin-lotto/sh1mj1/75-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
  508. package/lessons/woowacourse-kotlin-lotto/sh1mj1/91-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +140 -0
  509. package/lessons/woowacourse-kotlin-lotto/songpink/65-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +96 -0
  510. package/lessons/woowacourse-kotlin-lotto/songpink/99-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +64 -0
  511. package/lessons/woowacourse-kotlin-lotto/sujin9/10-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
  512. package/lessons/woowacourse-kotlin-lotto/sujin9/35-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
  513. package/lessons/woowacourse-kotlin-lotto/tmdgh1592/22-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +30 -0
  514. package/lessons/woowacourse-kotlin-lotto/tmdgh1592/30-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
  515. package/lessons/woowacourse-kotlin-lotto/tobae-time/114-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +158 -0
  516. package/lessons/woowacourse-kotlin-lotto/tobae-time/145-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +120 -0
  517. package/lessons/woowacourse-kotlin-lotto/whk06061/42-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  518. package/lessons/woowacourse-kotlin-lotto/whk06061/9-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +89 -0
  519. package/lessons/woowacourse-kotlin-lotto/wondroid-world/118-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +100 -0
  520. package/lessons/woowacourse-kotlin-lotto/wondroid-world/150-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +142 -0
  521. package/lessons/woowacourse-kotlin-lotto/yrsel/108-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
  522. package/lessons/woowacourse-kotlin-lotto/yrsel/143-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +108 -0
  523. 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
  524. 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
  525. 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
  526. 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
  527. 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
  528. 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
  529. 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
  530. 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
  531. 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
  532. 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
  533. package/lessons/woowacourse-racingcar/Hevton/118-/353/246/254/355/214/251/355/204/260/353/247/201.md +51 -0
  534. 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
  535. 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
  536. 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
  537. 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
  538. 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
  539. 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
  540. 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
  541. 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
  542. package/lessons/woowacourse-racingcar/PROGRESS.md +94 -0
  543. package/lessons/woowacourse-racingcar/README.md +69 -0
  544. 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
  545. 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
  546. 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
  547. package/lessons/woowacourse-racingcar/SUMMARY.md +339 -0
  548. 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
  549. 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
  550. 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
  551. 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
  552. 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
  553. package/lessons/woowacourse-racingcar/aprilgom/130-/353/246/254/355/214/251/355/204/260/353/247/201.md +52 -0
  554. 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
  555. 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
  556. 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
  557. 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
  558. 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
  559. package/lessons/woowacourse-racingcar/chaehyuns/131-/353/246/254/355/214/251/355/204/260/353/247/201.md +49 -0
  560. 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
  561. 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
  562. 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
  563. 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
  564. 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
  565. 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
  566. 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
  567. 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
  568. 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
  569. 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
  570. 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
  571. 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
  572. 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
  573. 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
  574. 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
  575. package/lessons/woowacourse-racingcar/gaeun5744/124-/353/246/254/355/214/251/355/204/260/353/247/201.md +53 -0
  576. 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
  577. 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
  578. 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
  579. 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
  580. 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
  581. package/lessons/woowacourse-racingcar/haeum808/129-/353/246/254/355/214/251/355/204/260/353/247/201.md +46 -0
  582. 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
  583. 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
  584. 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
  585. 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
  586. 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
  587. 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
  588. 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
  589. 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
  590. 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
  591. 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
  592. 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
  593. 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
  594. 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
  595. 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
  596. 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
  597. 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
  598. 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
  599. 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
  600. 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
  601. 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
  602. 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
  603. 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
  604. 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
  605. 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
  606. 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
  607. 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
  608. 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
  609. 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
  610. package/lessons/woowacourse-racingcar/kimhm0728/116-/353/246/254/355/214/251/355/204/260/353/247/201.md +54 -0
  611. 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
  612. package/lessons/woowacourse-racingcar/kkosang/126-/353/246/254/355/214/251/355/204/260/353/247/201.md +53 -0
  613. 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
  614. 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
  615. 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
  616. 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
  617. 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
  618. 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
  619. 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
  620. 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
  621. 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
  622. 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
  623. 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
  624. 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
  625. 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
  626. 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
  627. 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
  628. 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
  629. 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
  630. 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
  631. 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
  632. 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
  633. 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
  634. 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
  635. 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
  636. 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
  637. 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
  638. 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
  639. 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
  640. 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
  641. 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
  642. 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
  643. 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
  644. 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
  645. 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
  646. 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
  647. 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
  648. 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
  649. 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
  650. 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
  651. 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
  652. 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
  653. 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
  654. 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
  655. 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
  656. 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
  657. 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
  658. 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
  659. package/package.json +46 -0
  660. package/skills/oh-my-oop/SKILL.md +39 -0
@@ -0,0 +1,232 @@
1
+ # PR #78 — [블랙잭 1단계] 채드 미션
2
+
3
+ - **Reviewee:** [@dpcks0509](https://github.com/dpcks0509)
4
+ - **PR:** https://github.com/woowacourse/kotlin-blackjack/pull/78
5
+ - **단계:** 1단계 (블랙잭 기본 게임 — 카드 분배 / Hit·Stay 진행 / 승패 판정)
6
+ - **리뷰어:** @Gyuil-Hwnag
7
+ - **라인 코멘트:** 30 (리뷰어 19 / 리뷰이 11)
8
+
9
+ ## 잘한 점 (설계 관점)
10
+
11
+ - **`State`를 `sealed interface`로 모델링** — `Running.Hit` / `Finished.Stay`/`Bust`/`BlackJack`. 상태 전이를 `when` 분기 없이 타입으로 표현. 블랙잭의 핵심 도메인 패턴.
12
+ - **`Denomination`(13종) × `Suit`(4종)으로 `Card` 구성** — 두 축 직교 분해. 52장을 곱집합으로.
13
+ - **`Referee` 객체로 승패 판정 책임 분리** — Controller에서 빼냄.
14
+ - **`PlayerEntry` 일급 컬렉션** — `List<Player>` 노출 대신 묶음.
15
+ - **`@BeforeEach`로 test fixture 도입** (리뷰 후 반영) — 매 테스트 setup 중복 제거.
16
+
17
+ ## 못한 점 (설계 관점)
18
+
19
+ ### 1. `BlackJackController`가 god-object — UI/도메인/진행 책임 혼재
20
+
21
+ ```kotlin
22
+ object BlackJackController {
23
+ fun run() {
24
+ val playersName = readPlayersName()
25
+ val (dealer, playerEntry) = showInitialSettingCard(playersName)
26
+ playGame(playerEntry, dealer)
27
+ showGameResult(dealer, playerEntry)
28
+ }
29
+
30
+ private fun readPlayersName(): List<String> {
31
+ showPlayersNameReadMessage()
32
+ return try {
33
+ val playersName = readln().split(',').map { it.trim() }
34
+ require(playersName.all { it.isNotBlank() }) { INVALID_PLAYER_NAME }
35
+ playersName
36
+ } catch (e: IllegalArgumentException) { ... }
37
+ }
38
+
39
+ private fun determinestate(player: Player) {
40
+ if (isBust(player)) player.state = State.Finished.Bust
41
+ else if (isBlackjack(player)) player.state = State.Finished.BlackJack
42
+ }
43
+ }
44
+ ```
45
+
46
+ 리뷰어: "과연 해당내용은 Controller 에서 관리를 하는 것이 맞을지 고민해보면 좋을 것 같습니다!! 요구사항에 `UI 로직을 InputView, ResultView와 같은 클래스를 추가해 분리한다.` 와 같은 내용이 있습니다!!" / "딜러의 상태를 체크하는 것이 과연 Controller 에서 가지고 있어야 하는 책임인지에 대해서 고민해보면 좋을 것 같습니다!!🤔" — *입력 파싱*은 InputView, *상태 결정*은 Player 자신.
47
+
48
+ ### 2. `Card.toString()`이 UI 표현(한국어 + JQKA)을 도메인에 보유
49
+
50
+ ```kotlin
51
+ class Card(val denomination: Denomination, val suit: Suit) {
52
+ override fun toString(): String {
53
+ val number = when (denomination) {
54
+ Denomination.JACK -> "J"
55
+ Denomination.QUEEN -> "Q"
56
+ Denomination.KING -> "K"
57
+ Denomination.ACE -> "A"
58
+ else -> denomination.score
59
+ }
60
+ val shape = when (suit) {
61
+ Suit.CLUBS -> "클로버"
62
+ Suit.DIAMONDS -> "다이아몬드"
63
+ Suit.HEARTS -> "하트"
64
+ Suit.SPADES -> "스페이드"
65
+ }
66
+ return "$number$shape"
67
+ }
68
+ }
69
+ ```
70
+
71
+ 리뷰어: "number & shape에 대한 분기 내용이 Card에서 책임을 지고 있어야 하는지는 고민해보면 좋을 것 같습니다!🤔" — `OutputView`가 카드 → 문자열 매핑을 가져야 함. *UI 언어 변경 = 도메인 수정*은 의존 역전.
72
+
73
+ ### 3. `Deck`을 `object` (Singleton) — 테스트마다 `initialize()` 필요
74
+
75
+ ```kotlin
76
+ object Deck {
77
+ // 전역 단일 상태. 매 테스트 BeforeEach에서 Deck.initialize() 호출.
78
+ fun dealCard(): Card { ... }
79
+ }
80
+
81
+ // 테스트
82
+ class DealerTest {
83
+ @BeforeEach
84
+ fun deckInitialize() { Deck.initialize() }
85
+ }
86
+ ```
87
+
88
+ 리뷰어: "Deck을 object 키워드로 정의하신 이유가 있을까요??" — *전역 변경 가능 상태*는 테스트 격리를 깬다. `class Deck`로 매 게임 새 덱.
89
+
90
+ ### 4. `ScoreCalculation` 정적 유틸 객체 — `Hand`의 책임 누수
91
+
92
+ ```kotlin
93
+ object ScoreCalculation {
94
+ fun calculate(hand: Hand): Int {
95
+ val totalScore = calculateTotalScore(hand)
96
+ return convertAceToOne(totalScore, hand)
97
+ }
98
+ private fun calculateTotalScore(hand: Hand) =
99
+ hand.cards.sumOf { card -> card.denomination.score }
100
+ private fun convertAceToOne(totalScore: Int, hand: Hand): Int {
101
+ var score = totalScore
102
+ val aceCount = hand.cards.count { it.denomination == Denomination.ACE }
103
+ repeat(aceCount) { if (score > BLACKJACK_SCORE) score -= CONVERT_ACE }
104
+ return score
105
+ }
106
+ }
107
+ ```
108
+
109
+ 리뷰어: "해당 객체의 경우 hand 에 대한 계산만을 담당하고 있는 객체 같은데, 해당 책임을 hand 에서 가지고 기능을 하도록 해도 될 것 같다는 생각이 듭니다!!" — `hand.score()` 가 Tell-Don't-Ask. 정적 유틸은 *데이터를 빼앗긴 객체* 신호 (feature-envy).
110
+
111
+ ### 5. `Dealer.judgeDraw()` 매직넘버 16
112
+
113
+ ```kotlin
114
+ class Dealer(val hand: Hand) {
115
+ var state: State = State.Running.Hit
116
+ fun judgeDraw(): Boolean = ScoreCalculation.calculate(hand) <= 16
117
+ }
118
+ ```
119
+
120
+ 리뷰어: "조건의 경우 하드 코딩되어 있는 내용을 상수로 관리를 해봐도 좋을 것 같다는 생각이 듭니다🤔" — `DEALER_HIT_THRESHOLD = 16`. 더 본질적으로는 *딜러 정책*을 `Dealer`만의 룰로 표현.
121
+
122
+ ### 6. `State`에 `READY` 누락 — 게임 시작 직후 상태 없음
123
+
124
+ ```kotlin
125
+ sealed interface State {
126
+ sealed interface Running : State {
127
+ data object Hit : Running
128
+ }
129
+ sealed interface Finished : State {
130
+ data object Stay : Finished
131
+ data object Bust : Finished
132
+ data object BlackJack : Finished
133
+ }
134
+ }
135
+ ```
136
+
137
+ 리뷰어: "유저가 카드를 뽑지 않는 경우도 존재를 하는데, 이에 대해서도 추가를 하면 추후에 조건이 바뀌었을 때 좀더 유연하게 적용을 할 수 있을것 같다는 생각이 듭니다🤔" — 모든 Player가 `Hit`로 시작하면 *2장 받은 직후 = Hit* 상태인지 *Ready* 상태인지 모호. 학생은 후속에 `READY` 추가.
138
+
139
+ ### 7. `Hand`가 외부에서 `Deck.dealCard()`를 받아 넣음
140
+
141
+ ```kotlin
142
+ // Controller가 Hand에 카드 주입
143
+ dealer.hand.draw(Deck.dealCard())
144
+
145
+ // askPlayerDraw 내부
146
+ player.hand.draw(Deck.dealCard())
147
+ ```
148
+
149
+ `Hand`는 *어떤 카드인지*만 알고 *어디서 왔는지* 무관해야 함. *진행자 객체*(Dealer 또는 GameInformation)가 Deck과 Hand 사이 *중개* 책임을 가져야 자연. (이는 PR #125 jerry8282의 학생 자가 의문과 연결 — *카드를 나누어주는 진행자의 역할*은 누구인가.)
150
+
151
+ ### 8. 함수명과 변수명 동명 — `drawOrNot`
152
+
153
+ ```kotlin
154
+ private fun askPlayerDraw(player: Player) {
155
+ while (player.state is State.Running.Hit) {
156
+ val drawOrNot = askPlayersDraw(player) // 변수
157
+ if (drawOrNot == DRAW_DECISION) {
158
+ player.hand.draw(Deck.dealCard())
159
+ drawOrNot(drawOrNot, player) // 함수 (변수와 동명)
160
+ ...
161
+ }
162
+ }
163
+ }
164
+ ```
165
+
166
+ 리뷰어: "drawOrNot 함수와 drawOrNot 변수는 물론 다르지만 네이밍이 같음으로서 자칫 혼란을 야기할 수 있겠다는 생각이 듭니다🥲" — 더 큰 문제는 *동일 메서드 호출 흐름이 두 번 발생* (`drawOrNot()` 안에서 `determinestate()` 호출되는데 바로 다음 줄에서도 `determinestate()`를 또 호출 — 코드 자체의 *의도 불명*).
167
+
168
+ ### 9. `Hand(mutableListOf<Card>())`를 Controller가 직접 구성
169
+
170
+ ```kotlin
171
+ private fun dealingCards(playersName: List<String>): List<Hand> {
172
+ val hands = List(playersName.size + 1) { Hand(mutableListOf()) }
173
+ repeat(2) { hands.forEach { hand -> hand.draw(Deck.dealCard()) } }
174
+ return hands
175
+ }
176
+ ```
177
+
178
+ `Hand(mutableListOf())`로 외부에서 *빈 컬렉션*을 만들어 주입. `Hand()`의 기본 생성자가 빈 상태로 시작해야 자연. *컬렉션 mutable 노출* + *외부 채우기*는 lotto의 `empty-object-external-fill` 안티패턴과 동일.
179
+
180
+ ### 10. `ProgressView.showPlayerHand` vs `showDealerHand` — 중복
181
+
182
+ ```kotlin
183
+ fun showPlayerHand(player: Player) { ... } // top-level
184
+ private fun showDealerHand(dealer: Dealer) { ... } // top-level private
185
+ ```
186
+
187
+ 리뷰어: "같은 기능을 하는 것으로 보이는데, 하나의 함수로 통합할 수 있다면 통합해보는 것도 좋을 것 같다는 생각이 듭니다!💪" — `Player`와 `Dealer`가 *카드 가진 자*라는 공통 상위 추상이 없어 view에서 중복. 도메인의 *역할 부재*가 view 중복으로 드러남.
188
+
189
+ ### 11. 테스트 함수명이 *결과만* 표현
190
+
191
+ ```kotlin
192
+ @Test
193
+ fun `Denomination, Suit 조합으로 된 객체 생성`() { ... }
194
+ ```
195
+
196
+ 리뷰어 권고: ``자동차가 1칸 이동하면 거리는 1이다`` 같은 *시나리오 + 결과* 형식. 학생은 후속에 반영.
197
+
198
+ ## 리뷰어 의견 요지
199
+
200
+ - **Controller는 진행 흐름만** — UI 입출력은 View, 상태 판단은 도메인.
201
+ - **`Card.toString` UI 표현 분리** — `OutputView`가 카드→문자열 책임.
202
+ - **`Deck` Singleton 회피** — 매 게임 새 덱 (테스트 격리).
203
+ - **점수 계산은 `Hand`의 책임** — 정적 유틸 객체 제거.
204
+ - **매직넘버 16 상수화** + 딜러 정책으로 캡슐화.
205
+ - **`State`에 READY 추가** — 초기 상태 명시.
206
+ - **테스트 fixture (`@BeforeEach`)** + 시나리오 + 결과 네이밍.
207
+
208
+ ## 대표 인용
209
+
210
+ > 해당 객체의 경우 hand 에 대한 계산만을 담당하고 있는 객체 같은데, 해당 책임을 hand 에서 가지고 기능을 하도록 해도 될 것 같다는 생각이 듭니다!!
211
+ > — @Gyuil-Hwnag on `src/main/kotlin/blackjack/model/game/ScoreCalculation.kt`
212
+
213
+ > number & shape에 대한 분기 내용이 Card에서 책임을 지고 있어야 하는지는 고민해보면 좋을 것 같습니다!🤔
214
+ > — @Gyuil-Hwnag on `src/main/kotlin/blackjack/model/card/Card.kt`
215
+
216
+ > 딜러의 상태를 체크하는 것이 과연 Controller 에서 가지고 있어야 하는 책임인지에 대해서 고민해보면 좋을 것 같습니다!!🤔
217
+ > — @Gyuil-Hwnag on `src/main/kotlin/blackjack/controller/BlackJackController.kt`
218
+
219
+ > 유저가 카드를 뽑지 않는 경우도 존재를 하는데, 이에 대해서도 추가를 하면 추후에 조건이 바뀌었을 때 좀더 유연하게 적용을 할 수 있을것 같다는 생각이 듭니다🤔
220
+ > — @Gyuil-Hwnag on `src/main/kotlin/blackjack/model/game/State.kt`
221
+
222
+ ## 얻은 교훈
223
+
224
+ - **`State` = `sealed interface`** — 블랙잭의 핵심 도메인. `Running`(Hit) / `Finished`(Stay/Bust/BlackJack) + 초기 `Ready`. `when` 분기 대신 *타입으로 분리*하면 상태별 메서드를 각 데이터 객체에 둘 수 있음.
225
+ - **점수 계산은 `Hand`의 책임** — `ScoreCalculation.calculate(hand)`는 *데이터를 빼앗긴 객체* (feature-envy). `hand.score()`가 Tell-Don't-Ask.
226
+ - **`Card.toString`에 UI 표현 박지 말 것** — JACK→"J" / CLUBS→"클로버" 같은 *언어/UI 결합*은 `OutputView`로. (lotto의 `side-effect-in-holder` 룰 적용 가능.)
227
+ - **`Deck` Singleton(`object`) 금지** — 전역 변경 가능 상태. 매 게임 새 `Deck` 인스턴스가 자연. *셔플도 새 덱마다 한 번*.
228
+ - **딜러 정책(`<=16 then Hit`)은 `Dealer` 안에** — 매직넘버 16은 *블랙잭 규칙*. Controller가 *조건 비교*를 하면 정책이 누수.
229
+ - **`Hand(mutableListOf())` + 외부 채우기 = `empty-object-external-fill`** — `Hand()` 기본 생성자가 빈 상태로 시작. Deck에서 받는 책임은 *Dealer/Game* 같은 *진행자*.
230
+ - **테스트 함수명 = 시나리오 + 결과** — *"객체 생성"* 같은 기능 라벨 X. *"딜러 합이 16 이하면 카드를 더 받는다"* 같은 *행동 기술*.
231
+ - **`State.READY` 누락은 *시작 = 진행 중*과 *시작 직후 = 미결정*의 혼동 신호** — sealed로 모델링하면서 *모든 가능 상태*를 빠뜨리지 않는 것이 핵심.
232
+ - **`drawOrNot` 함수와 변수 동명** — 가장 작은 안티패턴이지만 *읽기 비용*은 큼. 변수는 `decision` 등 *결과*를 표현하는 이름으로.
@@ -0,0 +1,137 @@
1
+ # PR #88 — [블랙잭 2단계] 채드 미션
2
+
3
+ - **Reviewee:** [@dpcks0509](https://github.com/dpcks0509)
4
+ - **PR:** https://github.com/woowacourse/kotlin-blackjack/pull/88
5
+ - **단계:** 2단계 (베팅 / 수익률 / 블랙잭 1.5배)
6
+ - **리뷰어:** @Gyuil-Hwnag (두루)
7
+ - **라인 코멘트:** 28 스레드 / 48 코멘트 — *reviewer 칭찬 위주 + 학생이 모든 코멘트 후속 반영*
8
+
9
+ ## 잘한 점 (설계 관점)
10
+
11
+ - **`BettingAmount` 원시값 포장** — 두루 자가 칭찬: *"BettingAmount 에 대한 원시값 포장 좋습니다~👍"*. *Int → 도메인 객체 wrap* 정공.
12
+ - **`Calculator → Revenue → GameRevenue` 책임 분리 흐름 자가 반영** — 두루의 *"Player의 이윤을 계산하는 것인데, 해당 내용이 과연 Calculator 에 있어야 하는지"* 진단 → 학생 *"Revenue 클래스를 따로 만들어 분리"* → 추가 진단 *"게임 Player에 대한 결과를 구하는 것인데, 과연 Revenue에 있는 것이 맞을까"* → 학생 *"Result 클래스에서 승무패 결과를 구하도록 분리"* → *PlayerRevenue/DealerRevenue sealed class → GameRevenue 통합* (지나친 추상화 회피).
13
+ - **`Card data class + toString() override` 자가 학습** — 두루 자가 인용: *"toString의 활용과 Card를 data class로 만들어주셨네요~ 이번 리뷰때 여쭤보려고 남겨두었는데ㅎㅎ 정말 좋습니다!!"*. *Kotlin data class + toString 어휘 활용*.
14
+ - **`Revenue.toString()` 오버라이딩 — View 책임 분리** — 두루의 *"해당 내용을 Revenue라는 객체를 만들고 toString을 오버라이딩 하는 방법으로 해봐도 좋을 것 같다"* 권고 → 학생 자가 반영: *"Revenue클래스에서 toString으로 처리하였습니다!"*.
15
+ - **InputView / OutputView 분리 자가 반영 — `SettingInputView` / `ProgressInputView` + `ProgressOutputView` / `ResultOutputView`** — 두루의 *"InputView도 InitializeInputView, GameInputView 등으로 분리"* 권고 → 학생 자가 반영. *View 책임을 단계별로 분리* — *입력 받기 단계 vs 게임 진행 단계*. *MCP 룰 후보 — `view-by-stage-split`*. PR #131 (다이스 2단계) 의 *BlackJackInputView/BlackJackOutputView interface* 와 비교: *interface vs 단계별 분리* 트레이드오프.
16
+ - **`model` 패키지 분리 — `card` / `game` / `user`** — 두루 권고 *"model 내에서도 금액, 참가자, 결과를 담당하는 객체들의 패키지를 나눠두는 것"* 자가 반영. *도메인 그룹별 패키지* 가 *프로젝트 구조 명료성*.
17
+ - **`PlayerRevenue` / `DealerRevenue` sealed class → `GameRevenue` 통합 자가 후퇴** — 두루: *"현재 구현하신 내용을 보면 너무 지나치게 Sealed Class로 Player와 Delear를 나눈 것으로 보입니다🥲 ... `명확하게 기능을 담당하지 않은 상태에서의 지나친 추상화 가독성과 해당 객체에 대한 명확한 책임 판별을 와해 시킨다는 생각이 듭니다`"*. 학생 자가 반영: *"PlayerRevenue와 DealerRevenue를 Revenue라는 객체를 가지는 GameRevenue라는 하나의 클래스로 통합"*. **지나친 추상화 회피 자가 학습 모범**.
18
+ - **`GameInformation` 삭제 → Hand + State 분리 자가 반영** — 두루의 *"Participant 객체에서 Score를 가지고 있는다. Hand 내부에서 State에 대해서 상태를 들고 있으며, State에 결정은 Hand 에서 draw()함수를 호출할 때 내부적으로 판단을 한다. ... player.gameInformation.hand.cards 이렇게 계속 깊게 들어가는 구현이 사라질수 있을 것 같다"* 진단 → 학생 자가 반영: *"Hand 내부에서 cards를 가지고 있기 때문에 Participant보다는 Hand가 score를 가지고 있는게 더 어울린다고 생각하여 수정하였고, Participant가 state를 가지고 있게 하여 GameInformation을 삭제"*. **Demeter 위반 해소**. PR #133 (시아 2단계) 의 *Items + Demeter 깊이* 와 같은 결.
19
+ - **테스트 함수명 *행위→결과* 자가 학습** — 두루의 *"테스트 함수명을 좀 더 명확하게 `행위 -> 결과`로 작성"* + *"`Ace가 2장 있을 때 카드 점수의 합은 12이다` 라는 테스트 함수명"* 권고 자가 반영. *테스트 = 명세*.
20
+ - **테스트 매직넘버 상수화 자가 반영** — 두루 권고 자가 후속.
21
+ - **Kotlin `named arguments` 자가 학습** — 두루의 *실제 이슈 예시 (`val foo = Foo(100)` → 의도와 다른 결과)* + named arguments 권고 → 학생 자가 반영: *"judgeDrawOrNot함수의 readDecision과 output에 대하여 named arguments을 적용"*.
22
+ - **`readDecision() = false` 같은 *불필요한 헬퍼* 자가 삭제** — 두루의 *"아래의 해당 코드가 있어야 하는 이유가 궁금합니다"* 진단 → 학생 *"함수를 삭제하고 true, false를 직접 넣어주는 방식으로 변경"*.
23
+ - **Players 객체 생성 위치 자가 결정 (`SettingInputView`)** — 두루 권고 *"Players 객체에서 담당을 해보도록"* 에 대해 학생 자가 답변: *"Players 객체를 따로 만드는 것 보다는 이름과 베팅금액을 입력받을때 바로 Players를 만들어서 반환하는 것이 더 좋은 방법이 될 것 같다는 생각에 SettingInputView에서 처리"*. **권고 vs 자가 판단의 합리적 분리**.
24
+ - **함수 분리 자가 반영** — 두루의 *"`딜러의 이윤을 출력`, `플레이어의 이윤을 출력` 과 같이 하나의 함수에서는 하나의 기능을 담당"* 권고 후속.
25
+
26
+ ## 못한 점 (설계 관점)
27
+
28
+ ### 1. `GameInformation` 통합 객체 — *3 변수 제약 회피용 인공 객체 (자가 인식)*
29
+
30
+ 학생 자가 답변: *"GameInformation이 없고 Hand와 State를 각각 나눠서 가지고 있게 되면 Participant에서 ParticipantInformation, Hand, State를 생성자에서 가지고 있기 때문에 \"3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다.\"라는 요구조건을 지키지 못한다고 생각하여, GameInformation을 Hand와 State를 가지도록 묶었습니다..!"*
31
+
32
+ → **`GameInformation = Hand + State` 묶음 = *3 변수 제약 회피용 인공 객체***. *학생이 자가 인식*. *후속 반영* 시 GameInformation 삭제 → Hand + State 직접 보유로 후퇴. 깊이 ↓ + 인공 객체 ↓.
33
+
34
+ PR #133 (시아 2단계) 의 *Items* / PR #132 (환노 2단계) 의 *BetStatus/ProceedStatus* / PR #136 (밀러 2단계) 의 *BlackJackPair* 와 같은 결의 *3 변수 제약 부산물* 패턴.
35
+
36
+ ### 2. `Information` / `Manager` / `Calculator` 만능 명사 — 자가 후퇴 흐름
37
+
38
+ 학생 흐름:
39
+ 1. `Calculator` (이윤 계산) — 두루 진단 *"Calculator 에 있어야 하는지"*
40
+ 2. `Revenue` 클래스 분리
41
+ 3. `GameRevenue` 게임 결과 분리
42
+ 4. `PlayerRevenue` / `DealerRevenue` sealed class (지나친 추상화)
43
+ 5. `GameRevenue` 통합 (자가 후퇴)
44
+
45
+ → **`Calculator` 같은 *만능 명사*가 *초기 책임 분배의 함정***. *MCP 룰 후보 — `vague-class-name` 룰의 *Calculator/Information/Manager* 변형*. 학생 자가 후퇴로 *완전한 도메인 어휘 (Revenue/GameRevenue)*로 정착.
46
+
47
+ ### 3. `Participant.gameInformation.hand.cards` Demeter 깊이 (수정 전) — 자가 해소
48
+
49
+ 두루 진단: *"`player.gameInformation.hand.cards` 이렇게 계속 깊게 들어가는 구현이 사라질수 있을 것 같다"*. 학생 자가 반영 후 *`player.cards` (Participant 위임)* 로 짧아짐.
50
+
51
+ ### 4. *지나친 추상화 (`Sealed Class`로 Player/Dealer Revenue 분리)*
52
+
53
+ 두루 진단: *"명확하게 기능을 담당하지 않은 상태에서의 지나친 추상화 가독성과 해당 객체에 대한 명확한 책임 판별을 와해 시킨다는 생각이 듭니다"*
54
+
55
+ → **추상화 = 도메인 차이가 있을 때만**. *PlayerRevenue vs DealerRevenue 의 책임 차이가 크지 않으면 통합*. *학생 자가 후퇴 = 추상화의 트레이드오프 학습 모범*. PR #131 (다이스 2단계) 의 *Hand → PersonCards 수직 분리 후 다시 합침* 과 같은 결.
56
+
57
+ ### 5. 메서드명 *judgeXXX* / *readXXX* — 명확성 개선 여지
58
+
59
+ ```kotlin
60
+ fun readDecision(): Boolean = false // ⚠ 호출자가 어떤 의미인지 모름
61
+ fun judgeDrawOrNot(...) { ... }
62
+ ```
63
+
64
+ → *judgeXX = 판단 + 결과*. *Kotlin 어휘로는 `shouldDraw(): Boolean`* 같은 *부울 메시지*가 자연. 학생 자가 일부 반영.
65
+
66
+ ### 6. *`Hand` 부 생성자 미사용* 자가 발견
67
+
68
+ ```kotlin
69
+ class Hand(cards: List<Card>) { ... }
70
+ ```
71
+
72
+ 두루 진단 → 학생 *"다른데서 사용한다고 생각하고 생성자로 만들어놓았는데 다른데서 사용이 되지않아 삭제 처리"*.
73
+
74
+ → **불필요한 생성자 미리 추가 = 추측 코딩**. *YAGNI 위반*. *현재 사용처에서 시작 + 필요 시 추가*가 정공.
75
+
76
+ ## 리뷰어 의견 요지
77
+
78
+ - **칭찬 위주 + 메타 질문** — *🤔 / 👍 / 💪* 다수. *깊은 진단 < 자가 학습 기회 제공*. PR #131 (다이스 2단계) 와 같은 결.
79
+ - **지나친 추상화 = 가독성 + 책임 판별 와해** — *추상화는 도메인 차이가 있을 때만*. *Sealed class 무분별 사용 경계*.
80
+ - **테스트 함수명 = 행위 → 결과** — *`Ace가 2장 있을 때 카드 점수의 합은 12이다`* 같은 *기능 명세*.
81
+ - **named arguments — 실제 이슈 예시** — *`Foo(100)` 호출이 의도와 다른 결과* 의 실제 사례. *Kotlin named arguments 가 그 방지*.
82
+ - **`toString` override = View 책임 분리** — *도메인 객체의 문자열 표현* 을 *도메인 자체가 알리고 View는 받기만*.
83
+ - **단일 책임 함수 분리** — *딜러 + 플레이어 출력 한 함수 → 별도 함수*.
84
+ - **만능 명사 → 도메인 어휘** — *Calculator → Revenue → GameRevenue* 흐름.
85
+ - **3 변수 제약 = 연습 도구, 너무 얽매이지 말 것** — *GameInformation 같은 인공 객체 회피*.
86
+
87
+ ## 대표 인용
88
+
89
+ **두루 (지나친 추상화 경계, Revenue.kt):**
90
+ > 현재 구현하신 내용을 보면 너무 지나치게 Sealed Class로 Player와 Delear를 나눈 것으로 보입니다🥲
91
+ > 해당 내용은 Revenue라는 객체를 가지고 함수로 PlayerRevenue와 DelearRevenue를 분리하는 것은 어떤가 하는 생각이 듭니다🤔
92
+ >
93
+ > `명확하게 기능을 담당하지 않은 상태에서의 지나친 추상화 가독성과 해당 객체에 대한 명확한 책임 판별을 와해 시킨다는 생각이 듭니다`
94
+
95
+ **두루 (Demeter 위반 자가 해소 권고, GameInformation.kt):**
96
+ > 추후에 시간이 된다면 아래와 같은 방법으로 바꿔보는 것도 해보시면 좋을 것 같다는 생각이 듭니다!!
97
+ > 1. Participant 객체에서 Score를 가지고 있는다.
98
+ > 2. Hand 내부에서 State에 대해서 상태를 들고 있으며, State에 결정은 Hand 에서 draw()함수를 호출할 때 내부적으로 판단을 한다.
99
+ >
100
+ > 위의 2가지가 충족이 된다면, GameInformation 이라는 객체는 사라질 수 있겠다는 생각이 듭니다💪
101
+ > 또한, 위처럼 수정을 하게된다면, player.gameInformation.hand.cards 이렇게 계속 깊게 들어가는 구현이 사라질수 있을 것 같다는 생각이 듭니다~
102
+
103
+ **두루 (named arguments 실제 이슈 예시, BlackJackController.kt):**
104
+ > 실제로 있었던 이슈를 예시로 공유를 드리고자 합니다.
105
+ > 아래와 같은 `Foo()`라는 함수가 존재를 하며, 각각의 a, b, c 에 들어가는 값에 따라서 로직에서 호출을 하는 함수가 다르다고 할때, Foo()에 대해서 파악을 하지 않은 상태에서 아래와 같이 `val foo = Foo(100)` 으로 선언을 하여, c라는 결과를 생각했지만, a라는 결과가 나와서 중요기능이 동작을 하지 않았던 이슈가 있었습니다.
106
+
107
+ **학생 자가 답변 (GameInformation 통합 이유 자가 인식, GameInformation.kt):**
108
+ > GameInformation이 없고 Hand와 State를 각각 나눠서 가지고 있게 되면 Participant에서 ParticipantInformation, Hand, State를 생성자에서 가지고 있기 때문에 "3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다."라는 요구조건을 지키지 못한다고 생각하여, GameInformation을 Hand와 State를 가지도록 묶었습니다..!
109
+ > State를 판별하는 로직을 GameState 안에서 판별하도록 로직의 위치를 변경하였습니다!
110
+
111
+ **학생 자가 후속 (Demeter 해소 + 인공 객체 삭제, GameInformation.kt):**
112
+ > Hand 내부에서 cards를 가지고 있기 때문에 Participant보다는 Hand가 score를 가지고 있는게 더 어울린다고 생각하여 수정하였고, Participant가 state를 가지고 있게 하여 GameInformation을 삭제해 보았습니다!
113
+
114
+ **학생 자가 답변 (권고 vs 자가 판단 합리적 분리, BlackJackController.kt):**
115
+ > Players 객체를 따로 만드는 것 보다는 이름과 베팅금액을 입력받을때 바로 Players를 만들어서 반환하는 것이 더 좋은 방법이 될 것 같다는 생각에 SettingInputView에서 처리하게 수정해 보았습니다!
116
+
117
+ ## 얻은 교훈
118
+
119
+ 1. ***지나친 추상화 = 가독성 + 책임 판별 와해***. *PlayerRevenue / DealerRevenue sealed class* 처럼 *책임 차이가 작은데 추상화*는 *코드 복잡도 ↑ + 의의 부재*. *통합 = 추상화의 트레이드오프 학습*. PR #131 (다이스 2단계) 의 *Hand → PersonCards 분리 후 다시 합침* 과 같은 결.
120
+
121
+ 2. ***`Calculator`/`Information`/`Manager` 같은 만능 명사 = 책임 분배의 함정***. *책임이 안 잡힌 곳에 *Calculator* 가 등장*. *Revenue / GameRevenue / Result* 같은 *도메인 어휘*로 후퇴가 정공. *MCP `vague-class-name` 룰 확장*: *Calculator/Information/Manager* 추가 후보. PR #128·#125·#114·#10 와 같은 결의 *vagueName 안티패턴 변형*.
122
+
123
+ 3. ***`GameInformation = Hand + State` 묶음 = 3 변수 제약 회피용 인공 객체*** — 학생 자가 인식 + 후속 삭제. PR #133·#132·#136 와 같은 결의 *제약 부산물 vs 정당한 도메인 객체* 트레이드오프. *제약은 연습 도구* (말리빈/두루 공통 진단).
124
+
125
+ 4. ***Demeter 위반 = `a.b.c.d` 점 체인 = 협력 부재 신호***. *`player.gameInformation.hand.cards`* 가 *4 단계*. *위임 메서드 (Participant.cards)* 가 *호출자가 알아야 하는 객체 수 최소화*. PR #133·#131·#152·#136·#128·#135 와 같은 결.
126
+
127
+ 5. ***Kotlin `named arguments` = 인자 순서 함정 방지***. *실제 이슈 사례 = Foo(100) 호출이 의도와 다른 결과*. *`Foo(a = 0, b = 0, c = 100)` named* 가 *호출 의도 명시 + 컴파일러 안전성*. *Kotlin 어휘 활용 모범*.
128
+
129
+ 6. ***`toString` override = 도메인 객체가 자기 문자열 표현 알림***. *View 의 형식 지정 책임 vs 도메인 객체의 표현 책임* 트레이드오프. *현재는 도메인 객체가 자기 표현* — *Tell-Don't-Ask 변형*. *주의: 도메인 객체가 view 의 모든 형식을 흡수하면 도메인-뷰 결합*. *toString = 디버깅 + 단순 표현*에 한정 권고.
130
+
131
+ 7. ***테스트 함수명 = 행위 → 결과 (기능 명세)***. *"Ace가 2장 있을 때 카드 점수의 합은 12이다"* 같은 *도메인 명세*. *함수명 종속 X*. PR #128·#135·#152·#124·#125 와 같은 결.
132
+
133
+ 8. ***View 단계별 분리 (`SettingInputView` / `ProgressInputView`)*** = *View 책임이 단계별로 다름을 노출*. *입력 받기 단계 (베팅, 이름) vs 게임 진행 단계 (Hit/Stay)* 가 *다른 책임*. **MCP 룰 후보 — `view-by-stage-split`** (PR #131 의 *interface 분리* vs PR #88 의 *단계별 분리* 두 표현). PR #131·#132 와 같은 결.
134
+
135
+ 9. ***불필요한 생성자 미리 추가 = YAGNI 위반***. *Hand 부 생성자 미사용 자가 발견 + 삭제*. *현재 사용처에서 시작 + 필요 시 추가* 가 *Kotlin 어휘 활용 정공*.
136
+
137
+ 10. ***리뷰어 칭찬 위주 + 학생 100% 후속 반영 = PR #131·#136 와 같은 결의 모범 학습***. *두루의 *🤔/👍/💪* 메타 질문 위주 + 학생이 모든 코멘트 후속 반영*. *깊은 안티패턴 진단 < 자가 학습 기회 제공* 의 reviewer 스타일 변형.
@@ -0,0 +1,269 @@
1
+ # PR #112 — [블랙잭 1단계] 에타마 미션
2
+
3
+ - **Reviewee:** [@etama123](https://github.com/etama123)
4
+ - **PR:** https://github.com/woowacourse/kotlin-blackjack/pull/112
5
+ - **단계:** 1단계
6
+ - **리뷰어:** @krrong (크롱)
7
+ - **라인 코멘트:** 30 (리뷰어 14 / 리뷰이 16)
8
+
9
+ ## 잘한 점 (설계 관점)
10
+
11
+ - **`Card private constructor + Card.of()` + `Card.getAllCard()` 캐시 — Flyweight 패턴** — 52장 인스턴스를 *유한 집합*으로 제어. lotto의 `LottoNumber` Flyweight와 동일 결.
12
+ - **`Participant` 추상 클래스 + `Dealer`/`Player`** — `hitThreshold`만 추상화하고 *Hit 가능 판단*은 공통.
13
+ - **`Deck(shuffledDeck: List<Card>)` 명시 주입** — 외부에서 카드 순서 제어 → 결정적 테스트.
14
+ - **`Suit`/`Rank` enum + `getScore()`** — Ace=11 기본, 보정은 별도.
15
+ - **학생 자가 토론 — *현실 세계 딜러 vs 객체 딜러* 차이를 미리 PR 본문에 제기** (못한 점 §1).
16
+ - **후속 반영 — `@BeforeEach`로 Deck 격리 + `Card.toString` UI 이관 + `FakeParticipant`를 test 클래스 내부로 이동**.
17
+
18
+ ## 못한 점 (설계 관점)
19
+
20
+ ### 1. `Dealer.getCard(deck: Deck)`가 *초기화 시점에 모든 카드 뽑기* — 현실 게임과 어긋남
21
+
22
+ ```kotlin
23
+ class Dealer : Participant() {
24
+ override val hitThreshold: Int get() = DEALER_HIT_THRESHOLD
25
+ fun getCard(deck: Deck) {
26
+ while (canHit()) {
27
+ addCard(deck.draw())
28
+ }
29
+ }
30
+ fun hasAdditionalCard(): Boolean = cards.size > INITIAL_CARD_COUNT
31
+ }
32
+ ```
33
+
34
+ 학생 자가 토론(PR 본문): "딜러는 첫 번째 카드만 오픈하기 때문에 / hit / stay 여부를 외부에서 입력받지 않기 때문에 / 로직 자체에서 hit의 여부가 결정되기 때문에 딜러 내부에서 카드를 뽑는 로직을 설정했습니다. 하지만 이처럼 *카드를 미리 뽑아두는게, 현실 세계에서의 게임 진행과 다르기 때문에 괜찮을까* 의문이 들었어요."
35
+
36
+ 리뷰어: "현실에서는 딜러가 가지고 있는 카드를 나눠주지만, 객체지향에서는 *참가자와 마찬가지로 카드를 받는 존재*로 볼 수 있습니다!"
37
+
38
+ 학생 해명: "딜러가 2장의 카드를 받은 후, 합이 16 이하일 경우 추가 카드를 뽑고, 17 이상이면 멈추는 규칙을 반영하기 위해 2장 이상의 카드를 미리 뽑아두는 것을 의미했습니다."
39
+
40
+ → 패턴: *흐름 단순화*를 위해 *시점을 압축*. 그러나 *Player는 turn 단위 진행 / Dealer는 한 번에 끝남* 의 *비대칭*이 생김. *진행자(Game)*가 Dealer에게 *한 장씩* 메시지 보내는 것이 *대칭적 추상*. 이후 `hasAdditionalCard()` 같은 *상태 조회 메서드*가 *압축된 시점 복구*용으로 필요해진 점이 신호 (못한 점 §2).
41
+
42
+ ### 2. `Dealer.hasAdditionalCard()` — 압축된 시점을 풀기 위한 추적 메서드
43
+
44
+ ```kotlin
45
+ fun hasAdditionalCard(): Boolean = cards.size > INITIAL_CARD_COUNT
46
+ ```
47
+
48
+ 리뷰어: "이 메서드가 필요한 이유는 무엇인가요? 🤔" — *Dealer가 미리 다 뽑은* 결과를 *나중에 "추가로 뽑았는지" 묻는* 메서드. *시점 압축 → 복구 메서드*의 안티패턴. *한 장씩 진행*하면 *추가 뽑기 발생 = 그 자체로 사건*이라 별도 추적 불필요.
49
+
50
+ ### 3. `Card.toString()` UI 표현 박힘
51
+
52
+ ```kotlin
53
+ class Card private constructor(val rank: Rank, val suit: Suit) {
54
+ fun getScore() = this.rank.score
55
+ override fun toString(): String = rank.toDisplayName() + suit.toDisplayName()
56
+ }
57
+
58
+ fun Rank.toDisplayName(): String = when (this) { Rank.ACE -> "A"; ... }
59
+ fun Suit.toDisplayName(): String = when (this) { Suit.SPADE -> "♠"; ... }
60
+ ```
61
+
62
+ 리뷰어: "`toString`을 오버라이드 한 이유에 대해 생각해보고 도메인에서 필요로 하는 것인가 고민해보면 좋겠어요 🤔"
63
+ 학생 자가 인정: "주소값이 출력되었기 때문에 toString을 오버라이드하면 문제가 해결되기에 가벼운 마음으로 사용했습니다. 하지만 결국 이 부분도 UI 로직에 더 가깝다고 생각이 되네요 🥶" — *디버깅 편의*로 시작한 *도메인 메서드*가 *UI 표현 의존*을 도메인에 끌어들임. PR #78·#125와 같은 결.
64
+
65
+ ### 4. `Rank.toDisplayName()` 확장 함수 — 도메인 파일에 *View 함수*
66
+
67
+ ```kotlin
68
+ // blackjack/domain/Rank.kt
69
+ enum class Rank(val score: Int) {
70
+ ACE(11), ... ;
71
+ }
72
+ fun Rank.toDisplayName(): String = when (this) { ... "A" ... } // 같은 파일
73
+
74
+ // blackjack/domain/GameResultStatus.kt
75
+ enum class GameResultStatus { PLAYER_WIN, PLAYER_LOSE, DRAW }
76
+ fun GameResultStatus.toDisplayName(): String = when (this) { PLAYER_WIN -> "승"; ... }
77
+ ```
78
+
79
+ 학생 자가 변호: "각 Enum 클래스와 밀접한 관련이 있기 때문에 해당 클래스 아래에 위치하는 것이 가독성과 직관성 측면에서 더 적절하다고 생각합니다."
80
+
81
+ 리뷰어: "관련이 있는 enum클래스에 함께 작성하는 것과 OutputView에 작성하기 모두 장단점이 있어서 트레이드 오프의 영역이라고 볼 수 있어요. 현재의 구현 방식은 출력의 형태를 Win, Lose, Draw 로 변경하려 할 때 *Domain역시 변경이 필요*한데요. 이에 대해서도 고민해보면 좋을 것 같습니다. 그런데 이와는 별개로 *꼭 확장 함수를 사용해야할까요?* 🤔"
82
+
83
+ 학생 후속 인정: "view 관련 로직들은 모두 outputview로 이동시켰습니다." — *Kotlin DSL 수업에서 배운 확장 함수*를 *어디든 적용해보기*는 *기능 사용 욕구*가 *역할 결정*을 압도한 신호.
84
+
85
+ ### 5. `Deck`이 `LinkedList<Card>` — 자료구조 선택의 정당화 부재
86
+
87
+ ```kotlin
88
+ class Deck(shuffledDeck: List<Card>) {
89
+ private val deck = LinkedList(shuffledDeck)
90
+ }
91
+ ```
92
+
93
+ 리뷰어: "`LinkedList`...요? 🤔" — *왜 `ArrayDeque`나 `MutableList`가 아니고 `LinkedList`인가?* 자료구조 선택은 *접근 패턴에 따른 결정*(랜덤 액세스 빈도, 양 끝 추가/제거 등). 블랙잭의 *맨 위 카드 꺼내기*는 `ArrayDeque.removeFirst()` 또는 `MutableList.removeFirst()`로 충분. `LinkedList`는 *Java 컬렉션 어휘*를 *습관적 선택*한 신호.
94
+
95
+ ### 6. `Participant.addCard()`가 *카드 추가 + 합산* 두 일
96
+
97
+ ```kotlin
98
+ fun addCard(card: Card) {
99
+ cards.add(card)
100
+ totalSum = calculateTotalSum() // 추가하면서 totalSum도 갱신
101
+ }
102
+ ```
103
+
104
+ 리뷰어: "addCard라는 메서드명을 보고 카드를 뽑겠구나라고 기대했지만 내부에서는 *총합을 함께 계산*하고 있어요. 하나의 함수가 하나의 일만 할 수 있도록 변경해볼까요 🤠" — *Command-Query 혼합* 변형. `addCard()`는 *카드 추가*만, `totalSum`은 *접근 시점 계산*(custom get())이 자연. *상태 캐시 갱신*을 *액션과 묶으면* 호출자가 `totalSum`의 *최신성*을 *항상* 신경 써야 함.
105
+
106
+ ### 7. `Participant.cards: MutableList<Card>` public — 일급 컬렉션 부재
107
+
108
+ ```kotlin
109
+ abstract class Participant {
110
+ var totalSum: Int = 0
111
+ private set
112
+ val cards: MutableList<Card> = mutableListOf() // public mutable
113
+ ...
114
+ }
115
+ ```
116
+
117
+ 리뷰어: "*카드들을 갖는 일급 컬렉션을 만들어볼까요?* 어떤 장점을 얻을 수 있을까요? 🤔" — `Hand`/`Cards` 일급 컬렉션이 *cards 보관 + 점수 계산 + Ace 보정*을 담당하면 `Participant`는 *결정 + 정체성*만. (PR #123 후반의 자가 인정과 같은 결.)
118
+
119
+ ### 8. `BLACKJACK_LIMIT = 21` 이름 — 상수 의미와 사용처 불일치
120
+
121
+ ```kotlin
122
+ companion object {
123
+ const val BLACKJACK_LIMIT = 21
124
+ const val ACE_SCORE_DIFFERENCE = 10
125
+ }
126
+
127
+ fun isBust(): Boolean = totalSum > BLACKJACK_LIMIT
128
+ ```
129
+
130
+ 리뷰어: "21은 *BUST의 기준!* 으로 네이밍하는게 더 적절해 보이네요 🤠" — 21을 *블랙잭 한계*로 표현했으나 *사용처는 모두 Bust 판정*. `BUST_THRESHOLD = 21` 또는 `BLACKJACK_SCORE = 21`이 도메인 어휘와 *사용 의도* 둘 다 일치.
131
+
132
+ ### 9. `Rank.ACE.score = 11` — 일반 통념과 어긋남
133
+
134
+ ```kotlin
135
+ enum class Rank(val score: Int) {
136
+ ACE(11), // ⚠ 일반적으로 1
137
+ TWO(2), THREE(3), ...
138
+ }
139
+ ```
140
+
141
+ 리뷰어: "일반적으로 ACE는 몇이라고 생각할까요? 🤔" — *Ace를 11로 시작 + 합이 21 초과면 보정*은 *블랙잭의 한 가지 알고리즘*이지만, *Ace의 기본값*은 보통 *1*. *알고리즘 편의*가 *도메인 어휘를 왜곡*한 신호. (대안: *Ace를 1로 시작 + 11점 추가 검토 시점에 +10*. — PR #63 리뷰어 권고와 동일.)
142
+
143
+ ### 10. `calculateTotalSum`이 *while + 차감* Ace 보정 — 복잡
144
+
145
+ ```kotlin
146
+ private fun calculateTotalSum(): Int {
147
+ var score = cards.sumOf { it.getScore() }
148
+ var aceCount = cards.count { it.rank == Rank.ACE }
149
+ while (score > BLACKJACK_LIMIT && aceCount > 0) {
150
+ score -= ACE_SCORE_DIFFERENCE
151
+ aceCount--
152
+ }
153
+ return score
154
+ }
155
+ ```
156
+
157
+ 리뷰어: "ACE가 포함된 카드의 총합을 구하는 방법을 다시 한 번 고민해볼까요? 🤔" — PR #63와 동일한 *while + 차감* 패턴. *Ace = 1로 시작 + 합 ≤ 11이면 +10* 한 줄 룰로 단순화 가능.
158
+
159
+ ### 11. `DealerResult` / `GameResult` / `PlayerResult` — 결과 객체 셋
160
+
161
+ ```kotlin
162
+ class GameResult(private val dealer: Dealer, val players: List<Player>) {
163
+ val dealerResult = DealerResult()
164
+ private val playerResult: MutableList<PlayerResult> = mutableListOf()
165
+ }
166
+ class DealerResult { /* WIN count, LOSE count, ... */ }
167
+ class PlayerResult { /* Player + GameResultStatus */ }
168
+ ```
169
+
170
+ 리뷰어: "`DealerResult`, `GameResult`, `PlayerResult` 게임의 결과를 위한 길이 많이 험난해보여요 😵‍💫 블랙잭은 *딜러와 플레이어간의 게임*입니다. 이 말을 잘 곱씹어보면 *플레이어의 승패는 딜러의 승패와 관련*이 있는 것 같아요." — *Dealer 결과 = Player 결과의 역집계*. `Map<Player, GameResultStatus>` 한 자료구조로 *딜러 통계 = entries.groupBy { it.value }* 도출 가능. 객체 3개로 흩뜨리면 *동기화 책임*만 늘어남.
171
+
172
+ 학생 자가 토론: "Dealer와 Player 모두 같은 **Participant**이므로, 결과도 비슷한 형태로 저장할 수 있지 않을까 고민했습니다. 현재 `PlayerResult가` `Player`와 `GameResultStatus`를 가지는 것처럼, `Result`도 `Participant`와 `GameResult`를 가지는 방식으로 구조를 개선하는 것을 고민 중입니다." — *공통 추상*까지 도달했으나 *역집계로 단순화*는 미발견.
173
+
174
+ ### 12. `CardTest`가 *Deck 기능 테스트*
175
+
176
+ ```kotlin
177
+ class CardTest {
178
+ @Test
179
+ fun `Card는 52개의 인스턴스만 가질 수 있다`() {
180
+ // Card.getAllCard().size == 52 검증
181
+ }
182
+ }
183
+ ```
184
+
185
+ 리뷰어: "CardTest이지만 Deck의 기능을 테스트하는 것처럼 보이네요 🤔" — `Card.getAllCard()`는 *Card의 정적 메서드*지만 *전체 카드 집합 = Deck의 책임*. *Flyweight 캐시 보유자*와 *덱의 책임*이 같은 메서드에 모임. `Card.getAllCard()` → `Deck.createShuffledDeck()` 같은 이름이 자연.
186
+
187
+ ### 13. `ParticipantTest`에서 *Deck 호출 = 한 장 가져오기*로 오해 가능 함수명
188
+
189
+ ```kotlin
190
+ @Test
191
+ fun `덱에서 한 장의 카드를 가져올 수 있다`() {
192
+ val fake = FakeParticipant()
193
+ fake.addCard(Card.of(Rank.ACE, Suit.SPADE)) // Deck 안 거치고 직접
194
+ ...
195
+ }
196
+ ```
197
+
198
+ 리뷰어: "작성한 테스트는 *덱에서 한 장의 카드를 가져오는 것처럼 보이지 않*네요 😅" — 테스트가 *FakeParticipant.addCard()*를 호출하지만 함수명은 *덱에서 가져오기*. *시나리오 + 결과*가 *코드와 일치*해야.
199
+
200
+ ### 14. `DeckTest`에서 *enum 순서 의존 + 클래스 멤버 직접 초기화*
201
+
202
+ ```kotlin
203
+ class DeckTest {
204
+ private val testDeck = Deck(Card.getAllCard()) // 클래스 필드 초기화
205
+ @Test
206
+ fun `뽑은 카드는 덱에 존재하지 않는다`() {
207
+ val card1 = testDeck.draw()
208
+ assertThat(card1).isEqualTo(Card.of(Rank.ACE, Suit.SPADE)) // enum 순서 의존
209
+ ...
210
+ }
211
+ }
212
+ ```
213
+
214
+ 리뷰어: "`testDeck`을 위처럼 선언하면 어떤 문제가 생길 수 있을까요? 🤔" / "`Suit` 혹은 `Rank`의 순서가 변경되면 어떻게 될까요? 🤔" — *순서 의존* + *공유 인스턴스*. 학생 후속 반영: `@BeforeEach` + *반환값이 덱에 포함되어 있는지*로 *명시적 검증*.
215
+
216
+ ### 15. `FakeParticipant` 위치 — 프로덕션 소스 X, 테스트 fixture로
217
+
218
+ ```kotlin
219
+ // src/test/kotlin/blackjack/FakeParticipant.kt
220
+ class FakeParticipant : Participant() { ... }
221
+ ```
222
+
223
+ 리뷰어: "테스트용 객체를 만들었네요 👏 한 곳에서만 사용하고 있는 것 같으니 *위치를 옮겨볼 수도* 있을 것 같아요!" — 1회만 쓰이면 *fixture* 파일에 둘 필요 없이 *테스트 클래스 내부 private*. 학생 후속 반영.
224
+
225
+ ## 리뷰어 의견 요지
226
+
227
+ - **현실 딜러 ≠ 객체 딜러** — 객체 딜러도 *카드를 받는 존재*. *미리 다 뽑기*는 *시점 압축 + 복구 메서드 필요*의 신호.
228
+ - ***DealerResult/GameResult/PlayerResult* 셋은 과잉** — *Player 결과 → Dealer 통계 역집계*.
229
+ - **`toString` 도메인 X, `OutputView` ○.**
230
+ - **enum 옆 *toDisplayName 확장함수*는 *도메인-뷰 결합*** — 가까이 두고 싶은 욕구 vs 변경 전파.
231
+ - ***`addCard`가 합산까지*** — CQS 혼합.
232
+ - ***일급 컬렉션 부재*** — `MutableList<Card>` public.
233
+ - **`LinkedList` 선택의 정당화** — `ArrayDeque`/`MutableList`가 자연.
234
+ - **`BLACKJACK_LIMIT` 명명** — 사용처가 Bust 판정.
235
+ - **`ACE = 11` 일반 통념과 어긋남.**
236
+ - ***while + 차감 Ace 보정* 복잡** — *Ace 1 시작 + 11점 단일 검토*.
237
+ - ***테스트 멤버 직접 초기화 + enum 순서 의존*** — `@BeforeEach` + 명시 검증.
238
+
239
+ ## 대표 인용
240
+
241
+ > 현실에서는 딜러가 가지고 있는 카드를 나눠주지만, 객체지향에서는 *참가자와 마찬가지로 카드를 받는 존재*로 볼 수 있습니다!
242
+ > — @krrong on `src/main/kotlin/blackjack/domain/Dealer.kt`
243
+
244
+ > `DealerResult`, `GameResult`, `PlayerResult` 게임의 결과를 위한 길이 많이 험난해보여요 😵‍💫 블랙잭은 *딜러와 플레이어간의 게임*입니다. 이 말을 잘 곱씹어보면 *플레이어의 승패는 딜러의 승패와 관련*이 있는 것 같아요.
245
+ > — @krrong on `src/main/kotlin/blackjack/domain/DealerResult.kt`
246
+
247
+ > addCard라는 메서드명을 보고 카드를 뽑겠구나라고 기대했지만 내부에서는 *총합을 함께 계산*하고 있어요. 하나의 함수가 하나의 일만 할 수 있도록 변경해볼까요 🤠
248
+ > — @krrong on `src/main/kotlin/blackjack/domain/Participant.kt`
249
+
250
+ > 일반적으로 ACE는 몇이라고 생각할까요? 🤔
251
+ > — @krrong on `src/main/kotlin/blackjack/domain/Rank.kt`
252
+
253
+ > 출력의 형태를 Win, Lose, Draw 로 변경하려 할 때 *Domain역시 변경이 필요*한데요. [...] 그런데 이와는 별개로 *꼭 확장 함수를 사용해야할까요?* 🤔
254
+ > — @krrong on `src/main/kotlin/blackjack/domain/GameResultStatus.kt`
255
+
256
+ ## 얻은 교훈
257
+
258
+ - **객체 딜러는 *카드를 받는 존재*. *현실 비유*가 *시점 압축*을 정당화하면 *복구용 상태 조회 메서드*(`hasAdditionalCard()`)가 필요해짐 — 시점 압축 신호.**
259
+ - **`toString()`은 *도메인 메서드*가 아님** — 디버깅 편의로 시작해도 결국 *UI 결합*. `OutputView.format(card)` 자연.
260
+ - **enum 옆 `toDisplayName()` 확장 함수 = *근거리 변경 편의*가 *역할 결정*을 압도** — *수업에서 배운 기능 적용 욕구*가 *역할 분리*를 흐림.
261
+ - ***`addCard()`가 합산까지* = CQS 혼합** — `addCard` 액션 + `totalSum` 접근 시 계산이 자연.
262
+ - ***결과 객체 셋(`DealerResult`/`GameResult`/`PlayerResult`)은 과잉*** — `Map<Player, GameResultStatus>` 단일 자료구조 + 역집계가 더 단순. *공통 추상*까지 갔는데 *단순화*는 미발견.
263
+ - **`LinkedList`는 *Java 어휘 습관* 선택** — Kotlin은 `ArrayDeque`/`MutableList`로 *맨 위 카드 꺼내기*가 더 자연.
264
+ - **`BLACKJACK_LIMIT = 21` 명명은 *사용처와 의도*로** — 모든 사용처가 Bust 판정이면 `BUST_THRESHOLD`가 정직.
265
+ - **`Rank.ACE.score = 11` = 일반 통념 위배** — *알고리즘 편의*가 *도메인 어휘*를 왜곡. *Ace = 1 기본 + 11 검토*가 통념 일치.
266
+ - ***while + 차감 Ace 보정*은 PR #63·#78과 동일한 안티패턴 — *합 ≤ 11이면 +10* 한 줄 룰.**
267
+ - **`CardTest`가 *Deck 책임* 검증** — `Card.getAllCard()`라는 *Flyweight 캐시 메서드* 위치가 모호하면 *덱의 책임*도 *Card에 누수*.
268
+ - ***테스트 fake가 한 곳만 쓰이면 내부 private*** — 별도 파일은 *재사용 의도가 있을 때만*.
269
+ - **enum `entries` 순서를 *테스트 진실*로 삼지 말 것** — 순서 변경 = 테스트 깨짐.