코딩도장

tic-tac-toe game

아마존 본사 입사 문제였습니다.

tic-tac-toe는 두 명의 플레이어가 턴을 돌아가면서 1부터 9까지 포지션을 선택하는 게임 입니다. 선택된 포지션은 X나 0로 표시가 되며, 선택된 포지션은 다시 선택할 수가 없습니다. 게임 그리드는 3*3으로 다음과 같습니다.


 * * 
 1 * 2 * 3 
 * * 
 * * 
 4 * 5 * 6 
 * * 
 * * 
 7 * 8 * 9 
 * *

가로 세로 대각선으로 먼저 세 줄을 연속으로 만드는 플레이어가 우승하게 되며 무승부인 경우도 생깁니다. (매 턴마다 포지션을 입력해야 하지만, 출력은 게임이 끝이 났을 때만 하셔도 됩니다)

입력의 예:


Player 1 - please type a position (available position(s) are 1,2,3,4,5,6,7,8,9):


출력의 예:


 * * 
 X * X * 0 
 * * 
 * * 
 X * 0 * 6 
 * * 
 * * 
 X * 8 * 9 
 * *

Win playear is: player 1


sort
(追記) (追記ここまで)
댓글 작성은 로그인이 필요합니다.
이거 빙고게임이라고 생각하면 되나요? - 김 한길, 2014年12月05日 22:58 M D
네 ᄒ 3*3 빙고게임이라고 생각하시면 됩니다. - Straß Böhm Jäger, 2015年05月15日 08:06 M D
(注記) 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

37개의 풀이가 있습니다. 2 / 4 Page

pinkey = 0
board = [['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9']]
def keyreplacer(strnum, pl):
 for x in board:
 for xx in range(0, len(x)):
 if x[xx] == strnum and pl == 1:
 x[xx] = 'X'
 elif x[xx] == strnum and pl == 2:
 x[xx] = 'O'
def winident():
 for v in board:
 if v == ['X', 'X', 'X']:
 print("Player 1 won!")
 return 1
 break
 elif v == ['O', 'O', 'O']:
 print("Player 2 won!")
 return 1
 break
 elif board[1][1] == 'X':
 if (board[0][0] == 'X' and board[2][2] == 'X') or (board[0][2] == 'X' and board[2][0] == 'X'):
 print("Player 1 won!")
 return 1
 break
 elif board[1][1] == 'O':
 if (board[0][0] == 'O' and board[2][2] == 'O') or (board[0][2] == 'O' and board[2][0] == 'O'):
 print("Player 2 won!")
 return 1
 break
 else:
 return 0
 break
def showboard():
 print(" * * ")
 print(" ", board[0][0], " *", " ", board[0][1], " * ", " ", board[0][2], " ", sep = "")
 print(" * * ")
 print(" * * ")
 print(" ", board[1][0], " *", " ", board[1][1], " * ", " ", board[1][2], " ", sep = "")
 print(" * * ")
 print(" * * ")
 print(" ", board[2][0], " *", " ", board[2][1], " * ", " ", board[2][2], " ", sep = "")
 print(" * * ") 
print("Let\'s play a tix-tac-toe game!\neach turn, each player can choose a number between 1 and 9.\n")
for i in range(0, 9):
 if i%3 != 1:
 print(" * * ")
 else:
 print(" ", i, " *", " ", i+1, " * ", " ", i+2, " ", sep = "")
i = 0
while(pinkey == 0):
 display = []
 for lv1 in board:
 if type(lv1) is not list and lv1 != 'X' and lv1 != 'O':
 display.append(lv1)
 elif type(lv1) is list:
 for lv2 in lv1:
 if lv2 != 'X' and lv2 != 'O':
 display.append(lv2)
 print("Current available position(s) is(are): ", ", ".join(display))
 pl1insert = input("Player 1 - please type a position: ")
 keyreplacer(pl1insert, 1)
 if winident() == 1:
 showboard()
 pinkey = 1
 break
 display = []
 for lv1 in board:
 if type(lv1) is not list and lv1 != 'X' and lv1 != 'O':
 display.append(lv1)
 elif type(lv1) is list:
 for lv2 in lv1:
 if lv2 != 'X' and lv2 != 'O':
 display.append(lv2)
 print("Current available position(s) is(are): ", ", ".join(display))
 pl2insert = input("Player 2 - please type a position: ")
 keyreplacer(pl2insert, 2)
 if winident() == 1:
 showboard()
 pinkey = 1
 break

