2012-07-07 2 views
0

저는 C++에서 간단한 TAC TAC Toe 게임을 제작하고 있지만 컴퓨터가 돌아 왔을 때 벡터 구독 오류가 발생합니다. 이 오류에 대한 이유를 찾을 수 없습니다. 긴 코드C에서 벡터 구독 오류

//Tic-Tac-Toe 
//Plays the game of Tic-Tac-Toe with a human opponent 

#include <iostream> 
#include <string> 
#include <vector> 
#include <algorithm> 

using namespace std; 

//global constants 
const char X = 'X'; 
const char O = 'O'; 
const char EMPTY = ' '; 
const char TIE = 'T'; 
const char NO_ONE = 'N'; 

//function prototypes 
void instructions(); 
char asYesNo(string question); 
int askNumber(string question, int high, int low = 0); 
char humanPiece(); 
char opponent(char piece); 
void displayBoard(const vector<char>& board); 
char winner(const vector<char>& board); 
bool isLegal(const vector<char>& board, int move); 
int humanMove(const vector<char>& board, char human); 
int computerMove(vector<char> board, char computer); 
void announceWinner(char winner, char computer, char human); 


//main function 
int main() 
{ 
    int move; 
const int NUM_SQUARES = 9; 
vector<char> board(NUM_SQUARES, EMPTY); 

instructions(); 
char human = humanPiece(); 
char computer = opponent(human); 
char turn = X; 
displayBoard(board); 

while (winner(board) == NO_ONE) 
{ 
    if (turn == human) 
    { 
     move = humanMove(board, human); 
     board[move] = human; 
    } 
    else 
    { 
     move = computerMove(board, computer); 
     board[move] = computer; 
    } 
    displayBoard(board); 
    turn = opponent(turn); 
} 

announceWinner(winner(board), computer, human); 

return 0; 
} 

//displays instructions 
void instructions() 
{ 
cout << "Welcome to the ultimate man-machine showdown: Tic-Tac-Toe.\n"; 
cout << "--where human brain is pit against silicon processor\n\n"; 

cout << "Make your move known by entering a number, 0 - 8. The number\n"; 
cout << "corresponds to the desired board position, as illustrated:\n\n"; 

cout << " 0 | 1 | 2\n"; 
cout << " ---------- \n"; 
cout << " 3 | 4 | 5\n"; 
cout << " ---------- \n"; 
cout << " 6 | 7 | 8\n\n"; 

cout << "Prepare yourself, human. The battle is about to begin.\n\n"; 
} 

//asks 'yes' or 'no' until it gets an answer either equel to 'y' or 'n' 
char askYesNo(string question) 
{ 
char response; 
do 
{ 
    cout << question << "(y/n): "; 
    cin >> response; 
}while (response != 'y' && response != 'n'); 

return response; 
} 

//asks a number within a range ans keeps asking untill the number is within that range, next it return that number within the specific range 
int askNumber(string question, int high, int low) 
{ 
int number; 
do 
{ 
    cout <<question << " (" <<low <<" - " <<high <<"): "; 
    cin >> number; 
}while (number > high || number < low); 

return number; 
} 

//asks who will go first, X always starts cuz of tradition 
char humanPiece() 
{ 
char go_first = askYesNo("Do you require the first move?"); 
if (go_first == 'y') 
{ 
    cout <<"\nThen take the first move, you will need it!\n"; 
    return X; 
} 
else 
{ 
    cout <<"\nYour bravery will be your undoing...I will go first.\n"; 
    return O; 
} 
} 

//cuz X always starts we need to decide who will be X 
char opponent(char piece) 
{ 
if (piece == X) 
{ 
    return O; 
} 
else 
{ 
    return X; 
} 
} 

//Displays the board 
void displayBoard(const vector<char>& board) 
{ 
cout <<"\n\t" <<board[0] << " | " <<board[1] << " | "<<board[2]; 
cout <<"\n\t" <<"---------"; 
cout <<"\n\t" <<board[3] << " | " <<board[4] << " | "<<board[5]; 
cout <<"\n\t" <<"---------"; 
cout <<"\n\t" <<board[6] << " | " <<board[7] << " | "<<board[8]; 
cout <<"\n\t" <<"---------"; 
cout <<"\n\n"; 
} 

//checks every possible way for someone to win, if there is no winner it checks for a tie 
char winner(const vector<char>& board) 
{ 
//all possible winning rows 
const int WINNING_ROWS[8][3] = {{0, 1, 2}, 
           {3, 4, 5}, 
           {6, 7, 8}, 
           {0, 3, 6}, 
           {1, 4, 7}, 
           {2, 5, 8}, 
           {0, 4, 8}, 
           {2, 4, 6}}; 
const int TOTAL_ROWS = 8; 

//if any winning row has three values that are the same (and not EMPTY), 
//then we have a winner 
for (int row = 0; row < TOTAL_ROWS; ++row) 
{ 
    if ((board[WINNING_ROWS[row][0]] != EMPTY) && 
     (board[WINNING_ROWS[row][0]] == board[WINNING_ROWS[row][1]]) && 
     (board[WINNING_ROWS[row][1]] == board[WINNING_ROWS[row][2]])) 
    { 
     return board[WINNING_ROWS[row][0]]; 
    } 
} 

// since nobody has won, check for a tie (no EMPTY squares left) 
if (count (board.begin(), board.end(), EMPTY) == 0) 
    return TIE; 
// since nobody has won an it isn't a tie, the game ain't over 
return NO_ONE; 
} 

