์‚ฌ์šฉ์ž ๋„๊ตฌ

์‚ฌ์ดํŠธ ๋„๊ตฌ


wiki:it:dream_of_enc:metaverse:game_logic

์ฐจ์ด

๋ฌธ์„œ์˜ ์„ ํƒํ•œ ๋‘ ํŒ ์‚ฌ์ด์˜ ์ฐจ์ด๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์ฐจ์ด ๋ณด๊ธฐ๋กœ ๋งํฌ

๋‹ค์Œ ํŒ
์ด์ „ ํŒ
wiki:it:dream_of_enc:metaverse:game_logic [2025/07/28 05:57] โ€“ ๋งŒ๋“ฆ - ๋ฐ”๊นฅ ํŽธ์ง‘ 127.0.0.1wiki:it:dream_of_enc:metaverse:game_logic [2025/07/30 06:43] (ํ˜„์žฌ) โ€“ ๋ฐ”๊นฅ ํŽธ์ง‘ 127.0.0.1
์ค„ 7: ์ค„ 7:
 ๋ฐ”๋‘‘ ๊ฒŒ์ž„์˜ ํ•ต์‹ฌ ๊ทœ์น™๊ณผ ๋กœ์ง์„ JavaScript๋กœ ๊ตฌํ˜„ํ•˜์—ฌ ์ •ํ™•ํ•œ ๋ฐ”๋‘‘ ๊ฒŒ์ž„์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”๋‘‘ ๊ฒŒ์ž„์˜ ํ•ต์‹ฌ ๊ทœ์น™๊ณผ ๋กœ์ง์„ JavaScript๋กœ ๊ตฌํ˜„ํ•˜์—ฌ ์ •ํ™•ํ•œ ๋ฐ”๋‘‘ ๊ฒŒ์ž„์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  
 +{{https://api.dreamofenc.com/uploads/20250728171755_image.png?600}}
 ===== ๐ŸŽฏ ๊ธฐ๋ณธ ๊ทœ์น™ ===== ===== ๐ŸŽฏ ๊ธฐ๋ณธ ๊ทœ์น™ =====
  
-**๋ฐ”๋‘‘์˜ ๊ธฐ๋ณธ ๊ทœ์น™:**ย +''๋ฐ”๋‘‘์˜ ๊ธฐ๋ณธ ๊ทœ์น™:''ย 
-1. **์ฐฉ์ˆ˜**: ํ‘๋Œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ๋Œ์„ ๋†“์Šต๋‹ˆ๋‹ค.ย +  ''์ฐฉ์ˆ˜'': ํ‘๋Œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ๋Œ์„ ๋†“์Šต๋‹ˆ๋‹ค.ย 
-2. **์ž์œ ๋„**: ๋Œ์€ ์ตœ์†Œ ํ•˜๋‚˜์˜ ์ž์œ ๋„๋ฅผ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค.ย +  ''์ž์œ ๋„'': ๋Œ์€ ์ตœ์†Œ ํ•˜๋‚˜์˜ ์ž์œ ๋„๋ฅผ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค.ย 
-3. **์ฐฉ์ˆ˜**: ์ƒ๋Œ€๋ฐฉ ๋Œ์˜ ์ž์œ ๋„๋ฅผ ๋ชจ๋‘ ์—†์• ๋ฉด ๊ทธ ๋Œ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.ย +  ''์ฐฉ์ˆ˜'': ์ƒ๋Œ€๋ฐฉ ๋Œ์˜ ์ž์œ ๋„๋ฅผ ๋ชจ๋‘ ์—†์• ๋ฉด ๊ทธ ๋Œ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.ย 
-4. **์ž์ถฉ**: ์ž์‹ ์˜ ๋Œ์„ ์ž์œ ๋„ ์—†์ด ๋†“์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.ย +  ''์ž์ถฉ'': ์ž์‹ ์˜ ๋Œ์„ ์ž์œ ๋„ ์—†์ด ๋†“์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.ย 
-5. **๊ณ„๊ฐ€**: ๊ฒŒ์ž„ ์ข…๋ฃŒ ํ›„ ์ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.+  ''๊ณ„๊ฐ€'': ๊ฒŒ์ž„ ์ข…๋ฃŒ ํ›„ ์ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
  
-===== ๐Ÿ—๏ธ ๊ฒŒ์ž„ ์ƒํƒœ ๊ด€๋ฆฌ =====+----ย 
 +==== 1. ๊ฒŒ์ž„ ์ƒํƒœ ๊ด€๋ฆฌ ====
  
-**๊ฒŒ์ž„ ์ƒํƒœ ํด๋ž˜์Šค:**ย +์ด ์„น์…˜์—์„œ๋Š” ๋ฐ”๋‘‘ ๊ฒŒ์ž„์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์ €์žฅํ•˜๋Š” ''BadukGameState'' ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์ด ํด๋ž˜์Šค๋Š” ๋ฐ”๋‘‘ํŒ์˜ ๋Œ ๋ฐฐ์น˜, ํ˜„์žฌ ํ”Œ๋ ˆ์ด์–ด, ์žก์€ ๋Œ์˜ ์ˆ˜, ๊ฒŒ์ž„ ๋‹จ๊ณ„ ๋“ฑ ๊ฒŒ์ž„์˜ ๋ชจ๋“  ์ค‘์š”ํ•œ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.ย 
-<code javascript>+ย 
 +=== 1) ์ƒ์„ฑ์ž (Constructor) - ๊ฒŒ์ž„ ์ดˆ๊ธฐํ™” ===ย 
 +์ด ์ฝ”๋“œ๋Š” ''BadukGameState'' ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ํ˜ธ์ถœ๋˜๋ฉฐ, ๊ฒŒ์ž„์˜ ์ดˆ๊ธฐ ์ƒํƒœ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”๋‘‘ํŒ์„ 19x19 ๊ฒฉ์ž๋กœ ์ดˆ๊ธฐํ™”ํ•˜๊ณ , ํ˜„์žฌ ํ”Œ๋ ˆ์ด์–ด๋ฅผ ํ‘๋Œ๋กœ ์„ค์ •ํ•˜๋ฉฐ, ์žก์€ ๋Œ์˜ ์ˆ˜์™€ ์˜์—ญ ์ ์ˆ˜๋ฅผ 0์œผ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ฒŒ์ž„ ๋‹จ๊ณ„๋Š” 'playing'์œผ๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +<code>
 export default class BadukGameState { export default class BadukGameState {
     constructor() {     constructor() {
์ค„ 30: ์ค„ 36:
         this.lastMove = null;         this.lastMove = null;
     }     }
 +</code>
 +
 +=== 2) ์ƒํƒœ ์žฌ์„ค์ • (Resetting State) ===
 +''reset()'' ๋ฉ”์„œ๋“œ๋Š” ๊ฒŒ์ž„ ์ƒํƒœ๋ฅผ ์ฒ˜์Œ ์‹œ์ž‘ํ–ˆ์„ ๋•Œ์™€ ๋™์ผํ•œ ์ดˆ๊ธฐ ์ƒํƒœ๋กœ ๋˜๋Œ๋ฆฝ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๊ฒŒ์ž„์„ ์‹œ์ž‘ํ•  ๋•Œ๋‚˜ ๊ฒŒ์ž„์„ ๋‹ค์‹œ ํ”Œ๋ ˆ์ดํ•  ๋•Œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  
 +<code>
     // ๊ฒŒ์ž„ ์ƒํƒœ ์ดˆ๊ธฐํ™”     // ๊ฒŒ์ž„ ์ƒํƒœ ์ดˆ๊ธฐํ™”
     reset() {     reset() {
์ค„ 41: ์ค„ 52:
         this.lastMove = null;         this.lastMove = null;
     }     }
 +</code>
 +
 +=== 3) ์ƒํƒœ ์ง๋ ฌํ™” (Serialization - toJSON) ===
 +''toJSON()'' ๋ฉ”์„œ๋“œ๋Š” ํ˜„์žฌ ๊ฒŒ์ž„ ์ƒํƒœ๋ฅผ ์ผ๋ฐ˜ JavaScript ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๊ฒŒ์ž„ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๊ฑฐ๋‚˜ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ์ „์†กํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ณต์žกํ•œ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค ๋Œ€์‹  ๊ฐ„๋‹จํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  
 +<code>
     // ํ˜„์žฌ ์ƒํƒœ๋ฅผ JSON์œผ๋กœ ์ง๋ ฌํ™”     // ํ˜„์žฌ ์ƒํƒœ๋ฅผ JSON์œผ๋กœ ์ง๋ ฌํ™”
     toJSON() {     toJSON() {
์ค„ 54: ์ค„ 70:
         };         };
     }     }
 +</code>
 +
 +=== 4) ์ƒํƒœ ๋ณต์› (Deserialization - fromJSON) ===
 +''fromJSON()'' ๋ฉ”์„œ๋“œ๋Š” ''toJSON()''์œผ๋กœ ์ง๋ ฌํ™”๋œ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„ ''BadukGameState'' ์ธ์Šคํ„ด์Šค์˜ ์ƒํƒœ๋ฅผ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋กœ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. ์ €์žฅ๋œ ๊ฒŒ์ž„์„ ๋ถˆ๋Ÿฌ์˜ค๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ๊ฒŒ์ž„ ์ƒํƒœ๋ฅผ ๋™๊ธฐํ™”ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  
 +<code>
     // JSON์—์„œ ์ƒํƒœ ๋ณต์›     // JSON์—์„œ ์ƒํƒœ ๋ณต์›
     fromJSON(data) {     fromJSON(data) {
์ค„ 68: ์ค„ 89:
 </code> </code>
  
-===== ๐ŸŽฎ ์ด๋™ ๊ฒ€์ฆ =====+----ย 
 +==== 2. ์ด๋™ ๊ฒ€์ฆ ====
  
-**์œ ํšจํ•œ ์ด๋™ ํ™•์ธ:**ย +์ด ์„น์…˜์—์„œ๋Š” ํ”Œ๋ ˆ์ด์–ด์˜ ์ฐฉ์ˆ˜๊ฐ€ ์œ ํšจํ•œ์ง€ ํ™•์ธํ•˜๋Š” ''BadukMoveValidator'' ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”๋‘‘์˜ ๋ณต์žกํ•œ ๊ทœ์น™(์ž์œ ๋„, ์ž์ถฉ, ์ฝ” ๋“ฑ)์„ ์ ์šฉํ•˜์—ฌ ์˜ฌ๋ฐ”๋ฅธ ์ฐฉ์ˆ˜๋งŒ ํ—ˆ์šฉํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.ย 
-<code javascript>+ย 
 +=== 1) ์ƒ์„ฑ์ž (Constructor) ===ย 
 +''BadukMoveValidator''๋Š” ํ˜„์žฌ ๊ฒŒ์ž„ ์ƒํƒœ(''gameState'')๋ฅผ ์ฐธ์กฐํ•˜์—ฌ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฐ”๋‘‘ํŒ์˜ ํ˜„์žฌ ์ƒํ™ฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฐฉ์ˆ˜์˜ ์œ ํšจ์„ฑ์„ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.ย 
 +ย 
 +<code>
 export default class BadukMoveValidator { export default class BadukMoveValidator {
     constructor(gameState) {     constructor(gameState) {
         this.gameState = gameState;         this.gameState = gameState;
     }     }
 +</code>
 +
 +=== 2) ์œ ํšจํ•œ ์ด๋™ ํ™•์ธ (isValidMove) ===
 +''isValidMove(x, y, player)'' ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ์ขŒํ‘œ ''(x, y)''์— ''player''๊ฐ€ ๋Œ์„ ๋†“์•˜์„ ๋•Œ ์œ ํšจํ•œ ์ฐฉ์ˆ˜์ธ์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๋Š” ํ•ต์‹ฌ ๋กœ์ง์ž…๋‹ˆ๋‹ค. ๋ฐ”๋‘‘์˜ ์—ฌ๋Ÿฌ ๊ทœ์น™(๋ฐ”๋‘‘ํŒ ๋ฒ”์œ„, ์ด๋ฏธ ๋Œ์ด ๋†“์ธ ๊ณณ, ์ž์ถฉ, ์ฝ” ๊ทœ์น™)์„ ์ˆœ์ฐจ์ ์œผ๋กœ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  
 +<code>
     // ์ด๋™์ด ์œ ํšจํ•œ์ง€ ํ™•์ธ     // ์ด๋™์ด ์œ ํšจํ•œ์ง€ ํ™•์ธ
     isValidMove(x, y, player) {     isValidMove(x, y, player) {
์ค„ 101: ์ค„ 132:
         return { valid: true, reason: '์œ ํšจํ•œ ์ด๋™์ž…๋‹ˆ๋‹ค.' };         return { valid: true, reason: '์œ ํšจํ•œ ์ด๋™์ž…๋‹ˆ๋‹ค.' };
     }     }
 +</code>
 +
 +=== 3) ๋ฐ”๋‘‘ํŒ ๋ฒ”์œ„ ํ™•์ธ (isInBounds) ===
 +์ด ๊ฐ„๋‹จํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ์ขŒํ‘œ ''(x, y)''๊ฐ€ 19x19 ๋ฐ”๋‘‘ํŒ์˜ ์œ ํšจํ•œ ๋ฒ”์œ„ ๋‚ด์— ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์ฐฉ์ˆ˜ ๋ฐ ์ฃผ๋ณ€ ํƒ์ƒ‰ ์ „์— ํ•„์ˆ˜์ ์œผ๋กœ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.
  
 +<code>
     // ๋ฐ”๋‘‘ํŒ ๋ฒ”์œ„ ํ™•์ธ     // ๋ฐ”๋‘‘ํŒ ๋ฒ”์œ„ ํ™•์ธ
     isInBounds(x, y) {     isInBounds(x, y) {
         return x >= 0 && x < 19 && y >= 0 && y < 19;         return x >= 0 && x < 19 && y >= 0 && y < 19;
     }     }
 +</code>
 +
 +=== 4) ์ž์ถฉ ํ™•์ธ (isSuicide) ===
 +์ž์ถฉ์€ ๋ฐ”๋‘‘์—์„œ ์ž์‹ ์˜ ๋Œ์„ ๋‘์—ˆ์„ ๋•Œ ๊ทธ ๋Œ์ด ์ฆ‰์‹œ ์žกํžˆ๊ฒŒ ๋˜๋Š” ์ˆ˜๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ์œ„์น˜์— ์ž„์‹œ๋กœ ๋Œ์„ ๋†“์•„๋ณด๊ณ , ํ•ด๋‹น ๋Œ์ด ์ž์œ ๋„๋ฅผ ๊ฐ€์ง€๋Š”์ง€ ๋˜๋Š” ์ƒ๋Œ€๋ฐฉ ๋Œ์„ ์žก์„ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์—ฌ ์ž์ถฉ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค. ํ™•์ธ ํ›„์—๋Š” ๋ฐ”๋‘‘ํŒ์„ ์›๋ž˜ ์ƒํƒœ๋กœ ๋˜๋Œ๋ฆฝ๋‹ˆ๋‹ค.
  
 +<code>
     // ์ž์ถฉ ํ™•์ธ     // ์ž์ถฉ ํ™•์ธ
     isSuicide(x, y, player) {     isSuicide(x, y, player) {
์ค„ 121: ์ค„ 162:
         return !hasLiberties && !canCapture;         return !hasLiberties && !canCapture;
     }     }
 +</code>
 +
 +=== 5) ๋Œ ๊ทธ๋ฃน์˜ ์ž์œ ๋„ ํ™•์ธ (hasLiberties & checkGroupLiberties) ===
 +๋ฐ”๋‘‘์—์„œ ๋Œ์ด ์‚ด๊ธฐ ์œ„ํ•ด์„œ๋Š” '์ž์œ ๋„'(์ˆจ๊ตฌ๋ฉ)๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ''hasLiberties()''๋Š” ํŠน์ • ๋Œ์ด ์†ํ•œ ๊ทธ๋ฃน ์ „์ฒด๊ฐ€ ์ž์œ ๋„๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์‹œ์ž‘์ ์ด๋ฉฐ, ''checkGroupLiberties()''๋Š” ์žฌ๊ท€์ ์œผ๋กœ ๋˜๋Š” ์Šคํƒ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋Œ ๊ทธ๋ฃน์„ ํƒ์ƒ‰ํ•˜๋ฉฐ ๋นˆ ๊ณต๊ฐ„(์ž์œ ๋„)์„ ์ฐพ์Šต๋‹ˆ๋‹ค. ''visited'' ์ง‘ํ•ฉ์€ ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ๋Œ์„ ์ถ”์ ํ•˜์—ฌ ๋ฌดํ•œ ๋ฃจํ”„๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  
 +<code>
     // ์ž์œ ๋„ ํ™•์ธ     // ์ž์œ ๋„ ํ™•์ธ
     hasLiberties(x, y) {     hasLiberties(x, y) {
์ค„ 158: ์ค„ 204:
         return false;         return false;
     }     }
 +</code>
 +
 +=== 6) ์ƒ๋Œ€๋ฐฉ ๋Œ ์žก์„ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธ (canCaptureOpponent) ===
 +์ด ๋ฉ”์„œ๋“œ๋Š” ํŠน์ • ์œ„์น˜์— ๋Œ์„ ๋†“์•˜์„ ๋•Œ, ๊ทธ ๋Œ ์ฃผ๋ณ€์— ์žˆ๋Š” ์ƒ๋Œ€๋ฐฉ ๋Œ ๊ทธ๋ฃน์˜ ์ž์œ ๋„๊ฐ€ ๋ชจ๋‘ ์‚ฌ๋ผ์ ธ ์žก์„ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ฐฉ์ˆ˜ ์งํ›„ ์ƒ๋Œ€๋ฐฉ ๋Œ์„ ์ œ๊ฑฐํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์ค‘์š”ํ•œ ๋กœ์ง์ž…๋‹ˆ๋‹ค.
  
 +<code>
     // ์ƒ๋Œ€๋ฐฉ ๋Œ์„ ์žก์„ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธ     // ์ƒ๋Œ€๋ฐฉ ๋Œ์„ ์žก์„ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธ
     canCaptureOpponent(x, y, player) {     canCaptureOpponent(x, y, player) {
์ค„ 179: ์ค„ 230:
         return false;         return false;
     }     }
 +</code>
 +
 +=== 7) ์ฝ” ๊ทœ์น™ ์œ„๋ฐ˜ ํ™•์ธ (isKoViolation) ===
 +'์ฝ”'๋Š” ๋ฐ”๋‘‘์—์„œ ๊ฐ™์€ ํ˜•ํƒœ๊ฐ€ ๋ฐ˜๋ณต๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๊ทœ์น™์ž…๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ๋งˆ์ง€๋ง‰ ์ด๋™์ด ์ƒ๋Œ€๋ฐฉ์˜ ๋Œ์„ ํ•˜๋‚˜ ์žก๋Š” '๋‹จ์ˆ˜'์˜€์„ ๊ฒฝ์šฐ, ๊ทธ ์œ„์น˜์— ์ฆ‰์‹œ ๋‹ค์‹œ ๋Œ์„ ๋†“๋Š” ๊ฒƒ์„ ๊ธˆ์ง€ํ•˜์—ฌ ๋ฌดํ•œ ๋ฐ˜๋ณต์„ ๋ง‰์Šต๋‹ˆ๋‹ค.
  
 +<code>
     // ์ฝ” ๊ทœ์น™ ํ™•์ธ     // ์ฝ” ๊ทœ์น™ ํ™•์ธ
     isKoViolation(x, y) {     isKoViolation(x, y) {
์ค„ 195: ์ค„ 251:
 </code> </code>
  
-===== ๐ŸŽฏ ์ฐฉ์ˆ˜ ๋กœ์ง =====+----ย 
 +==== 3. ์ฐฉ์ˆ˜ ๋กœ์ง ====
  
-**์ฐฉ์ˆ˜ ์ฒ˜๋ฆฌ:**ย +์ด ์„น์…˜์—์„œ๋Š” ์‹ค์ œ๋กœ ๋ฐ”๋‘‘ํŒ์— ๋Œ์„ ๋†“๊ณ , ๋Œ์ด ์žกํ˜”์„ ๋•Œ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ''BadukCaptureLogic'' ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.ย 
-<code javascript>+ย 
 +=== 1) ์ƒ์„ฑ์ž (Constructor) ===ย 
 +''BadukCaptureLogic'' ํด๋ž˜์Šค๋Š” ๊ฒŒ์ž„ ์ƒํƒœ(''gameState'') ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„ ํ˜„์žฌ ๊ฒŒ์ž„์˜ ๋ฐ”๋‘‘ํŒ๊ณผ ๊ธฐํƒ€ ์ •๋ณด๋ฅผ ์กฐ์ž‘ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +<code>
 export default class BadukCaptureLogic { export default class BadukCaptureLogic {
     constructor(gameState) {     constructor(gameState) {
         this.gameState = gameState;         this.gameState = gameState;
     }     }
 +</code>
 +
 +=== 2) ๋Œ ๋†“๊ธฐ ๋ฐ ์ฐฉ์ˆ˜ ์ฒ˜๋ฆฌ (placeStone) ===
 +''placeStone(x, y, player)'' ๋ฉ”์„œ๋“œ๋Š” ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ํŠน์ • ์œ„์น˜์— ๋Œ์„ ๋†“์œผ๋ ค ํ•  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ํ•ต์‹ฌ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
 +  *   ๋จผ์ € ''BadukMoveValidator''๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฐฉ์ˆ˜๊ฐ€ ์œ ํšจํ•œ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
 +  *   ์œ ํšจํ•˜๋ฉด ๋ฐ”๋‘‘ํŒ์— ๋Œ์„ ๋†“๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋กœ ์ฃผ๋ณ€์˜ ์ƒ๋Œ€๋ฐฉ ๋Œ์ด ์žกํžˆ๋Š”์ง€ ''processCapture()''๋ฅผ ํ†ตํ•ด ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
 +  *   ๋ชจ๋“  ์ฐฉ์ˆ˜์™€ ์ฐฉ์ˆ˜ ๊ฒฐ๊ณผ๋Š” ''moveHistory''์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค.
 +  *   ๋งˆ์ง€๋ง‰์œผ๋กœ ํ˜„์žฌ ํ”Œ๋ ˆ์ด์–ด๋ฅผ ๋‹ค์Œ ํ”Œ๋ ˆ์ด์–ด(ํ‘ -> ๋ฐฑ, ๋ฐฑ -> ํ‘)๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
  
 +<code>
     // ๋Œ ๋†“๊ธฐ ๋ฐ ์ฐฉ์ˆ˜ ์ฒ˜๋ฆฌ     // ๋Œ ๋†“๊ธฐ ๋ฐ ์ฐฉ์ˆ˜ ์ฒ˜๋ฆฌ
     placeStone(x, y, player) {     placeStone(x, y, player) {
์ค„ 240: ์ค„ 310:
         return { success: true, captured: captured };         return { success: true, captured: captured };
     }     }
 +</code>
 +
 +=== 3) ์ฐฉ์ˆ˜ ์‹คํ–‰ (processCapture) ===
 +๋Œ์„ ๋†“์€ ํ›„, ์ด ๋ฉ”์„œ๋“œ๋Š” ์ƒˆ๋กœ ๋†“์ธ ๋Œ ์ฃผ๋ณ€์˜ 4๋ฐฉํ–ฅ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ธ์ ‘ํ•œ ์ƒ๋Œ€๋ฐฉ ๋Œ ๊ทธ๋ฃน์ด ์ž์œ ๋„๋ฅผ ๋ชจ๋‘ ์žƒ์—ˆ๋‹ค๋ฉด, ''removeGroup()'' ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ•ด๋‹น ๊ทธ๋ฃน์˜ ๋ชจ๋“  ๋Œ์„ ๋ฐ”๋‘‘ํŒ์—์„œ ์ œ๊ฑฐํ•˜๊ณ , ์žก์€ ๋Œ์˜ ์ˆ˜๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
  
 +<code>
     // ์ฐฉ์ˆ˜ ์ฒ˜๋ฆฌ     // ์ฐฉ์ˆ˜ ์ฒ˜๋ฆฌ
     processCapture(x, y, player) {     processCapture(x, y, player) {
์ค„ 273: ์ค„ 348:
         return totalCaptured;         return totalCaptured;
     }     }
 +</code>
 +
 +=== 4) ๋Œ ๊ทธ๋ฃน ์ œ๊ฑฐ (removeGroup) ===
 +์ด ๋ฉ”์„œ๋“œ๋Š” ์žกํžŒ ๋Œ ๊ทธ๋ฃน์˜ ํŠน์ • ๋Œ ''(x, y)''๋ฅผ ์‹œ์ž‘์ ์œผ๋กœ ์‚ผ์•„, ํ•ด๋‹น ๊ทธ๋ฃน์— ์†ํ•œ ๋ชจ๋“  ๋Œ์„ ๋ฐ”๋‘‘ํŒ์—์„œ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ์Šคํƒ(Stack)์„ ์ด์šฉํ•œ ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰(DFS) ๋ฐฉ์‹์œผ๋กœ ๊ทธ๋ฃน ์ „์ฒด๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ๋Œ์„ ''null''๋กœ ์„ค์ •ํ•˜๊ณ , ์ œ๊ฑฐ๋œ ๋Œ์˜ ์ด ๊ฐœ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  
 +<code>
     // ๊ทธ๋ฃน ์ œ๊ฑฐ     // ๊ทธ๋ฃน ์ œ๊ฑฐ
     removeGroup(x, y) {     removeGroup(x, y) {
์ค„ 303: ์ค„ 383:
         return count;         return count;
     }     }
 +</code>
 +
 +=== 5) ์ž์œ ๋„ ํ™•์ธ ์œ ํ‹ธ๋ฆฌํ‹ฐ (hasLiberties, checkGroupLiberties, isInBounds) ===
 +์ด ๋ฉ”์„œ๋“œ๋“ค์€ ''BadukMoveValidator'' ํด๋ž˜์Šค์— ์žˆ๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ๋Œ ๊ทธ๋ฃน์˜ ์ž์œ ๋„๋ฅผ ํ™•์ธํ•˜๊ณ  ๋ฐ”๋‘‘ํŒ ๋ฒ”์œ„ ๋‚ด์— ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ ์ค‘๋ณต์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ๋ณ„๋„์˜ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ชจ๋“ˆ๋กœ ๋ถ„๋ฆฌํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ์—ฌ๊ธฐ์„œ๋Š” ํ•ด๋‹น ๋กœ์ง ๋‚ด์—์„œ ์ง์ ‘ ํฌํ•จ๋˜์–ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  
 +<code>
     // ์ž์œ ๋„ ํ™•์ธ (BadukMoveValidator์™€ ๋™์ผ)     // ์ž์œ ๋„ ํ™•์ธ (BadukMoveValidator์™€ ๋™์ผ)
     hasLiberties(x, y) {     hasLiberties(x, y) {
์ค„ 346: ์ค„ 431:
 </code> </code>
  
-===== ๐ŸŽฏ ํŒจ์Šค ๋ฐ ํ•ญ๋ณต =====+----ย 
 +==== 4. ํŒจ์Šค ๋ฐ ํ•ญ๋ณต ====
  
-**ํŒจ์Šค ์ฒ˜๋ฆฌ:**ย +์ด ์„น์…˜์—์„œ๋Š” ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ๋Œ์„ ๋†“๋Š” ๋Œ€์‹  'ํŒจ์Šค'ํ•˜๊ฑฐ๋‚˜ 'ํ•ญ๋ณต'ํ•˜๋Š” ๊ฒฝ์šฐ์˜ ๋กœ์ง, ๊ทธ๋ฆฌ๊ณ  ๊ฒŒ์ž„์ด ์ข…๋ฃŒ๋  ๋•Œ ์˜์—ญ๊ณผ ์ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ''BadukPassLogic'' ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.ย 
-<code javascript>+ย 
 +=== 1) ์ƒ์„ฑ์ž (Constructor) ===ย 
 +''BadukPassLogic'' ํด๋ž˜์Šค๋Š” ํ˜„์žฌ ๊ฒŒ์ž„ ์ƒํƒœ(''gameState'')๋ฅผ ์ฐธ์กฐํ•˜๋ฉฐ, ์—ฐ์†์œผ๋กœ ํŒจ์Šคํ•œ ํšŸ์ˆ˜๋ฅผ ์ถ”์ ํ•˜๋Š” ''consecutivePasses'' ๋ณ€์ˆ˜๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +<code>
 export default class BadukPassLogic { export default class BadukPassLogic {
     constructor(gameState) {     constructor(gameState) {
์ค„ 355: ์ค„ 445:
         this.consecutivePasses = 0;         this.consecutivePasses = 0;
     }     }
 +</code>
 +
 +=== 2) ํŒจ์Šค ์ฒ˜๋ฆฌ (pass) ===
 +ํ”Œ๋ ˆ์ด์–ด๊ฐ€ 'ํŒจ์Šค' ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ''consecutivePasses'' ํšŸ์ˆ˜๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๊ณ , ํŒจ์Šค ๊ธฐ๋ก์„ ''moveHistory''์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์—ฐ์†์œผ๋กœ ๋‘ ๋ฒˆ ํŒจ์Šคํ•˜๋ฉด ๊ฒŒ์ž„์ด ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.
  
 +<code>
     // ํŒจ์Šค ์ฒ˜๋ฆฌ     // ํŒจ์Šค ์ฒ˜๋ฆฌ
     pass(player) {     pass(player) {
์ค„ 375: ์ค„ 470:
         return { success: true, consecutivePasses: this.consecutivePasses };         return { success: true, consecutivePasses: this.consecutivePasses };
     }     }
 +</code>
 +
 +=== 3) ํ•ญ๋ณต ์ฒ˜๋ฆฌ (surrender) ===
 +ํ”Œ๋ ˆ์ด์–ด๊ฐ€ 'ํ•ญ๋ณต'ํ–ˆ์„ ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ํ•ญ๋ณตํ•œ ํ”Œ๋ ˆ์ด์–ด์˜ ์ƒ๋Œ€๋ฐฉ์„ ์Šน์ž๋กœ ์„ ์–ธํ•˜๊ณ , ๊ฒŒ์ž„ ๋‹จ๊ณ„๋ฅผ 'finished'๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ์ฆ‰์‹œ ๊ฒŒ์ž„์„ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. ํ•ญ๋ณต ๊ธฐ๋ก ๋˜ํ•œ ''moveHistory''์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.
  
 +<code>
     // ํ•ญ๋ณต ์ฒ˜๋ฆฌ     // ํ•ญ๋ณต ์ฒ˜๋ฆฌ
     surrender(player) {     surrender(player) {
์ค„ 392: ์ค„ 492:
         return { success: true, winner: winner };         return { success: true, winner: winner };
     }     }
 +</code>
 +---
  
 +=== 4) ๊ฒŒ์ž„ ์ข…๋ฃŒ (endGame) ===
 +๋‘ ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ์—ฐ์†์œผ๋กœ ํŒจ์Šคํ–ˆ๊ฑฐ๋‚˜ ํ•œ ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ํ•ญ๋ณตํ•˜์—ฌ ๊ฒŒ์ž„์ด ์ข…๋ฃŒ๋  ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ๊ฒŒ์ž„ ๋‹จ๊ณ„๋ฅผ 'counting'(๊ณ„๊ฐ€)์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ณ , ''calculateTerritory()'' ๋ฐ ''calculateFinalScore()'' ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ตœ์ข… ์ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
 +
 +<code>
     // ๊ฒŒ์ž„ ์ข…๋ฃŒ     // ๊ฒŒ์ž„ ์ข…๋ฃŒ
     endGame() {     endGame() {
์ค„ 399: ์ค„ 505:
         this.calculateFinalScore();         this.calculateFinalScore();
     }     }
 +</code>
 +
 +----
 +=== 5) ์˜์—ญ ๊ณ„์‚ฐ (calculateTerritory & analyzeTerritory) ===
 +๋ฐ”๋‘‘ํŒ์˜ ๋นˆ ๊ณต๊ฐ„(์ง‘)์„ ํƒ์ƒ‰ํ•˜์—ฌ ๊ฐ ์˜์—ญ์ด ์–ด๋А ํ”Œ๋ ˆ์ด์–ด์˜ ์†Œ์œ ์ธ์ง€ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
 +  *   ''calculateTerritory()''๋Š” ๋ฐ”๋‘‘ํŒ์˜ ๋ชจ๋“  ๋นˆ ๊ณต๊ฐ„์„ ์ˆœํšŒํ•˜๋ฉฐ ์•„์ง ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋นˆ ์ง€์ ์„ ์ฐพ์•„ ''analyzeTerritory()''๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
 +  *   ''analyzeTerritory()''๋Š” ์‹œ์ž‘ ์ง€์ ์œผ๋กœ๋ถ€ํ„ฐ ์—ฐ๊ฒฐ๋œ ๋นˆ ๊ณต๊ฐ„๋“ค์„ ํƒ์ƒ‰ํ•˜๊ณ , ํ•ด๋‹น ์˜์—ญ์„ ๋‘˜๋Ÿฌ์‹ธ๊ณ  ์žˆ๋Š” ๋Œ์ด ํ‘๋Œ๋งŒ ์žˆ๋Š”์ง€ ๋ฐฑ๋Œ๋งŒ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์˜์—ญ์˜ ์†Œ์œ ์ž๋ฅผ ํŒ๋‹จํ•˜๊ณ , ํ•ด๋‹น ์˜์—ญ์˜ ํฌ๊ธฐ๋ฅผ ์ ์ˆ˜์— ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค.
  
 +<code>
     // ์˜์—ญ ๊ณ„์‚ฐ     // ์˜์—ญ ๊ณ„์‚ฐ
     calculateTerritory() {     calculateTerritory() {
์ค„ 453: ์ค„ 567:
         }         }
     }     }
 +</code>
 +
 +----
 +=== 6) ์˜์—ญ ์†Œ์œ ์ž ๊ฒฐ์ • (determineTerritoryOwner) ===
 +์ด ๋ฉ”์„œ๋“œ๋Š” ํŠน์ • ๋นˆ ์˜์—ญ์„ ๋‘˜๋Ÿฌ์‹ธ๊ณ  ์žˆ๋Š” ๋Œ์˜ ์ƒ‰๊น”์„ ๋ถ„์„ํ•˜์—ฌ ํ•ด๋‹น ์˜์—ญ์˜ ์†Œ์œ ์ž๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ์˜์—ญ ์ฃผ๋ณ€์— ํ‘๋Œ๋งŒ ์žˆ์œผ๋ฉด ํ‘์˜ ์˜์—ญ์œผ๋กœ, ๋ฐฑ๋Œ๋งŒ ์žˆ์œผ๋ฉด ๋ฐฑ์˜ ์˜์—ญ์œผ๋กœ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ํ‘๋Œ๊ณผ ๋ฐฑ๋Œ์ด ๋ชจ๋‘ ์กด์žฌํ•˜๊ฑฐ๋‚˜ ๋Œ์ด ์ „ํ˜€ ์—†๋Š” ๊ฒฝ์šฐ (์˜ˆ: ์„ธํ‚ค), ํ•ด๋‹น ์˜์—ญ์€ ์†Œ์œ ์ž๊ฐ€ ์—†๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค.
  
 +<code>
     // ์˜์—ญ ์†Œ์œ ์ž ๊ฒฐ์ •     // ์˜์—ญ ์†Œ์œ ์ž ๊ฒฐ์ •
     determineTerritoryOwner(blackStones, whiteStones) {     determineTerritoryOwner(blackStones, whiteStones) {
์ค„ 460: ์ค„ 580:
         } else if (whiteStones > 0 && blackStones === 0) {         } else if (whiteStones > 0 && blackStones === 0) {
             return 'white';             return 'white';
 +        } else {
 +            return null; // ์†Œ์œ ์ž ์—†์Œ (์˜ˆ: ์„ธํ‚ค ๋˜๋Š” ๊ณตํ†ต ์˜์—ญ)
         }         }