3x3 틱택토로 구성되어 있고, 플레이어 1이 찍은 자리는 'X', 플레이어 2가 찍은 자리는 'O'로 표기하도록 하였습니다.

2015年10月13日 20:05

박재우

댓글 작성은 로그인이 필요합니다.
(注記) 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
import sys
def display(ttt):
 s=' '
 empty_line = s*5+'*'+s*9+'*'
 for i in range(3):
 print empty_line
 print ttt[i*3+1]+s*4+'*'+s*4+ttt[i*3+2]+s*4+'*'+s*4+ttt[i*3+3]
 print empty_line
ttt=map(str,range(10)) #tic tac toe plate
display(ttt)
while True:
 for player,mark in [('Player 1','O'),('Player 2','X')]:
 available = [int(e) for e in ttt if e.isdigit() and e!='0']
 if not available :
 print 'Tie game'
 sys.exit()
 print player, '- please type a position(available position(s)are ',available,'):',
 i = input()
 while not i in available :
 print "wrong selection. type again : ",
 i = input()
 ttt[i] = mark
 display(ttt)
 marks = set([])
 for i in range(1,10):
 if ttt[i]==mark: marks.add(i)
 for s in [{1,2,3},{4,5,6},{7,8,9},{1,4,7},{2,5,8},{3,6,9},{1,5,9},{7,5,3}]:
 if s<=marks :
 print 'winning player is',player
 sys.exit()

2016年01月29日 17:08

상파

댓글 작성은 로그인이 필요합니다.
(注記) 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

Ruby

made = ->u { %w(123 456 789 147 258 369 159 357).any? {|e| (e.chars&u)[2] } }
prt = ->w,m { puts "[Winner: #{w}]", m.each_slice(3).map {|row| row*" " } }
play = ->p1=[],p2=[],map=[*1..9],n=gets.chop do
 map[n.to_i-1] = (p1|p2).size.odd? ? (p2<<n; "X") : (p1<<n; "O")
 winner = made[p1]? "P1" : made[p2]? "P2" : ("None" if (p1+p2)[8])
 winner ? prt[winner,map] : play[p1,p2,map]
end

Test

expect_p1_win = "[Winner: P1]\n" +
 "O 2 3\n" +
 "X O 6\n" +
 "7 X O\n"
expect_p2_win = "[Winner: P2]\n" +
 "O O X\n" +
 "4 X X\n" +
 "X O O\n"
expect_draw = "[Winner: None]\n" +
 "X O O\n" +
 "O O X\n" +
 "X X O\n"
test_data = ->p1,p2 { StringIO.new(p1.zip(p2).flatten*"\n") } # for stdin
# case : P1 Win
$stdin = test_data[[9,5,1], [4,8]]
expect{ play[] }.to output( expect_p1_win ).to_stdout
# case : P2 Win
$stdin = test_data[[1,2,9,8,4], [3,6,7,5]]
expect{ play[] }.to output( expect_p2_win ).to_stdout
# case : draw
$stdin = test_data[[4,5,9,2,3], [8,7,6,1]]
expect{ play[] }.to output( expect_draw ).to_stdout
댓글 작성은 로그인이 필요합니다.
(注記) 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

승패판정을 정규식검사로 처리해봤습니다.

import re
win1 = """OOO...... ...OOO... ......OOO O..O..O.. .O..O..O. ..O..O..O O...O...O ..O.O.O..""".split()
win2 = """XXX...... ...XXX... ......XXX X..X..X.. .X..X..X. ..X..X..X X...X...X ..X.X.X..""".split()
def print_grid(data):
 print(('\n' + '-' * 9 + '\n').join(
 ' | '.join(data[x*3 + y] for y in range(3)) for x in range(3)))
