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,541 @@
1
+ # PR #133 — [블랙잭 2단계] 시아 미션
2
+
3
+ - **Reviewee:** [@Leeyerin0210](https://github.com/Leeyerin0210)
4
+ - **PR:** https://github.com/woowacourse/kotlin-blackjack/pull/133
5
+ - **단계:** 2단계 (베팅 / 수익률 / 블랙잭 1.5배)
6
+ - **리뷰어:** @malibinYun (말리빈)
7
+ - **라인 코멘트:** 23 스레드 / 46 코멘트
8
+
9
+ ## 잘한 점 (설계 관점)
10
+
11
+ - **`Card` private constructor + `getCashed` 팩토리** — 1단계 *`operator fun invoke` + public class* 의 모호함 (말리빈: *"바이트코드 안 보면 호출 모름"*) 을 *private constructor + 명명된 팩토리*로 자가 해소. 학생 자가 인용: *"첫 의도는 52장의 카드 의외의 카드를 만들게 할 수 있게 하려고 하였으나, 정의되지 않은 카드가 추가되면 게임에 문제가 생길 수 있을 것 같아 기본 생성장를 프라이빗으로 변경하였습니다."*
12
+ - **`Participant` interface (1단계 abstract class → 2단계 interface)** — 말리빈의 1단계 *"abstract할 게 하나도 없으니, abstract를 사용할 이유가 없다고 생각해요"* 진단을 *완전 반영*. `interface Participant` + `val items: Items` 추상 프로퍼티 + *default 메서드*로 *공통 동작 공유*. *abstract 의미 부재*를 *interface 의 추상 property + default method*로 자가 해결. *PR 본문 자가 인용 부재이나 코드 자체가 답변*.
13
+ - **`Player.compareHand(other: Participant): WinningResult` 메시지** — 1단계 `object CalculateResult.getResult(...)` 정적 헬퍼 (말리빈 진단: *"객체에게 메시지를 던져보는 건"*) 를 *플레이어 메시지*로 자가 이전. 말리빈 코멘트: *"딜러도 결국 하나의 플레이어라고 생각할 수도 있지요. 그러면 승패의 결과는 플레이어와 플레이어를 비교해도 나올 수 있는 것은 아닐지."* 학생 답변 (커밋 `258e602`): *"참가자에게 비교하는 함수를 만들고, 플레이어와 딜러에게 구현을 약간 다르게 하였습니다."*
14
+ - **`WinningResult` enum 의 `BLACKJACK` 분리** — 1단계 *WIN/PUSH/LOSE* 에 *블랙잭 (1.5배)* 추가. *2장 + 21* 정확 판정 (`getHandSize() == 2 && getScore() == 21`) + *별도 enum 멤버*로 *수익률 1.5배 분리 표현*. PR #128·#135·#114·#124 와 같은 결의 블랙잭 룰 정확성.
15
+ - **`WinningResult.getPrize(WinningResult): Double` 외부 룰 표** — 1.5 / 1.0 / 0.0 / -1.0. *수익률 = WinningResult enum의 부가 정보*로 분리. *enum 멤버 안에 `val prize: Double`* 로 *프로퍼티 통합*도 가능했으나 *함수 분리*가 *룰 변경 시 enum 멤버 안전*.
16
+ - **`EventListener` / `EventProvider` 인터페이스 = 모델-뷰 느슨한 결합** — 1단계 말리빈 *"도메인이 뷰만 모른다는 사실에 집중 → 인터페이스 혹은 람다 등으로 가져올 수 있도록"* 의 *완전한 후속 반영*. `EventListener.displayParticipantCards(name, cards)` 같은 *콜백 인터페이스*로 *도메인 → View 통보*. 학생 PR 본문: *"인터페이스를 활용해서 모델은 입력받는 구조를 모르고, 뷰에서 구현할 수 있도록 하였는데"*. 말리빈 답변: *"네 :) 의도한 방향이 맞아요."*
17
+ - **`tailrec fun drawUntilFinished` — 말리빈 권고 자가 학습** — 말리빈의 *"재귀 함수로 게임 진행 + tailrec 키워드 알아보세요"* 권고 (반영 안 해도 좋다는 단서) 를 *Dealer.drawUntilFinished* 에 적용. 학생 자가 인용: *"재귀함수로 게임을 원하는 만큼 계속 진행하도록 변경하였습니다. tailrec 엄청나네요 오버플로우를 신경 쓸 필요가 없다니..!"*
18
+ - **`Items(hand, money)` 일급 컬렉션 시도** — 말리빈의 *3 인스턴스 변수 제약 = 연습 도구* + *"2개를 묶어 하나의 클래스로 만들어보세요"* 힌트 반영. `Player(name, items)` / `Dealer(name, items)` 로 *Items 안에 hand + money 묶음*. *클래스 분리 연습*. 다만 *깊은 함정* (못한 점 §4) 도 동반.
19
+ - **`Money` 연산자 오버로딩 후속 반영** — 말리빈의 *"연산자 오버로딩을 활용해볼 수도 있겠어요"* 권고에 *`operator fun plus`* 자가 도입. 학생 자가 인용: *"코드가 훨씬 더 깔끔해졌네요!"* 다만 *가변 객체 + 연산자 오버로딩 상성 문제* (못한 점 §1) 가 자가 학습 후속 토론으로 남음.
20
+ - **테스트 픽스처 (`SPADE_ACE`) 도입** — 말리빈 *"테스트에 필요한 카드를 매번 만들어내는 건 매우 귀찮은 일이지요. 미리 카드 스텁을 테스트 패키지에 만들어 두고 재활용해보는건 어떨까요?"* 권고 후속 반영. 학생: *"매번 만들지 않아도 되니 너무 간편해졌습니다."*
21
+ - **카드 한 장 전달 — `Participant.draw(card)`** — 1단계 *Participant.draw(cardDeck: CardDeck)* 가 *Participant이 deck 의존* (말리빈: *"카드를 뽑을 때 덱을 주는 것 보다 카드 한 장을 주는 건 어떤지에 대한 의견"*) → 2단계 *`draw(card: Card)`* 로 *카드 1장만 전달* + *engine 이 deck 보유*. 학생 자가 답변: *"카드 한장을 주도록 수정했습니다. 플레이어의 경우는 효과적으로 수정되었다고 생각하지만, 딜러의 경우에는 여러번 계속 뽑기를 해야 해서 덱을 가져와야 할 수 밖에 없었습니다."* — *Player.draw(card)* 단일 + *Dealer.drawUntilFinished(deck)* 는 deck 의존 (트레이드오프 인식 + 정당화).
22
+
23
+ ## 못한 점 (설계 관점)
24
+
25
+ ### 1. `Money` 가변 + `plus` 가 `Unit` 반환 — *연산자 오버로딩 안티패턴 정공*
26
+
27
+ ```kotlin
28
+ class Money(
29
+ var value: Double, // ⚠ var
30
+ ) {
31
+ operator fun plus(money: Money) {
32
+ value = value + money.value // ⚠ 자기 변경 + Unit 반환
33
+ }
34
+
35
+ fun multiplyMoney(factor: Double): Money = Money(value * factor)
36
+ }
37
+ ```
38
+
39
+ 말리빈 (Money.kt:11 — 미해결): *"Money가 가변 객체였네요. 연산자 오버로딩이 되어있는 다른 것들을 참고해보세요. 가변객체와 연산자 오버로딩은 상성이 그리 좋지 않음을 이번 경험으로 알게되시면 좋겠어요 :)"*
40
+
41
+ → **`Money` 가변 + `operator fun plus` Unit 반환 = 두 가지 안티패턴 동시**:
42
+
43
+ 1. **Kotlin operator plus 는 *새 객체 반환*이 표준** — `val total = a + b` 가 *자연*. *a + b 가 Unit 반환*하면 *`a + b` 자체가 표현식으로 사용 불가*. `BetResult.getDealerResult`의 `dealerResult + money` 가 *결과 무시 + 자기 변경* — *호출자가 "왜 이 줄이 있는지" 추측해야 함*.
44
+ 2. **`Int`/`Long`/`Double` 표준 산술과 의미 충돌** — *Kotlin 표준에선 `a + b` 가 immutable + 새 값*. *Money 가변 plus* 는 *Kotlin 어휘에 안 맞음*. *문서 안 보면 함정*.
45
+
46
+ `multiplyMoney(factor)` 가 *Money 새 객체 반환* (불변 스타일) 인 반면 `plus`는 *가변 self 변경* — *동일 클래스 내 두 스타일 혼재*. *연산자 오버로딩의 원칙 = 직관적 의미 + 표준 표현*.
47
+
48
+ 또한 *Money 가변 + multi-thread 안전성 < Money 불변* (학생이 1단계에서 자가 학습한 결론) 과 모순.
49
+
50
+ ### 2. `BetResult.getDealerResult` — *Money 가변에 묶인 버그 패턴*
51
+
52
+ ```kotlin
53
+ private fun getDealerResult(
54
+ playerResults: Map<Participant, Money>,
55
+ dealer: Dealer,
56
+ ): Map<Participant, Money> {
57
+ var dealerResult = Money(0.0)
58
+ playerResults.forEach { (_, money) ->
59
+ dealerResult + money // ⚠ 결과 무시. Money.plus(Unit) 가변 self 변경에 의존
60
+ }
61
+ dealerResult = dealerResult.multiplyMoney(-1.0)
62
+ return mapOf(Pair(dealer, dealerResult))
63
+ }
64
+ ```
65
+
66
+ → **`dealerResult + money` 의 *결과 무시 + 가변 변경 의도***. *Money.plus 가 Unit 반환 + value 변경*이므로 *동작은 함*. 다만 *코드만 보면 *`dealerResult + money` 한 줄이 NoOp* 으로 읽힘* — *Money.plus 의 가변 구현 알아야* 의미 파악. *코드 가독성 0*.
67
+
68
+ 또한 *딜러 결과 = 플레이어 결과 합 × -1* 룰. *플레이어들이 +5000원 벌면 딜러는 -5000원 잃음* 의 총합 0 게임. 표현은 정합. 다만 *Money 가변 의존*은 *수정 시 사고 유발*.
69
+
70
+ `var dealerResult = Money(0.0)` 후 *dealerResult.multiplyMoney(-1.0)* 으로 *재할당* — *불변 스타일* 표현. *plus도 불변이면 모두 일관 — `dealerResult + money` 가 *새 Money* 반환 + *fold/sum* 패턴*.
71
+
72
+ ```kotlin
73
+ val dealerLoss = playerResults.values.sumOf { it.value }
74
+ return mapOf(dealer to Money(-dealerLoss))
75
+ ```
76
+
77
+ 이 한 줄이면 *Money 가변 의존 0*.
78
+
79
+ ### 3. `BlackjackEngine.bets: MutableMap<Player, Money>` + `Items.money` 이중 보유 — *SSOT 위반*
80
+
81
+ ```kotlin
82
+ class BlackjackEngine(...) {
83
+ var bets: MutableMap<Player, Money> = mutableMapOf()
84
+
85
+ fun getPlayersBet(players: Players) {
86
+ players.value.forEach { player ->
87
+ bets[player] = Money(eventProvider.getBetAmount(player.name).toDouble())
88
+ }
89
+ }
90
+ ...
91
+ }
92
+
93
+ // Items
94
+ class Items(val hand: Hand, val money: Money)
95
+ ```
96
+
97
+ 말리빈 (BlackjackEngine.kt:8 — 미해결): *"플레이어가 돈을 갖고있는데, 여기에서 베팅 금액을 한 번 더 관리하고 있는 것이 혼란스럽네요. 어디가 SSOT인지 알기가 어려워요. 이 부분은 없애보는 건 어떨까요?"*
98
+
99
+ → **`Player.items.money` (플레이어 자기 돈) + `BlackjackEngine.bets[player]` (베팅 금액 별도 보관) 이중 보유**. *베팅 금액 = 플레이어 책임* 인지 *게임 책임* 인지 모호. *Player.items.money* 가 *현재 보유금* 이면 *bet은 라운드 시작 시 자기 보유금에서 빼서 게임에 거는 흐름*. *둘 다 보유*는 *상태 일관성*을 *암묵적 invariant*로 유지해야 함.
100
+
101
+ 학생 PR 본문 자가 인용: *"플레이어에 3개 이상의 인스턴스 변수가 생기는걸 방지하기 위해 플레이어의 소지금을 없애고, 판돈을 엔진에 저장한 다음, 판돈을 기준으로 결과를 출력하도록 하였는데, 이렇게 하면 차후에 게임을 몇번 이어서 하는 기능을 확장하기 힘들게 될 것 같다는 생각이 듭니다."*
102
+
103
+ 말리빈 자가 답변: *"인스턴스 변수 3개 유지는 확실히 극단적인 방법이에요. 그러나 지금은 연습을 위해 일부러 극단적인 방법을 택했다고 생각해주세요. 분리를 연습하려면 이런 극단적임이 가장 적합하더라구요."*
104
+
105
+ → ***3 변수 제약 = 연습 도구, 절대 룰 X***. *프로그래밍 요구사항* 의 제약을 *학생이 "왜 이렇게 까지 해야 하나"* 자가 회의 → 말리빈 *"분리 연습"* 정당화. *제약의 의도 = 결합 분해 능력 키우기*. *결과적인 SSOT 위반* 은 *연습 과정의 부산물*. **MCP 룰 후보 — 형식 규칙(3변수)이 만든 인공 객체**. PR #128·#135 의 `Wallet`/`PlayerBetInfo`/`UserInformation` 와 같은 결.
106
+
107
+ ### 4. `Items` + `setNewHand(newHand)` — *val items + hand 가변 변경의 우회*
108
+
109
+ ```kotlin
110
+ class Items(
111
+ val hand: Hand,
112
+ val money: Money,
113
+ ) {
114
+ fun setNewHand(newHand: Hand) {
115
+ hand.clear()
116
+ newHand.cards.forEach { card ->
117
+ hand.add(card)
118
+ }
119
+ }
120
+ }
121
+
122
+ // Hand
123
+ fun clear() { _cards.clear() }
124
+ fun add(card: Card) { _cards.add(card) }
125
+ ```
126
+
127
+ 말리빈 (Dealer.kt 미해결): *"아래 코드를 실행시키면 어떤 문제가 발생할까요? `val dealer = Dealer(...); dealer.items = Items(...)`"*
128
+
129
+ 학생 자가 답변 (커밋 `241741c`): *"딜러의 손패와 아이템을 마음대로 변경할 수 있겠네요. 관련 val로 수정했습니다. 그러나 결과적으로 핸드는 무조건 수정되어야 하다 보니 var로 수정하였는데, 책에서 읽기로는 val 가변객채 보다는 var 불변객체 가 더 멀티 쓰레드에서 안전하다고 들었습니다. 그러면 items 에서 hand를 가변으로 수정하려고 하다보니, 그럼 이전과 같은 문제가 발생 할 것 같더라고요. 그래서 일단은 val 가변객채로 선언한 _cards 의 카드를 전부 빼고 새 핸드의 카드를 전부 넣는 식으로 구상하였습니다."*
130
+
131
+ → **`val items` 외부 (좋은 면) + `Items.hand: val Hand` + `Hand.clear() + add(card)` 가변 변경 (얕은 불변 함정)**. *`val items`* 외부 보호 → *Items 객체 자체는 교체 불가*. 그러나 *Items.hand 도 val* 인데 *Hand가 가변 (clear/add)* 이므로 *Items 객체의 hand 내용은 바뀜*. 깊은 불변 X.
132
+
133
+ 학생이 *"val 가변 vs var 불변"* 트레이드오프 의식. *Kotlin 스타일 = "var 불변" (var prop + immutable Hand)*. 라운드 종료 시 *`items = items.copy(hand = newHand)` (Items도 data class면 자연)* 패턴. *현재 *val items + setNewHand 가변 변경* 은 *불변 스타일 흉내 + 깊은 가변* 절충.
134
+
135
+ 또한 `Hand.clear()` 가 *블랙잭 도메인 메시지로 의미 있는가* — *블랙잭에서 손패를 비우는 행위가 *라운드 종료 시 새 라운드 시작* 외에 있는가*. *도메인 메시지가 아니라 *Hand 가변 변경 우회 메서드**. *진짜 도메인은 `Items.startNewRound(hand)` 같은 명시적 메시지*.
136
+
137
+ ### 5. `Hand.BUST_SCORE = -1` 센티넬 트릭 — *1단계 미해결 그대로*
138
+
139
+ ```kotlin
140
+ class Hand(...) {
141
+ fun isBust(): Boolean = score() == BUST_SCORE
142
+ fun score(): Int {
143
+ val baseScore = cards.sumOf { it.rank.score }
144
+ return maxOf(baseScore.formatIfBust(), maxScoreWithAce(baseScore).formatIfBust())
145
+ }
146
+ private fun maxScoreWithAce(hardScore: Int): Int = if (containsAce) hardScore + 10 else hardScore
147
+ private fun Int.formatIfBust(): Int = if (this > 21) BUST_SCORE else this
148
+
149
+ companion object {
150
+ private const val BUST_SCORE = -1
151
+ ...
152
+ }
153
+ }
154
+ ```
155
+
156
+ → **`score()` 가 Bust 시 *-1* 반환 + `isBust()` 가 *score == -1* 비교**. 1단계 미해결의 *센티넬 트릭이 호출자에 새는 함정* 그대로 유지. *호출자가 `score()` 만 부르면 *Bust일 때 -1 정수* → 잘못된 비교*. *`WinningResult.getResult`* 의 *`one.getScore() > other.getScore()` 비교* 가 *둘 중 한쪽 Bust*면 *`isBusted()` 분기로 먼저 분리*하는 *방어 코드*에 의존.
157
+
158
+ ```kotlin
159
+ // WinningResult.getResult
160
+ other.isBusted() -> WIN
161
+ one.isBusted() -> LOSE
162
+ other.getScore() > one.getScore() -> LOSE // ⚠ 두 isBusted 분기 후에야 안전
163
+ ```
164
+
165
+ *호출자가 *Bust 분기 먼저 검증* 이 강제됨* — *센티넬 트릭의 비용*. *진짜 분리* 는 *`Hand.scoreOrNull()` / `sealed class Score { Valid(Int), Bust }`* 같은 *타입 표현*.
166
+
167
+ ### 6. `WinningResult.getResult` 의 *플레이어 양측 Bust* 안티 분기
168
+
169
+ ```kotlin
170
+ fun getResult(one: Participant, other: Participant): WinningResult {
171
+ val otherBlackjack = other.getHandSize() == 2 && other.getScore() == 21
172
+ val oneBlackjack = one.getHandSize() == 2 && one.getScore() == 21
173
+ return when {
174
+ otherBlackjack && oneBlackjack -> PUSH
175
+ oneBlackjack -> BLACKJACK
176
+ otherBlackjack -> LOSE
177
+ (one.isBusted() && other.isBusted() && one is Player) -> LOSE // ⚠ Player 타입 검사
178
+ other.isBusted() -> WIN
179
+ one.isBusted() -> LOSE
180
+ other.getScore() > one.getScore() -> LOSE
181
+ other.getScore() < one.getScore() -> WIN
182
+ else -> PUSH
183
+ }
184
+ }
185
+ ```
186
+
187
+ → **`(one.isBusted() && other.isBusted() && one is Player) -> LOSE` 분기 — *Player/Dealer 비대칭***. *블랙잭 룰 = Bust 양측이면 둘 다 패배*. *플레이어 LOSE*만 명시되어 *딜러 입장에서 두 명 다 Bust면?* *fallback 으로 흘러가서 *other.getScore() == one.getScore() = -1 == -1 = PUSH*** 가 됨. *카지노 룰은 *플레이어 Bust 즉시 LOSE, 딜러 Bust면 모든 플레이어 WIN**. *양측 Bust* 도 *플레이어 LOSE*가 룰. *현재 분기*는 *`one is Player`* 일 때 *플레이어 LOSE* 만 표현 — *딜러 입장 비대칭 + Player 타입 검사 = 안티 다형성*.
188
+
189
+ *`Player.compareHand(dealer)` 의 *Player → 자기 입장에서 결과*는 자연. 그렇다면 `one is Player` 라는 분기 자체가 *Player.compareHand* 호출 시점에 이미 *one = this(Player)* 로 고정됨 — *타입 검사 불필요*. *Dealer.compareHand 가 호출되지 않는다면 *분기 자체 죽은 코드*. PR #133에서 *Player.compareHand 만 호출* (`makeBetResultByPlayers`) 이므로 *Dealer 입장 호출 = 죽은 코드*. *복잡도 부담 + 의미 부재*.
190
+
191
+ ### 7. `WinningResult.getResult` 가 *정적 헬퍼* — Tell-Don't-Ask 미완성
192
+
193
+ ```kotlin
194
+ class Player(...) : Participant {
195
+ fun compareHand(other: Participant): WinningResult = WinningResult.getResult(this, other)
196
+ }
197
+
198
+ // WinningResult
199
+ fun getResult(one: Participant, other: Participant): WinningResult { ... }
200
+ ```
201
+
202
+ → **`Player.compareHand` 메시지는 *겉만 메시지*, *내부는 정적 호출***. *Player.compareHand → WinningResult.getResult(this, other)* 는 *`this`/`other.getHandSize()`/`getScore()`/`isBusted()`* 정보를 *Static 함수가 추출 + 비교*. *Tell-Don't-Ask 의 본질 = `this` 가 자기 정보로 결과 결정*. 현재는 *one/other 모두 ask + static logic*. PR #108 (시아 1단계) 의 *`object CalculateResult`* 정적 헬퍼와 *형태만 바뀜*.
203
+
204
+ 말리빈의 *"객체에게 메시지를 던져보는 건"* 의도는 *Player 자기 정보로 결과 결정* — *외부 enum 정적 함수 의존 X*. *Player 내부에서 자기 손패/Bust 상태 + 상대 메시지로 결과 계산* 이 진짜 메시지. *enum WinningResult* 는 *결과 표현*만, *결정 로직*은 *Participant 안*.
205
+
206
+ 다만 *Dealer/Player 다형성 차이 발생 시 분리*가 의도라면 *abstract method `compareHand(other)` 의 각 구현체에서 다른 로직*도 가능. *현재는 Player에만 compareHand* — *Dealer는 호출 안 됨*.
207
+
208
+ ### 8. `BlackjackEngine.progressXXX` 명사형 / `progress + 동사` 합성
209
+
210
+ ```kotlin
211
+ fun progressPlayersDraw(players: Players) { ... }
212
+ fun progressDealerDraw(dealer: Dealer) { ... }
213
+ fun progressCalculateResult(dealer: Dealer, players: Players): Map<Participant, Money> { ... }
214
+ fun progressCalculateFullResult(currentResult: Map<Participant, Money>) { ... }
215
+ fun progressPlayerDrawUntilFinished(player: Player) { ... }
216
+ ```
217
+
218
+ → **`progress + XX` = *Engine이 진행 단계*를 명사적 prefix로 묶음**. *Kotlin 동사형 메서드명* 권고와 충돌. `playerDraw` / `dealerDraw` / `calculateResult` 같은 *동사*가 자연. *`progress` prefix*는 *Engine이 게임 진행자임을 메서드명에 새김* — *Engine god-object 자기 인식의 신호*.
219
+
220
+ 또한 `progressCalculateResult` + `progressCalculateFullResult` 두 단계가 *결과 계산 (단순)* + *결과 합산 (Player money 변경)* 분리. *왜 두 단계?* *전자는 단순 read-only, 후자는 Player.items.money 가변 변경* — *Side-effect 분리 의도*면 합리. 다만 *명명에서 안 드러남*.
221
+
222
+ ### 9. `Items.hand.cards` / `player.items.hand.cards` — *Demeter 위반 + 학생 자가 의문*
223
+
224
+ ```kotlin
225
+ // 사용처
226
+ eventListener.displayParticipantCards(player.name, player.items.hand.cards)
227
+ eventListener.displayParticipantInfo(
228
+ dealer.name,
229
+ dealer.items.hand.cards,
230
+ dealer.items.hand.score(),
231
+ dealer.items.hand.isBust(),
232
+ )
233
+ ```
234
+
235
+ 학생 PR 본문 자가 인용: *"items을 활용해서 적용시켜보았습니다. 확실히 확장성은 좋아진 것 같은데, 아이템에 접근 할 때 마다 player.items.hand.value 이렇게 접근하는게 너무 번거롭다는 생각이 드네요. player 안에 함수를 만들어서 핸드를 달라는 메세지를 전달하는게 맞을까요? 하니면 벨류를 사용해서 적용하는게 맞을까요?"*
236
+
237
+ 말리빈 답변 (Items.kt:1): *"맞고 틀림에 집중하기 보다, 그 불편함을 해결하기 위해 어떤 방법을 사용하면 좋을지에 대해 더 초점을 맞춰보세요. 디미터의 법칙에 대해서도 알아보시면서 마주한 불편함을 어떻게 해결하면 좋을지 고민해보세요!"*
238
+
239
+ 학생 답변: *"단순히 getter로 데이터를 가져오는 것이 아닌 메세지를 주고받기! 제 코드도 무조건 자료를 가져와서 비교하는 방식이었는데, 객체지향에 위배되는줄 몰랐네요. 이건 범위가 너무 넓어서 시간이 날 때 천천히 리펙토링 해보겠습니다."*
240
+
241
+ → **Items 일급 컬렉션 도입의 부작용 = Demeter 깊이 증가**. *Player → Items → Hand → cards/score/isBust* 가 *3 단계 점 접근*. *Items 도입 = 변수 묶음* 의도였으나 *접근 경로 길어짐 + Demeter 위반*. *Player.cards()*, *Player.score()* 등 *위임 메서드*로 *접근 한 단계*가 자연. *호출자는 Items 존재 모름* — *Items 은 Player 내부 구현*.
242
+
243
+ *EventListener.displayParticipantInfo(name, cards, score, isBusted)* 가 *4 개 정보를 한 번에 받음* — *participant 한 객체*를 받으면 더 자연. 다만 *EventListener interface = 도메인 → View 통보* 이므로 *Participant 도메인 객체를 View에 노출*은 *View가 도메인 알아야* 함. *DTO* 변환이 *완전한 분리*. 트레이드오프.
244
+
245
+ ### 10. `BlackjackEngine` god-object — *bets + cardDeck + eventListener + eventProvider 4 인스턴스 변수*
246
+
247
+ ```kotlin
248
+ class BlackjackEngine(
249
+ val cardDeck: CardDeck = CardDeck(),
250
+ val eventListener: EventListener,
251
+ val eventProvider: EventProvider,
252
+ ) {
253
+ var bets: MutableMap<Player, Money> = mutableMapOf()
254
+ ...
255
+ }
256
+ ```
257
+
258
+ → **4 인스턴스 변수 + 11 메서드 (`getPlayersBet`, `preparePlayers`, `prepareDealer`, `drawPlayer`, `drawDealer`, `makeFirstHand`, `progressPlayersDraw`, `progressPlayerDrawUntilFinished`, `progressDealerDraw`, `progressCalculateResult`, `progressCalculateFullResult`, `setParticipantCard`)** — *Engine 이 모든 진행 흡수*. 1단계 *Controller god-object → 2단계 Engine god-object* 의 *책임 이전 + 분리 미완*.
259
+
260
+ 말리빈 (BlackjackEngine.kt:1 — 미해결): *"네 :) 의도한 방향이 맞아요. ... 어떤 차이가 있을까요?"* + *"어떤 의존성이 심해지나요? 또, 어떤 확장에 문제가 생길 수 있었나요?"* (두 단계 메타 질문).
261
+
262
+ 학생: *"음..그래도 지금처럼 게임 진행에 대한 로직과 출력만 담당하는 로직을 나눠서 진행은 엔진에서, 출력은 컨트롤러에서 진행하는 것이 맞다고 생각했습니다."*
263
+
264
+ → **Engine + Controller 의 책임 경계 = 학생 자가 결정**. *Engine = 진행*, *Controller = 출력* 분리. 그러나 *EventListener interface 가 도메인-뷰 콜백*이므로 *Controller = 의존성 주입 + EventListener 구현* 인지 *Controller = 메인 흐름 (run 함수)* 인지 *추가 분리*가 모호. *Engine.progressXX 11개 메서드*는 *Engine = 모든 흐름의 진입점* — *Controller 가 그저 Engine.progressXX 순차 호출자*면 *Engine 안에 `run()`* 도 가능 (PR #131 (다이스) 와 같은 결).
265
+
266
+ ### 11. `EventListener.displayDealerDrawInfo(name, count)` — *카운트 = 출력용 카운터*
267
+
268
+ ```kotlin
269
+ fun displayDealerDrawInfo(name: String, count: Int)
270
+
271
+ // 사용처
272
+ eventListener.displayDealerDrawInfo(dealer.name, dealer.getHandSize() - START_CARD_COUNT)
273
+ ```
274
+
275
+ → **`dealer.getHandSize() - START_CARD_COUNT` = *현재 핸드 - 초기 카드 수* = *추가 뽑은 수***. 1단계 *Dealer.getAdditionalDrawCount* (말리빈 진단: *"콘솔의 영향으로 이렇게 구성했다는 느낌이 강하게 드네요"*) 와 같은 결. *2단계에서도 동일한 *출력용 카운터*가 Engine에 살아 있음*. *Dealer는 자기 추가 뽑은 카드 수*를 *메시지로 알리지 않음* + *Engine이 외부에서 계산*. 도메인 책임 누수.
276
+
277
+ ### 12. `Player` 가 `compareHand(other: Participant)` 만 가짐 — *Dealer.compareHand 없음 = 비대칭*
278
+
279
+ ```kotlin
280
+ class Player(...) : Participant {
281
+ fun compareHand(other: Participant): WinningResult = WinningResult.getResult(this, other)
282
+ }
283
+
284
+ class Dealer(...) : Participant {
285
+ tailrec fun drawUntilFinished(cardDeck: CardDeck) { ... }
286
+ // compareHand 없음
287
+ }
288
+ ```
289
+
290
+ → **`Player.compareHand` 만 존재 = *플레이어 vs 다른 참가자* 메시지로 *플레이어 입장* 결과**. *Dealer.compareHand* 가 없으므로 *Dealer 입장 결과*는 *BetResult.getDealerResult* 에서 *플레이어 합 × -1* 로 *우회*. *Tell-Don't-Ask 의 *Dealer 입장* 부재*.
291
+
292
+ *Participant interface에 `compareHand`* 가 *abstract method* 면 *Player/Dealer 각각 구현 다형성* — *카지노 룰 (딜러는 모든 플레이어와 동시 비교)* 도 *Dealer.compareHand(players: Players)* 같은 *다른 시그니처* 로 표현. 현재는 *Player에만 method 존재 + 정적 헬퍼* 가 그 한계.
293
+
294
+ ### 13. `Card.getCashed` — *cashed* 오타 + *findLast* naming 모순
295
+
296
+ ```kotlin
297
+ class Card private constructor(
298
+ val rank: CardRank,
299
+ val suit: CardSuit,
300
+ ) {
301
+ companion object {
302
+ val SINGLE_DECK = ...
303
+
304
+ fun getCashed(
305
+ rank: CardRank,
306
+ suit: CardSuit,
307
+ ): Card =
308
+ SINGLE_DECK.findLast { it.rank == rank && it.suit == suit }
309
+ ?: throw IllegalArgumentException("[ERROR] 잘못된 카드 번호나 문양입니다.")
310
+ }
311
+ }
312
+ ```
313
+
314
+ → **`getCashed` = `cached`의 오타 (현금화 cash와 혼동)**. *Card 캐시 lookup* 의미 — *getCached* 가 표준. *팩토리 함수 이름 = `Card.of(rank, suit)` / `Card.from(rank, suit)`* 가 Kotlin 표준 어휘. *명명 오타*는 *향후 사용자 혼란*.
315
+
316
+ 또한 `findLast` — *SINGLE_DECK이 unique*인데 *마지막 매칭*은 *의미 부재*. *`first { ... }` 또는 `single { ... }`* 가 자연. PR #108 (시아 1단계) 와 같은 결의 *naming 부조화* 잔존.
317
+
318
+ ### 14. `Items.hand: Hand` + `Items.money: Money` 둘 다 val — *깊은 불변 부족 + Items 정당화 모호*
319
+
320
+ ```kotlin
321
+ class Items(
322
+ val hand: Hand, // val + Hand 가변 (clear/add)
323
+ val money: Money, // val + Money 가변 (var value: Double)
324
+ ) {
325
+ fun setNewHand(newHand: Hand) { ... }
326
+ }
327
+ ```
328
+
329
+ → **Items 두 멤버 모두 *val + 내부 가변***. *val 보호는 객체 교체 차단*만, *내부 변경은 그대로*. *Items 도입의 의미 = 데이터 묶음 + 메시지 발신처*. 다만 *Items.setNewHand* 같은 *상태 변경 메서드* 가 *Items 안에 있는 것*은 *Items = 일급 컬렉션이 자기 정보 관리* 패턴. *현재는 setNewHand 외에 다른 메서드 0개* — *데이터 클래스에 가까움*.
330
+
331
+ *Kotlin data class 로 재선언* 하면 *equals/hashCode/copy* 자동. *`items.copy(hand = newHand)` 같은 *불변 사본*이 자연 — *현재 *clear + add* 가변 변경*과 정공.
332
+
333
+ 말리빈 메타 답변 (BlackjackEngine.kt 첫 두 단계 질문): *"인스턴스 변수 3개 유지는 확실히 극단적인 방법이에요. 그러나 지금은 연습을 위해 일부러 극단적인 방법을 택했다고 생각해주세요."*
334
+
335
+ → **Items = 3 변수 제약 우회로 만들어진 인공 객체** 의 측면. *블랙잭 도메인에서 "참가자의 아이템" = hand + money* 가 *자연한 묶음*인가 *아니면 변수 갯수 제약 인공물*인가. *답은 트레이드오프* — 학생/말리빈 둘 다 의식.
336
+
337
+ ### 15. `Participant.addPrize(prize)` — *Money 가변에 묶인 부수효과 메서드*
338
+
339
+ ```kotlin
340
+ interface Participant {
341
+ val items: Items
342
+ ...
343
+ fun addPrize(prize: Money) = items.money + prize // ⚠ items.money + prize = Unit, 가변 변경
344
+ }
345
+ ```
346
+
347
+ → **`items.money + prize` 결과 무시 + Money.plus 가변 변경 의존**. *Participant.addPrize(prize)* 가 *부수효과 메서드 (Unit)* 인데 *내부 `items.money + prize`* 도 *Unit + 가변 변경* — *두 단계 가변에 의존*. *Money 불변 + plus 새 객체*면 *`items = items.copy(money = items.money + prize)`* 같은 *명시적 재할당*. 그러나 *items val* 이므로 *Items 도 copy 의존*.
348
+
349
+ *Kotlin 가변 vs 불변 정공* — *모두 불변 + copy* 패턴. 현재는 *가변 plus 호출 + val 우회* 가 *복잡도 증가*.
350
+
351
+ ### 16. `BlackjackEngine.setParticipantCard` — *라운드 재시작 시 새 핸드 분배*
352
+
353
+ ```kotlin
354
+ fun setParticipantCard(dealer: Dealer, players: Players) {
355
+ dealer.changeHand(makeFirstHand())
356
+ players.value.forEach { player ->
357
+ player.changeHand(makeFirstHand())
358
+ }
359
+ }
360
+ ```
361
+
362
+ → **`changeHand` = Items.setNewHand 호출 = Hand.clear() + add()**. 라운드 종료 후 *같은 Dealer/Player 객체* 의 *Hand 만 비우고 새 카드 추가*. *학생 자가 학습 (`tailrec` + 재귀로 게임 N회) 의 확장 기능*. *Player/Dealer 동일성 유지 + 라운드 간 손패 교체*.
363
+
364
+ 말리빈 (BlackjackEngine.kt 미해결): *"여러운 도전 과제일 수도 있지만 한 번 남겨둘게요 이건 반영하지 않으셔도 좋아요 :) 재귀 함수로 게임 진행을 구현해볼 수도 있겠어요. 코틀린의 tailrec 키워드도 함께 알아보세요!"*
365
+
366
+ → **`tailrec` 자가 학습은 좋은 면** + **`setParticipantCard` 가 *in-place 핸드 교체*로 *Player 동일성 유지*** 는 *말리빈의 도전 과제* 의 답. 다만 *Player 가 라운드 마다 다른 손패* = *Player 동일성 의미가 "참가자 신원"으로 좁아짐* + *Hand 가변 변경 의존* 의 부산물.
367
+
368
+ *불변 스타일 정공* = *라운드마다 새 Player(이름, newItems)* 객체 생성. 다만 *Player 객체 identity 가 라운드별로 달라짐* — *총 결과 집계* 등에서 *같은 이름 = 같은 사람* 판정 필요. *현재 in-place 교체*는 *identity 유지*를 위한 트레이드오프.
369
+
370
+ ### 17. `Players` 가 `value: List<Player>` 만 가짐 — *행위 미부여*
371
+
372
+ ```kotlin
373
+ class Players(val value: List<Player>) {
374
+ init { require(...) }
375
+ // 일급 컬렉션이지만 메서드 0개
376
+ }
377
+ ```
378
+
379
+ 말리빈 (Players.kt — 미해결): *"value 프로퍼티가 있는데 getPlayers() 함수를 따로 만든 이유가 궁금하네요!"*
380
+
381
+ 학생 자가 답변 (커밋 `04edcd9`): *"지난 리뷰에서 메세지를 줘야한다 이런 생각이 들어서 get을 붙였는데 지금 생각해보니 쓸대 없는 함수였네요.."*
382
+
383
+ → **`Players` 일급 컬렉션이지만 *행위 메서드 0개***. *`results(dealer: Dealer): Map<...>` 메서드 (1단계)* 가 *2단계에서 BetResult로 이전됨*. *지금 Players는 *컬렉션 wrapper + 검증*만*. *일급 컬렉션의 가치 = 자기 정보 + 자기 행위*. *현재는 자기 정보만*. *`Players.eachDraw(deck)`* 같은 *분배 메시지* 추가 후보.
384
+
385
+ ### 18. `getCashed` factory naming + *생성자 vs 팩토리 표준 어휘*
386
+
387
+ ```kotlin
388
+ fun getCashed(rank: CardRank, suit: CardSuit): Card =
389
+ SINGLE_DECK.findLast { it.rank == rank && it.suit == suit }
390
+ ?: throw IllegalArgumentException(...)
391
+ ```
392
+
393
+ → **Kotlin 팩토리 함수 표준 어휘 미준수**:
394
+ - `from(rank, suit)`: 다른 형태에서 객체 생성
395
+ - `of(rank, suit)`: 여러 인자로 객체 생성
396
+ - `valueOf(rank, suit)`: 더 명시적
397
+ - `getInstance()`: 싱글톤
398
+ - `getCached()`: 캐시 명시
399
+
400
+ *`getCashed`* 는 *명명 오타 + 표준 어휘 부재*. *Effective Java/Kotlin 팩토리 함수 어휘* 권고.
401
+
402
+ ### 19. `assertThat` vs `assertEquals` 학생 자가 학습 영역
403
+
404
+ ```kotlin
405
+ // 학생: 빨간 줄이 떠서 assertEquals 사용
406
+ ```
407
+
408
+ 말리빈 (BlackjackEngineTest.kt:40): *"빨간 줄이 나타났다는 건, 컴파일이 안됐다는 의미인가요? 그렇다면 그냥 문법을 잘못 활용한 경우예요. assertAll과 assertThat은 서로 사용할 수 있어요. ... 왜 assertThat 으로 시작하는 테스트 라이브러리가 등장했는지 알아보셔도 좋겠어요."*
409
+
410
+ → **AssertJ `assertThat` = fluent API + 풍부한 매처**. *JUnit `assertEquals` = 단순 동등*. *복잡한 어설션 (`assertThat(list).containsExactly(...)` 등)* 은 *assertThat 만의 영역*. *학생이 컴파일 오류를 이유로 회피한 것은 학습 회피 신호* — 말리빈 진단.
411
+
412
+ ### 20. `Hand.score()` 의 `maxOf(baseScore.formatIfBust(), maxScoreWithAce(baseScore).formatIfBust())` — *과잉 트릭 잔존*
413
+
414
+ ```kotlin
415
+ fun score(): Int {
416
+ val baseScore = cards.sumOf { card -> card.rank.score }
417
+ return maxOf(baseScore.formatIfBust(), maxScoreWithAce(baseScore).formatIfBust())
418
+ }
419
+
420
+ private fun maxScoreWithAce(hardScore: Int): Int =
421
+ if (containsAce) hardScore + 10 else hardScore
422
+
423
+ private fun Int.formatIfBust(): Int = if (this > 21) BUST_SCORE else this
424
+ ```
425
+
426
+ → **1단계 트릭 그대로**. *baseScore (Ace=1)* + *maxScoreWithAce (Ace 있으면 +10)* 두 후보 + *각각 Bust면 -1* + *maxOf*. *Ace 단일 +10 if (sum + 10 ≤ 21)* 한 줄 패턴 (PR #128·#135·#114) 으로 충분.
427
+
428
+ *containsAce && baseScore + 10 ≤ 21 → baseScore + 10 else baseScore* 이 *부정확한 경우* — *Ace 2장* (예: A♠ A♥). *baseScore = 2, maxScoreWithAce = 12 (한 Ace만 +10)*. *현재 `containsAce` boolean → +10 1번* 이 *Ace 2장 처리 정확* (둘 다 11이면 22 > 21이므로 한 Ace만 11 + 나머지는 1). OK.
429
+
430
+ 다만 *세 Ace* 경우: *baseScore = 3, maxScoreWithAce = 13*. *현실 시나리오*는 *극히 드물지만 룰 = 한 Ace만 11* 이 정확. 현재 구현 OK.
431
+
432
+ ### 21. `Items` 도입의 *Demeter 비용 vs 변수 묶음 이득* — 학생 자가 의문이 미해결
433
+
434
+ 학생 PR 본문 (items): *"player.items.hand.value 이렇게 접근하는게 너무 번거롭다는 생각이 드네요. player 안에 함수를 만들어서 핸드를 달라는 메세지를 전달하는게 맞을까요? 하니면 벨류를 사용해서 적용하는게 맞을까요?"*
435
+
436
+ 학생 후속 답변: *"이건 범위가 너무 넓어서 시간이 날 때 천천히 리펙토링 해보겠습니다."*
437
+
438
+ → **Items 도입의 *Demeter 비용*을 학생이 자가 인식 + 미해결**. *Player.cards()*, *Player.score()*, *Player.isBust()* 같은 *위임 메서드* 가 *Player가 자기 정보 노출 + 호출자 한 단계 접근* 의 정공. *Participant interface 의 default 메서드* `getHandSize()`, `getScore()`, `isBusted()` 가 *그 방향*인데 *EventListener 호출 시 *cards 자체*가 필요해 *items.hand.cards 직접 접근*. 도메인 메시지 (Participant) + View 호환 (cards 노출) 의 트레이드오프.
439
+
440
+ ## 리뷰어 의견 요지
441
+
442
+ - **Money 가변 + 연산자 오버로딩 = 상성 안 좋음** — *operator plus = 새 객체 반환* 표준 + *불변* 안전. *가변 + plus = 표현식 의미 무너짐*.
443
+ - **SSOT — 같은 정보 두 곳 보유 X** — *Player.items.money* + *Engine.bets[player]* 이중 = *상태 일관성 암묵 invariant*.
444
+ - **3 변수 제약 = 연습 도구, 절대 룰 X** — *분리 능력 키우기 위한 극단적 방법*. *Items 같은 인공 객체*는 *연습 부산물*. *완전히 정당한 도메인 객체*가 되려면 *블랙잭 도메인에서 "참가자의 아이템"이 자연한 묶음인가* 검증.
445
+ - **재귀 + tailrec = 게임 N회 진행** — *while loop 의존 X*. *tailrec 키워드 = 스택 안전 재귀*. *Kotlin 다중 패러다임 학습*.
446
+ - **Demeter — `player.items.hand.value` 같은 점 체인 = 객체 협력 부재 신호** — *Player.cards()* 위임이 *호출자가 알아야 하는 객체 수 최소화*.
447
+ - **참가자 vs 참가자 메시지 = 딜러도 플레이어로 일반화** — *Player.compareHand(participant)* 도입은 좋은 면. 다만 *내부가 정적 헬퍼*면 *Tell-Don't-Ask 의 절반*.
448
+ - **연습 의도 = 다각도 시점 갖기, 맞고 틀림 X** — 말리빈의 *"맞고 틀림을 가르는 것으로 초점을 맞추기보다, 다각도의 시점으로 본다는 것에 더 집중해보세요. 이런 고민들이 앞으로 기준을 나누는데 자신만의 힘을 기를 수 있게 해줄거라 의심치 않아요."*
449
+ - **assertThat 도입 이유 = 매처 풍부함** — *JUnit assertEquals 한계*. *복잡한 어설션 표현력*.
450
+ - **테스트 픽스처 = 재사용 + 가독성** — *매번 카드 만들기 X*. *상수 fixture* 가 *테스트 의도 명료*.
451
+ - **`dealer.items = ...` 외부 변경 가능성 = val 보호 필요** — *property val*은 *교체 차단*. *내부 가변* 은 별개.
452
+
453
+ ## 대표 인용
454
+
455
+ **말리빈 (3 변수 제약의 의도, BlackjackEngine.kt):**
456
+ > 인스턴스 변수 3개 유지는 확실히 극단적인 방법이에요.
457
+ > 그러나 지금은 연습을 위해 일부러 극단적인 방법을 택했다고 생각해주세요. 분리를 연습하려면 이런 극단적임이 가장 적합하더라구요.
458
+ > 처음부터 분리에 익숙해지면, 합치는 것은 매우 쉬워져요.
459
+ > 그러나 분리를 할 줄 모르면 합쳐져있는 것에서 분리할 수 있다는 사실 자체를 깨닫지 못하지요.
460
+ >
461
+ > 객체가 어떤 값을 가지는 게 너무 자연스럽다면 그 객체에 위치하는 것이 당연하지요.
462
+ > 야매라고 생각하실 수도 있겠지만, 3개가 필요한 곳에서, 2개를 묶어 하나의 클래스로 만들어보세요.
463
+ > 이 클래스의 이름을 짓는 것 조차도 굉장히 어려운 일이 될 수도 있으니 좋은 연습이 될거예요.
464
+
465
+ **말리빈 (가변 객체 + 연산자 오버로딩, Money.kt:11):**
466
+ > Money가 가변 객체였네요. 연산자 오버로딩이 되어있는 다른 것들을 참고해보세요.
467
+ > 가변객체와 연산자 오버로딩은 상성이 그리 좋지 않음을 이번 경험으로 알게되시면 좋겠어요.
468
+
469
+ **말리빈 (SSOT, BlackjackEngine.kt:8):**
470
+ > 플레이어가 돈을 갖고있는데, 여기에서 베팅 금액을 한 번 더 관리하고 있는 것이 혼란스럽네요.
471
+ > 어디가 SSOT인지 알기가 어려워요.
472
+ > 이 부분은 없애보는 건 어떨까요?
473
+
474
+ **말리빈 (Demeter, Items.kt:1):**
475
+ > 맞고 틀림에 집중하기 보다, 그 불편함을 해결하기 위해 어떤 방법을 사용하면 좋을지에 대해 더 초점을 맞춰보세요.
476
+ > 디미터의 법칙에 대해서도 알아보시면서 마주한 불편함을 어떻게 해결하면 좋을지 고민해보세요!
477
+
478
+ **말리빈 (재귀 + tailrec, BlackjackEngine.kt):**
479
+ > 어려운 도전 과제일 수도 있지만 한 번 남겨둘게요 이건 반영하지 않으셔도 좋아요.
480
+ > 재귀 함수로 게임 진행을 구현해볼 수도 있겠어요.
481
+ > 코틀린의 tailrec 키워드도 함께 알아보세요!
482
+
483
+ **말리빈 (참가자 일반화, Dealer.kt):**
484
+ > 그렇다면 WinningResult 자체를 만들어내는 로직은 WinningResult에 옮겨보는 건 어떨까요?
485
+ > 로또의 등수를 계산했듯이요.
486
+ >
487
+ > 또 하나 생각할 점을 던져드릴게요.
488
+ > 딜러도 결국 하나의 플레이어라고 생각할 수도 있지요.
489
+ > 그러면 승패의 결과는 플레이어와 플레이어를 비교해도 나올 수 있는 것은 아닐지.
490
+ > 그것을 코드로 충분히 표현해볼 수는 있지 않을지 고민해보세요.
491
+
492
+ **말리빈 (다각도 시점, BlackjackEngine.kt:1):**
493
+ > 맞고 틀림을 가르는 것으로 초점을 맞추기보다, 다각도의 시점으로 본다는 것에 더 집중해보세요. 이런 고민들이 앞으로 기준을 나누는데 자신만의 힘을 기를 수 있게 해줄거라 의심치 않아요.
494
+
495
+ **학생 자가 학습 (tailrec, BlackjackEngine.kt):**
496
+ > 재귀함수로 게임을 원하는 만큼 계속 진행하도록 변경하였습니다. tailrec 엄청나네요 오버플로우를 신경 쓸 필요가 없다니..!
497
+
498
+ **학생 자가 학습 (Demeter 깨달음, Items.kt):**
499
+ > 단순히 getter로 데이터를 가져오는 것이 아닌 메세지를 주고받기! 제 코드도 무조건 자료를 가져와서 비교하는 방식이었는데, 객체지향에 위배되는줄 몰랐네요. 이건 범위가 너무 넓어서 시간이 날 때 천천히 리펙토링 해보겠습니다.
500
+
501
+ **학생 자가 답변 (val 가변 vs var 불변 트레이드오프, Dealer.kt):**
502
+ > 딜러의 손패와 아이템을 마음대로 변경할 수 있겠네요. 관련 val로 수정했습니다. 그러나 결과적으로 핸드는 무조건 수정되어야 하다 보니 var로 수정하였는데, 책에서 읽기로는 val 가변객채 보다는 var 불변객체 가 더 멀티 쓰레드에서 안전하다고 들었습니다. 그러면 items 에서 hand를 가변으로 수정하려고 하다보니, 그럼 이전과 같은 문제가 발생 할 것 같더라고요. 그래서 일단은 val 가변객채로 선언한 _cards 의 카드를 전부 빼고 새 핸드의 카드를 전부 넣는 식으로 구상하였습니다.
503
+
504
+ **학생 자가 학습 (블랙잭 룰 정확성, Dealer.kt — 1단계 연장):**
505
+ > 현실 세계에서는 딜러가 플레이어 카드를 보고 계산한다고 생각해서 그렇게 구현하였으나, 딜러가 너무 많은 기능을 가지고 있는게 아닌가 싶습니다. 어디까지 현실 세계를 반영해야 하는지 궁금합니다.
506
+
507
+ ## 얻은 교훈
508
+
509
+ 1. ***가변 객체 + 연산자 오버로딩 = 상성 안 좋음***. *`operator fun plus(other) = Unit + 자기 변경`* 은 *Kotlin 표준 어휘 위반*. *`a + b`* 가 *표현식*으로 사용 불가 + *결과 무시 + 부수효과* 가독성 0. *불변 객체 + 새 객체 반환* 패턴이 *operator overloading 의 정공*. PR #131 (다이스 2단계) 의 *BetAmount value class* 와 *반대 패턴*.
510
+
511
+ 2. ***SSOT — 같은 정보 두 곳 보유는 invariant 비용***. *`Player.items.money` + `Engine.bets[player]` 이중*은 *베팅금 갱신 시 두 곳 동기화*. *상태 변경의 모든 경로*가 *두 곳 함께 변경* 보장해야 함 — *암묵적 invariant*. *SSOT (Single Source Of Truth)* = *상태 1곳*. *베팅금 = Player 책임* 이면 *Engine은 read-only*.
512
+
513
+ 3. ***3 변수 제약 = 연습 도구, 절대 룰 X*** — 학생/말리빈 둘 다 의식. *형식 규칙 (3변수)* 이 *Wallet/Items/PlayerBetInfo 같은 인공 객체*를 만들 위험. *연습의 의도 = 분리 능력 키우기*. *완전한 도메인 정당화*가 *진짜 객체와 인공 객체* 의 경계. PR #128·#135 의 *Wallet*/*UserInformation* 과 같은 결.
514
+
515
+ 4. ***Demeter — `a.b.c.d` 점 체인 = 협력 부재 신호***. *Player.items.hand.cards* 가 *3단계 접근*. *Player.cards()* 위임이 *호출자가 알아야 하는 객체 수 최소화*. *Items 일급 컬렉션 도입의 부작용 = 접근 경로 길어짐* — *위임 메서드*로 *외부에는 한 단계 접근*만 보이게.
516
+
517
+ 5. ***`Player.compareHand(other)` 메시지는 *겉만 메시지*, *내부 정적 헬퍼*면 Tell-Don't-Ask 절반***. *`Player.compareHand → WinningResult.getResult(this, other)`* 는 *Static 함수가 self/other 정보 추출 + 비교*. *진짜 메시지*는 *Player 자기 정보로 결과 결정* — *외부 enum 정적 함수 의존 X*. PR #108 (시아 1단계) 의 *object CalculateResult* 변형.
518
+
519
+ 6. ***Bust 양측 + Player 타입 검사 = 안티 다형성***. *`(one.isBusted() && other.isBusted() && one is Player) -> LOSE`* 분기는 *Participant 다형성 부재 신호*. *Player.compareHand 만 호출* 이라면 *one is Player* 검사 = *죽은 코드*. 그렇다면 *코드 자체 삭제* 가능. *블랙잭 룰 (Bust 양측 = 양측 패배)* 명시도 부재.
520
+
521
+ 7. ***`Card private constructor + named factory` 가 정공 — 1단계 invoke 함정 자가 해소***. 학생이 1단계 *operator fun invoke + public class* 의 모호함을 *private constructor + getCashed*로 자가 후속. 다만 *`getCashed` 명명 오타 (cached)* + *Kotlin 팩토리 표준 어휘 (`of`/`from`)* 미준수.
522
+
523
+ 8. ***`tailrec` = 스택 안전 재귀***. *Kotlin tailrec 키워드*는 *꼬리 재귀 최적화 강제*. *`drawUntilFinished` 같은 *조건 만족 시 종료 + 자기 재귀** 가 *while 루프와 동등한 성능 + 함수형 어휘*. *학생 자가 학습 + 도전 과제 반영 모범*.
524
+
525
+ 9. ***val + 가변 내부 = 얕은 불변***. *`val items: Items` + `Items.hand: Hand` 가변 (clear/add)* 은 *외부 교체 차단 + 내부 변경 허용*. *깊은 불변*은 *모든 멤버 불변 + copy 패턴*. *학생이 "val 가변 vs var 불변" 트레이드오프 의식* + *현재는 *val + clear/add 우회**.
526
+
527
+ 10. ***EventListener/EventProvider interface = 도메인-뷰 느슨한 결합 정공***. 1단계 말리빈의 *"도메인이 뷰만 모른다는 사실에 집중 → 인터페이스 혹은 람다 등으로 가져올 수 있도록"* 의 완전한 후속 반영. *EventListener.displayParticipantCards(name, cards)* 콜백으로 *도메인 → View 통보*. *Controller 가 EventListener 구현체* 주입. PR #131 (다이스 2단계) 의 *BlackJackView interface* 와 같은 결.
528
+
529
+ 11. ***Engine god-object 가능성 — Controller 분리 + 진행 흡수의 후속***. *1단계 Controller god-object → 2단계 Engine god-object* 의 책임 이전 + 분리 미완. *Engine 11 메서드 + 4 인스턴스 변수* 가 *god-object 변형 신호*. *각 객체 자기 책임* 흐름이 *Engine 거치는 wrapper* 보다 메시지 패턴에 맞음.
530
+
531
+ 12. ***Hand BUST_SCORE = -1 센티넬 트릭 잔존 (1단계 미해결 그대로)***. *score() = Bust 시 -1* 트릭이 *호출자가 isBust 먼저 분리*를 *암묵적 invariant*로 강제. *WinningResult.getResult* 의 *isBusted 분기 후 score 비교* 가 그 우회. *진짜 분리*는 *sealed class Score { Valid(Int), Bust }* 또는 *Hand.scoreOrNull(): Int?*.
532
+
533
+ 13. ***`getXXX` 명사형 → Kotlin property 또는 동사형***. `getHandSize()`, `getScore()`, `isBusted()` 가 *Java Bean 어휘*. *Kotlin val handSize get(), val score get(), val busted get()* 이 *Kotlin 어휘*. *Participant interface default property* 활용.
534
+
535
+ 14. ***`progress + XX` prefix = Engine god-object 자기 인식 신호***. *`progressPlayersDraw` / `progressDealerDraw` / `progressCalculateResult`* 는 *Engine 이 게임 진행자임을 메서드명에 새김*. *분리된 객체*들 각자 *자기 책임 메시지* 면 *progress prefix 불필요*. *명명이 책임의 분배 상태를 노출*.
536
+
537
+ 15. ***학생 자가 답변에 커밋 SHA 첨부 + 자가 학습 모범 패턴 지속***. Leeyerin0210 이 1단계와 동일하게 *모든 자가 답변에 커밋 SHA* (`258e602`, `46cb1ab`, `a854fe5`, `7bdab32`, `04edcd9`, `f51bab8`, `241741c`, `09a3758`, `bedbaf0`, `41651a0`, `ac6a151` 등) + *책 정리 + 자가 의문 + 후속 학습* 흐름. *Kotlin Multiplatform·Effective Kotlin·Demeter·tailrec* 자가 학습. *외부 자료 → 본인 코드 적용* 학습 모범.
538
+
539
+ 16. ***라운드 N회 게임의 *Player identity 유지* vs *불변 사본*의 트레이드오프***. *현재 in-place 핸드 교체 (Items.setNewHand → Hand.clear + add)* 는 *Player 동일성 유지 + 가변 변경*. *불변 사본 (Player.copy(items = newItems))* 은 *Player 객체 매 라운드 새로 생성*. *총 결과 집계 시 같은 사람 매핑*은 *이름 키* 사용. *동일성 의미*가 *identity (참조) vs equality (이름)* 의 트레이드오프.
540
+
541
+ 17. ***일급 컬렉션의 가치 = 자기 정보 + 자기 행위***. *Players 클래스가 *value: List<Player>* 만 + *행위 메서드 0* 이면 *컬렉션 wrapper*에 그침. *Players.eachDraw(deck)*, *Players.results(dealer)* 같은 *컬렉션 메시지* 가 *일급 컬렉션 정당화*. *현재는 init 검증만 + 메서드 0개* — *행위 부재* 가 *일급 컬렉션의 가치 미실현*.