Tic Tac Toe(틱택토) 게임은 3*3 형태의 판에서 두 명이서 번갈아가며 같은 모양을 가로,세로,대각선 상에 놓는 게임으로, 먼저 완성한 사람이 이기는 게임입니다.
1. 초기 맵 만들기
딕셔너리(dictionary)를 사용하여 9개의 (키,값)을 만들어주고 모든 값은 공백으로 넣어줍니다.
{1:' ', 2:' ', 3:' ' ... 8:' ', 9:' '}
#초기맵 만들기
the_board = {}
for i in range(1,10):
the_board[i] = ' '
2. 맵 그리기
9칸으로 구분만 하면 됩니다.
(공백) | (공백) | (공백) |
------------------------------
(공백) | (공백) | (공백) |
------------------------------
(공백) | (공백) | (공백) |
------------------------------
#맵 그리기1
def print_board(board):
for k,v in board.items():
print(v, "| ", end="")
if k % 3 == 0:
print("\n" + "-" * 10)
(공백) | (공백) | (공백)
------------------------------
(공백) | (공백) | (공백)
------------------------------
(공백) | (공백) | (공백)
#맵 그리기2
def print_board(board):
for k,v in board.items():
if k % 3 == 0 and k != 9:
print("\n" + "-" * 10)
elif k == 9:
print()
else:
print(v, "| ", end="")
3. 게임종료 확인 함수
가로/세로/대각선이 같으면서 각 값이 공백이 아니면 게임을 종료합니다.
처음에 딕셔너리를 만들 때 각 값을 공백으로 설정해 놓았기 때문에 서로 같은 값이 공백인지 아닌지도 확인해주어야 합니다.
- 가로의 경우 range(1,8,3) => 1,4,7 기준으로 i, i+1, i+2 즉, 1,2,3 / 4,5,6 / 7,8,9 의 값이 같은지 확인합니다.
- 세로의 경우 range(1,4) => 1 2 3 기준으로 i, i+3, i+6 즉, 1,4,7 / 2,5,8 / 3,6,9 의 값이 같은지 확인합니다.
- 대각선의 경우 1,5,9 / 3,5,7의 값이 같은지 확인합니다.
- 공백은 가로/세로/대각선의 값이 같은지 확인한 후 첫 번째 값이 공백인지 확인하는 방식으로 구현하였습니다.
#게임종료 확인
#가로/세로/대각선이 같으면서 공백 X
def game_over(board):
#가로
for i in range(1,8,3):
if board[i] == board[i+1] == board[i+2]:
if board[i] != ' ':
print(f'승자는 {board[i]}입니다')
return True
#세로
for i in range(1,4):
if board[i] == board[i+3] == board[i+6]:
if board[i] != ' ':
print(f'승자는 {board[i]}입니다')
return True
#대각션
if board[1] == board[5] == board [9]:
if board[1] != ' ':
print(f'승자는 {board[1]}입니다')
return True
if board[3] == board[5] == board [7]:
if board[3] != ' ':
print(f'승자는 {board[3]}입니다')
return True
return False
4. 초기 설정
빈 맵을 먼저 출력해주고, 사용자 모양은 'O' / 컴퓨터는 'X'로 설정합니다. 초기 값은 사용자 먼저 시작하는 것으로 설정하였습니다. 그리고 컴퓨터가 랜덤으로 값을 넣어야 하기 때문에 1~9까지의 값을 담은 num_list도 만들어주었습니다. 컴퓨터는 num_list에 있는 값 중 랜덤으로 뽑아 모양('X')을 표시합니다.
#빈 맵 출력
print_board(the_board)
#O/X
turn = 'O'
#9번까지만 실행 가능해야하며 컴퓨터가 랜덤으로 값을 뽑기위한 리스트, 1~9까지 숫자 중 이미 사용된 숫자는 제거됨
num_list = [i for i in range(1,10)]
5. 반복문으로 게임 실행
O와 X 모양으로 나눠서 O는 사용자, X는 컴퓨터로 설정하고 구현하였습니다.
사용자 입력을 받는 경우
- try~except문으로 입력값이 숫자가 아니라면 다시 입력할 수 있도록 구현
- 정규식을 이용하여 숫자는 1~9 사이의 값이 입력되었는지 확인(re 모듈 사용)
- 사용자 입력값 자리가 공백인지 확인
컴퓨터 입력을 받는 경우
- num_list에 남아있는 값을 랜덤으로 선택하도록 구현(random 모듈 사용)
사용자/컴퓨터의 입력을 받으면 해당 칸에 O 또는 X 모양을 넣고, 이후에 컴퓨터가 입력할 수 없도록 num_list에서 해당 값을 제거하도록 구현하였습니다. 이어 순서를 바꾸고 게임 종료를 확인합니다. 종료가 되지 않았다면 다시 반복문을 실행합니다.
while True:
if turn == 'O': #사용자 입력을 받는 경우
while True:
try: #int로 묶어서 문자가 들어오면 무조건 오류발생. 때문에 예외처리함
print('어느 위치에 표시하시겠습니까? > ')
space = int(input())
break
except:
print("숫자를 입력해주세요.")
#정규식 사용((1~9)사이의 숫자인지 확인), 입력된 위치가 비어있는지 확인
if not re.match('^[1-9]{1}$', str(space)):
print('(1~9) 숫자 중 입력해주세요.')
continue
if not the_board[space] == ' ':
print('그 자리는 표시할 수 없습니다.')
continue
else: #랜덤으로 입력을 받는 경우, 남아있는 숫자 중 랜덤으로 선택
print("컴퓨터의 랜덤 입력입니다.")
space = random.choice(num_list)
#맵에 체크표시 남기고, 해당 위치 값을 num_list에서 지우기
the_board[space] = turn
num_list.remove(space)
#맵 그리기
print_board(the_board)
#순서 바꾸기
if turn == 'O':
turn = 'X'
else:
turn = 'O'
#게임종료 확인하기
if game_over(the_board) == True:
print('게임이 종료되었습니다.')
break
else:
if len(num_list) == 0:
print('무승부 입니다.')
print('게임이 종료되었습니다.')
break
6. 전체 코드
#틱택토(Tic Tac Toe)
import re, random
#초기맵 만들기
the_board = {}
for i in range(1,10):
the_board[i] = ' '
#맵 그리기
def print_board(board):
for k,v in board.items():
print(v, "| ", end="")
if k % 3 == 0:
print("\n" + "-" * 10)
# #맵 그리기2
# def print_board(board):
# for k,v in board.items():
# if k % 3 == 0 and k != 9:
# print("\n" + "-" * 10)
# elif k == 9:
# print()
# else:
# print(v, "| ", end="")
#게임종료 확인
#가로/세로/대각선이 같으면서 공백 X
def game_over(board):
#가로
for i in range(1,8,3):
if board[i] == board[i+1] == board[i+2]:
if board[i] != ' ':
print(f'승자는 {board[i]}입니다')
return True
#세로
for i in range(1,4):
if board[i] == board[i+3] == board[i+6]:
if board[i] != ' ':
print(f'승자는 {board[i]}입니다')
return True
#대각션
if board[1] == board[5] == board [9]:
if board[1] != ' ':
print(f'승자는 {board[1]}입니다')
return True
if board[3] == board[5] == board [7]:
if board[3] != ' ':
print(f'승자는 {board[3]}입니다')
return True
return False
#빈 맵 출력
print_board(the_board)
#O/X
turn = 'O'
#9번까지만 실행 가능해야하며 컴퓨터가 랜덤으로 값을 뽑기위한 리스트, 1~9까지 숫자 중 이미 사용된 숫자는 제거됨
num_list = [i for i in range(1,10)]
while True:
if turn == 'O': #사용자 입력을 받는 경우
while True:
try: #int로 묶어서 문자가 들어오면 무조건 오류발생. 때문에 예외처리함
print('어느 위치에 표시하시겠습니까? > ')
space = int(input())
break
except:
print("숫자를 입력해주세요.")
#정규식 사용((1~9)사이의 숫자인지 확인), 입력된 위치가 비어있는지 확인
if not re.match('^[1-9]{1}$', str(space)):
print('(1~9) 숫자 중 입력해주세요.')
continue
if not the_board[space] == ' ':
print('그 자리는 표시할 수 없습니다.')
continue
else: #랜덤으로 입력을 받는 경우, 남아있는 숫자 중 랜덤으로 선택
print("컴퓨터의 랜덤 입력입니다.")
space = random.choice(num_list)
#맵에 체크표시 남기고, 해당 위치 값을 num_list에서 지우기
the_board[space] = turn
num_list.remove(space)
#맵 그리기
print_board(the_board)
#순서 바꾸기
if turn == 'O':
turn = 'X'
else:
turn = 'O'
#게임종료 확인하기
if game_over(the_board) == True:
print('게임이 종료되었습니다.')
break
else:
if len(num_list) == 0:
print('무승부 입니다.')
print('게임이 종료되었습니다.')
break