def game():
 data = "123456789"
 winner = 0
 user, i = 'OX', 0
 for _ in range(9):
 availables = ', '.join([x for x in data if x not in 'OX'])
 x = 0
 while True:
 print_grid(data)
 x = int(input(
 "Player {} - please type a position (avaiable pos are {})"\
 .format(i + 1, availables)))
 if not (0 < x < 10) or data[x-1] in 'OX':
 print('invalid position')
 else:
 break
 data = data[:x-1] + user[i] + data[x:]
 i = (i + 1) % 2
 if any([True if re.match(x, data) else False for x in win1]):
 winner = 1
 elif any([True if re.match(x, data) else False for x in win2]):
 winner = 2
 if winner != 0:
 break
 else:
 print('No Winner')
 return
 print_grid(data)
 print('Win player is: player %d' % winner)
game()

2016年04月22日 14:25

룰루랄라

댓글 작성은 로그인이 필요합니다.
(注記) 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

C#으로 작성했습니다.

 public static void GenerateTicTacToe(string[,] board)
 {
 var complete = false;
 var turn = true;
 while (!complete)
 {
 var n = int.Parse(Console.ReadLine().ToString()) - 1;
 var row = n / 3;
 var column = n % 3;
 if (board[row, column] == null) board[row, column] = turn ? "O" : "X";
 else Console.WriteLine("Error Occured");
 complete = CheckBoard(board, row, column, turn ? "O" : "X");
 if (!complete) turn = !turn;
 }
 }
 public static bool CheckBoard(string[,] board, int x, int y, string mark)
 {
 var rowCount = 0;
 var columnCount = 0;
 for (int i = 0; i < 3; i++)
 {
 if (board[x, i] == mark) rowCount++;
 if (board[i, y] == mark) columnCount++;
 }
 if (rowCount == 3 || columnCount == 3) return true;
 if (board[1, 1] == mark)
 {
 if (board[0, 0] == mark && board[2, 2] == mark) return true;
 if (board[2, 0] == mark && board[0, 2] == mark) return true;
 }
 return false;
 }
댓글 작성은 로그인이 필요합니다.
(注記) 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
from itertools import cycle
nums = ''.join(str(x) for x in range(1,10))
pw = lambda : print('Wrong input')
av_pos = lambda res : 'available pos: '+ ', '.join(x for x in res if x not in ('A', 'B')) +'\n'
inpt = lambda fr, res: int(input(av_pos(res) + fr + ' : '))-1
check = lambda b: any(True if x == b&x else False for x in (448, 56, 7, 292, 146, 73, 273, 84))
output = lambda res: print(''.join(x+'\n' if i%3 == 2 else x for i, x in enumerate(res)))
main_code = list(compile('''while 1:\n {0} = inpt('{0}', res); n = 1 << {0}\n if (1 << {0}) & game == 1: pw(); continue\n else: break\ngame += n; {1} += n; res = res[:{0}] + '{0}' + res[{0}+1:]'''.format(T, T.lower()), '<string>', 'exec') for T in 'AB')
check_code = list(compile('check({})'.format(T.lower()), '<string>', 'eval') for T in 'AB')
while __name__ == '__main__':
 game = 2**9; draw = game-1
 res = nums
 a, b = 0, 0
 for i in cycle((0, 1)):
 exec(main_code[i])
 if eval(check_code[i]): break
 if a + b == draw: print('draw'); break
 output(res)
 output(res)

이진수로 풀어보았습니다. 반복되는 코드를 없애다 보니 문자열이 난무하네요. 파이썬 3.5.1

+

itertools.cycle:해당 반복가능한 객체를 반복.

