아마존 본사 입사 문제였습니다.
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
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'로 표기하도록 하였습니다.
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()
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
2016年04月02日 03:32
승패판정을 정규식검사로 처리해봤습니다.
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()
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;
}
2016年06月02日 22:39
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:해당 반복가능한 객체를 반복.
2016年06月27日 22:10
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를 벗어날 경우 잡아주었고, 그외의 예외(중복 선택이라던가..등등..)는 무시했습니다.
#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;
}
#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;
}
2017年02月15日 16:19
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()
2017年09月01日 17:05
풀이 작성