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,269 @@
1
+ # PR #135 — [블랙잭 2단계] 화이팅 미션
2
+
3
+ - **Reviewee:** [@ijh1298](https://github.com/ijh1298)
4
+ - **PR:** https://github.com/woowacourse/kotlin-blackjack/pull/135
5
+ - **단계:** 2단계 (베팅 추가 — 수익률 계산, 블랙잭 1.5배 규칙)
6
+ - **리뷰어:** @krrong (크롱)
7
+ - **라인 코멘트:** 30 (리뷰어 13 / 리뷰이 17)
8
+
9
+ ## 잘한 점 (설계 관점)
10
+
11
+ - **`Card.standardCards: Map<Pair<CardNumber, Suit>, Card>` Flyweight** — *(13×4 = 52)* 인스턴스만 공유. `Card.of(cn, suit)` 팩토리.
12
+ - **`BetAmount` 원시값 포장** — 베팅 금액의 invariant 분리.
13
+ - **`PlayerBetInfo(player, betAmount)` 묶음 객체** — *세 변수 이상 클래스 회피* 요구사항 대응.
14
+ - **`drawSafely + Deck.refill()` 빈 덱 복구 패턴 (후속)** — null 반환 → refill → 재시도. (못한 점 §1 참고.)
15
+ - **`Hand.isBlackJack()` *2장 + 21점*으로 명시 분리** — *점수 동률 = 무승부 오판* (PR #128) 수정.
16
+ - **`Casino` Controller 명명** — *블랙잭 게임을 진행하는 장소* 도메인 비유.
17
+ - **후속 반영 — `Scoreboard`에서 *수익 계산*만 `BetRecords`로 이전 + `Dealer.profit = -sum(players.profit)` 단순화 + Elvis 연산자**.
18
+
19
+ ## 못한 점 (설계 관점)
20
+
21
+ ### 1. `Deck.refill()` 자동 채움 vs 명시 신호
22
+
23
+ ```kotlin
24
+ // Before
25
+ fun pop() = if (cards.isEmpty()) { refill(); cards.removeFirst() } else cards.removeFirst()
26
+
27
+ // After (학생 후속)
28
+ private fun drawSafely(number: Int, deck: Deck): List<Card> {
29
+ val drawnDeck = deck.pop(number)
30
+ if (drawnDeck == null) {
31
+ deck.refill()
32
+ return drawSafely(number, deck)
33
+ }
34
+ return drawnDeck
35
+ }
36
+ ```
37
+
38
+ 리뷰어 (PR #128 시점): "*덱이 비어있으면 덱을 스스로 채우고 있는데요. 이를 사용하는 동료 개발자가 이를 예상할 수 있을까요?* 🤔"
39
+ 학생 후속: "컨트롤러에서 카드를 꺼내오고, *null이 반환되었다면 카드에게 refill을 해달라는 메시지*를 던진 후에 다시 카드를 꺼내올 수 있도록 메서드를 추가"
40
+ 리뷰어 평가: "*처음 의견은 덱을 채우지 않아도 괜찮다였는데, 이런 방식도 새롭고 좋네요* 😊" — *컨트롤러가 refill 시점을 명시*. 다만 *재귀 호출*은 *덱이 항상 채워질 수 있다*는 가정에 의존.
41
+
42
+ ### 2. `Casino` Controller의 모든 변수에 *명시 타입 선언* — 과잉 명시
43
+
44
+ ```kotlin
45
+ fun run() {
46
+ val deck: Deck = Deck(cardsGenerator)
47
+ val participants: Participants = Participants(Dealer(), setPlayers())
48
+ val playerBetInfos: List<PlayerBetInfo> = setPlayerBetInfos(participants.players)
49
+ ...
50
+ }
51
+ ```
52
+
53
+ 리뷰어: "*nit: 자료형을 명시해주는 이유가 있나요?* (https://github.com/woowacourse/kotlin-blackjack/pull/128#discussion_r1989251469 *2트째*)"
54
+
55
+ 학생 자가 변호: "원래는 해당 습관이 없었지만 *레벨1 제이슨의 수업을 계속해서 들으면서 자료형을 명시하는 게 더 이해가 쉽다고 생각*했습니다. 제가 작성한 코드더라도 *시간이 지난 후 읽으면 이 변수의 자료형이 무엇인지 쉽게 짐작하기 어려울 때*가 있고 [...] 제 기준은 *모든 자료형을 다 남기는 것*입니다!"
56
+
57
+ → *모든 변수 타입 명시*는 Kotlin 관례와 어긋남. `val deck = Deck(cardsGenerator)`는 *우변이 타입 자명*. *명시가 도움 되는 경우*(예: 인터페이스 반환의 *상위 추상*으로 다루고 싶을 때)가 아니면 *과잉*. *읽기 수월함*은 *변수명 + 우변*으로도 충분.
58
+
59
+ ### 3. `Player.play()` / `Dealer.play()` Controller로 회수 — 학생 자가 토론
60
+
61
+ ```kotlin
62
+ // PR #128 (1단계)
63
+ fun play(deck: Deck, onResponse: (String) -> Boolean, displayCards: (Player) -> Unit) {
64
+ while (isDrawable()) {
65
+ if (!onResponse(name)) { displayCards(this); break }
66
+ drawCard(deck)
67
+ displayCards(this)
68
+ }
69
+ }
70
+ // PR #135 — 제거 후 Controller로 이동
71
+ ```
72
+
73
+ 학생 자가 인정: "play 메서드를 컨트롤러로부터 이전했던 이유는 *Player가 게임을 자기 턴을 진행하는 게 능동적*이라는 생각했기 때문이었습니다. 이전하고 나니 제가 생각하는 play 메서드는 다음과 같은 단점이 생겼습니다. 😅 - *테스트하기 어렵다*. - *모델에게 view를 호출하는 메서드를 고차함수로 넘기는 찝찝함*. - *메서드가 단일 책임을 가지고 있지 않음*. 따라서, 차라리 *모델의 흐름을 제어할 수 있는 컨트롤러에서 적절한 순서로 메서드를 호출*하는 게 적합하다는 판단을 했습니다."
74
+
75
+ 리뷰어: "*플레이어 혹은 딜러가 자기 턴을 진행하는 것은 능동적인 것이 맞습니다. 현실 세계에서는요. 하지만 객체지향의 세계에서도 능동적인 것이 맞을지 혹은 다른 객체들과의 협력을 통해 할 수는 없는지 와 같은 부분들을 앞으로도 고민*해보면 좋을 것 같습니다." — *현실 비유로 자율성*은 *반쪽*. *객체지향 자율성*은 *결정 책임이 자기에게 있느냐*. `play()`에 *입력 callback*과 *출력 callback*이 들어오면 *결정은 외부*. → 자율성 흉내만. *Controller로 회수*가 옳은 선택. 학생도 자가 정리.
76
+
77
+ ### 4. `Hand.cards: deepCopy()` 방어적 복사 변경 — 백킹 프로퍼티 사용 미숙
78
+
79
+ ```kotlin
80
+ // Before
81
+ class Hand {
82
+ private var _cards = mutableListOf<Card>()
83
+ private val cards get() = _cards.toList()
84
+ }
85
+ // After (학생 후속 시도)
86
+ class Hand {
87
+ private var _cards = listOf<Card>() // ⚠ List는 이미 불변
88
+ private val cards get() = _cards.deepCopy()
89
+ }
90
+ ```
91
+
92
+ 리뷰어: "*backing property를 어떻게 사용하는지 한번 더 확인해보면 좋겠습니다.* 또한, *방어적 복사를 위해 이렇게 수정한 이유가 무엇일까요?* 이전 방법과는 어떻게 다른지 알려주세요"
93
+
94
+ 학생 자가 인정: "*backing property를 적용한 이유는 외부에서 cards 리스트를 수정하지 않게 하고 싶어서였습니다!* 그런데 *이미 둘 다 private으로 선언해두고 있는 실수* 때문에 *제대로 그 효과를 얻지 못한* 것 같습니다😓 [...] *deepCopy를 통해서 외부에 보여주는 hand의 cards는 새로운 카드 객체가 생성되고 있어서 캐싱해놓은 이점이 사라지지 않는 것 아닐까* 하는 생각이 듭니다.."
95
+
96
+ → 백킹 프로퍼티의 정석은 `private val _cards: MutableList<Card>` + `val cards: List<Card> get() = _cards`. *외부에 List 인터페이스만 노출* → 불변 view. `deepCopy()`는 *Card 자체가 불변*이면 *불필요한 비용*. `Card`가 Flyweight (52장 캐싱)인데 *deepCopy*로 새 인스턴스 생성하면 *Flyweight 이점 무효화*. 학생도 자가 의문.
97
+
98
+ ### 5. `Hand.isBlackJack()` + `isNotBlackJack()` 둘 다 — 부정형 함수의 *역설*
99
+
100
+ ```kotlin
101
+ fun isBlackJack(): Boolean = cards.size == 2 && getScore() == BLACK_JACK_NUMBER
102
+ fun isNotBlackJack(): Boolean = !isBlackJack()
103
+ ```
104
+
105
+ 리뷰어: "*블랙잭인가 블랙잭이 아닌가를 나눌 이유가 있나요?* 🤔"
106
+
107
+ 학생 자가 변호: "코틀린 역시 `isBlank()`, `isNotBlank()` 메서드를 따로 지원하기도 하고, `!opponent.hand.isBlackJack()`처럼 *긴 코드는 not 연산자를 보지 못하고 지나칠 수 있다*고 생각했습니다."
108
+
109
+ → Kotlin stdlib `isBlank`/`isNotBlank`는 *고빈도 + 사용 측이 명확히 읽기 위한* 예외. *도메인 객체*에 *둘 다 노출*하면 *호출 측 선택*이 증가하고 *부정 의미 함수 명*가 *컬렉션처럼* 늘어남. 한 가지로 통일하고 호출 측 `!isBlackJack()`이 더 적은 책임.
110
+
111
+ ### 6. `Participant.drawCard(cards: List<Card>)` + `cards.forEach(hand::add)` — 메서드 참조 사용
112
+
113
+ ```kotlin
114
+ fun drawCard(cards: List<Card>) {
115
+ cards.forEach(hand::add)
116
+ }
117
+ ```
118
+
119
+ 리뷰어: "*일반 함수에 비해 메서드 참조가 갖는 장점은 무엇인지 찾아보시고 위 코드에서 메서드 참조를 통해 넘겨야 하는 이유를 설명해주세요.*"
120
+
121
+ 학생 자가 변호: "메서드 참조를 사용한 이유는 *수업에서 함수형 프로그래밍에 대해 배웠고 적용해볼겸 사용*했습니다. drawCard 메서드에 적용하는 메서드 참조는 비교적 간단해서 *굳이 적용할 필요가 없어 보이기도 하지만*, 람다 식이 복잡해지면 *참조를 이용해서 간결하게 적을 수 있다*는 장점이 있을 듯 합니다!" — *기능 사용 욕구*가 *적용 정당화*. `cards.forEach { hand.add(it) }`도 동일. *메서드 참조의 가치*는 *재사용성 + 람다 본문 노이즈 제거*이지 *수업 적용*이 아님. (PR #65 callback 폭증과 같은 결.)
122
+
123
+ ### 7. `Participants(dealer, players)` vs `List<Participant>` — 학생 자가 토론
124
+
125
+ ```kotlin
126
+ class Participants(val dealer: Dealer, val players: List<Player>)
127
+ ```
128
+
129
+ 리뷰어: "`Dealer`와 `Player`모두 `Participant`를 상속받고 있기 때문에 `List<Participant>`로 묶어줄 수 있고, *이 점을 알고 있던 것처럼 보입니다. 코드가 변경된 이유가 무엇인가요?*"
130
+
131
+ 학생 자가 변호: "*메서드에 넘기는 인자의 수를 줄이기 위해 딜러와 플레이어의 조합인 Participants 객체를 만들었습니다.* 또한 `List<Participants>`를 사용하면 *Dealer, List<Player>를 분리하는 로직이 (가능은 하겠지만) 직관적이지 못할 듯해서* Participants 클래스를 만들어 사용했습니다. [...] 다만 *역할과 책임이 없고 단순히 프로퍼티를 감싸기 위한 객체*를 생성하고 있다는 생각이 들었습니다. 😅 *이 방식은 객체를 적절하게 사용하고 있지 않은 걸까요..?*"
132
+
133
+ → PR #63 (jinuemong)의 *Participants 첫 0번 = Dealer invariant* 문제를 *타입 분리*로 해결. 그러나 *프로퍼티 묶음만*이라 *역할*이 없음. *initialCardsDistribute / runPlayersDrawPhase* 같은 *공통 작업*을 `Participants` 메서드로 끌어오면 *Tell-Don't-Ask*. 학생이 자가 의문 인식.
134
+
135
+ ### 8. `PlayerBetInfo(player, betAmount)` — *세 변수 회피* 요구사항이 만든 분리
136
+
137
+ ```kotlin
138
+ class PlayerBetInfo(private val player: Player, private val betAmount: BetAmount) { ... }
139
+ ```
140
+
141
+ 학생 자가 인정: "*인스턴스 변수가 세 개 이상인 클래스를 사용하지 마라는 요구사항에 의해* 이 객체를 생성하게 되었습니다. BetAmount 객체를 만들 때, *플레이어가 베팅 금액을 들고 있는게 제일 적절*하다고 생각했습니다! 다만 *Player가 name, hand를 이미 지니고 있어 betAmount의 프로퍼티를 추가하게 되면 요구사항을 어기게 되었습니다*.😓 따라서 *플레이어와 그 사람의 베팅 정보를 지니고 있는 객체*를 만들어서 이 객체가 *수익금을 구하는 역할*을 지니게 했습니다."
142
+
143
+ 리뷰어: "*커밋 기록을 보니 베팅금액의 위치가 바뀌었던데 이유가 무엇인가요?* *플레이어 개인의 베팅금액은 스스로가 가지고 있는게 좋지 않을까요?*"
144
+
145
+ → **형식 규칙(*변수 3개 이하*)이 도메인 모델을 왜곡한 신호**. *PlayerBetInfo*는 *요구사항 회피용 인공물*. *Player가 betAmount를 갖는 자연 표현*이 *형식 규칙*에 의해 *분리*. 형식 규칙은 *코드를 단순화하는 도구*인데 *목적이 도구 자체*가 되면 안 됨. PR #63의 `BlackJack` 객체 / PR #128의 `Rule` 객체와 같은 결.
146
+
147
+ ### 9. `Scoreboard`가 *결과 + 수익* 둘 다 — 책임 비대
148
+
149
+ ```kotlin
150
+ class Scoreboard(private val participants: Participants) {
151
+ fun getDealerProfit(playerBetInfos: List<PlayerBetInfo>): Double {
152
+ val playersProfit: Collection<Double> = getPlayersProfit(playerBetInfos).values
153
+ return -playersProfit.filter { it < 0.0 }.sum() - playersProfit.filter { it > 0.0 }.sum()
154
+ }
155
+ fun getPlayersProfit(...): Map<Player, Double> { ... }
156
+ fun getResults(): Map<Player, GameResult> { ... }
157
+ ...
158
+ }
159
+ ```
160
+
161
+ 리뷰어: "*현재 구현한 `Scoreboard`는 게임 결과를 가져오는 것 외에도 많은 일을 하고 있습니다.* 그렇다면 *우리는 이제 뭔가 해야겠죠?*" / "*현재 구현에서는 플레이어의 수익을 통해 딜러의 수익을 쉽게 구할 수 있는 것처럼 보이네요.*" — *결과 조회*(승/패/무) + *수익 계산*(원금 × 배수) 두 책임. 학생 후속: *수익 계산*만 `BetRecords`로 이전 + `dealerProfit = -sum(playersProfit)` 단순화 (PR #112와 같은 *역집계* 패턴).
162
+
163
+ ### 10. `Dealer.showFirstCard()` + `Player.showCards(): List<Card>` — *공개 카드 수*가 도메인 룰
164
+
165
+ ```kotlin
166
+ class Dealer : Participant {
167
+ fun showFirstCard(): Card = hand.toList().first()
168
+ }
169
+ class Player : Participant {
170
+ // showCards는 모든 카드 공개
171
+ }
172
+ ```
173
+
174
+ 리뷰어: "*카드를 처음으로 공개할 때 딜러는 1장을, 플레이어는 2장을 공개하는데, 이는 비즈니스 로직으로 볼 수 있지 않을까요?* 즉, *우리가 만든 참가자 아래에서 딜러와 플레이어가 각각 어떻게 다른 구현을 갖도록 만들어 볼* 수 있을 것 같아요." — `Participant.showInitialCards()` 추상 메서드 + Dealer는 1장, Player는 2장 *Liskov 호환 구현*. 도메인 룰을 *Participant 추상화 아래*로. 학생 후속 시도: "*다음과 같이 수정해봤는데 크롱의 피드백의 의도에 맞는지 정확히 모르겠습니다..*"
175
+
176
+ ### 11. `Player.compareTo`에 *블랙잭 우선 + Bust 우선* 순서 분기
177
+
178
+ ```kotlin
179
+ override fun compareTo(opponent: Participant): GameResult {
180
+ return when {
181
+ hand.isBlackJack() && opponent.hand.isNotBlackJack() -> GameResult.BLACKJACK_WIN
182
+ hand.isBlackJack() && opponent.hand.isBlackJack() -> GameResult.DRAW
183
+ hand.isBust() -> GameResult.LOSE
184
+ opponent.hand.isBust() -> GameResult.WIN
185
+ myScore > opponentScore -> GameResult.WIN
186
+ myScore == opponentScore -> GameResult.DRAW
187
+ else -> GameResult.LOSE
188
+ }
189
+ }
190
+ ```
191
+
192
+ 학생 자가 토론: "*같은 21점으로 무승부인 경우에도 블랙잭인 사람이 이기는 조건을 고려*했습니다!" — *블랙잭 룰* 충실. PR #128에서 *점수 동률 = 무승부* 오판한 결을 수정. *순서 의존 when* 분기 — *블랙잭 ↗ Bust ↗ 점수 비교*. 가독성은 그럭저럭이나 *룰 = 코드 분기 순서*가 *암묵 invariant*. 별도 *룰 객체*로 표현 가능하지만 *과잉*. 현 상태도 합리적.
193
+
194
+ ### 12. `setBetAmount` 재시도 — *재귀로 invariant 보호*
195
+
196
+ ```kotlin
197
+ private fun setBetAmount(playerName: String): BetAmount {
198
+ val input: Double = inputView.readBetAmount(playerName)
199
+ return runCatching { BetAmount(input) }.getOrElse { setBetAmount(playerName) }
200
+ }
201
+ ```
202
+
203
+ `runCatching + getOrElse + 재귀`. *예외 → 재시도*가 모범 패턴이지만 *재귀 깊이*가 *사용자 오타 횟수*에 의존. *while 루프*가 *Stack overflow 보호 + 의도 명시*. PR #65 (kmkim2689)의 `runCatching` 폭증과 같은 결.
204
+
205
+ ### 13. `Card.standardCards` Map 키 — `String 연결` → `Pair<CardNumber, Suit>` 변경
206
+
207
+ ```kotlin
208
+ // Before
209
+ val standardCards: Map<String, Card> = ... .associateBy { it.cardNumber.name + it.suit.name }
210
+ fun of(cn, suit) = standardCards[cn.name + suit.name] ?: throw ...
211
+
212
+ // After (학생 후속)
213
+ val standardCards: Map<Pair<CardNumber, Suit>, Card> = ... .associateBy { it.cardNumber to it.suit }
214
+ fun of(cn, suit) = standardCards[cn to suit] ?: throw ...
215
+ ```
216
+
217
+ 학생 자가 토론: "*Pair<CardNumber, Suit>를 선택하지 않았던 이유*는 of 메서드를 호출하는 개발자 입장에서 *안의 key값이 어떻게 구성되어 있는지 큰 관심사가 아니라 생각*했고, *객체지향에서 의미가 불분명한 Pair 사용을 지양해야 한다는 생각*이 무의식적으로 있었기 때문입니다! [...] *수정하면서도 크게 좋은 개선인지는 의아한 심정*입니다.."
218
+
219
+ → *String 연결 key*는 *충돌 가능*(예: `name = "TEN"` + `suit = ""` vs `name = "TE"` + `suit = "N"`) + *enum.name 의존*. `Pair<CardNumber, Suit>`는 *타입 안전*. 학생의 *의미 불분명 Pair 회피* 직관은 *공개 API에 노출되는 Pair*에는 맞지만 *internal Map key*는 다른 맥락. 모든 *원칙*을 *맥락 무관 적용*하면 부적합.
220
+
221
+ ## 리뷰어 의견 요지
222
+
223
+ - ***Deck.refill() 자동은 호출자 모름 → 명시 신호 (Elvis + 재시도) 좋음***.
224
+ - ***모든 변수 타입 명시는 과잉*** — Kotlin 추론 활용.
225
+ - ***play() callback 폭증 = 자율성 흉내*** — Controller로 회수가 자연.
226
+ - ***backing property 정석*** — `private val _cards: MutableList` + `val cards: List`.
227
+ - ***`Card` Flyweight 캐싱 vs `deepCopy()` 충돌*** — 카드가 불변이면 deepCopy 불필요.
228
+ - ***`isBlackJack` + `isNotBlackJack` 둘 다 노출 = 호출 측 선택 증가***.
229
+ - ***메서드 참조는 재사용성/노이즈 제거 가치 있을 때*** — *수업 적용*이 정당화 X.
230
+ - ***`Participants(dealer, players)`는 프로퍼티 묶음 X, 공통 작업 메서드 보유*** — Tell-Don't-Ask.
231
+ - ***형식 규칙(변수 3개 이하)이 도메인 모델 왜곡*** — `PlayerBetInfo`는 인공물 신호.
232
+ - ***Scoreboard 책임 분리*** — 결과 조회 / 수익 계산.
233
+ - ***Dealer 1장 vs Player 2장 공개 = 비즈니스 룰 = Participant 추상 메서드***.
234
+ - ***`runCatching + 재귀`보다 `while` 루프*** — Stack overflow 보호.
235
+ - ***Map key는 Pair가 타입 안전*** — *Pair 회피*는 *공개 API* 맥락 한정.
236
+
237
+ ## 대표 인용
238
+
239
+ > 플레이어 혹은 딜러가 자기 턴을 진행하는 것은 능동적인 것이 맞습니다. 현실 세계에서는요. *하지만 객체지향의 세계에서도 능동적인 것이 맞을지* 혹은 *다른 객체들과의 협력을 통해 할 수는 없는지* 와 같은 부분들을 앞으로도 고민해보면 좋을 것 같습니다.
240
+ > — @krrong on `Player.kt`
241
+
242
+ > 카드를 처음으로 공개할 때 *딜러는 1장을, 플레이어는 2장을 공개*하는데, 이는 비즈니스 로직으로 볼 수 있지 않을까요?
243
+ > — @krrong on `Dealer.kt`
244
+
245
+ > 커밋 기록을 보니 *베팅금액의 위치가 바뀌었던데* 이유가 무엇인가요? *플레이어 개인의 베팅금액은 스스로가 가지고 있는게 좋지 않을까요?*
246
+ > — @krrong on `PlayerBetInfo.kt`
247
+
248
+ > 일반 함수에 비해 *메서드 참조가 갖는 장점은 무엇인지 찾아보시고 위 코드에서 메서드 참조를 통해 넘겨야 하는 이유*를 설명해주세요.
249
+ > — @krrong on `Participant.kt`
250
+
251
+ > 현재 구현에서는 *플레이어의 수익을 통해 딜러의 수익을 쉽게 구할 수 있는 것*처럼 보이네요.
252
+ > — @krrong on `Scoreboard.kt`
253
+
254
+ ## 얻은 교훈
255
+
256
+ - ***Deck 자동 refill은 호출자 모름 = 의외 동작*** — Elvis/null 반환 + 호출자 재시도가 *명시 신호*.
257
+ - ***모든 변수 타입 명시 = 과잉*** — Kotlin은 *추론*이 기본. *명시*는 *상위 추상 강제*나 *컴파일 오류 회피* 같은 *목적이 있을 때만*.
258
+ - ***`play()`에 입력/출력 callback이 들어오면 *자율성 흉내*가 됨*** — 결정 주체가 외부면 자율성은 *현실 비유*에만 머무름. *Controller로 회수*가 객체지향 자율성 정의에 충실.
259
+ - ***Backing property 정석*** — `private val _cards: MutableList<Card>` + `val cards: List<Card> get() = _cards`. *둘 다 private*은 *백킹 의미 무효*.
260
+ - ***`Card` Flyweight + deepCopy 충돌*** — *Flyweight = 카드 불변*. *deepCopy로 새 인스턴스*는 *캐싱 이점 무효화*. 객체가 *불변*이면 *그냥 노출*해도 안전.
261
+ - ***`isBlackJack` + `isNotBlackJack` 둘 다 = 호출 측 선택 증가*** — `isBlank`/`isNotBlank` 같은 stdlib 예외는 *고빈도 + 가독성 ↑*. 도메인 객체에는 한 가지로.
262
+ - ***메서드 참조의 가치 = 재사용성 + 람다 본문 노이즈 제거*** — *수업 적용*은 정당화가 못 됨.
263
+ - ***`Participants(dealer, players)`가 프로퍼티 묶음만이면 단순 record*** — `initialCardsDistribute` 같은 공통 작업을 메서드로 끌어오면 Tell-Don't-Ask. 학생 자가 의문 인식 신호.
264
+ - ***형식 규칙(변수 3개 이하)이 도메인 모델을 왜곡한 신호 = 인공 객체 등장*** — `PlayerBetInfo`는 `Player.betAmount`의 *형식 회피용*. *형식은 코드 단순화 도구*. *목적이 도구 자체*가 되면 안 됨. PR #63 `BlackJack` 객체와 같은 결.
265
+ - ***책임 분리 = 새 객체 + 역집계*** — Scoreboard에서 *수익 계산*만 `BetRecords`로 + `dealerProfit = -sum(playersProfit)` 역집계. PR #112와 같은 패턴.
266
+ - ***Dealer 1장 vs Player 2장 공개 = 비즈니스 룰*** — `Participant.showInitialCards()` 추상 메서드 Liskov 호환.
267
+ - ***`runCatching + 재귀` < `while + try-catch`*** — Stack overflow 보호 + 의도 명시.
268
+ - ***Pair 회피 직관은 공개 API 맥락에서*** — *internal Map key*에는 Pair가 *타입 안전*. *모든 원칙을 맥락 무관 적용* 위험.
269
+ - ***학생이 자가 의문을 명시*하는 PR은 리뷰가 깊어짐** — PR #135처럼 학생이 *내가 한 결정의 단점*을 먼저 쓰면 *리뷰어 코칭이 인정 + 다음 단계 질문*으로 연결.
@@ -0,0 +1,346 @@
1
+ # PR #28 — [블랙잭 1단계] 인선 미션
2
+
3
+ - **Reviewee:** [@inseonyun](https://github.com/inseonyun)
4
+ - **PR:** https://github.com/woowacourse/kotlin-blackjack/pull/28
5
+ - **단계:** 1단계
6
+ - **리뷰어:** @laco-dev
7
+ - **라인 코멘트:** 30 (리뷰어 30 / 리뷰이 0 — *학생 답변이 별도 thread 또는 코멘트로 회신*)
8
+
9
+ ## 잘한 점 (설계 관점)
10
+
11
+ - **`Name` `@JvmInline value class` + 정규식 invariant** — 원시값 포장 + 생성 시 검증.
12
+ - **`Cards` 일급 컬렉션 + 방어적 복사 (`_cards.toList()`)** — 리뷰어 칭찬 명시.
13
+ - **`Card private constructor` + Factory 사용** (학생 후속 반영).
14
+ - **`CardPickerGenerator` → `CardDeck.drawCard()` 통합 (후속)** — 셔플 책임 Deck 내부로.
15
+ - **`Cards(Set<Card>)`로 변경 (후속)** — 중복 검증 자체를 자료구조가 보장.
16
+ - **`Cards.sum()` Ace 보정을 *합 + 10 ≤ 21*로 단순화 (후속)** — 리뷰어 권고 반영.
17
+
18
+ ## 못한 점 (설계 관점)
19
+
20
+ ### 1. `Suit`/`Rank` enum에 `description: String` UI 표현 보유
21
+
22
+ ```kotlin
23
+ enum class Suit(val description: String) {
24
+ DIAMOND("다이아몬드"), CLOVER("클로버"), SPADE("스페이드"), HEART("하트")
25
+ }
26
+ enum class Rank(private val score: Int, val description: String? = null) {
27
+ ACE(1, "A"), KING(10, "K"), QUEEN(10, "Q"), JACK(10, "J"),
28
+ DEUCE(2), THREE(3), ...
29
+ }
30
+ ```
31
+
32
+ 리뷰어: "description은 UI의 관심사이지 않을까요? 가령 스페이드를 "spade" "♤" 이렇게 출력할 수도 있습니다." — *UI 표현 다국어/심볼* 변경이 *도메인 enum 수정*을 강요. PR #78·#112·#125와 같은 결.
33
+
34
+ ### 2. `Card.toString()`이 UI 표현
35
+
36
+ ```kotlin
37
+ data class Card(val rank: Rank, val suit: Suit) {
38
+ override fun toString(): String {
39
+ if (rank.description != null) return rank.description + suit.description
40
+ return rank.getScore().toString() + suit.description
41
+ }
42
+ }
43
+ ```
44
+
45
+ 리뷰어: "카드가 어떻게 UI에 그려져야 할지는 *UI 영역의 관심사*입니다. 비슷하게 다른 도메인 모델에서 toString() 사용하고 있는 곳은 모두 동일합니다." — 일관 패턴 (PR #78·#112와 동일).
46
+
47
+ ### 3. `GameResult`가 `Map<String, Boolean>` — Win/Lose 단편
48
+
49
+ ```kotlin
50
+ class GameResult private constructor(val playersResult: Map<String, Boolean>) {
51
+ fun getDealerWinResult(): Int = playersResult.count { !it.value }
52
+ fun getDealerLoseResult(): Int = playersResult.count { it.value }
53
+ companion object {
54
+ private fun match(dealer: Dealer, player: Player): Boolean {
55
+ if (player.isBust()) return false
56
+ if (dealer.isBust()) return true
57
+ return (BLACKJACK_POINT - dealer.cards.sum()) > (BLACKJACK_POINT - player.cards.sum())
58
+ }
59
+ fun of(dealer: Dealer, players: List<Player>): GameResult =
60
+ GameResult(buildMap { players.forEach { put(it.name.value, match(dealer, it)) } })
61
+ }
62
+ }
63
+ ```
64
+
65
+ 리뷰어: "승부를 결정짓는 것은 *딜러, 플레이어와 상관없이 참가자가 다른 참가자와 판단할 요소*이지 않을까요? [...] abstract class Player { fun match(otherPlayer: Player): Result } [...] 그리고 GameResult를 만들때 *누구의 입장에서 승리인지* 알기가 어렵게 느껴집니다." — `Boolean`은 *정보 부족*(True가 누구 입장인지?) + *match가 GameResult.Companion*에 있으면 *참가자의 자율성* 손상. PR #63·#125와 같은 *Tell-Don't-Ask* 결.
66
+
67
+ ### 4. `CardPicker` — `Deck`과 별도 + 인덱스 비교 후 throw
68
+
69
+ ```kotlin
70
+ class CardPicker(private val cards: Cards) {
71
+ private var cursor = 0
72
+ fun pick(): Card {
73
+ require(cursor < cards.size) { OUT_OF_INDEX_CARDS_CURSOR }
74
+ return cards.cards[cursor++]
75
+ }
76
+ }
77
+ ```
78
+
79
+ 리뷰어: "카드를 뽑는 개념이 아닌 *선택한다는 Pick 개념은 새롭네요* 👍🏻 그런데 *크기 비교를 먼저할 필요가 있을까?* 라는 생각이 들어요 cards에게서 *특정 위치의 카드를 가져오도록 하고, 없다면 null을 반환*하도록 해서 로직을 판단할 수 있지 않을까요?" / "*CardPicker가 단순히 "보기" 기능만 제공*하다보니 카드뭉치가 해야할 역할을 이곳저곳으로 코드가 분리되어있는 느낌이 들어요. *카드뭉치라는 개념을 만들어 보면 어떨까요?*" — *Picker*는 *덱이 해야 할 일*의 *부분*만 함. *Deck*에 *셔플 + 뽑기 + 빈 덱 처리*를 모두 응집.
80
+
81
+ ### 5. `CardPackGenerator` 별도 객체 — Deck이 스스로
82
+
83
+ ```kotlin
84
+ class CardPackGenerator {
85
+ fun createCards(): Cards =
86
+ Cards(buildList {
87
+ Rank.values().forEach { rank -> addAll(Suit.values().map { suit -> Card(rank, suit) }) }
88
+ })
89
+ }
90
+ ```
91
+
92
+ 리뷰어: "*컬렉션의 flatMap { ... } 을 활용 해보세요*" / "*카드덱이 스스로 할 수 있을 것 같은데 카드팩 제너레이터 개념이 유지될 필요가 있을까요?*" — Generator/Picker/Cards 셋이 *덱의 책임을 셋으로 쪼갬*. `CardDeck`이 *생성 + 셔플 + 뽑기* 한 객체로 응집이 자연.
93
+
94
+ ### 6. `Names`가 *최대 8명* invariant 보유 + `InputView`도 8명 검증
95
+
96
+ ```kotlin
97
+ data class Names(val names: List<Name>) : List<Name> by names {
98
+ init {
99
+ require(names.size < PLAYER_MAX) { PLAYER_COUNT_ERROR }
100
+ require(names.distinct().size == names.size) { PLAYER_NAME_DUPLICATE }
101
+ }
102
+ companion object { private const val PLAYER_MAX = 8 }
103
+ }
104
+
105
+ class InputView {
106
+ fun readName(): List<String> {
107
+ ...
108
+ require(players.size <= PLAYER_MAX) { PLAYER_COUNT_ERROR } // 도메인 룰이 UI에도
109
+ return players
110
+ }
111
+ }
112
+ ```
113
+
114
+ 리뷰어: "*Names 객체가 플레이어가 최대 8명이라는 것을 알 필요가 있을까요?*" → 학생이 *도메인 위치*로 옮긴 후 다시: "*8명까지 참여 가능한 것은 도메인 로직이 아닐까요?*" — *도메인 invariant는 도메인 한 곳*에. UI에서 *예방 차원*으로 또 검사하면 *변경 시 두 곳 수정*.
115
+
116
+ 또: `Names: List<Name> by names` 위임 — 리뷰어: "*저는 개인적으로 `by List<T>` 형태의 위임은 위와 같은 이유 때문에 지양*하는 편입니다. [...] *해당 객체가 해야할 비즈니스 로직을 모두 이곳에서 처리하는 실수로 이어지고 있어요*. 플레이어들만 반환하는 기능은 Participants 객체가 해야할 역할이 아닐까요?" — *위임으로 외부에 List 인터페이스를 그대로 노출*하면 *호출자가 .filter/.map을 직접 사용*하게 되어 *비즈니스 로직이 호출자로 누수*.
117
+
118
+ ### 7. `Participant.isHit(): Boolean` — Hit가 *상태 머신*인데 Boolean으로 환원
119
+
120
+ ```kotlin
121
+ abstract class Participant(val cards: Cards, val name: Name) {
122
+ abstract fun isHit(): Boolean
123
+ fun isBust(): Boolean = cards.sum() > BUST_POINT
124
+ }
125
+ ```
126
+
127
+ 리뷰어: "*블랙잭 게임에서 Hit라는 상태 는 단순한 Boolean 형태로 판단하기가 어렵습니다.* 단순히 21점보다 낮다 혹은 16점보다 낮다라는 조건은 "스테이" 상태 가 될 수도 있습니다. [...] 21점보다 낮은데 *더 안뽑겠다고 하면 -> 스테이* / 21점보다 낮은데 *더 뽑겠다고 하면 -> 히트* / 21점보다 높으면 -> 버스트 [...] *"카드를 더 뽑을 수 있니" 를 묻고싶은 것은 아닐까요?*" — `isHit`은 *Hit이라는 상태*를 묻는 것처럼 보이지만 실제로는 *카드를 더 받을 수 있는지*. **이름이 상태 머신을 흉내내지만 의미는 능력 질의**. PR #78의 `State` sealed interface가 이 혼동을 해결하는 모델.
128
+
129
+ ### 8. `Cards.add(card: Card)`가 *중복 검사 + 추가*
130
+
131
+ ```kotlin
132
+ fun add(card: Card) {
133
+ require(!_cards.contains(card)) { CARD_DUPLICATE_ERROR }
134
+ _cards.add(card)
135
+ }
136
+ ```
137
+
138
+ 리뷰어: "카드를 추가할 때 마다 항상 가지고 있는지 검사하고 *오류를 발생시키고 있는데요*. *오류를 발생시키지 않도록 자료구조를 이용*해보면 어떨까요?" — *Set*을 쓰면 *중복 자체가 자료구조 invariant*. *룰을 자료구조에 위임*. 학생 후속: `Cards(Set<Card>)`.
139
+
140
+ ### 9. `Rank.getScore(score: Int = 0)` — 파라미터 의미 모호
141
+
142
+ ```kotlin
143
+ enum class Rank(private val score: Int, val description: String? = null) {
144
+ ACE(1, "A"), ...
145
+ ;
146
+ fun getScore(score: Int = 0): Int {
147
+ when (this) {
148
+ ACE -> {
149
+ if (score + ACE_SCORE_ELEVEN > WIN_SCORE) return ACE_SCORE_ONE
150
+ return ACE_SCORE_ELEVEN
151
+ }
152
+ else -> return this.score
153
+ }
154
+ }
155
+ }
156
+ ```
157
+
158
+ 리뷰어: "`getScore()` 함수의 파라미터가 *무엇을 하기 위한 역할인지 잘 와닿지 않는 것 같아요*. 이 내용은 앞서 *카드의 합계를 계산하는 방법을 개선*하면 달라질 수 있겠네요" — *Ace 점수를 카드 한 장이 결정*하려면 *현재까지의 합*을 인자로 받아야 함. 그러나 *합산은 컬렉션의 책임*이지 *카드 한 장*의 책임이 아님. `Cards.sum()`에서 *Ace 보정 단일 룰*로 통일하면 *Rank.score는 인자 없는 단순 값*.
159
+
160
+ 또: `getScore`의 `score` 파라미터 동명 — *함수명 = 변수명*은 PR #78 (`drawOrNot`)과 같은 결.
161
+
162
+ ### 10. `Participants(List<Participant>)` + `Participants.of(dealer, players)` — 명시 분리의 가치 의문
163
+
164
+ ```kotlin
165
+ data class Participants(val participants: List<Participant>) : List<Participant> by participants {
166
+ companion object {
167
+ fun of(dealer: Dealer, players: Players) =
168
+ Participants(listOf(dealer as Participant) + players as List<Participant>)
169
+ }
170
+ }
171
+ ```
172
+
173
+ 리뷰어: "딜러도 플레이어도 모두 Participant 타입으로 동일하기 때문에 *단순하게 생성할 수 있지는 않을까요?* *딜러와 플레이어를 명시적으로 받는 것에 대한 장점이 없어 보여요.*" — *Participants.of(dealer, players)* 같은 *역할별 명시 인자*가 *추상화*와 *모순*. 도메인 비유로는 *딜러는 0번째*가 자연스럽지만 *Participant.match(other)*를 보면 *균등 추상*이 자연.
174
+
175
+ ### 11. `CardGame`이 *초기화만* — 진행 부재
176
+
177
+ ```kotlin
178
+ class CardGame(private val cardPicker: CardPicker) {
179
+ fun initPlayers(names: List<Name>): Players = Players(names.map { Player(pickTwice(), it) })
180
+ fun initDealer(): Dealer = Dealer(pickTwice())
181
+ fun pickTwice(): Cards = Cards(buildList { add(cardPicker.pick()); add(cardPicker.pick()) })
182
+ }
183
+ ```
184
+
185
+ 리뷰어: "*카드 게임에 대한 기본적인 진행 방식*을, 위 객체에서 담당할 것이라고 기대했는데 *초기화만 하고 아무런 역할을 하지 않네요*. 게임을 진행할 수 있도록 기능을 추가 해보면 어떨까요?" — 이름이 *Game*인데 *Game을 안 함*. `Controller`가 진행 로직을 모두 가짐. *이름 = 책임 기대치*의 불일치.
186
+
187
+ ### 12. `CardGame.drawPlayersCard(players, input: (String) -> Boolean, output: (Participant) -> Unit)` — UI callback이 도메인에
188
+
189
+ ```kotlin
190
+ fun drawPlayersCard(players: Players, input: (String) -> Boolean, output: (Participant) -> Unit) {
191
+ players.filter { it.isHit() }.forEach { drawPlayerCard(it, input, output) }
192
+ }
193
+ ```
194
+
195
+ 리뷰어: "1. 카드게임의 함수에서 *UI를 연상시키는 이름을 사용하면 안됩니다*. (input, output)과 같은 이름 대신 *도메인 기능에 맞는 이름*을 사용해야 합니다. 2. *파라미터는 Participant를 사용하는 반면, 함수 이름에서 구현체가 드러나면 안됩니다.* 3. 더 뽑을지 여부를 UI로부터 받도록 *Player에서 협력 관계*를 만들어 줄 수 있을 것 같습니다. ``` class Player(val needToDraw: () -> Boolean) { fun isHit(): Boolean = "더 뽑을 수 있고" && needToDraw() } ```" — *callback이 도메인 함수 인자*면 *UI 어휘가 도메인 메서드명에 누수*. *Player의 의도* 자체에 *Hit 의사*를 callback으로 주입.
196
+
197
+ ### 13. `CardGame.pickTwice()` public — *외부 미사용, 테스트만 사용*
198
+
199
+ 리뷰어: "위 함수는 외부에서 *사용이 되지 않고 있어요* 테스트 코드에서만 사용하는 것은 *사용된다고 하지 않습니다*. 위 기능은 *다른 메소드를 통해 테스트가 가능하도록 만들어 져야* 하겠습니다." — PR #63 (jinuemong)의 `changeState() public`과 동일 결. *테스트 위해 public화*는 *캡슐화 위반*. *입력 → 출력*으로 검증.
200
+
201
+ ### 14. `Dealer.getGameResult(players)` + `Player.getGameResult(dealer)` — 같은 메시지 두 구현
202
+
203
+ ```kotlin
204
+ class Dealer(...) : Participant(...) {
205
+ fun getGameResult(players: Players): Map<Result, Int> {
206
+ val playersResult = players.getGameResult(this)
207
+ return mapOf(
208
+ Result.WIN to (playersResult.count { it.value == Result.LOSE }),
209
+ Result.LOSE to (playersResult.count { it.value == Result.WIN }),
210
+ )
211
+ }
212
+ }
213
+ ```
214
+
215
+ 리뷰어: "이 함수가 *플레이어, 딜러가 각각 따로 새롭게 정의될 필요가 있을까요?* 외부에서는 `Participant.getGameResult(...)` *메시지를 요청하는 것*으로 볼 수 있지 않을까요?" — *동일 메시지*를 *역할 다른 두 클래스*에 *별도 구현*하면 *추상화 부재*. `Participant.getGameResult(other: Participant)`로 *Liskov 호환*.
216
+
217
+ ### 15. `OutputView`가 `participant.cards.cards.elementAt(0)`로 직접 접근
218
+
219
+ ```kotlin
220
+ fun printPlayerStatus(participant: Participant) {
221
+ if (participant.name.value == DEALER) {
222
+ println(MESSAGE_DEALER_STATUS.format(participant.cards.cards.elementAt(0).getCardFormat()))
223
+ } ...
224
+ }
225
+ ```
226
+
227
+ 리뷰어: "*참가자에게 -> 처음 뽑은 카드 목록을 요청한다 라는 기능*으로 만들어 볼 수 있지 않을까요? `abstract fun getFirstOpenCards(): Cards` [...] *지금 Player, Dealer, Participant등의 cards에 직접 접근해서 비즈니스 로직을 처리하는 것이 아닌 해당 객체가 스스로 처리할 수 있도록 만들어 주셔야 합니다.* 극단적으로는 *cards를 private으로 만들고 구현을 유지*시킨다?" — *View가 도메인 내부 구조 분해 접근*. `.cards.cards.elementAt(0)`는 *세 단계 의존*. `participant.firstOpenCard()` 메시지.
228
+
229
+ ### 16. `Controller`의 *재진입 시 Bust 가드 누락*
230
+
231
+ ```kotlin
232
+ private fun askGetMorePlayerCard(player: Player) {
233
+ while (player.isHit() && inputView.readYesOrNo()) {
234
+ player.cards.add(picker.pick())
235
+ outputView.printPlayerStatus(player)
236
+ if (player.isHit()) outputView.printGetCardMore(player.name)
237
+ }
238
+ }
239
+ ```
240
+
241
+ 리뷰어: "*카드를 받고나면 버스트 상태가 되어버릴 수도 있지 않을까요?* 그러면 의도와 달리 출력이 되지 않을 것 같아요" — `isHit()`이 *Hit 가능 == 21 미만*이라면 *카드 받은 후 22가 되어 isHit=false*. *if 분기*가 *Bust 발생 시 잘못된 메시지*. 상태 머신이 있으면 *Bust 메시지가 자동*.
242
+
243
+ ### 17. `Cards.sum()` Ace 계산 — *합 + 10 ≤ 21*인지 *2번 검토*는 무의미
244
+
245
+ ```kotlin
246
+ fun sum(): Int {
247
+ var sum = _cards.sumOf { it.rank.score }
248
+ repeat(_cards.filter { it.rank == Rank.ACE }.size) {
249
+ if (sum + ACE_BONUS_TEN <= PARTICIPANT_STANDARD_BUST_POINT) sum += ACE_BONUS_TEN
250
+ }
251
+ return sum
252
+ }
253
+ ```
254
+
255
+ 리뷰어: "*에이스 카드가 2장인 경우에 과연 20점의 보너스를 받는 경우가 있을까?* 를 생각해보세요. 조금 더 간단하게 만들어 질 수 있습니다." — *Ace 두 장 모두 11로 계산 = 22*는 *항상 Bust*. → *Ace는 최대 한 장만 11* (다른 한 장은 1). 룰 단순화 = *한 번만 검토*.
256
+
257
+ ### 18. `ParticipantsTest` setup 장황 — Factory 함수 권고
258
+
259
+ ```kotlin
260
+ val dealer = Dealer(Cards(listOf(Card(Rank.KING, Suit.HEART))))
261
+ val players = Players(listOf(
262
+ Player(Cards(listOf(Card(Rank.ACE, Suit.HEART))), Name("jason")),
263
+ Player(Cards(listOf(Card(Rank.DEUCE, Suit.HEART))), Name("pobi"))
264
+ ))
265
+ ```
266
+
267
+ 리뷰어: "*테스트 코드를 만들기 위해 준비하는 재료가 가독성을 떨어트리고 있어요.* [...] `val players = Players(Player("jason", Card(ACE, HEART)), Player("pobi", Card(DEUCE, HEART)))`" — *테스트는 시나리오*. *생성 boilerplate*가 *의도*를 가림. *vararg 생성자 + 간결한 Card factory*.
268
+
269
+ ### 19. `PlayerTest`가 *CardPicker + CardPackGenerator*로 테스트
270
+
271
+ ```kotlin
272
+ @Test
273
+ fun `플레이어는 카드 두 장을 받을 수 있다`() {
274
+ val cards = CardPackGenerator().createCards()
275
+ val cardPicker = CardPicker(cards)
276
+ ...
277
+ }
278
+ ```
279
+
280
+ 리뷰어: "플레이어가 카드를 두장 받는 기능을 테스트 하는 것이기 때문에 *카드 피커와 카드 제너레이터는 이곳에서 고려하거나 사용하는 것은 적절하지 않습니다*." — *Player의 책임*은 *카드 보유*. *카드 출처*는 무관. *테스트 격리 = 테스트 대상의 책임만*.
281
+
282
+ ### 20. `CardTest`가 *Rank 테스트*
283
+
284
+ ```kotlin
285
+ @Test
286
+ fun `ACE가 플레이어에게 11이 더 유리한 경우, 유리한 숫자로 반환된다`() {
287
+ val card = Card(Rank.ACE, Suit.CLOVER)
288
+ assertThat(card.rank.getScore(1)).isEqualTo(11)
289
+ }
290
+ ```
291
+
292
+ 리뷰어: "위 테스트는 *Card를 테스트하는 것이 아니고, Rank를 테스트 한 것이지 않을까요?*" — `card.rank.getScore(1)`은 *Rank의 메서드*. *Card 클래스 = Rank + Suit 묶음*인데 *묶음의 동작*이 아닌 *Rank 동작*을 검증.
293
+
294
+ ## 리뷰어 의견 요지
295
+
296
+ - ***enum description (UI 표현)은 도메인 X*** — PR #78·#112·#125와 일관.
297
+ - ***toString 도메인 메서드 X***.
298
+ - ***match는 참가자의 메시지*** — `Participant.match(other)` Tell-Don't-Ask.
299
+ - **`CardPicker`/`CardPackGenerator` 셋이 *덱의 책임을 흩뜨림*** — `Deck` 단일 응집.
300
+ - ***도메인 invariant는 도메인 한 곳*** — UI/Domain 양쪽 검증은 변경 비용.
301
+ - ***`by List<T>` 위임은 비즈니스 로직 누수 위험***.
302
+ - ***`isHit(): Boolean`은 상태 머신을 흉내내지만 의미는 능력 질의*** — 상태와 능력 분리.
303
+ - ***Set은 중복 검사를 자료구조에 위임***.
304
+ - ***`getScore(score: Int)` 파라미터 모호*** — 합산 위치 개선.
305
+ - ***`Dealer.getGameResult` vs `Player.getGameResult` = 추상화 부재*** — `Participant.getGameResult(other)`.
306
+ - ***`participant.cards.cards.elementAt(0)`는 캡슐화 분해*** — `firstOpenCard()` 메시지.
307
+ - ***UI callback `input`/`output`이 도메인 함수명에 노출*** — 도메인 어휘만.
308
+ - ***테스트 위해 public화 금지***.
309
+ - ***Ace 2장 = +20은 항상 Bust*** — 룰 단순화.
310
+
311
+ ## 대표 인용
312
+
313
+ > 승부를 결정짓는 것은 딜러, 플레이어와 상관없이 *참가자가 다른 참가자와 판단할 요소*이지 않을까요?
314
+ > — @laco-dev on `src/main/kotlin/model/GameResult.kt`
315
+
316
+ > 블랙잭 게임에서 Hit라는 *상태* 는 단순한 Boolean 형태로 판단하기가 어렵습니다. [...] "카드를 더 뽑을 수 있니"를 묻고싶은 것은 아닐까요?
317
+ > — @laco-dev on `src/main/kotlin/model/Participant.kt`
318
+
319
+ > CardPicker가 단순히 *"보기" 기능만 제공*하다보니 카드뭉치가 해야할 역할을 *이곳저곳으로 코드가 분리*되어있는 느낌이 들어요. *"카드뭉치" 라는 개념을 만들어 보면 어떨까요?*
320
+ > — @laco-dev on `src/main/kotlin/controller/Controller.kt`
321
+
322
+ > Names 객체가 *플레이어가 최대 8명이라는 것을 알 필요가 있을까요?* / 8명까지 참여 가능한 것은 도메인 로직이 아닐까요?
323
+ > — @laco-dev (Names → InputView 양쪽)
324
+
325
+ > 카드를 뽑는건 *Participant 객체가 자율적으로* 할 수 있도록 해주세요
326
+ > — @laco-dev on `src/main/kotlin/domain/CardGame.kt`
327
+
328
+ > 참가자에게 -> *처음 뽑은 카드 목록을 요청한다* 라는 기능으로 만들어 볼 수 있지 않을까요?
329
+ > — @laco-dev on `src/main/kotlin/view/OutputView.kt`
330
+
331
+ ## 얻은 교훈
332
+
333
+ - ***enum description (UI 표현) 도메인 보유는 일관 안티패턴*** — PR #78/#112/#125와 합쳐 *4개 PR 연속 등장*. MCP 룰 후보로 강력.
334
+ - ***`Map<String, Boolean>` 같은 자료구조는 의미 부족*** — *True가 누구 입장 승리?* 같은 *의미 손실*. enum/sealed로 명시.
335
+ - ***Generator + Picker + Cards 셋은 Deck의 책임을 셋으로 쪼갬*** — *덱 한 객체*가 *생성 + 셔플 + 뽑기*를 응집.
336
+ - ***Names가 "8명 제한"을 알면 도메인, UI가 알면 누수*** — *도메인 invariant는 도메인 한 곳*. UI에서 *예방*은 변경 비용.
337
+ - ***`by List<T>` 위임은 비즈니스 로직을 호출자로 누수*** — 컨트롤러가 `.filter`/`.map` 쓰기 시작. 일급 컬렉션의 *메서드만 노출*.
338
+ - ***`isHit(): Boolean`은 상태와 능력의 혼동*** — Hit은 *상태*(Hit/Stay/Bust)인데 Boolean은 *능력*(더 받을 수 있나). *상태 머신* + *능력 질의*는 별도.
339
+ - ***Set으로 중복 검사를 자료구조에 위임*** — `_cards.contains(card)` + throw 대신.
340
+ - ***`Rank.getScore(score: Int)` 파라미터는 책임 위치 신호*** — 카드 한 장이 *문맥 합*을 받으면 *합산 책임이 카드에*. *합산은 컬렉션*이 자연.
341
+ - ***UI callback (`input`/`output`)을 도메인 함수 인자로 받으면 도메인 어휘 침범*** — *Player의 의도* 자체를 `needToDraw: () -> Boolean`으로 협력.
342
+ - ***`Dealer.getGameResult` vs `Player.getGameResult` = 동일 메시지 두 구현 → 추상화 부재*** — `Participant.getGameResult(other)` 한 메서드.
343
+ - ***View가 `participant.cards.cards.elementAt(0)`로 분해 접근 = 캡슐화 깨짐*** — `firstOpenCard()` 메시지.
344
+ - ***`pickTwice()` 외부 미사용 + 테스트만 사용은 *사용된다고 하지 않음*** — 입력→출력 경로로 테스트.
345
+ - ***Ace 두 장 = +20은 항상 Bust*** — *Ace는 최대 한 장만 11*. 한 번 검토로 충분.
346
+ - ***CardTest가 `card.rank.getScore()`를 검증하면 Rank 테스트*** — *대상 클래스의 책임*에 한정된 시나리오.