//checks if the move is legal 
inline bool isLegal(int move , const vector<char>& board) 
{ 
return (board[move] == EMPTY); 
} 

//asks the human to typ his move and checks if it legal 
int humanMove(const vector<char>& board, char human) 
{ 
int move = askNumber("Where will you move?", (board.size() -1)); 
while (!isLegal(move, board)) 
{ 
    cout <<"\nThat square is already occupied, foolish human.\n"; 
    move = askNumber("Where will you move?", (board.size() -1)); 
} 
cout <<"Fine...\n"; 

return move; 
} 

//calculate's the computers move 
int computerMove(vector<char> board, char computer) 
{ 
//three good steps to win: 
// 
//1. if the computer can win, make that winning move 
//2. if the human can win, block that son of a b*tch 
//3. otherwise take the middle, if not possible the corners and so on 

unsigned int move = O; 
bool found = false; 

//if the computer can win, make that winning move 
while (!found && move < board.size()) 
{ 
    if (isLegal (move, board)) 
    { 
     board[move] = computer; 
     found = winner(board) == computer; 
     board[move] = EMPTY; 
    } 

    if (!found) 
    { 
     ++move; 
    } 
} 

//if the human can win, block that son of a b*tch 
if (!found) 
{ 
    move = O; 
    char human = opponent(computer); 

    while (!found && move < board.size()) 
    { 
     if (isLegal(move, board)) 
     { 
      board[move] = human; 
      found = winner(board) == human; 
      board[move] = EMPTY; 
     } 

     if (!found) 
     { 
      ++move; 
     } 
    } 
} 

//otherwise take the middle, if not possible the corners and so on 
if (!found) 
{ 
    move = O; 
    unsigned int i = O; 

    const int BEST_MOVES[] = {4, 0, 2, 6, 8, 1, 3, 5, 7}; 
    //pick best open square 
    while (!found && i < board.size()) 
    { 
     move = BEST_MOVES[i]; 
     if (isLegal(move, board)) 
     { 
      found = true; 
     } 

     ++i; 
    } 
} 

cout <<"I shall take a square number " <<move <<endl; 
return move; 
} 

//tells (epicly) who won the game 
void announceWinner(char winner, char computer, char human) 
{ 
if (winner == computer) 
{ 
    cout << winner <<"'s won!\n"; 
    cout << "As i predicted, human, I am triumphant once more -- proof\n"; 
    cout << "that computers are superior to humans in all regards.\n"; 
} 

else if (winner == human) 
{ 
    cout << winner <<"'s won!\n"; 
    cout <<"No, no! It cannot be! Somehow you tricked me, human.\n"; 
    cout <<"But never again! I, the computer, so swear it!\n"; 
} 

else 
{ 
    cout <<"It's a tie.\n"; 
    cout <<"You were most lucky, human, and somehow managed to tie me.\n"; 
    cout <<"Celebrate... for this is the best you will ever archieve.\n"; 
} 
} 

죄송합니다 :

여기 내 코드입니다. 자세한 정보가 필요하면 의견을 보내주십시오. computerMove에서

+0

정확한 오류가 무엇입니까의 각 단계에서 아마

int move = 0; 

입니까? –

+0

잘 컴파일되고 실행되지만 인공 지능 재생이 없습니다 – SRN

+0

@ KirilKirov 내가 컴파일 할 때 완벽하게 재생할 수 있지만 컴퓨터가 켜져있을 때 벡터 구독 오류 – Stijn

답변

4

당신이 그래서

const char O = 'O'; 

에 의해 정의된다

int move = O; 

를 썼다 ... 움직임의 크기보다 더 큰 가치가 79 (문자 O의 ASCII 값)이며, 당신의 보드 (9). computerMove의 루프의 결과 아무도 당신은 항상 이동> board.size을 (가지고 있기 때문에 실행되지) 당신은 이동 = 79 반환 될 때 - 당신이 라인에서 보드의 크기를 초과하기 때문에, 그래서 오류 :

board[move] = computer; 

당신이 원하는 것은 당신의 기능 computerMove()

+0

이 프로그램은 79 세에 숯을 넣을 것이라고 말했습니다. 나는 모든 O를 computerMove()에서 0으로 바꿨고 지금은 정상적으로 작동한다. 이 답변을 주셔서 대단히 감사합니다! – Stijn

+1

실제 실수는''const char O = 'O';'입니다. 실제 값은 더 이상 존재하지 않아 잡히지 않는 "0/O"오류가 발생할 것입니다 – stefaanv