-        return null; // ์ค‘๋ฆฝ ์˜์—ญ 
     }     }
 +</code>
 +===== ๐ŸŽฒ ๋ฐ”๋‘‘ ๊ฒŒ์ž„ ํ•ต์‹ฌ ๊ธฐ๋Šฅ =====
 +
 +==== 1. ๊ฒŒ์ž„ ์ƒํƒœ ๋ฐ ์ ์ˆ˜ ๊ณ„์‚ฐ ====
 +์ด ์„น์…˜์—์„œ๋Š” ๋ฐ”๋‘‘ ๊ฒŒ์ž„์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ , ๊ฒŒ์ž„ ์ข…๋ฃŒ ์‹œ ์ตœ์ข… ์ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜๋ฉฐ, ๋ฐ”๋‘‘ํŒ ๋‚ด ์œ ํšจํ•œ ์œ„์น˜๋ฅผ ํ™•์ธํ•˜๋Š” ํ•ต์‹ฌ ํ•จ์ˆ˜์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.
 +
 +----
 +=== 1) ์ตœ์ข… ์ ์ˆ˜ ๊ณ„์‚ฐ ===
 +''calculateFinalScore'' ํ•จ์ˆ˜๋Š” ๊ฒŒ์ž„์ด ์ข…๋ฃŒ๋œ ํ›„ ํ‘๊ณผ ๋ฐฑ์˜ ์ตœ์ข… ์ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ๊ฐ ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ์ฐจ์ง€ํ•œ ์˜ํ† ์™€ ํš๋“ํ•œ ํฌ๋กœ์˜ ์ˆ˜๋ฅผ ํ•ฉ์‚ฐํ•˜์—ฌ ์ด์ ์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ฐฑ์—๊ฒŒ๋Š” ์ถ”๊ฐ€๋กœ 6.5์ง‘์˜ ๋ฐ˜์ง‘(๋ค, komi)์ด ๋ถ€์—ฌ๋ฉ๋‹ˆ๋‹ค.
  
