2012-07-07 71 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"; 
} 
} 

很抱歉的长码。 如果您需要更多信息,请发表评论。

+0

什么是确切的错误的每一步? – 2012-07-07 16:34:55

+0

它编译好,运行,但没有艾播 – SRN 2012-07-07 16:35:53

+0

@KirilKirov当我编译我可以完美播放,但当它的计算机转向那里是一个向量订阅错误 – Stijn 2012-07-07 16:38:36

回答

4

在computerMove你写

int move = O; 

这是由

const char O = 'O'; 

这样定义...举动值得一79(字母O的ASCII值),这比规模更大你的董事会(9)。作为computerMove的循环的结果没有被执行,因为你总是有招> board.size(),并返回移动= 79 - 这样的错误,因为你行超过电路板的尺寸:

board[move] = computer; 

你要什么可能

int move = 0; 

是在你的函数computerMove()

+0

该计划确实表示,他将在79(这是不是在该领域)字符。我用computerMove()中的0更改了每个O,现在它工作正常。非常感谢您的回答! – Stijn 2012-07-07 16:50:38

+1

真正的错误是行'const char O ='O';'它没有真正的附加值,并且可能会导致更多未被捕获的“0/0”错误 – stefaanv 2012-07-07 17:01:56