0

我正在用 C++ 构建一个简单的 Tac Tac Toe 游戏,但是当计算机轮到我时出现矢量订阅错误。我找不到这个错误的原因,请告诉我。

这是我的代码:

//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";
}
}

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

4

1 回答 1

4

在computerMove你写

int move = O;

定义为

const char O = 'O';

所以... move 值 79(字母 O 的 ASCII 值),它大于你的棋盘大小(9)。结果,没有执行 computerMove 的任何循环,因为您始终拥有 move > board.size() 并且您返回 move = 79 - 所以错误,因为您超过了线路板的大小:

board[move] = computer;

你想要的大概是

int move = 0;

在你的函数 computerMove() 的每一步

于 2012-07-07T16:42:52.087 回答