
์๊ณ ๊ท์ฌ์ด ๋จธ๋ฆฌ๋ก ์ค๋ชฉ ๊ท์น์ด๋ ๋ก์ง ์๊ฐํ๋ค๊ฐ... 1์ฐจ๋ก ์์ ๊ฐ์ด ์ฌ๋ฌ ์กฐ๊ฑด์ ์๊ฐํด์ ๋ง๋ค์๋ค. ์ด๊ฒ์ด ๋จ์ผ ๋จ๊ณ ํ๊ฐ(1-Ply Evaluation)๋ผ๊ณ ํ๋ค.
์ด๊ฒ๋ ์ฌ๋ฐ๊ธด ํ๋๋ฐ, ๋ฌธ์ ๋ ์ปดํจํฐ๊ฐ ๋ค์ฑ๋ก์ด ๋ฐฉ์์ผ๋ก ๊ฒ์์ ํ์ง ๋ชปํ๋ค. ๋ฌด์จ ๋ฌธ์ ๊ฐ ์์๋๋ฉด..
- ๊ณต๊ฒฉ๊ณผ ๋ฐฉ์ด๋ฅผ ์ ์ ํ ์์ด์ ์๋ฅผ ๋ฌ์ผ ํ๋๋ฐ ๊ทธ๋ ์ง ๋ชปํจ(๊ณต๊ฒฉ๋ง, ๋ฐฉ์ด๋ง ์ฃผ๊ตฌ์ฅ์ฐฝ ํ๋ค๋๊ฐ)
- ์๋์ ๋์(์ฆ, ๋์ ๋์)์ ์์ธกํ์ง ๋ชปํจ
- ๋๊ฐ์ ์ ์ฝํจ
์ด๋ ๋ฏ ๋จ์ํ๊ฒ ๋ก์ง์ ์์ฑํ๋ค๋ฉด ์๋๊ฐ ๋ ๋ฏธ๋์ ์๋ฅผ ๋ณด์ง ๋ชปํ๊ณ , ํจ์ ์ ์์๋ฌด์ฑ ์ด๋ผ๊ณ ํ๋ค.
๊ทธ๋์ ์ด๋ฅผ ๋ณด์ํ๊ธฐ ์ํด 2-ply ์ด์ ํ์, ์ฆ ๋ฏธ๋๋งฅ์ค ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ํ์ฅํด์ ์์ฑํ๋ค.
๋ก์ง์ ์์ฑํ๊ธฐ ์ํด์ ์ฐ์ ๋ฏธ๋๋งฅ์ค ์๊ณ ๋ฆฌ์ฆ์ ์์์ผ ํ๋ค..
๋ฏธ๋๋งฅ์ค ์๊ณ ๋ฆฌ์ฆ(Minimax Algorithm)
๋๋ ์ต์ ์ ๋คํ๊ณ , ์๋๋ ์ต์ ์ ๋คํ๋ค๊ณ ๊ฐ์ ํ์ ๋, ์ต์ข ์ ์ผ๋ก ๋ด๊ฐ ๊ฐ์ฅ ์ ๋ฆฌํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ ์๋ฅผ ์ฐพ๋ ์๊ณ ๋ฆฌ์ฆ
๋ด๊ฐ ๊ฐ์ฅ ์ ์ด๊ธฐ๊ฒ ๋๊ณ , ์๋๋ ๋๋ฅผ ๊ฐ์ฅ ๋ชป์ด๊ธฐ๊ฒ ๋๋ค๋ ๊ฐ์ ์ผ๋ก ๊ฐ๋ฅํ ์๋ฅผ ์๋ฎฌ๋ ์ด์ ํด์ ์ต์ ์ ์๋ฅผ ์ฐพ๋๋ค.

