BLOG
인공지능

강화학습: 파이썬으로 구현한 TIC TAC TOE 환경


June 8, 2022, 12:25 p.m.



이번에는 강화학습 알고리즘 테스트 용으로 프롬프트에서 출력되는 TIC TAC TOE 환경을 만들어 보았습니다. 사실 이것은 군대에서 당직 근무설 때 인트라넷 컴퓨터로 강화학습을 공부하기 위해서 만든 환경인데요, 만든 코드를 인쇄해서 다시 인터넷으로 옮겼답니다.

먼저 코드 전문을 보겠습니다.

import numpy as np
import pandas as pd
import time
from collections import defaultdict
import random
import os

class TicTacToe:
  def __init__(self):
    self.matrix = [0, 0, 0, 0, 0, 0, 0, 0, 0] #게임 정보 담을 변수
    self.answers = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]] #한줄 맞춰지는 조건
    self.state = self.matrix.copy()
    self.unavailable_reward = -1
    self.winning_reward = 1
    self.code_to_str = [" ", "O", "X"]
    self.state_size = 8
    self.action_size = 8
    self.DELAY = 1

  def reset(self):
    self.matrix = [0, 0, 0, 0, 0, 0, 0, 0, 0]
    self.state = self.matrix.copy()
    return self.state

  def swap(self): # O와 X를 바꾸는 함수
    for i in range(9):
      a = self.matrix[i]
      if a==1:
        self.matrix[i] = 2
      elif a==2:
        self.matrix[i] = 1

  def step(self, side, action, show=False):
    reward = 0
    next_state = self.state
    done = False
    active = True

    if self.matrix[action]==0: #빈 공간에 돌 놓기
      self.matrix[action] = side

      next_state = self.matrix.copy()

      for ans in self.answers: #줄이 완성되어서 게임이 끝났는가?
        temp = [3, 4, 5]
        for a in range(3):
          if self.matrix[ans[a]]!=0:
            temp[a] = self.matrix[ans[a]]
          else:
            break
        if temp[0]==temp[1] and temp[1]==temp[2]:
          done = True
          reward += self.winning_reward
          break
    else:
      reward += self.unavailable_reward
      active = False

    temp = True
    for i in range(9): #9칸이 모두 다 찼는가?
      if self.matrix[i] == 0:
        temp = False
    if temp:
      done = True
    if show:
      self.show(side, action, reward)

    return next_state, reward, active, done

  def show(self, side, act, reward):
    os.system('cls')
    print(f"Side:{side}, A:{act}, R:{reward}")
    print("---------")
    print("|",self.code_to_str[self.matrix[0]],self.code_to_str[self.matrix[1]],self.code_to_str[self.matrix[2]],"|")
    print("|",self.code_to_str[self.matrix[3]],self.code_to_str[self.matrix[4]],self.code_to_str[self.matrix[5]],"|")
    print("|",self.code_to_str[self.matrix[6]],self.code_to_str[self.matrix[7]],self.code_to_str[self.matrix[8]],"|")
    print("---------")
    time.sleep(self.DELAY)

사용 방법을 알아보겠습니다.

1) 초기화, state = reset()

env = TICTACTOE()

state = env.reset()

환경 객체를 생성하고 reset()함수를 통해 게임을 초기상태로 만들고 그때의 상태를 반환합니다.

2) 행동하기, next_state, reward, active, done = step(1, 2, show=False)

next_state, reward, active, done = env.step(1, 2) # 1번 팀으로 2번 위치에 놓음

step()으로 행동을 한 스텝 할 수 있는데요, 틱택토에서 행동은 바로 돌을 놓는 것입니다. 여기서 중요한 점은 두개의 팀이 있다는 것인데요, step()함수의 첫번째 매개변수로 팀(1, 2)를 넣어줍니다. 그 다음으로 0~8까지 위치를 입력합니다.

반환값으로는 다음상태값, 보상, 그리고 유효값, 게임 완료여부를 반환합니다. 다음상태값은 돌을 놓고 난 후의 상태값이며, 해당 돌을 놓으므로써 얻는 보상, 유효값은 해당 행동이 유효했는지(이때 유효함이라 함은 실제로 돌을 놓는 행동을 했는지에 대한 여부입니다. 이미 돌이 놓여있는 곳에 놓음으로써 패널티를 받고 실제로 놓지 않았을 때는 해당 안됨), 그리고 게임 완료여부(1줄이 완성되었거나 9칸이 모두 꽉 찼을 때 게임이 완료됨)를 반환합니다.

위의 반환값 정보들로 학습에 활용할 수 있습니다.

추가적으로 step()의 세번째 인수로 프롬프트에 출력할 여부를 정할 수 있습니다.

간단하게 사용법에 대해서 알아보았습니다.

강화학습 틱택토



Search