아마존 본사 입사 문제였습니다.
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
C++입니다.
position 입력 메시지 출력시 빈칸 숫자들을 ","로 구분하여 나열하는 부분을 간과하면 안될 듯.
프로그램 설명:
"turn"이 9가 될 때까지 진행. 짝수 "turn"은 "O", 홀수 "turn"은 "X". "board[]"값은 Empty, O, X 중 하나.
Winning 조건 점검은, Clever한 방법을 고민하다가 포기하고 평범하게 갔습니다.
board[] index에 따른 보드판이 다음과 같다면:
0|1|2
3|4|5
6|7|8
Note : 현재 위치가 4가 아닌 경우, 현재 위치가 속한 한쪽 사선만 점검하면 되지만 조건식 추가로 코드가 복잡해지는거 같아서 그냥 두 사선 뱡향을 모두 점검합니다.
#include <iostream>
using namespace std;
typedef enum { Player_Empty, Player_O, Player_X } PlayerType;
static PlayerType board[9];
int getValidPosition(int turn)
{
int position;
int numEmpty = 10-turn;
do {
cout << "Player " << (turn%2 ? 1 : 2) << " - please type a position ";
cout << "(available position(s) are ";
for (int i=0, count=0; i<9; ++i)
{
if (board[i] == Player_Empty)
{
cout << i+1;
cout << (numEmpty != ++count ? "," : "):");
}
}
cin >> position;
if (position < 1 || 9 < position || board[position-1] != Player_Empty)
cout << "Invalid position. Try again.\n";
else
return position-1; // convert to array index
} while (true);
}
bool hasWon(PlayerType player, int ndx)
{
// check row
int base = (ndx/3)*3;
if (board[base + (ndx-base+0)%3] == player &&
board[base + (ndx-base+1)%3] == player &&
board[base + (ndx-base+2)%3] == player) return true;
// check column
if (board[(ndx+0*3)%9] == player &&
board[(ndx+1*3)%9] == player &&
board[(ndx+2*3)%9] == player) return true;
// check diagonals
if (ndx % 2 != 0)
return false; // indices 1,3,5,7 cannot make a diagonal win condition
if (board[0] == player &&
board[4] == player &&
board[8] == player) return true;
if (board[2] == player &&
board[4] == player &&
board[6] == player) return true;
return false;
}
bool printBoard()
{
for (int row=0; row<3; ++row)
{
cout << "|";
for (int col=0; col<3; ++col)
{
int ndx = row*3+col;
switch (board[ndx])
{
case Player_O: cout << "O"; break;
case Player_X: cout << "X"; break;
default: cout << ndx+1; break;
}
cout << "|";
}
cout << endl;
}
}
int main(void)
{
int turn = 0; // even = "O", odd = "X"
printBoard();
while (++turn < 10)
{
int position = getValidPosition(turn);
board[position] = (turn%2) ? Player_X : Player_O;
printBoard();
if (hasWon(board[position], position))
{
cout << ((board[position] == Player_X) ? "X" : "O") << " has won.\n";
return 0;
}
}
cout << "This game is a draw\n";
return 0;
}
2014年12月29日 10:27
#include <iostream>
using namespace std;
int main()
{
int pb[9] = {0};
int input = 0;
int turn = 0;
int end = 1;
int e;
while (end!=0)
{
e = 1;
int c=1;
if (turn == 1) turn = 2;
else turn=1;
while (e)
{
cout << "player" << turn << "- ";
cin >> input;
cin.get();
if (pb[input - 1]) continue;
e = 0;
if (turn == 1) pb[input - 1] = 1;
else pb[input - 1] = -1;
}
for (int i = 0; i < 3; i++) if ((pb[i] + pb[i + 1] + pb[i + 2]) == 3 || (pb[i] + pb[i + 1] + pb[i + 2]) == -3) end=0;
for (int i = 0; i < 3; i++) if ((pb[i] + pb[i + (1* 3)] + pb[i+(2 *3)]) == 3 || (pb[i] + pb[i+(1* 3)] + pb[i+(2 *3)] ==3 )) end = 0;
if ((pb[0] + pb[4] + pb[8]) == -3 || (pb[0] + pb[4] + pb[8])==3) end = 0;
if ((pb[2] + pb[4] + pb[6]) == -3 || (pb[2] + pb[4] + pb[6])==3) end = 0;
c++;
if (c == 9) break;
}
for (int i = 0; i < 9; i++)
{
if (i % 3 == 0) cout << endl;
if (pb[i] == 1) cout <<"O ";
else if (pb[i] == -1) cout << "X ";
else cout << i+1<<" ";
}
cout << endl <<"win players is " << turn<<endl;
cin.get();
cin.get();
return 0;
}
검토부탁드립니다. ps.중간에 입력에서 잘못된 값을 받는 경우는 생각하지 않았습니다.
2014年12月05日 23:45
#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;
}
풀이 작성