์ ๋ฐ์์ผ๋ก ์ปดํจํฐ - ์ฌ๋ ํ๋ ์ด์ด ๊ฐ ์ต์ ์ ์๋ฅผ ์ฐพ๊ธฐ ์ํด ๋ฒ๊ฐ์๊ฐ๋ฉด์ ์คํํ๋ค.
miniMax()ํจ์๋ก ๊ตฌํ
๋๋ช ์ ํ๋ ์ด์ด๊ฐ ์๋ฒฝํ ํ๋ ์ดํ๋ค๊ณ ๊ฐ์ ํ์ ๋, ์ง๊ธ ์ด๋ค ์๋ฅผ ๋๋ฉด ๊ฐ์ฅ ์ ๋ฆฌํ ์ง ๊ณ์ฐํด์ฃผ๋ ์ญํ ์ ํ๋ค.
- Max(์ฐ๋ฆฌ ์ฐจ๋ก) : ์ ์๋ฅผ ์ต๋ํ ๋์ด๋ ค๋ ํ๋ ์ด์ด
- Min(์๋ ์ฐจ๋ก) : ์ ์๋ฅผ ์ต๋ํ ๋ฎ์ถ๋ ค๋ ํ๋ ์ด์ด
๊ทธ๋์ miniMax()ํจ์๋ ๋๊ฐ์ง์ ์ผ์ ๋ฒ๊ฐ์ ๊ฐ๋ฉด์ ํ๊ฒ ๋๋ค.
- ์ฐ๋ฆฌ ์ฐจ๋ก๋ผ๋ฉด : ๊ฐ์ฅ ๋์ ์ ์๋ฅผ ์ ํ(์ด๊ธฐ๊ธฐ ์ํด)
- ์๋ ์ฐจ๋ก๋ผ๋ฉด : ๊ฐ์ฅ ๋ฎ์ ์ ์๋ฅผ ์ ํ(์ฐ๋ฆฌ๋ฅผ ๋ถ๋ฆฌํ๊ฒ ๋ง๋ค๊ธฐ ์ํด)
Ex : ํฑํํ ๊ฒ์
๋ค์๊ณผ ๊ฐ์ ์ ํ์ง๊ฐ ๋ค์๊ณผ ๊ฐ๋ค๊ณ ํ์.
A : ์ด๊ธฐ๋ ์ : ์ ์ +10
B : ๋น๊ธฐ๋ ์ : ์ ์ 0
C : ์ง๋ ์ : ์ ์ - 10
์ด๋ฐ ์ํฉ์์ miniMax()๋
๋ด๊ฐ ์ง๊ธ ๋ ๋ค์, ์๋๋ ์ต์ ์ ๋คํ ๊ฑฐ์ผ. ๊ทธ๋ผ ๊ฐ ๊ฒฝ์ฐ๋ง๋ค ๊ฒฐ๊ณผ๊ฐ ์ด๋ป๊ฒ ๋ ๊น?
๋ผ๊ณ ์๊ฐํ๊ฒ ๋๋ค.
๊ตฌ์ฑ
miniMax(board, depth, isMaximizing)
- board : ํ์ฌ ๊ฒ์ ์ํ
- depth : ์ผ๋ง๋ ๊น์ด ๊ณ์ฐํ ์ง(๋ฏธ๋ ์์ ๋จ๊ณ)
- isMaximizing : ์ง๊ธ "์ฐ๋ฆฌ ํด"์ธ์ง "์๋ ํด"์ธ์ง
์์
- ๊ธฐ์ ์กฐ๊ฑด(Base Case) : ๊ฒ์์ด ๋๋ฌ๋ค๋ฉด ๊ทธ ์ ์๋ฅผ ๋ฐํํ๋ค. ์นํจ๊ฐ ์ ํด์ง๊ฑด, ๋ ๋ ๊ณณ์ด ์์ ๋๋ฅผ ์ํ ์ข ๋ฃ ์กฐ๊ฑด์ ์์ฑ
- ์ฌ๊ท ํธ์ถ(Recursive Call) : ๊ฒ์์ด ๋๋์ง ์์๋ค๋ฉด ๊ฐ๋ฅํ ๋ชจ๋ ์๋ฅผ ๋ณด๊ณ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ miniMax()๋ก ๋ค์ ํธ์ถํ์ฌ ๊ณ์ฐํ๋ค.
- ์ต๋๊ฐ/์ต์๊ฐ ์ ํ : ์ฐ๋ฆฌ ํด์ด๋ฉด "๊ฐ์ฅ ํฐ ๊ฐ", ์๋ ํด์ด๋ฉด "๊ฐ์ฅ ์์ ๊ฐ"์ ์ ํํ๋ค.
function miniMax(board, depth, isMaximizing) {
// 1๋จ๊ณ: ์ข
๋ฃ ์กฐ๊ฑด (๊ธฐ์ ์กฐ๊ฑด)
if (depth === 0 || ๊ฒ์์ด๋๋ฌ๋ค๋ฉด) {
return ํ์ฌ์ํ์์ ์ // ํ๊ฐ ํจ์ ํธ์ถ
}
// 2๋จ๊ณ: Max ํ๋ ์ด์ด ํด
if (isMaximizing) {
let maxScore = -Infinity // ๊ฐ์ฅ ์์ ๊ฐ์ผ๋ก ์์
for (๊ฐ๋ฅํ๋ชจ๋ ์) {
// ๊ฐ์์ผ๋ก ์๋ฅผ ๋
์๋ฅผ๋๋ค(board, ์)
// ์ฌ๊ท: ์๋๋ฐฉ ํด์ผ๋ก ๋๊น
let score = miniMax(board, depth - 1, false)
// ์๋ฅผ ๋๋๋ฆผ
์๋ฅผ์ทจ์ํ๋ค(board, ์)
// ์ต๋๊ฐ ๊ฐฑ์
maxScore = Math.max(maxScore, score)
}
return maxScore
}
// 3๋จ๊ณ: Min ํ๋ ์ด์ด ํด
else {
let minScore = Infinity // ๊ฐ์ฅ ํฐ ๊ฐ์ผ๋ก ์์
for (๊ฐ๋ฅํ๋ชจ๋ ์) {
// ๊ฐ์์ผ๋ก ์๋ฅผ ๋
์๋ฅผ๋๋ค(board, ์)
// ์ฌ๊ท: ์๋๋ฐฉ ํด์ผ๋ก ๋๊น
let score = miniMax(board, depth - 1, true)
// ์๋ฅผ ๋๋๋ฆผ
์๋ฅผ์ทจ์ํ๋ค(board, ์)
// ์ต์๊ฐ ๊ฐฑ์
minScore = Math.min(minScore, score)
}
return minScore
}
}
์ต๋ํ ์ดํดํ๊ธฐ ์ฝ๊ฒ๋ ์์ฑ์ ํ๋๋ฐ... ํ๊ณ๊ฐ ์์ด์ AI์๊ฒ ๋ณด์ถฉ ์ค๋ช ์ ๋ถํํ๋ค.
โก๏ธ ์๋ฅผ ์ทจ์ํ๋ ์ด์ ?
๋ฏธ๋๋งฅ์ค๋ "๋ง์ฝ ์ด๋ ๊ฒ ๋๋ฉด ์ด๋จ๊น?"๋ผ๊ณ ๋ฏธ๋ฆฌ ์์ธกํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์
๊ฐ์์ผ๋ก ๋๊ณ →
์ ์๋ฅผ ๊ณ์ฐํ๊ณ →
๋ค์ ๋์ ์์ค๋ค.
์ฌ๋ฐ๋ฅธ ์งํ ์์
ํ์ฌ ๋ณด๋:
โซ โช _ _ _
_ _ _ _ _
_ _ _ _ _
๋ผ๊ณ ๋๋ค ์ณค์ ๋
0. ํ์ฌ ์ํ
board[0][2] = null // ๋น์นธ
// 1. ์๋ฅผ๋๋ค(board, {x:0, y:2})
board[0][2] = 'โซ' // ๊ฐ์์ผ๋ก ๊ฒ์๋ ๋๊ธฐ
โซ โช โซ _ _ // ์ด๋ ๊ฒ ๋จ
_ _ _ _ _
_ _ _ _ _
2. ์ด ์ํ๋ก ์ฌ๊ท ํธ์ถ
let score = miniMax(board, ...) // ์ด ์ํ์์์ ์ ์ ๊ณ์ฐ → ๋ค์ ํธ์ถํด์ ์๋ ํด์ผ๋ก ๋๊น
3. ์๋ฅผ์ทจ์ํ๋ค(board, {x:0, y:2})
board[0][2] = null // ๋ค์ ์๋๋๋ก
โซ โช _ _ _ // ์์๋ณต๊ตฌ!
_ _ _ _ _
_ _ _ _ _
๋ค์ ์นธ ์๋ฎฌ๋ ์ด์
๊ณ์...
โ ์ทจ์ ์ ํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
1. 1๋ฒ์งธ ๋ฐ๋ณต - A์นธ ์๋ฎฌ๋ ์ด์
board[0][2] = 'โซ' // A์นธ์ ๋
๋ณด๋ ์ํ:
โซ โช โซ _ _ <- A์นธ์ ๋ ์๊น
scoreA = miniMax(board, ...) // ์ด ์ํ๋ก ์ ์ ๊ณ์ฐ
2. 2๋ฒ์งธ ๋ฐ๋ณต - B์นธ ์๋ฎฌ๋ ์ด์
board[0][3] = 'โซ' // B์นธ์ ๋
์์ํ๋ ๋ณด๋ ์ํ :
'โซ' โซ โช _ โซ _ <- A์นธ์ ์๊ณ B์นธ๋ง ์์! โ
ํ์ค ๋ณด๋ ์ํ:
โซ โช โซ โซ _ <- A์นธ ๋์ด ์์ง ์์! + B์นธ ๋ ์ถ๊ฐ๋จ!
scoreB = miniMax(board, ...) // ์๋ชป๋ ์ํ๋ก ์ ์ ๊ณ์ฐ!
3. 3๋ฒ์งธ ๋ฐ๋ณต - C์นธ ์๋ฎฌ๋ ์ด์
board[1][0] = 'โซ' // C์นธ์ ๋
์์ํ๋ ๋ณด๋ ์ํ :
'โซ' โซ โช _ _ _ <- A์นธ, B์นธ์ ์๊ณ
โซ _ _ _ _ <- C์นธ๋ง ์์! โ
ํ์ค ๋ณด๋ ์ํ:
โซ โช โซ โซ _ <- A์นธ, B์นธ ๋์ด ๋ชจ๋ ๋จ์์์!
โซ _ _ _ _ <- C์นธ ๋ ์ถ๊ฐ๋จ!
scoreC = miniMax(board, ...) // ์์ ํ ์๋ชป๋ ์ํ!
์ฐ๋ฆฌ๊ฐ ์ํ๋ ๊ฒ์
"A์นธ ํ๋๋ง ๋์ ๋" ์ ์๋?
"B์นธ ํ๋๋ง ๋์ ๋" ์ ์๋?
"C์นธ ํ๋๋ง ๋์ ๋" ์ ์๋?
์ธ๋ฐ, ์ค์ ๋ก๋
"A์นธ ํ๋๋ง ๋์ ๋" ์ ์๋? โ ์ ํ
"A+B ์นธ ๋ ๋ค ๋์ ๋" ์ ์๋? โ ์๋ชป๋จ!
"A+B+C ์นธ ์ ๋ค ๋์ ๋" ์ ์๋? โ ์๋ชป๋จ!
๋ฐ๋ผ์ ๋ฏธ๋๋งฅ์ค ์๊ณ ๋ฆฌ์ฆ์ ๊ฐ ๋ฐ๋ณต(Iteration)๋ง๋ค ๋ค์ 2๊ฐ์ง ์ค ํ๋๋ฅผ ์ํํด์ผ ํ๋ค.
- ์ํ ๋ณต์ฌ ํ ๋ณ๊ฒฝ (Deep Clone): ํ์์ ์ํ ์๋ก์ด ๋ณด๋๋ฅผ ๋ง๋ค๊ณ (๋ณต์ฌ), ์ฌ๊ธฐ์ ๋์ ๋ก๋๋ค.
- ์ํ ๋ณ๊ฒฝ ํ ๋ณต๊ตฌ (Undo/Redo): ์๋ณธ ๋ณด๋์ ๋์ ๋์๋ค๊ฐ, ์ฌ๊ท ํธ์ถ์ด ๋๋ ํ ๋ฐ๋์ ๋์ ๋ค์ ๋นผ๋ ๋๋ค. (๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ด ํจ์จ์ ์ธ ๋ฐฉ์)
โก๏ธ ์๋ฅผ ์ทจ์ํ๋ ๋ฐฉ๋ฒ
ํต์ฌ ๊ฐ๋ — ์ ๋ฐ๋์ ์์๋ณต๊ตฌํด์ผ ํ๋?
๋ฏธ๋๋งฅ์ค๋ “๊ฐ ํ๋ณด(์นธ) ๋ณ๋ก ๋
๋ฆฝ์ ์ธ ๊ฒฐ๊ณผ”๋ฅผ ์๊ธฐ ์ํจ
๋ฐ๋ผ์ ๊ฐ ํ๋ณด๋ฅผ ์๋ฎฌ๋ ์ด์
ํ ๋ ๋ณด๋ ์ํ๋ ๊ทธ ํ๋ณด๋ง ๋ฐ์๋ ์ํ์ฌ์ผ ํ๋ค.
๋์ ๋๊ณ ์ฌ๊ท ๊ณ์ฐํ ๋ค ๋์ ๋ค์ ์ ๊ฑฐํ์ง ์์ผ๋ฉด ๋ค์ ํ๋ณด๋ฅผ ์๋ฎฌ๋ ์ด์
ํ ๋ ์ด์ ํ๋ณด์ ๋ณ๊ฒฝ์ด ๋จ์ ์์ด ๊ฒฐ๊ณผ๊ฐ ๋ค์์ฌ ๋ฒ๋ฆฐ๋ค.
์) A ์นธ ์๋ฎฌ๋ ์ด์ ํ A๋ฅผ ์ ๊ฑฐํ์ง ์์ผ๋ฉด B ์๋ฎฌ๋ ์ด์ ์ A+B๊ฐ ๋์ธ ์ํ๋ฅผ ๋ณด๊ณ ๊ณ์ฐํ๋ค → ์๋ชป๋ ๊ฒฐ๊ณผ.
๊ตฌํ ๋ฐฉ๋ฒ — ๋ ๊ฐ์ง ์ผ๋ฐ์ ํจํด
๋ฐฉ๋ฒ A — ๋ถ๋ณ(immutable) ๋ฐฉ์: ๋งค ์๋ฎฌ๋ ์ด์ ๋ง๋ค ์ ๋ฐฐ์ด/๋ณด๋๋ฅผ ๋ง๋ค์ด ์ฌ๊ท์ ๋๊ธด๋ค
์ฅ์ : ์ฝ๋๊ฐ ์์ ํ๊ณ ๋ฒ๊ทธ๊ฐ ๋ ๋จ. React ์คํ์ผ๊ณผ๋ ์ด์ธ๋ฆผ.
๋จ์ : ๋ณต์ฌ ๋น์ฉ(๋ฉ๋ชจ๋ฆฌ·์๋)์ด ๋ฐ์ํ ์ ์์(ํนํ ๊น๊ฒ/๋ง์ด ๋ณต์ฌํ๋ฉด).
// stones: {x,y,color}[] ํํ์ผ ๋
for (const {x,y} of possibleMoves) {
const newStones = [...currentStones, { x, y, color: 'black' as const }]
const val = miniMax(newStones, depth - 1, alpha, beta, false) // ๋น๊ต/๊ฐฑ์
}
// ์ด ๋ฐฉ์์ board๋ stone ์๋ณธ์ ์ ๋ ์ง์ ๋ณ๊ฒฝํ์ง ์์ผ๋ฏ๋ก undo๊ฐ ํ์ ์์.
๋ฐฉ๋ฒ B — ๊ฐ๋ณ(mutable) ๋ฐฉ์: ๋ณด๋(2D ๋ฐฐ์ด)๋ฅผ ์ง์ ์์ ํ๊ณ ์ฌ๊ท ๋๋ ๋ค ๋๋๋ฆฌ๊ธฐ(undo)
์ฅ์ : ๋ฉ๋ชจ๋ฆฌ/์๋ ํจ์จ์ด ๋์(๋ณต์ฌ ๋น์ฉ ์์).
๋จ์ : ๋ฐ๋์ “๋๋๋ฆฌ๊ธฐ”๋ฅผ ์ ํํ ํด์ผ ํ๊ณ , ์ค์ํ๋ฉด ์ด์ ์ํ๊ฐ ์ค์ผ๋จ.
// board: string | null[][] (2D ๋ฐฐ์ด) ์ผ ๋
function tryMoveAndEval(board, x, y, color, depth, alpha, beta, isMax) {
board[x][y] = color // 1) ๊ฐ์์ผ๋ก ๋๊ธฐ
const val = miniMax(board, depth - 1, alpha, beta, !isMax) // 2) ์ฌ๊ท
board[x][y] = null // 3) ๋ฐ๋์ ๋๋๋ฆฌ๊ธฐ!
return val
}
//์ด ํจํด์ด “๋๊ณ → ๊ณ์ฐ → ์ทจ์”์ ์ ํํ ์ผ์นํ๋ค.
์ค์ ํ
- ์ ๋ setStone ๊ฐ์ React ์ํ ์
๋ฐ์ดํธ๋ฅผ ๋ฏธ๋๋งฅ์ค ๋ด๋ถ์์ ํธ์ถํ์ง ๋ง ๊ฒ
-> ์ฌ๊ท ์์์๋ ๋ก์ปฌ(์์) ๋ณ์๋ ๋ณต์ฌ๋ณธ/2D board๋ฅผ ์จ๋ผ. setState๋ ๋น๋๊ธฐ์ด๊ณ UI์ ์์ด๋ฉด ์ํด - ํค ํฌ๋งท์ด๋ Map/Set ์ฌ์ฉ ์ ํฌ๋งท ํต์ผ ("${x},${y}" ์ฒ๋ผ). ํฌ๋งท ๋ถ์ผ์น๋ ์น๋ช ์ ๋ฒ๊ทธ๋ฅผ ๋ณ์.
- ์ฑ๋ฅ: ๋ง์ด ๋ณต์ฌํ๋ฉด ๋๋ ค์ง๋ ๊น์ด์ ํ๋ณด ์(ex. ์ค๋ชฉ์์ ์๋ฅผ ์ฐพ๋ ํจ์)๋ฅผ ์ ์ ํ ์ ํํ๊ฑฐ๋, mutable + undo ๋ฐฉ์์ผ๋ก ์ต์ ํํ์.
- ๋๋ฒ๊น
:
- ์๋ฎฌ๋ ์ด์ ์งํ console.log๋ก ๋ณด๋ ์ํ ์ฐ์ด๋ณด๊ณ , ์ฌ๊ท ๋ฐํ ํ ๋์ผํ ์ํ๋ก ๋์์๋์ง ํ์ธํ๋ผ.
- ์์๊ณผ ๋ค๋ฅธ ๊ฐ(๋์ ๋ ๋)์ด ๋์ค๋ฉด “๋๋๋ฆฌ๊ธฐ ๋๋ฝ”๋ถํฐ ์ ๊ฒ.
์ธ์ mutable + undo๊ฐ ๋ ์ข์๊ฐ?
- ํ๋ณด๊ฐ ๋ง๊ณ ์ฌ๊ท ํธ์ถ์ด ํญ๋ฐํ ๋(์ฑ๋ฅ ์ ํ์ด ์ฌํ ์ํฉ), ๋ณด๋ 2D ๋ฐฐ์ด + ๊ฐ๋ณ/undo ๋ฐฉ์์ด ํจ์ฌ ๋น ๋ฆ.
- ๊ตฌํ์ ์กฐ๊ธ ๋ ๊น๋ค๋กญ์ง๋ง, ๋๊ท๋ชจ ํ์(๊น์ด 3~4 ์ด์)์์๋ ๊ถ์ฅ๋จ.
๊ฒฐ๋ก
- ํด๊ฒฐ ๋ฐฉ๋ฒ์ (A) ๋ถ๋ณ์ผ๋ก ์ ๋ณด๋/๋ฐฐ์ด ๋ง๋ค์ด ๋๊ธฐ๊ธฐ ๋๋ (B) ๊ฐ๋ณ ๋ณด๋์ ๋๊ณ ์ฌ๊ท ๋๋๋ฉด ๋๋๋ฆฌ๊ธฐ.
- React ํ๊ฒฝ์์๋ ๋ฏธ๋๋งฅ์ค ๋ด๋ถ์์ setState ์ฐ์ง ๋ง๊ณ ๋ก์ปฌ ๋ณต์ฌ๋ mutable-undo๋ฅผ ์ฌ์ฉํ ๊ฒ.
๊ทธ๋ฐ๋ฐ ๋ฏธ๋๋งฅ์ค๋ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ณ์ฐํ๊ธฐ ๋๋ฌธ์ ํ์ํ์ง ์์ ๊ฒฝ์ฐ์ ์๋ ์๋ตํด์ผ ์ฑ๋ฅ์ด ํฅ์๋๋ค.
๊ทธ๋ด ๋ ์ฌ์ฉํ๋ ๊ฒ์ด ์ํ-๋ฒ ํ ๊ฐ์ง์น๊ธฐ์ด๋ค!
์ํ - ๋ฒ ํ ๊ฐ์ง์น๊ธฐ(Alpha-beta pruning)
๋ฏธ๋๋งฅ์ค์์ ๊ณ์ฐํ๋ ๊ณผ์ ์ค "์ด ๊ฒฝ๋ก๋ก๋ ์ด์ฐจํผ ์ต์ ์ ๋ชป๋ฏธ์น๋๊น ๊ณ์ฐํ์ง ๋ง์"๊ณ ์ธ๋ฐ ์๋ ๊ฐ์ง๋ฅผ ์๋ผ๋ด๋ ๊ธฐ์ ์ด๋ค.
์ปดํจํฐ(Max) ํด: "์ต์ 10์ ์ ๋ณด์ฅ๋ฐ๊ณ ์ถ์ด!"
|
โโโ ์A๋ฅผ ๋๋ฉด → ์ฌ๋์ด ๋ญ ํด๋ ์ต์ 10์
|
โโโ ์B๋ฅผ ์ดํด๋ณด๋ ์ค...
โโโ ์ฌ๋์ด ์ฒซ ๋ฒ์งธ ์๋ฅผ ๋๋ 5์ ์ด ๋์ด
→ "์, ์B๋ ์ต๋ 5์ ์ด๋ค?"
→ "์ด๋ฏธ ์A๋ก 10์ ๋ณด์ฅ๋ฐ์์ผ๋ ์B๋ ๋ณผ ํ์ ์์ด!"
โ๏ธ ๊ฐ์ง์น๊ธฐ!
https://hello-kk.tistory.com/580
์ํ๋ฒ ํ ๊ฐ์ง์น๊ธฐ Alpha-beta pruning ์ค๋ช
์ํ๋ฒ ํ ๊ฐ์ง์น๊ธฐ์ ๋ํ ์ค๋ช ์ ์ฐพ์๋ณด๋ฉฐ ํ์ตํ ๋ด์ฉ์ ๋๋ค.๋๊ธ ๋ด์ฉ ๊ผญ ํ์ธ ๋ถํ๋๋ฆฝ๋๋ค.์๋ชป๋ ๋ถ๋ถ์ด ์๋ค๋ฉด ์๋ ค์ฃผ์๊ธฐ ๋ฐ๋๋๋ค. ๊ฐ์ฌํฉ๋๋ค! ๊ทธ๋ฆผ๊ณผ ๊ทธ๋ฆผ ํ๋จ์ ์ค๋ช ์ ์ฐธ๊ณ ํ์
hello-kk.tistory.com
์๊ณ ๋ฆฌ์ฆ ์๋ฆฌ๋ ์ฌ์ค ๋ด ์ค๋ช ๋ณด๋จ ์ด ๋ธ๋ก๊ทธ ์ค๋ช ๊ธ ๋ณด๋๊ฒ ์ดํด๊ฐ ๋ ๋น ๋ฅด๋ค.
๊ทธ๋์ ๋ด๊ฐ ๊ถ๊ธํ๋ ๊ฒ ์์ฃผ๋ก ์ ๋ฆฌํ์๋ค.
1๏ธโฃ ์ max๋ -∞์์, min์ ∞์์ ์์ํ ๊น?
Max(์ปดํจํฐ)๋ "๊ฐ๋ฅํ ํฐ ์ ์"๋ฅผ ์ฐพ๋ ์ญํ ์ด๊ธฐ ๋๋ฌธ์ ์์๊ฐ์ -∞๋ก ๋ฌ์ผ ํ๋ค → ์ด๋ค ์ค์ ์ซ์๋ฅผ ๋ง๋๋ "๊ทธ๊ฑด ์ง๊ธ๋ณด๋ค ํฌ๋ค"๊ณ ๊ฐฑ์ ํ ์ ์์
Min(์๋, ์ฌ๋)์ "๊ฐ๋ฅํ ์์ ์ ์"๋ฅผ ์ฐพ๋ ์ญํ ์ด๊ธฐ ๋๋ฌธ์ ์์๊ฐ์ +∞๋ก ๋ฌ์ผ ํ๋ค → ์ด๋ค ์ค์ ์ซ์๋ฅผ ๋ง๋๋ "๊ทธ๊ฑด ์ง๊ธ๋ณด๋ค ์๋ค"๊ณ ๊ฐฑ์ ํ ์ ์์
โก๏ธMax๋ ์ต์๊ฐ์์ ์ถ๋ฐํด์ ์ ์ ๋ ์ข์(ํฐ)๊ฑธ ์ฐพ๊ณ , Min์ ์ต๋๊ฐ์์ ์ถ๋ฐํด์ ์ ์ ๋ ๋์(์์)๊ฒ์ ์ฐพ๋๋ค.
โก๏ธ์ฒ์์๋ ์๋ฌด ์ง์๋ ์๊ธฐ ๋๋ฌธ์ ๋ฌด๋๋์๊ฐ์ ๋๋ค.
์ํ - ๋ฒ ํ ๊ฐ์ง์น๊ธฐ ์์(์ฝ๋๋ก ๋ณด๊ธฐ)
1. Max ์ฐจ๋ก์ ๊ฒฝ์ฐ
let maxEval = -Infinity
for (let child of children) {
const eval = miniMax(child, depth - 1, alpha, beta, false)
maxEval = Math.max(maxEval, eval)
if (beta <= alpha) break // ๊ฐ์ง์น๊ธฐ
}
์ฒซ๋ฒ์งธ ์์์ด 3์ด๋ฉด : maxEval = max(- ∞, 3) = 3
๋๋ฒ์งธ ์์์ด 7์ด๋ฉด : maxEval = max(3, 7) = 7
์ธ๋ฒ์งธ ์์์ด 2์ด๋ฉด : maxEval = max(7, 2) = 7
...
์ฆ ๊ณ์ ํฐ๊ฐ์ผ๋ก ์ ๋ฐ์ดํธํ๋ฉด์ ์ต๋๊ฐ์ ์ฐพ์๊ฐ๋ค.
2. Min ์ฐจ๋ก์ ๊ฒฝ์ฐ
let minEval = Infinity
for (let child of children) {
const eval = miniMax(child, depth -1, alpha, beta, true)
minEval = Math.min(minEval, eval)
if (beta <= alpha) break // ๊ฐ์ง์น๊ธฐ
}
์ฒซ๋ฒ์งธ ์์์ด 5๋ฉด : minEval = min(∞, 5) = 5
๋๋ฒ์งธ ์์์ด 2์ด๋ฉด : minEval = min(5, 2) = 2
์ธ๋ฒ์งธ ์์์ด 8์ด๋ฉด : minEval = min(2, 8) = 2
...
์ฆ ๊ณ์ ์์ ๊ฐ์ผ๋ก ์ต์๊ฐ์ ์ ๋ฐ์ดํธํ๋ค.
3. ์์ฌ ์ฝ๋
function alphabeta(node, depth, α, β, maximizingPlayer)
if depth = 0 or node is a terminal node
return the heuristic value of node
if maximizingPlayer
v := -∞
for each child of node
v := max(v, alphabeta(child, depth - 1, α, β, FALSE))
α := max(α, v)
if β ≤ α
break (* β cut-off *)
return v
else
v := ∞
for each child of node
v := min(v, alphabeta(child, depth - 1, α, β, TRUE))
β := min(β, v)
if β ≤ α
break (* α cut-off *)
return v
[์ฐธ๊ณ ์๋ฃ]
https://hello-kk.tistory.com/580
์ํ๋ฒ ํ ๊ฐ์ง์น๊ธฐ Alpha-beta pruning ์ค๋ช
์ํ๋ฒ ํ ๊ฐ์ง์น๊ธฐ์ ๋ํ ์ค๋ช ์ ์ฐพ์๋ณด๋ฉฐ ํ์ตํ ๋ด์ฉ์ ๋๋ค.๋๊ธ ๋ด์ฉ ๊ผญ ํ์ธ ๋ถํ๋๋ฆฝ๋๋ค.์๋ชป๋ ๋ถ๋ถ์ด ์๋ค๋ฉด ์๋ ค์ฃผ์๊ธฐ ๋ฐ๋๋๋ค. ๊ฐ์ฌํฉ๋๋ค! ๊ทธ๋ฆผ๊ณผ ๊ทธ๋ฆผ ํ๋จ์ ์ค๋ช ์ ์ฐธ๊ณ ํ์
hello-kk.tistory.com
https://lordofkangs.tistory.com/205
[์ธ๊ณต์ง๋ฅ] ๊ฒ์ํธ๋ฆฌ ( ์ํ๋ฒ ํ ๊ฐ์ง์น๊ธฐ )
[์ธ๊ณต์ง๋ฅ] ๊ฒ์ํธ๋ฆฌ ( MiniMax ์๊ณ ๋ฆฌ์ฆ ) ์ธ๊ณต์ง๋ฅ์๊ฒ ๊ฒ์์ด๋? ๊ฒ์์ ์ถ์์ ์ผ๋ก ์ ์๊ฐ๋ฅํ๋ฉฐ ๋น๊ต์ ์ ์ ์ฐ์ฐ์๋ฅผ ๊ฐ์ง๋ค. ๊ฒ์์ ์ธ๊ณต์ง๋ฅ ๊ตฌํ์ ์ง์ ๋ฅ๋ ฅ๊ณผ ๊ด๋ จ์๋ค๊ณ ์ฌ๊ฒจ์ง๋ค. ๊ฒ
lordofkangs.tistory.com
https://ssollacc.tistory.com/43
[์ธ๊ณต์ง๋ฅ] ๊ฒ์ ํธ๋ฆฌ - ๋ฏธ๋๋งฅ์ค(minimax) ์๊ณ ๋ฆฌ์ฆ, ์ํ๋ฒ ํ ๊ฐ์ง์น๊ธฐ, ํด๋ฆฌ์คํฑ ํ๊ฐ ํจ์(evaluat
์ธ๊ณต์ง๋ฅ์์ ๊ฒ์์ ์๋จํ ์ข์ ์ฐ๊ตฌ์ฃผ์ ์ ๋๋ค. Tic-Tac-Toe๋ ์ฒด์ค, ๋ฐ๋๊ณผ ๊ฐ์ ๊ฒ์์ ์ถ์์ ์ผ๋ก ์ ์ํ ์ ์๊ณ ์ง์ ๋ฅ๋ ฅ๊ณผ ์ฐ๊ด์ด ์๋ ๊ฒ์ผ๋ก ์๊ฐ๋์์ต๋๋ค. ๊ฒ์์ ๊ท์น์ ์๋์
ssollacc.tistory.com
์ํ-๋ฒ ํ ๊ฐ์ง์น๊ธฐ - ์ํค๋ฐฑ๊ณผ, ์ฐ๋ฆฌ ๋ชจ๋์ ๋ฐฑ๊ณผ์ฌ์
์ํค๋ฐฑ๊ณผ, ์ฐ๋ฆฌ ๋ชจ๋์ ๋ฐฑ๊ณผ์ฌ์ . ์ํ-๋ฒ ํ ๊ฐ์ง์น๊ธฐ(Alpha–beta pruning)๋ ํ์ ํธ๋ฆฌ์์ ์ต์๊ทน๋ํ(๋ฏธ๋๋งฅ์ค) ์๊ณ ๋ฆฌ์ฆ์ ์ ์ฉํ ๋ ํ๊ฐ(evaluate)ํ๋ ๋ ธ๋์ ์๋ฅผ ์ค์ด๊ธฐ ์ํ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
ko.wikipedia.org
'Computer Science๐งช > Data Structure, Algorithmโ๏ธ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [Algorithm] ์๊ฐ๋ณต์ก๋์ ๋ํด ์์๋ณด๊ธฐ (0) | 2025.12.10 |
|---|