Silinu's AI Study

[AI 오목] 2.1 오목 프로그램 만들기 본문

Project/AI Gomoku

[AI 오목] 2.1 오목 프로그램 만들기

Silinu 2023. 11. 12. 15:28

환경 : Window, Python 3.9, Jupyter notebook(Anaconda 설치된 상태), GPU 환경

 

오목 룰 중에서 다른 룰은 다음 글에 작성하기로 하고, 이 글에서는 5개가 연속으로 나란히 있을 때 승리인 조건으로 한다.

 

코드는 다음과 같다.

import sys
import pygame 
import numpy as np

 

아래 함수는 어느 플레이어가 이겼는지, 이기지 않았는지 확인하는 함수이다. 각각 가로, 세로, 대각선으로 나눠 확인한다.

def check_win(board):
    player_1 = np.array([1,1,1,1,1])
    player_2 = np.array([2,2,2,2,2])
    winner = 0
    # 가로(-)
    for i in range(board.shape[0]):
        for j in range(board.shape[1]-5+1):
            if sum(board[i,j:j+5]==player_1)==5:
                winner = 1
                return winner
            if sum(board[i,j:j+5]==player_2)==5:
                winner = 2
                return winner
    # 세로(I)
    for i in range(board.shape[0]-5+1):
        for j in range(board.shape[1]):
            if sum(board[i:i+5,j]==player_1)==5:
                winner = 1
                return winner
            if sum(board[i:i+5,j]==player_2)==5:
                winner = 2
                return winner
    # 대각선(×)
    for i in range(board.shape[0]-5+1):
        for j in range(board.shape[1]-5+1):
            diagonal = np.diagonal(board[i:i+5,j:j+5])
            diagonal2 = np.fliplr(board[i:i+5,j:j+5]).diagonal()
            if sum(diagonal==player_1)==5 or sum(diagonal2==player_1)==5:
                winner = 1
                return winner
            if sum(diagonal==player_2)==5 or sum(diagonal2==player_2)==5:
                winner = 2
                return winner
    return winner

 

아래 코드를 실행하여 게임을 진행한다. 우측 상단에 현재 차례가 흑돌 플레이어인지, 백돌 플레이어인지 나타낸다. 경기가 다 끝나고 이긴 플레이어는 좌측 상단에 표시된다. 여기서 폰트는 나눔스퀘어라운드extrabold 체를 사용한다.

pygame.init()
# 색(RGB) 설정
BACKGROUND = (242,176,109)
BLACK = (0,0,0)
WHITE = (255,255,255)

font = pygame.font.SysFont("나눔스퀘어라운드extrabold",20)
# 크기(width, height) 설정
width = 600
height = 600
size = [width,height]
screen = pygame.display.set_mode(size)

clock= pygame.time.Clock()

# Background 색, 선, 사각형 채우기
screen.fill(BACKGROUND)
for i in range(int(width/20),width-1,int(width/20)):
    pygame.draw.line(screen, BLACK, [int(width/20), i], [width-int(width/20),i], 2)
for i in range(int(height/20),height-1,int(height/20)):
    pygame.draw.line(screen, BLACK, [i, int(height/20)], [i,height-int(height/20)], 2)
for i in range(int(width/20)*4-3,width-1,int(width/20)*6):
    for j in range(int(height/20)*4-3,height-1,int(height/20)*6):
        pygame.draw.rect(screen,BLACK,[i, j, 8, 8],4)
text = font.render("Your Turn : ",True, BLACK)
screen.blit(text,(440,8))
pygame.display.update()
# 판(흑돌 = 1, 백돌 = 2)
board = np.array([[0 for i in range(20)] for j in range(20)])
# 실행하기
done= False

color = {1:BLACK,2:WHITE}
player_num = 1
pygame.draw.circle(screen,color[player_num],[558, 18],8,8)
pygame.display.update()
while not done:
    clock.tick(10)
    for event in pygame.event.get():
        if event.type == pygame.MOUSEBUTTONDOWN:
            # (Left, Middle ,Right)로 구성됨, 눌리면 1, 안눌리면 0
            mouse_get = pygame.mouse.get_pressed()
            if mouse_get[0]==True:
                mouse_x, mouse_y = pygame.mouse.get_pos()
                x, y = int(np.round(mouse_x/width*20)),int(np.round(mouse_y/height*20))
                print(x,y)
                if x==0 or y==0:
                    continue
                elif x==20 or y==20:
                    continue
                elif board[x, y]!=0:
                    continue
                else:
                    board[x, y] = player_num
                    pygame.draw.circle(screen,color[player_num],[x*30, y*30],15,15)
                    winner = check_win(board)
                    if winner!=0:
                        win_text = font.render("Winner : ",True, BLACK)
                        screen.blit(win_text,(20,8))
                        pygame.draw.circle(screen,color[winner],[118, 18],8,8)
                        pygame.display.update()
                        done = True
                    else:
                        player_num = 2 if player_num==1 else 1
                        pygame.draw.circle(screen,color[player_num],[558, 18],8,8)
                        pygame.display.update()
        if event.type==pygame.QUIT:
            pygame.quit()
            done = True

 

게임이 다 진행된 후에도 ×를 눌러 화면을 끌 수 있도록 마지막 코드를 추가한다.

end = False
while not end:
    clock.tick(10)
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            pygame.quit()
            end=True

 

 

+ 번외 

현재 사용할 수 있는 폰트는 다음과 같이 작성하여 나타낼 수 있다. 이 중에서 하나 골라서 사용하면 된다.

print(pygame.font.get_fonts())