댓글 작성은 로그인이 필요합니다.
(注記) 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
public void TicTacToe()
 {
 char[,] Board = { { '1', '2', '3' }, { '4', '5', '6' }, { '7', '8', '9' } };
 Console.WriteLine("[Player1]이 선택한 위치는 O로, [Player2]가 선택한 위치는 X로 표시됩니다.\n");
 int Player1WinCnt = 0;
 int Player2WinCnt = 0;
 for (int i = 0; i < 9; i++)
 {
 if (i % 2 == 0)
 {
 input1:
 Console.Write("[Player1]위치를 선택하십시요(이미 선택된 위치를 선택하여선 안됩니다) : ");
 int position = Convert.ToInt32(Console.ReadLine());
 if (position > 9 || position < 1)
 {
 Console.WriteLine("{0}에 해당하는 위치가 없습니다.", position);
 goto input1;
 }
 for (int k = 0; k < 3; k++)
 {
 for (int j = 0; j < 3; j++)
 {
 if ((int)(Board[k, j] - '0') == position)
 {
 Board[k, j] = 'O';
 }
 }
 }
 for (int k = 0; k < 3; k++)
 {
 for (int j = 0; j < 3; j++)
 {
 Console.Write("{0} ", Board[k, j]);
 }
 Console.WriteLine("\n");
 }
 }
 if ((Board[0, 0] == 'O' && Board[0, 1] == 'O' && Board[0, 2] == 'O') ||
 (Board[1, 0] == 'O' && Board[1, 1] == 'O' && Board[1, 2] == 'O') ||
 (Board[2, 0] == 'O' && Board[2, 1] == 'O' && Board[2, 2] == 'O') ||
 (Board[0, 0] == 'O' && Board[1, 0] == 'O' && Board[2, 0] == 'O') ||
 (Board[0, 1] == 'O' && Board[1, 1] == 'O' && Board[2, 1] == 'O') ||
 (Board[0, 2] == 'O' && Board[1, 2] == 'O' && Board[2, 2] == 'O') ||
 (Board[0, 0] == 'O' && Board[1, 1] == 'O' && Board[2, 2] == 'O') ||
 (Board[0, 2] == 'O' && Board[1, 1] == 'O' && Board[2, 0] == 'O'))
 {
 Console.WriteLine("[Player1]이 승리하였습니다!");
 Player1WinCnt++;
 break;
 }
 if (i % 2 == 1)
 {
 input2:
 Console.Write("[Player2]위치를 선택하십시요(이미 선택된 위치를 선택하여선 안됩니다) : ");
 int position = Convert.ToInt32(Console.ReadLine());
 if (position > 9 || position < 1)
 {
 Console.WriteLine("{0}에 해당하는 위치가 없습니다.", position);
 goto input2;
 }
 for (int k = 0; k < 3; k++)
 {
 for (int j = 0; j < 3; j++)
 {
 if ((int)(Board[k, j] - '0') == position)
 {
 Board[k, j] = 'X';
 }
 }
 }
 for (int k = 0; k < 3; k++)
 {
 for (int j = 0; j < 3; j++)
 {
 Console.Write("{0} ", Board[k, j]);
 }
 Console.WriteLine("\n");
 }
 }
 if ((Board[0, 0] == 'X' && Board[0, 1] == 'X' && Board[0, 2] == 'X') ||
 (Board[1, 0] == 'X' && Board[1, 1] == 'X' && Board[1, 2] == 'X') ||
 (Board[2, 0] == 'X' && Board[2, 1] == 'X' && Board[2, 2] == 'X') ||
 (Board[0, 0] == 'X' && Board[1, 0] == 'X' && Board[2, 0] == 'X') ||
 (Board[0, 1] == 'X' && Board[1, 1] == 'X' && Board[2, 1] == 'X') ||
 (Board[0, 2] == 'X' && Board[1, 2] == 'X' && Board[2, 2] == 'X') ||
 (Board[0, 0] == 'X' && Board[1, 1] == 'X' && Board[2, 2] == 'X') ||
 (Board[0, 2] == 'X' && Board[1, 1] == 'X' && Board[2, 0] == 'X'))
 {
 Console.WriteLine("[Player2]이 승리하였습니다!");
 Player2WinCnt++;
 break;
 }
 }
 if (Player1WinCnt < 1 && Player2WinCnt < 1)
 {
 Console.WriteLine("무승부!");
 }
 }

