I had to use an enumerated data type in my last program, and I couldn't get my program to stop giving me fatal run-time errors.

here is the enumerated data type:

enum piece {EMPTY, BLACK, WHITE};

Now, the trouble I am having is related to evaluation or assignment of this type.

by evaluation, I mean: if ( thePiece == WHITE ) type things, and return WHITE; type things.

by assignment, I obviously mean piece thePiece = WHITE I am pretty sure that I am doing assignment right, but the evaluation seems to be raping me.

If you would prefer that I post the code in its entirety, just say so, but I must warn you all that it is in 3 files: the header, the implementation, and the driver.

So please help me. This will be bothering me until I can figure it out, which it is proving too difficult for me to do alone.

Recommended Answers

All 6 Replies

Well, the comparison also seems okay. Also if it is runtime errors, the problem is not with the syntax. Better post the 3 source files.

Before I post the code, I will say that this is a program to allow two players to play Connect Four. if you don't know the rules, you should probably go find them on google or something.

Alrighty, here is the driver, first off.

"proj08.cpp"

#include <vector>
#include <iostream>
#include <string>
using namespace std;
#include "connectfour.h"

// Oh yeah! this is where I proto the overloaded operators
ostream& operator<<(ostream& Out, piece oPiece); // allows cout of piece type
ostream& operator<<(ostream& Out, ConnectFour oBoard); // allows cout of ConnectFour type

// Now for my extra function:
void processWinner(ConnectFour theBoard, string player1, string player2);
// processes who won

int main()
{
    ConnectFour theBoard;
    string player1,
           player2;
    cout << "This is Connect Four!\nThis is a game of wits.\n"
         << "When prompted, you input the column number (displayed above the column)\n"
         << "that you wish to place your piece in.\n"
         << "The first player to get 4 pieces in a row (vertically, horizontally,\n"
         << "or diagonally) wins! Let's begin by giving you each a name.\n"
         << "Would the first player please input their name: ";
    cin >> player1;
    cout << "Woud the second player please input their name: ";
    cin >> player2;
    
    cout << "Let's begin.\n";
    
    system("pause");
    
    
    for ( ; theBoard.full() == 0 ; )
    // Main game loop, exits if the board becomes full.
    {
        system("cls");
        
        if ( theBoard.currentplayer() == BLACK )
        {
             cout << player1 << ", colour black (B)";
        }
        else
        {
            cout << player2 << ", colour white (W)";
        }
        int chosenCol;
        cout << ", it is your turn.\n"
             << theBoard << "\n\n"
             << "What column would you like to place your piece in? -1 quits. ";
        
        cin >> chosenCol;
        if ( chosenCol == -1 ) //quit if they say -1
        {
             break;
        }
        
        while ( cin.fail() || chosenCol > 6 || chosenCol < -1 || theBoard.get(chosenCol, 0) != EMPTY )
        {
              cin.clear();
              cin.ignore(100,'\n');
              
              cout << "You are in trouble now! You can't place a piece in that column.\n"
                   << "What column would you like to place your piece in? -1 quits. ";
              cin >> chosenCol;
        }
        
        if ( chosenCol == -1 ) // quit if they say -1 (in case they putin invalid values)
        {
             break;
        }
        
        theBoard.move(chosenCol);
        if ( theBoard.winner() != EMPTY )
        {
             break;
        }
    }
    
    //process the winner
    processWinner(theBoard, player1, player2);
    
    system("pause");
    return 0;
}

ostream& operator<<(ostream& Out, piece oPiece)
{// overloaded << operator allowing the cout of 'piece's
         if ( oPiece == EMPTY || oPiece == 0 )
         {
              Out << " "; // if it's an EMPTY piece, I'll display a space
         }
         
         if ( oPiece == BLACK || oPiece == 1 )
         {
              Out << "B"; // If it's BLACK, display a B
         }
         
         if ( oPiece == WHITE || oPiece == 2 )
         {
              Out << "W"; // If it's WHITE, display a W
         }
         
         return Out;
};