-    // ์ตœ์ข… ์ ์ˆ˜ ๊ณ„์‚ฐ+<code>
     calculateFinalScore() {     calculateFinalScore() {
         const blackScore = this.gameState.territory.black + this.gameState.capturedStones.black;         const blackScore = this.gameState.territory.black + this.gameState.capturedStones.black;
         const whiteScore = this.gameState.territory.white + this.gameState.capturedStones.white + 6.5; // ๋ฐฑ์˜ ๋ฐ˜์ง‘         const whiteScore = this.gameState.territory.white + this.gameState.capturedStones.white + 6.5; // ๋ฐฑ์˜ ๋ฐ˜์ง‘
-        + 
         this.gameState.finalScore = {         this.gameState.finalScore = {
             black: blackScore,             black: blackScore,
์ค„ 475: ์ค„ 605:
         };         };
     }     }
 +</code>
  
 +----
 +=== 2) ๋ณด๋“œ ๋‚ด ์œ„์น˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ===
 +''isInBounds'' ํ•จ์ˆ˜๋Š” ์ฃผ์–ด์ง„ ์ขŒํ‘œ (x, y)๊ฐ€ ๋ฐ”๋‘‘ํŒ์˜ ์œ ํšจํ•œ ๋ฒ”์œ„(0๋ถ€ํ„ฐ 18๊นŒ์ง€) ๋‚ด์— ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋Œ์„ ๋†“๊ฑฐ๋‚˜ ํŠน์ • ์œ„์น˜๋ฅผ ์ฐธ์กฐํ•  ๋•Œ ํ•„์ˆ˜์ ์ธ ๊ฒ€์‚ฌ์ž…๋‹ˆ๋‹ค.
 +
 +<code>
     isInBounds(x, y) {     isInBounds(x, y) {
         return x >= 0 && x < 19 && y >= 0 && y < 19;         return x >= 0 && x < 19 && y >= 0 && y < 19;
     }     }