예외처리는 입력이 1~9를 벗어날 경우 잡아주었고, 그외의 예외(중복 선택이라던가..등등..)는 무시했습니다.

2016年09月23日 23:49

이규민

댓글 작성은 로그인이 필요합니다.
(注記) 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
#include <iostream> 
using namespace std;
char sBoard[3][3];
char fBoard[9] = { 1,2,3,4,5,6,7,8,9 };
char* player[2] = { "Player1","Player2" };
bool curPlayer = false;
bool isWin = false;
void Render();
void CheckBoard(int idx);
bool InspectBoard(int _x, int _y);
int main()
{
 Render();
 while (true)
 {
 cout << player[(int)curPlayer] << " 숫자 입력(1~9) : ";
 int input = 0;
 scanf_s("%d", &input);
 CheckBoard(input - 1);
 if(isWin) return 0;
 }
 return 0;
}
void Render()
{
 system("cls");
 for (int i = 0; i < 3; i++)
 {
 for (int j = 0; j < 3; j++)
 {
 sBoard[i][j] = fBoard[i * 3 + j];
 if (sBoard[i][j] == 'O' || sBoard[i][j] == 'X')
 printf_s("|%c", sBoard[i][j]);
 else
 printf_s("|%d", sBoard[i][j]);
 }
 cout << "|" << endl;
 }
}
void CheckBoard(int idx)
{
 if (idx > 8 || idx < 0 || fBoard[idx] == 'O' || fBoard[idx] == 'X')
 {
 cout << "다시입력하세요 : ";
 int input = 0;
 scanf_s("%d", &input);
 return CheckBoard(input - 1);
 }
 int x, y;
 x = idx / 3;
 y = idx % 3;
 fBoard[idx] = curPlayer ? 'O' : 'X';
 Render();
 if ((isWin = InspectBoard(x, y)))
 {
 cout << player[(int)curPlayer] << " 승리." << endl;
 }
 curPlayer = !curPlayer;
}
bool InspectBoard(int _x, int _y)
{
 int x = _x, y = _y;
 bool rev = false;
 char temp = sBoard[x][y];
 for (int i = 0; i < 2; i++)
 {
 for (int j = 0; j < 3; j++)
 {
 if (i == 0 ? (y + j >= 2) : (x + j >= 2))rev = true;
 if (temp != sBoard[i == 0 ? x : x + (rev ? -j : +j)][i == 0 ? y + (rev ? -j : +j) : y])break;
 if (j == 2) return true;
 }
 rev = false;
 for (int j = 0; j < 3; j++)
 {
 if (i==0?(y + j >= 2 && x + j >= 2):(x+j>=2&&y-j<0)) rev = true;
 if (temp != sBoard[x + (rev ? -j : +j)][i==0?(y + (rev ? -j : +j)): (y + (rev ? j : +j))])break;
 if (j == 2)return true;
 }
 rev = false;
 }
 return false;
}

2016年11月01日 10:30

이 재화

댓글 작성은 로그인이 필요합니다.
(注記) 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define size 3
bool turn; // true white O
 // false black X
