Jump to content
  • Advertisement
Sign in to follow this  
Niux

tic-tac-toe problem..

This topic is 4885 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hey.. im kinda noob in c++, so im reading the book Beginning c++ game programming, and one of the games in the game; tic-tac-toe has a bug i cant seem to find. here's the code:
#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';

//functions prototypes
void instructions();
char askYesNo(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);

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

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";
    
    cout << " Prepare yourselfm human. The battle is about to begin.\n\n";
}

char askYesNo(string question)
{
    char responce;
    
    do
    {
        cout << question << " [Y/N]: ";
        cin >> responce;
    } while (responce != 'y' && responce != 'n');
    
    return responce;
}

int askNumber(string question, int high, int low)
{
    int number;
    do
    {
        cout << question << " (" << low << " - " << high << "): ";
        cin >> number;
    } while (number > high || number < low);
    
    return number; 
}

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;
    }
    if (go_first = 'n')
    {
        cout << "\nYour bravery will be your undoing.. I will go first.\n";
        return O;
    }
}

char opponent(char piece)
{
    if (piece == X)
        return O;
    else 
        return X;
}

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\n";
}

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 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]];
}
}
//check for a tie
if (count(board.begin(), board.end(), EMPTY) == 0)
{
    return TIE; 
}

return NO_ONE;
}
//check to see if the move is legal
inline bool isLegal(int move, const vector<char>& board)
{
    return(board[move] == EMPTY);
}
//get human move + check legallity
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 allready occupied, foolish human.\n";
        move = askNumber("Where will you move?", (board.size() - 1));
    }
    cout << "Fine... \n";
    return move;
}

//computerMove - game AI
int computerMove(vector<char> board, char computer)
{
    cout << "I shall take square number ";
    //if computer can win on next move, make that move
    for(int move = 0; move < board.size(); ++move)
    {
        if (isLegal(move, board))
            {
            board[move] = computer;
            if (winner(board) == computer)
                    {
                           cout << move << endl;
                           return move;
                    }
        //done checking this move, undo
        board[move] = EMPTY;
        }//if isLegal
    }//for loop
    
    //check if human can win on next move
    char human = opponent(computer);
    for(int move = 0; move < board.size(); ++move)
    {
        if (isLegal(move, board))
        {
        board[move] = human;
        if (winner(board) == human)
        {
                cout << move << endl;
                return move;
        }
        //done checking this move, undo
        board[move] = EMPTY;
        }//if
    }//for loop
    
    //best moves to make in orden
    const int BEST_MOVES[] = {4, 0, 2, 6, 8, 1, 3, 5, 7};
    //no wins on next move, pick best square
    for(int i = 0; i < board.size(); ++i)
    {
        int move = BEST_MOVES;
        if (isLegal(move, board))
        {
                cout << move << endl;
                return move; 
        }
    }//for loop
}//function end

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!";
    cout << "You were most lucky, human, and somehow managed to tie me.\n";
    cout << "Celebrate.. for this is the best you will ever achive.\n";
    }
}

compiles without errors or warnings, but no matter if i answer y or n to the first question, i get the first move.. and i cant finde the problem,but think i must be in the humanPiece() function. i plan to expand the game, so that you cannot get a tie, but when u placed all 3 pieces, you move 1 of the 3 to another spot. maybe include a score system and improve game AI - and rewirte it to fit the "tie-change".. any comments? thanks for you time.. -niux

Share this post


Link to post
Share on other sites
Advertisement
If you turn up your warning level, your compiler should tell you about those kinds of mistakes.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!