[Farm SystemπŸͺ΄] 인곡지λŠ₯ μŠ€ν„°λ”” 5μ£Όμ°¨(μƒνƒœμ™€ 행동)

μž¬ν™(JH)Β·2025λ…„ 6μ›” 1일

πŸ™Œμ„œλ‘ 

이번 μ£Όμ°¨ λ‚΄μš©μ€ μƒνƒœμ™€ ν–‰λ™μž…λ‹ˆλ‹€. ꡐ재의 μ˜ˆμ œλ‘œλŠ” nλͺ©μ΄ μžˆμŠ΅λ‹ˆλ‹€. 사싀 μ €λ²ˆμ£Όμ°¨μ— 이번 μ£Όμ°¨ λ‚΄μš©μ˜ 단원 λͺ…λ§Œ 봀을 λ•Œ 이제 κ°•ν™”ν•™μŠ΅μ˜ λ¬΄μ–Έκ°ˆ λ°°μš°κ² κ΅¬λ‚˜ 라고 μƒκ°ν–ˆμ§€λ§Œ ν•™μŠ΅ν•˜λ‹€λ³΄λ‹ˆ μ €λ²ˆμ£Όμ°¨ 처럼 예제 ν•˜λ‚˜λ₯Ό κ°€μ§€κ³  μ•Œκ³ λ¦¬μ¦˜ 곡뢀λ₯Ό ν•˜λŠ” λŠλ‚Œμ΄κΈ΄ ν–ˆμŠ΅λ‹ˆλ‹€. κ·Έλž˜λ„ κ΅μž¬μˆœμ„œλŒ€λ‘œ μ°¨κ·Όμ°¨κ·Ό ν•™μŠ΅ν•΄ λ³΄κ² μŠ΅λ‹ˆλ‹€.

πŸ€”μƒνƒœμ™€ 행동

사싀 단어 κ·ΈλŒ€λ‘œ 의미λ₯Ό μœ μΆ”ν•˜λŠ” 것이 νŽΈν•˜κΈ΄ ν•˜κ² μŠ΅λ‹ˆλ‹€. κ΅μž¬μ— μ ν˜€μžˆλŠ” 것 κ·ΈλŒ€λ‘œ(κ΅μž¬μ—λŠ” 였λͺ©μ„ μ˜ˆμ‹œλ‘œ λ§ν–ˆμŠ΅λ‹ˆλ‹€) λ§ν•˜μžλ©΄ μ•„λž˜μ™€ 같이 μ •μ˜ κ°€λŠ₯ν•©λ‹ˆλ‹€.

μƒνƒœ : λ°”λ‘‘νŒ μœ„μ— ν‘λ°±μ˜ λŒλ“€μ΄ 놓인 κ΅­λ©΄
행동 : μ°Έμ—¬μžκ°€ λ‘λŠ” 수

✨Nλͺ© ν™˜κ²½

μš°μ„  이번 μ£Όμ°¨ μŠ€ν„°λ””μ—μ„œλŠ” λ‹€μŒκ³Ό 같은 λͺ¨λ“ˆ/νŒ¨ν‚€μ§€λ₯Ό μ΄μš©ν–ˆμŠ΅λ‹ˆλ‹€.

import numpy as np
import time

ν™˜κ²½μ€ λ‹€μŒκ³Ό 같이 μ„€μ •ν–ˆμŠ΅λ‹ˆλ‹€.

  • ν‘λŒκ³Ό λ°±λŒμ€ 각각 +1/-1
  • λŒμ„ 놓지 μ•Šμ€ 곳은 0으둜 ν‘œν˜„

λ”°λΌμ„œ 초기 μƒνƒœμ˜ λ³΄λ“œλŠ”
np.zeros(shape, dtype=int)이고 shapeλŠ” ν‹±νƒν† λŠ” (3,3), 였λͺ©μ€ (9,9) λ“±μž…λ‹ˆλ‹€.

μœ μ € μΈν„°νŽ˜μ΄μŠ€λŠ” GUI, CUIκ°€ μžˆμ§€λ§Œ μ—¬κΈ°μ„œλŠ” CUIλ₯Ό μ΄μš©ν•˜κ² μŠ΅λ‹ˆλ‹€.

κ°€λŠ₯ν•œ 착수점

돌이 두어지지 μ•Šμ€ 곳을 0으둜 λ‚˜νƒ€λ‚΄λ―€λ‘œ boardμ—μ„œ 0인 μš”μ†Œλ“€μ˜ 인덱슀λ₯Ό λ°˜ν™˜ν•˜λ©΄ λ©λ‹ˆλ‹€.

def get_legal_actions(board):
	zero_idx = np.where(board == 0)
    legal_actions = list(zip(zero_idx[0], zero_idx[1]))
    return legal_actions