void put(char board[size][size]);
int verdict(char board[size][size]);
void main() {
 turn = true;
 srand (time(NULL));
 char board[size][size] = {{'1' ,'2', '3'},{'4', '5', '6'},{'7', '8', '9'}};
 int count=0;
 int result=0;
 while(count<9) {
 result = verdict(board);
 if(result==1) {
 printf("white win!!\n");
 break;
 }
 else if(result==2) {
 printf("black win!!\n");
 break;
 }
 put(board);
 count++;
 }
 if(count == 9)
 printf("draw!!\n");
 for(int i=0;i<size; i++) {
 for(int j=0;j<size;j++) {
 printf("%c ", board[i][j]);
 }
 printf("\n");
 }
}
void put(char board[size][size]) {
 int input;
 scanf("%d", &input);
 for(int i=0;i<size; i++) 
 for(int j=0;j<size;j++) 
 if(board[i][j]==(input+48)) {
 if(turn) {
 board[i][j] = 'O';
 turn = false;
 }
 else {
 board[i][j] = 'X';
 turn = true;
 }
 }
}
int verdict(char board[size][size]) { // 1 whte, 2 black
 int black = 0;
 int white = 0;
 for(int i=0;i<size; i++) {
 black = 0;
 white = 0;
 for(int j=0;j<size;j++) {
 if(board[i][j]=='O')
 white++;
 if(board[i][j]=='X')
 black++;
 }
 if(black==3) return 2;
 if(white==3) return 1;
 black = 0;
 white = 0;
 for(int j=0;j<size;j++) {
 if(board[j][i]=='O')
 white++;
 if(board[j][i]=='X')
 black++;
 }
 if(black==3) return 2;
 if(white==3) return 1;
 }
 if((board[0][0] == 'O' && board[1][1] == 'O' && board[2][2] == 'O') || (board[3][1] == 'O' && board[1][1] == 'O' && board[1][3] == 'O'))
 return 1;
 if((board[0][0] == 'X' && board[1][1] == 'X' && board[2][2] == 'X') || (board[3][1] == 'X' && board[1][1] == 'O' && board[1][3] == 'X'))
 return 2;
 return 0;
}
댓글 작성은 로그인이 필요합니다.
(注記) 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
arr1_1 = [[['1','2','3'],['4','5','6'],['7','8','9']]
 , [['1','4','7'],['2','5','8'],['3','6','9']]
 , [['1','5','9'],['3','5','7'],['.','.','.']]]
def f1():
 result = ', '.join([', '.join([x1 for x1 in x if x1!='O' and x1!='X']) for x in arr1_1[0]])
 return result
def f2(nums, typ1):
 for i1 in range(0, len(arr1_1)):
 for i2 in range(0, len(arr1_1[i1])):
 if arr1_1[i1][i2].count(nums) > 0:
 arr1_1[i1][i2][arr1_1[i1][i2].index(nums)] = typ1
 print('\n'.join([' * '.join([x1 for x1 in x]) for x in arr1_1[0]]))
def f3(typ1, idx1):
 for i1 in range(0, len(arr1_1)):
 if arr1_1[i1].count([typ1 for x in range(0, 3)]) > 0:
 print('Win playear is: player ', idx1)
 return typ1
 return ''
def f():
 while f1()!='':
 for idx1, typ1 in enumerate(['X','O']):
 plys = ''
 str1 = f1()
 while True:
 plys = input('Player '+str(idx1+1)+' - please type a position (available position(s) are ' + str1 + '):')
 if str1.count(plys) > 0:
 break
 f2(plys, typ1)
 if f3(typ1, str(idx1+1)) != '':
 return False
 if f1() == '':
 print('End..')
 return True
f()
댓글 작성은 로그인이 필요합니다.
(注記) 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

풀이 작성

(注記) 풀이작성 안내
  • 본문에 코드를 삽입할 경우 에디터 우측 상단의 "코드삽입" 버튼을 이용 해 주세요.
  • 마크다운 문법으로 본문을 작성 해 주세요.
  • 풀이를 읽는 사람들을 위하여 풀이에 대한 설명도 부탁드려요. (아이디어나 사용한 알고리즘 또는 참고한 자료등)
  • 작성한 풀이는 다른 사람(빨간띠 이상)에 의해서 내용이 개선될 수 있습니다.
풀이 작성은 로그인이 필요합니다.
목록으로
코딩도장

코딩도장은 프로그래밍 문제풀이를 통해서 코딩 실력을 수련(Practice)하는 곳입니다.

sort x 2
연관 문제
Dasol Lee, 2025年02月25日 14:39

언어별 풀이 현황
전 체 x 37
python x 22
cpp x 3
java x 2
scala x 2
기 타 x 3
ruby x 1
cs x 3
haskell x 1
코딩도장 © 2014 · 문의 [email protected]
피드백 · 개인정보취급방침 · RSS

AltStyle によって変換されたページ (->オリジナル) /