ostream& operator<<(ostream& Out, ConnectFour oBoard)
{// overloaded operator allowing the cout of 'ConnectFour's
         Out << " 0  1  2  3  4  5  6\n";
         for ( int Row = 0 , Col = 0; Row < 6 ; Col++ )
         {/* a loop incrementing the column number, that ends when the row number is larger
         than the size of the columns */
             Out << "|" << oBoard.get(Col, Row) << "|"; /* goes through column by column and 
             outputs the ROWth term in the column */
             if ( Col == 6 ) /* if I went through every column, I need to end the line
             and then I need to goto the next row in the columns */
             {
                  Out << endl; // end the line
                  Row++; // next row
                  Col = 0 - 1 ; /* now you know why COL isn't unsigned.
                  the increment makes it 0 in the next loop. */
             }
         }
         Out << "---------------------\n";
         return Out;
};

// function to process the winner
void processWinner(ConnectFour theBoard, string player1, string player2)
{
    if ( theBoard.winner() == EMPTY )
    {
         cout << "\nIt would appear a though we have a tie!\n"
              << "I hope it's more exciting next time around...\n";
    }
    if ( theBoard.winner() == WHITE )
    {
         cout << player2 << " has won the game! Congratulations, " << player2 << "!\n"
              << "Sorry, " << player1 << "; better luck next time!\n";
    }
    if ( theBoard.winner() == BLACK )
    {
         cout << player1 << " has won the game! Congratulations, " << player1 << "!\n"
              << "Sorry, " << player2 << "; better luck next time!\n";
    }
    return;
};

Alright, now here's the header, "connectfour.h"

#include <vector>
using namespace std;

enum piece {EMPTY, BLACK, WHITE};
// enumerate three values for a 'piece' 

typedef vector <piece> column;
// define a datatype named column that is a vector of the enumerated datatype piece

class ConnectFour
{
private:
    vector <column> Board;
    // a vector named Board that contains vectors of the datatype column

    piece CurrentPlayer;
    // a piece named CurrentPlayer

public:
    ConnectFour();
    // default constructor

    bool move (int col);
    // places a piece of the current player in column col.
    // returns false if move is invalid, true if the move is valid.

    piece get(int col, int row);
    // returns the piece at the location (col,row)

    piece winner();
    // returns the winner.  EMPTY means that no one has won yet.

    piece currentplayer();
    // returns the current player

    bool full();
    // returns true if the board is full; returns false otherwise
};