μœ„ ν•¨μˆ˜λŠ” 0인 μš”μ†Œλ“€μ˜ 인덱슀λ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μž…λ‹ˆλ‹€.
np.where둜 0인 곳의 인덱슀λ₯Ό μ°Ύκ³  ν–‰κ³Ό 열이 λ”°λ‘œ λ°˜ν™˜λœ 이것을 zip을 μ΄μš©ν•˜μ—¬ (ν–‰, μ—΄) ν˜•νƒœμ˜ νŠœν”Œλ‘œ λ¬Άκ³  그것을 λ¦¬μŠ€νŠΈμ— λ‹΄μ•„ λ°˜ν™˜ν•©λ‹ˆλ‹€.

승리 νŒλ‹¨

μŠΉλ¦¬λŠ” n개의 돌이 κ°€λ‘œ/μ„Έλ‘œ/λŒ€κ°μ„  λ°©ν–₯으둜 연달아 λ‚˜μ˜€λ©΄ λ©λ‹ˆλ‹€. 즉 -1/+1 이 nκ°œκ°€ 연달아 μžˆλŠ”μ§€ μ—¬λΆ€λ‘œ νŒλ‹¨ν•˜λ©΄ λ©λ‹ˆλ‹€.

κ°€μž₯ κ°„λ‹¨ν•œ 방법은 길이가 n인 창을 ν•œμΉΈμ”© μ΄λ™μ‹œν‚€λ©΄μ„œ μ°½μ•ˆμ— λ³΄μ΄λŠ” λͺ¨λ“  μš”μ†Œλ“€μ΄ +1μ΄λ‚˜ -1 인지 ν™•μΈν•˜λ©΄ λ©λ‹ˆλ‹€. 이와 같은 기법을 ν™œμ£Όμ°½κΈ°λ²•μ΄λΌκ³  ν•©λ‹ˆλ‹€.
λ‹€λ₯Έ λ°©λ²•μœΌλ‘œλŠ” μ°½μ•ˆμ˜ μš”μ†Œλ“€μ˜ 합이 +5인지 -5인지 ν™•μΈν•˜λ©΄ λ©λ‹ˆλ‹€.
μ•„λž˜μ˜ μ½”λ“œμ™€ 같이 μž‘μ„±κ°€λŠ₯ν•©λ‹ˆλ‹€.

n_connects = 5

board_1d = np.zeros(10000, dtype=int)
board_1d[-n_connects:] = 1
win_mark = np.ones(n_connects)

for i in range(len(board_1d) - (n_connects-1)):
	window = board_1d[i:i+5]
    if (window==win_mark).all():
    	print("WIN")

λŒ€κ°μ„  λ°©ν–₯은 쑰금 κΉŒλ‹€λ‘­μŠ΅λ‹ˆλ‹€.
λŒ€κ°μ„ μ€ 두가지 λ°©ν–₯이 μžˆλŠ”λ° ν•˜λ‚˜λŠ” μ™Όμͺ½μœ„μ—μ„œ 였λ₯Έμͺ½ μ•„λž˜λ‘œ, λ‹€λ₯Έ ν•˜λ‚˜λŠ” 였λ₯Έμͺ½ μœ„μ—μ„œ μ™Όμͺ½ μ•„λž˜λ‘œ ν–₯ν•˜λŠ” λ°©ν–₯이 μžˆμŠ΅λ‹ˆλ‹€.

μ£Όμ–΄μ§„ 배열은 np.diag둜 얻을 수 μžˆλŠ”λ°, μ • μ€‘μ•™μ˜ μ£ΌλŒ€κ°μ„ μ—μ„œ λͺ‡μΉΈ λ–¨μ–΄μ Έ μžˆλŠ” λŒ€κ°μ„ μ— λŒ€ν•΄μ„œμΈμ§€λŠ” 인자 k[+λŠ” μœ„μͺ½, -λŠ” μ•„λž˜μͺ½]둜 μ§€μ •κ°€λŠ₯ν•©λ‹ˆλ‹€.
μ•„λž˜μ˜ μ½”λ“œμ™€ 같이 μž‘μ„±κ°€λŠ₯ν•©λ‹ˆλ‹€.

delta_row = n_rows - n_conn
delta_col = n_cols - n_conn

# diagonal forward (up left to down right)
for k in range(-delta_row, delta_col+1):
	l = list(np.diag(board, k))
    result = check_n_mok_in_list(l, player_type, n_conn)
    if result == True:
    	break
        
# diagonal backward (up right to down left)
for k in range(-delta_col, delta_row+1):
	l = list(np.diag(upside_down_board, k))
    result - check_n_mok_in_list(l, player_type, n_conn)
    if result == True:
    	break

κ²Œμž„μ’…λ£Œ/λ¬΄μŠΉλΆ€ νŒλ‹¨

λŒμ„ 더 λ‘˜ 곳이 μžˆλŠ”μ§€ νŒλ‹¨ν•˜λ©΄ λ©λ‹ˆλ‹€.
돌이 놓이지 μ•Šμ€ 곳이 0μ΄λ―€λ‘œ board의 λͺ¨λ“  μš”μ†Œλ“€μ„ κ³±ν•œ 값이 0인지 ν™•μΈν•˜λ©΄ λ©λ‹ˆλ‹€.

def check_if_game_finishied(board):
	if board.prod() == 0:
    	return False
    else:
    	return True