-} 
 </code> </code>
  
 ===== ๐Ÿ“Š ๊ฒŒ์ž„ ํ†ต๊ณ„ ===== ===== ๐Ÿ“Š ๊ฒŒ์ž„ ํ†ต๊ณ„ =====
 +์ด ์„น์…˜์—์„œ๋Š” ๋ฐ”๋‘‘ ๊ฒŒ์ž„์˜ ๋‹ค์–‘ํ•œ ํ†ต๊ณ„๋ฅผ ๊ธฐ๋กํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.
 +
 +==== 1. ๊ฒŒ์ž„ ํ†ต๊ณ„ ๊ด€๋ฆฌ ํด๋ž˜์Šค (BadukStatistics) ====
 +''BadukStatistics'' ํด๋ž˜์Šค๋Š” ๋ฐ”๋‘‘ ๊ฒŒ์ž„์˜ ์ „์ฒด์ ์ธ ํ†ต๊ณ„๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด ํด๋ž˜์Šค๋Š” ์ด ๊ฒŒ์ž„ ์ˆ˜, ์ŠนํŒจ ๊ธฐ๋ก, ํ‰๊ท  ๊ฒŒ์ž„ ๊ธธ์ด, ์ฐฉ์ˆ˜ ๋ฐ ํฌํš๋œ ๋Œ์˜ ์ˆ˜ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ฒŒ์ž„ ๊ด€๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ ํ•˜๊ณ , ํ†ต๊ณ„์— ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  