and finally, the implementation file, "connectfour.cpp" This one is where the problem has to be. (I wasn't allowed to change the header.)

#include <vector>
#include <iostream>
using namespace std;
#include "connectfour.h"

ConnectFour::ConnectFour()
// default constructor
{
           // an empty column
           column emptyColumn (6, EMPTY);
           
           // loop to push_back 7 empty columns
           for (unsigned int i = 0 ; i < 7 ; i++ )
           {
               Board.push_back(emptyColumn);
           }
           
           CurrentPlayer = BLACK;
           
};

bool ConnectFour::move (int col)
// places a piece of the current player in column col.
// returns false if move is invalid, true if the move is valid.
{
           //if they chose a full column, they can't do that!
           if ( Board[col][0] != 0 )
           {
                return 0;
           }
           
           // main loop, going through the column and placing the piece at the last 0 slot
           int ROW;
           for ( ROW = 0 ; ROW < 7 ; ROW++ )
           {
               if ( Board[col][ROW] != 0 ) // if I get a non-0 slot...
               {
                    ROW--; // go back a row...
                    Board[col][ROW] = CurrentPlayer; // set that spot to the currentplayer's colour...
                    break;// then leave the loop.
               }
               if ( ROW == 6 && Board[col][ROW] == 0 ) // if the last spot is 0...
               {
                    Board[col][ROW] = CurrentPlayer; // set it to the currentplayer's colour...
                    break; // then leave the loop.
               }
           }
           
           // switch players
           if ( CurrentPlayer == 1 )
           {
                CurrentPlayer = WHITE;
           }
           if ( CurrentPlayer == 2 )
           {
                CurrentPlayer = BLACK;
           }
           
           return 1;
};

piece ConnectFour::get(int col, int row)
// returns the piece at the location (col,row)
{
           piece thePiece = Board[col][row];
           return thePiece;
};

piece ConnectFour::winner()
// returns the winner.  EMPTY means that no one has won yet.
{
           int count = 0; // counter of the no. of pieces in a row
           piece currentColour; // the color of the piece I am checking.
           
           // first possibility : Horizontal
           
           for ( int r = 0, c = 0 ; c < 4 ; r++ )
           {/* stops when we pass the last possible column for a horizontal win
           and moves through row by row */
               
               //first test if we have a empty square and move down the column if we do
               if ( Board[c][r] == 0 )
               {
                    continue;
               }
               else // start searching for more pieces of that color in that row
               {
                    currentColour = Board[c][r];
                    count = 1;
                    int tempCol = c; /* so I can revert to the column I was in if
                    the colour doesn't match. */
                    
                    /* start search loop at one col further than the last piece,
                    ending with an interior break or return */
                    for ( c++ ; ; c++ )
                    {
                        if ( Board[c][r] == currentColour ) // if we have a match
                        {
                             count++;// one more of that type
                             if ( count == 4 ) // if we have four in a row
                             {
                                  return currentColour;
                             }
                             continue; //then try again
                        }
                        else // if there isn't a match...
                        {
                             c = tempCol; //return to column we started searching from
                             count = 0; // set our counter to 0
                             break; // go back to searching for pieces
                        }
                    }
               }
               
               // if we get to the bottom of the column, move to the next.
               if ( r == Board[0].size() - 1 )
               {
                    c++;
                    r = -1; /* b/c of increment I have to set it to become
                    0 in the beginning of the loop */
               }
           }
           // if there is a horizontal win, it would have 'return'ed by now
           
           // Second Possibility: vertical win
           for ( int r = 0, c = 0 ; c < Board.size() || r > 2; c++ )
           {/* stops when we pass the last possible row for a vertical win
           and moves through column by column */
               
               //first test if we have a 0 square and move to the next column if we do
               if ( Board[c][r] == 0 )
               {
                    continue;
               }
               
               else // start searching for more pieces of that color in that column
               {
                    currentColour = Board[c][r];
                    count = 1;
                    int tempRow = r; /* so I can revert to the row I was in if
                    the colour doesn't match at any point in time. */
                    
                    /* start search loop one row below the last one,
                    ending with an interior break or return */
                    for ( r++ ; ; r++ )
                    {
                        if ( Board[c][r] == currentColour ) // if we have a match
                        {
                             count++;// one more of that type
                             if ( count == 4 ) // if we have four in a row
                             {
                                  return currentColour;
                             }
                             continue; //then try again if it isn't the 4th
                        }
                        else // if there isn't a match...
                        {
                             r = tempRow; // return to row we started searching from
                             count = 0; // set our counter to 0
                             break; // go back to searching for pieces
                        }
                    }
               }
               
               // if we get to the last column, move to the next row.
               if ( c == Board.size() - 1 )
               {
                    r++;
                    c = -1; /* b/c of increment I have to set it to become
                    0 in the beginning of the loop */
               }
           }
           
           // Third possibility: diagonal upward
           
           for ( int r = 3, c = 0 ; c < 4 ; c++ )
           {/* starts at the first possible spot for a starting piece for a daigup win,
           and ends when we pass the last column where it's possible to start a
           diagup win, and goes through column by column. */
               
               //first test if we have a 0 square and move to the next column if we do
               if ( Board[c][r] == 0 )
               {
                    continue;
               }
               
               else // start searching for more pieces of that color in that column
               {
                    currentColour = Board[c][r];
                    count = 1;
                    int tempRow = r; /* so I can revert to the row I was in if
                    the colour doesn't match at any point in time. */
                    int tempCol = c; /* so I can revert to the column I was in if
                    the colour doesn't match at any point in time. */
                    
                    /* start search loop one row above the last piece and one column further,
                    ending with a break or return on the interior */
                    for ( r++ , c++ ; ; r++, c++ )
                    {
                        if ( Board[c][r] == currentColour ) // if we have a match
                        {
                             count++;// one more of that type
                             if ( count == 4 ) // if we have four in a row
                             {
                                  return currentColour;
                             }
                             continue; //then try again if it isn't the 4th
                        }
                        else // if there isn't a match...
                        {
                             r = tempRow; // return to row we started searching from
                             c = tempCol; // return to column we started searching from
                             count = 0; // set our counter to 0
                             break; // go back to searching for pieces
                        }
                    }
               }
               
               // if we get past the last possible column, move to the next row.
               if ( c == 3 )
               {
                    r++;
                    c = -1; /* b/c of increment I have to set it to become
                    0 in the beginning of the loop */
               }
           }
           
           // Fourth possibility: diagonal downward
           
           for ( int r = 0, c = 0 ; c < 4, r < 3 ; c++ )
           {/* starts at the first possible spot for a starting piece for a daigdown win,
           and ends when we pass the last column or row where it's possible to start a
           diagdown win, and goes through column by column. */
               
               //first test if we have a 0 square and move to the next column if we do
               if ( Board[c][r] == 0 )
               {
                    continue;
               }
               
               else // start searching for more pieces of that color in that column
               {
                    currentColour = Board[c][r];
                    count = 1;
                    int tempRow = r; /* so I can revert to the row I was in if
                    the colour doesn't match at any point in time. */
                    int tempCol = c; /* so I can revert to the column I was in if
                    the colour doesn't match at any point in time. */
                    
                    /* start search loop one row below the last piece and one column further,
                    ending with a break or return on the interior */
                    for ( r-- , c++ ; ; r--, c++ )
                    {
                        if ( Board[c][r] == currentColour ) // if we have a match
                        {
                             count++;// one more of that type
                             if ( count == 4 ) // if we have four in a row
                             {
                                  return currentColour;
                             }
                             continue; //then try again if it isn't the 4th
                        }
                        else // if there isn't a match...
                        {
                             r = tempRow; // return to row we started searching from
                             c = tempCol; // return to column we started searching from
                             count = 0; // set our counter to 0
                             break; // go back to searching for pieces
                        }
                    }
               }
               
               // if we get past the last possible column, move to the next row.
               if ( c == 3 )
               {
                    r++;
                    c = -1; /* b/c of increment I have to set it to become
                    0 in the beginning of the loop */
               }
           }
           
           // if it hasn't returned yet, it's a no-win situation, so the winner is EMPTY.
           return EMPTY;
};

piece ConnectFour::currentplayer()
// returns the current player
{
           return CurrentPlayer;
};

bool ConnectFour::full()
// returns true if the board is full; returns false otherwise
{
           // search the top row for empty spaces, if there is one, it's not full ^_^
           for ( int row = 0, col = 0 ; col < Board.size() ; col++ )
           {
               if ( Board[col][row] == 0 )
               {
                    return 0;
               }
           }
           return 1;
};

Sorry if this is like the worst case of page stretching EVAR.

if you don't know the rules, you should probably go find them on google or something.

Nope, no time. Give me the input sequence that can recreate the runtime error. When I enter column 1 as the very first input it exits.

that's the problem. It doesn't matter what you input. the problem happens during the call to theBoard.winner() ,
and it doesn't matter what you input. It has something to do with the winner function, and I can't find the damn problem.

I know it was the winner function because it doesn't encounter a problem and force-close if I don't call that function.

(Sorry, I should've added this part to the last post)

The reason you are not able to find the damn problem is because the way your winner function is designed. A function which spans almost 3 pages in C++ has some serious design problems.

Try splitting the function into logical componenets, maybe that would help you localize the problem. Since i dont know the game, cant help you a lot but looking at that function sure seems like a lot is getting repeated which could have been made into a single logical unit

Hope it helped, bye.

As for the repetition, each of those loops has to go through the vector a different way. One horizontally, one vertically, and one in both diagonal directions. I could figure it out, I can think of a way to do it... I could check each... yeah. I'll do that when I get dev-cpp for linux.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.