πŸ§™β€β™€οΈ λŒ€κ΅­μž

인간 λŒ€κ΅­μž

인간 λŒ€κ΅­μžμ˜ μˆ˜λŠ” λ³΄λ“œμ˜ ν–‰κ³Ό μ—΄μ˜ 인덱슀λ₯Ό μš”μ†Œλ‘œ ν•˜λŠ” νŠœν”Œλ‘œ μž…λ ₯λ°›μŠ΅λ‹ˆλ‹€.

def human(state):
	legal_actions = state.get_legal_actions()
    while True:
    	action = input("input player action (e.g., '0,0'): ")
        if "," in action:
        	action = tuple(int(float(x)) for x in action.split(","))
            if action in legal_actions:
            	break
            else:
            	print('invalid format")
        return action

μ˜€νƒ€ λ˜λŠ” 착수 λΆˆκ°€λŠ”ν•œ μˆ˜κ°€ μž…λ ₯λ˜λŠ” 것을 λ°©μ§€ν•˜κΈ° μœ„ν•˜μ—¬, μ°©μˆ˜κ°€ κ°€λŠ₯ν•œ μˆ˜κ°€ μž…λ ₯되기 μ „κΉŒμ§€λŠ” "invalid format"을 좜λ ₯ν•˜κ³  while루프가 λ°˜λ³΅λ˜λ„λ‘ ν•©λ‹ˆλ‹€.

λ¬΄μž‘μœ„μ μΈ 수λ₯Ό λ‘λŠ” 인곡지λŠ₯

착수 κ°€λŠ₯ν•œ 수 μ€‘μ—μ„œ 아무 μˆ˜λ‚˜ λ¬΄μž‘μœ„μ μ„ μ„ νƒν•˜μ—¬ λŒ€κ΅­ν•˜λŠ” λŒ€κ΅­μžλ₯Ό κ΅¬ν˜„ν•œ ν•¨μˆ˜μž…λ‹ˆλ‹€.

def AI-random(state):
	legal_actions = state.get_legal_actions()
    random_idx = np.random.randint(low=0, high=len(legal_actions))
    action = legal_actions[random_idx]
    return action

πŸ˜€λ§ˆλ¬΄λ¦¬

이번 μ£Όμ°¨ μŠ€ν„°λ””λ„ μ΄λ ‡κ²Œ λ§ˆλ¬΄λ¦¬λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 사싀 ν•˜λ‹€λ³΄λ‹ˆ μ €λ²ˆ 주차처럼 인곡지λŠ₯ λ³΄λ‹€λŠ” 파이썬과 numpy에 μ΅μˆ™ν•΄μ§€κ³  이것듀을 μ΄μš©ν•΄μ„œ κ°„λ‹¨ν•œ(?) μ•Œκ³ λ¦¬μ¦˜μ„ μž‘μ„±ν•΄ λ³Έ 것 κ°™μŠ΅λ‹ˆλ‹€. ν™•μ—°νžˆ np.random만 μ‚¬μš©ν•œ μ €λ²ˆμ£Όμ°¨ 보닀 numpyλ₯Ό 더 λ‹€μ–‘ν•˜κ²Œ μ΄μš©ν•΄ λ³Έ 것 κ°™κΈ΄ ν•©λ‹ˆλ‹€.

μ½”λ“œλ“€μ„ 보고 μž‘μ„±ν•΄λ³΄λ©΄μ„œ λŠλ‚€ 것인데 생각보닀 νŒŒμ΄μ¬λ„ λ³΅μž‘ν•˜κ²Œ μ½”λ“œκ°€ μž‘μ„±ν•  수 μžˆκ² κ΅¬λ‚˜ μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€. μ•„λ‹ˆλ©΄ μ‹€μ œλ‘œ λ³΅μž‘ν•œ 것이 μ•„λ‹Œλ° 제 μ‹€λ ₯이 λΆ€μ‘±ν•΄μ„œμΌ μˆ˜λ„ 있고 ν˜Ήμ€ 정말 이 ꡐ재의 μ½”λ“œκ°€ 쓸데없이 λ³΅μž‘ν•œ 것일 μˆ˜λ„ μžˆμ„ κ²ƒμž…λ‹ˆλ‹€. μ•„λ¬΄νŠΌ λ°©ν•™λ•Œ νŒŒμ΄μ¬λ„ 쑰금 더 곡뢀해야 κ² λ‹€κ³  λŠκΌˆμŠ΅λ‹ˆλ‹€.

벌써 6μ›” μž…λ‹ˆλ‹€. 그리고 μ‹œν—˜μ΄ λ‹€κ°€μ˜€λŠ”κ΅°μš”..😱😱
그만큼 쒅강이 λ³„λ‘œ μ•ˆλ‚¨μ•˜λ‹€λŠ” λœ»μ΄λ‹ˆ 저도 ν™”μ΄νŒ…ν•˜κ³  이글을 λ³΄λŠ” λͺ¨λ“  뢄듀도 ν™”μ΄νŒ…μž…λ‹ˆλ‹€!!

profile
I'm free to be whatever I

0개의 λŒ“κΈ€