-**๊ฒŒ์ž„ ํ†ต๊ณ„ ๊ด€๋ฆฌ:**ย +<code>
-<code javascript>+
 export default class BadukStatistics { export default class BadukStatistics {
     constructor() {     constructor() {
์ค„ 499: ์ค„ 637:
         };         };
     }     }
 + 
     // ๊ฒŒ์ž„ ๊ฒฐ๊ณผ ๊ธฐ๋ก     // ๊ฒŒ์ž„ ๊ฒฐ๊ณผ ๊ธฐ๋ก
     recordGameResult(gameState) {     recordGameResult(gameState) {
         this.stats.totalGames++;         this.stats.totalGames++;
-        + 
         if (gameState.surrender) {         if (gameState.surrender) {
             this.stats.surrenders++;             this.stats.surrenders++;
์ค„ 513: ์ค„ 651:
             }             }
         }         }
-        + 
         // ํ‰๊ท  ๊ฒŒ์ž„ ๊ธธ์ด ์—…๋ฐ์ดํŠธ         // ํ‰๊ท  ๊ฒŒ์ž„ ๊ธธ์ด ์—…๋ฐ์ดํŠธ
         const gameLength = gameState.moveHistory.length;         const gameLength = gameState.moveHistory.length;
         this.stats.averageGameLength =          this.stats.averageGameLength = 
             (this.stats.averageGameLength * (this.stats.totalGames - 1) + gameLength) / this.stats.totalGames;             (this.stats.averageGameLength * (this.stats.totalGames - 1) + gameLength) / this.stats.totalGames;
-        + 
         // ์ด ์ด๋™ ์ˆ˜ ์—…๋ฐ์ดํŠธ         // ์ด ์ด๋™ ์ˆ˜ ์—…๋ฐ์ดํŠธ
         this.stats.totalMoves += gameLength;         this.stats.totalMoves += gameLength;
-        + 
         // ์ฐฉ์ˆ˜ ํ†ต๊ณ„ ์—…๋ฐ์ดํŠธ         // ์ฐฉ์ˆ˜ ํ†ต๊ณ„ ์—…๋ฐ์ดํŠธ
         this.stats.captures.black += gameState.capturedStones.black;         this.stats.captures.black += gameState.capturedStones.black;
         this.stats.captures.white += gameState.capturedStones.white;         this.stats.captures.white += gameState.capturedStones.white;
-        + 
         // ํŒจ์Šค ํ†ต๊ณ„ ์—…๋ฐ์ดํŠธ         // ํŒจ์Šค ํ†ต๊ณ„ ์—…๋ฐ์ดํŠธ
         const passCount = gameState.moveHistory.filter(move => move.type === 'pass').length;         const passCount = gameState.moveHistory.filter(move => move.type === 'pass').length;
         this.stats.passes += passCount;         this.stats.passes += passCount;
     }     }
 + 
     // ํ†ต๊ณ„ ๊ฐ€์ ธ์˜ค๊ธฐ     // ํ†ต๊ณ„ ๊ฐ€์ ธ์˜ค๊ธฐ
     getStats() {     getStats() {
์ค„ 547: ์ค„ 685:
  
     // ํ†ต๊ณ„ ์ดˆ๊ธฐํ™”     // ํ†ต๊ณ„ ์ดˆ๊ธฐํ™”
-    reset() {+    resetStats() {
         this.stats = {         this.stats = {
             totalGames: 0,             totalGames: 0,
์ค„ 558: ์ค„ 696:
             surrenders: 0             surrenders: 0
         };         };
 +    }
 +
 +    // ํ†ต๊ณ„ ์ถœ๋ ฅ (์˜ˆ์‹œ)
 +    displayStats() {
 +        const currentStats = this.getStats();
 +        console.log("--- ๋ฐ”๋‘‘ ๊ฒŒ์ž„ ํ†ต๊ณ„ ---");
 +        console.log(`์ด ๊ฒŒ์ž„ ์ˆ˜: ${currentStats.totalGames}`);
 +        console.log(`ํ‘ ์Šน๋ฆฌ: ${currentStats.blackWins} (${currentStats.winRate.black}%)`);
 +        console.log(`๋ฐฑ ์Šน๋ฆฌ: ${currentStats.whiteWins} (${currentStats.winRate.white}%)`);
 +        console.log(`ํ‰๊ท  ๊ฒŒ์ž„ ๊ธธ์ด (์ˆ˜): ${currentStats.averageGameLength.toFixed(1)}`);
 +        console.log(`์ด ์ฐฉ์ˆ˜ ์ˆ˜: ${currentStats.totalMoves}`);
 +        console.log(`ํ‰๊ท  ํ‘ ํฌํš ์ˆ˜: ${currentStats.averageCaptures.black}`);
 +        console.log(`ํ‰๊ท  ๋ฐฑ ํฌํš ์ˆ˜: ${currentStats.averageCaptures.white}`);
 +        console.log(`ํŒจ์Šค ์ˆ˜: ${currentStats.passes}`);
 +        console.log(`๊ธฐ๊ถŒ ์ˆ˜: ${currentStats.surrenders}`);
     }     }
 } }
 </code> </code>
  
-===== ๐Ÿ“š ๊ด€๋ จ ๋ฌธ์„œ =====+----ย 
 +=== 1) ๊ฒŒ์ž„ ๊ฒฐ๊ณผ ๊ธฐ๋ก (recordGameResult) ===ย 
 +''recordGameResult'' ๋ฉ”์„œ๋“œ๋Š” ๊ฒŒ์ž„์ด ์ข…๋ฃŒ๋  ๋•Œ ํ˜ธ์ถœ๋˜์–ด ํ•ด๋‹น ๊ฒŒ์ž„์˜ ๊ฒฐ๊ณผ๋ฅผ ํ†ต๊ณ„์— ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ด ๊ฒŒ์ž„ ์ˆ˜, ์ŠนํŒจ ์—ฌ๋ถ€, ํ‰๊ท  ๊ฒŒ์ž„ ๊ธธ์ด, ์ด ์ฐฉ์ˆ˜ ์ˆ˜, ํฌํš๋œ ๋Œ์˜ ์ˆ˜, ํŒจ์Šค ๋ฐ ๊ธฐ๊ถŒ ํšŸ์ˆ˜ ๋“ฑ์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
  
-  * [[wiki:it:dream_of_enc:metaverse:phaser|Phaser.js ๊ฒŒ์ž„ ์—”์ง„]]ย +----ย 
-  * [[wiki:it:dream_of_enc:metaverse:ui|UI/UX ๊ตฌํ˜„]]ย +=== 2) ํ†ต๊ณ„ ๊ฐ€์ ธ์˜ค๊ธฐ (getStats) ===ย 
-  * [[wiki:it:dream_of_enc:metaverse:socketio|Socket.IO ์‹ค์‹œ๊ฐ„ ํ†ต์‹ ]]+''getStats'' ๋ฉ”์„œ๋“œ๋Š” ํ˜„์žฌ๊นŒ์ง€ ๊ธฐ๋ก๋œ ๋ชจ๋“  ํ†ต๊ณ„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค์ด ๊ฐ์ฒด์—๋Š” ์ด ๊ฒŒ์ž„ ์ˆ˜, ์ŠนํŒจ ๊ธฐ๋ก, ํ‰๊ท  ๊ฒŒ์ž„ ๊ธธ์ด, ์ด ์ฐฉ์ˆ˜ ์ˆ˜, ํฌํš ์ˆ˜ ๋“ฑ ๊ธฐ๋ณธ ํ†ต๊ณ„ ์™ธ์—๋„ ํ‘๋ฐฑ์˜ ์Šน๋ฅ  ๋ฐ ํ‰๊ท  ํฌํš ์ˆ˜์™€ ๊ฐ™์€ ๊ณ„์‚ฐ๋œ ์ง€ํ‘œ๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +----ย 
 +=== 3) ํ†ต๊ณ„ ์ดˆ๊ธฐํ™” (resetStats) ===ย 
 +''resetStats'' ๋ฉ”์„œ๋“œ๋Š” ๋ชจ๋“  ๊ฒŒ์ž„ ํ†ต๊ณ„ ๋ฐ์ดํ„ฐ๋ฅผ ์ดˆ๊ธฐ ์ƒํƒœ๋กœ ๋ฆฌ์…‹ํ•ฉ๋‹ˆ๋‹ค์ด๋Š” ์ƒˆ๋กœ์šด ์„ธ์…˜์ด๋‚˜ ํ…Œ์ŠคํŠธ๋ฅผ ์‹œ์ž‘ํ•  ๋•Œ ์œ ์šฉํ•˜๋ฉฐ, ๋ชจ๋“  ํ†ต๊ณ„ ์ˆ˜์น˜๋ฅผ 0์œผ๋กœ ๋˜๋Œ๋ฆฝ๋‹ˆ๋‹ค.ย 
 +ย 
 +----ย 
 +=== 4) ํ†ต๊ณ„ ์ถœ๋ ฅ (displayStats) ===ย 
 +''displayStats'' ๋ฉ”์„œ๋“œ๋Š” ํ˜„์žฌ ๊ธฐ๋ก๋œ ํ†ต๊ณ„๋ฅผ ์ฝ˜์†”์— ์ถœ๋ ฅํ•˜๋Š” ์˜ˆ์‹œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ''getStats''๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ตœ์‹  ํ†ต๊ณ„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„, ๊ฐ€๋…์„ฑ ๋†’์€ ํ˜•ํƒœ๋กœ ๊ฐ ์ง€ํ‘œ๋ฅผ ๋‚˜์—ดํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ์ด ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค์— ํ‘œ์‹œํ•˜๋Š” ๋ฐ ํ™œ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  
---- 
-//์ด ํŽ˜์ด์ง€๋Š” ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.//  
wiki/it/dream_of_enc/metaverse/game_logic.1753682235.txt.gz ยท ๋งˆ์ง€๋ง‰์œผ๋กœ ์ˆ˜์ •๋จ: ์ €์ž 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki