Skip to content

Instantly share code, notes, and snippets.

@itsjohncs
Created March 16, 2012 19:53
Show Gist options
  • Save itsjohncs/2052214 to your computer and use it in GitHub Desktop.
Save itsjohncs/2052214 to your computer and use it in GitHub Desktop.
Connect 4 Game for CS 10 SI Lab
#include <iostream>
#include <vector>
using namespace std;
const char EMPTY_SPACE = '_';
const char PLAYER1_PIECE = 'X';
const char PLAYER2_PIECE = 'O';
const unsigned int NCOLUMNS = 7;
const unsigned int NROWS = 6;
/// Converts a column's character into its number
/// (ex: A, B, C to 1, 2, 3 repectively).
int toColumn(char zinput)
{
return static_cast<int>(zinput - 'A');
}
/// Converts a column number into the column's character (A, B, C, etc.)
char fromColumn(unsigned int zcolumn)
{
return static_cast<char>(zcolumn + 'A');
}
/// Creates a two-dimensional vector with given width and height and fills
/// every cell with the given value.
vector<vector<char> > make2dVector(unsigned int zwidth,
unsigned int zheight,
char zvalue)
{
// Create a single row which we will then duplicate later
vector<char> row;
for (unsigned int i = 0; i < zwidth; ++i)
row.push_back(zvalue);
vector<vector<char> > v;
for (unsigned int i = 0; i < zheight; ++i)
v.push_back(row);
return v;
}
/// Prints a given two dimensional vector, assuming that v.at(y).at(x) is the
/// correct way to access the vector (as opposed to v.at(x).at(y)).
void printBoard(const vector<vector<char> > & zvector)
{
// Print out the column headers
cout << " ";
for (unsigned int i = 0; i < NCOLUMNS; ++i)
cout << fromColumn(i) << " ";
cout << endl;
for (unsigned int i = 0; i < zvector.size(); i++)
{
// Print out the row number
cout << i << " ";
// Print out the row
for (unsigned int j = 0; j < zvector.at(i).size(); j++)
{
cout << zvector.at(i).at(j) << " ";
}
cout << endl;
}
}
/// Returns true if and only if the entire board is filled with pieces
bool isTiedGame(const vector<vector<char> > & zvector)
{
for(unsigned int i = 0; i < zvector.size(); i++)
{
for(unsigned int j = 0; j < zvector.at(i).size(); j++)
{
if(zvector.at(i).at(j) == EMPTY_SPACE)
{
return false;
}
}
}
return true;
}
/// Checks to see if the given player won by lining up their pieces vertically
bool isWon_vertical_(const vector<vector<char> > & zvector, char zplayer)
{
for (unsigned int i = 0; i < zvector.size() - 3; i++)
{
for (unsigned int j = 0; j < zvector.at(i).size(); j++)
{
if (zvector.at(i).at(j) == zplayer && zvector.at(i+1).at(j) == zplayer
&& zvector.at(i+2).at(j) == zplayer && zvector.at(i+3).at(j) == zplayer)
return true;
}
}
return false;
}
/// Checks to see if the given player won by lining up their pieces horizontally
bool isWon_horizontal_(const vector <vector <char> > &zvector, char zplayer)
{
for (unsigned int i = 0; i < zvector.size(); i++)
{
for (unsigned int j = 0; j < zvector.at(i).size() - 3; j++)
{
if (zvector.at(i).at(j) == zplayer && zvector.at(i).at(j+1) == zplayer
&& zvector.at(i).at(j+2) == zplayer && zvector.at(i).at(j+3) == zplayer)
return true;
}
}
return false;
}
/// Checks to see if the player won by lining up their pieces diagonally with a
/// positive slope (so from SW to NE).
bool isWon_diagonalP_(const vector<vector<char> > & zvector, char zplayer)
{
for (unsigned int i = 3; i < zvector.size(); i++)
{
for (unsigned int j = 0; j < zvector.at(i).size() - 3; j++)
{
bool won = true;
for (unsigned int k = 0; k < 4; ++k)
if (zvector.at(i - k).at(j + k) != zplayer)
won = false;
if (won) return true;
}
}
return false;
}
/// Checks to see if the player won by lining upt heir pieces diagonally with a
/// negative slope (so from NW to SE).
bool isWon_diagonalN_(const vector<vector<char> > & zvector, char zplayer)
{
for (unsigned int i = 0; i < zvector.size() - 3; i++)
{
for (unsigned int j = 0; j < zvector.at(i).size() - 3; j++)
{
bool won = true;
for (unsigned int k = 0; k < 4; ++k)
if (zvector.at(i + k).at(j + k) != zplayer)
won = false;
if (won) return true;
}
}
return false;
}
/// Checks to see if the given player (given by the player's game piece) has
/// won.
bool isWon(const vector<vector<char> > & zvector, char zplayer)
{
return isWon_vertical_(zvector, zplayer) ||
isWon_horizontal_(zvector, zplayer) ||
isWon_diagonalP_(zvector, zplayer) ||
isWon_diagonalN_(zvector, zplayer);
}
/// Place a given player's piece in a given column and return true if and only
/// if the move was successful.
bool doMove(vector<vector<char> > & zvector, int zcolumn, char zplayer)
{
for(int i = static_cast<int>(zvector.size() - 1); i >= 0; i--)
{
if(zvector.at(i).at(zcolumn) == EMPTY_SPACE)
{
zvector.at(i).at(zcolumn) = zplayer;
return true;
}
}
return false;
}
int main()
{
vector<vector<char> > board = make2dVector(NCOLUMNS, NROWS, EMPTY_SPACE);
char curPlayer = PLAYER1_PIECE;
while (true)
{
printBoard(board);
// Get the player's move
char move;
cout << "It is " << curPlayer
<< "'s turn. Where would you like to move?: ";
cin >> move;
// Ensure that the move was valid
if (!cin)
{
cout << "Invalid Move!" << endl;
cin.clear();
cin.ignore(255, '\n');
}
else
{
// Try to place the player's piece and scold them if it didn't work.
if (doMove(board, toColumn(move), curPlayer))
{
// Check to see if the current player won
if (isWon(board, curPlayer))
{
cout << curPlayer << " won! Good game!" << endl;
break;
}
else if (isTiedGame(board))
{
cout << "Tied Game!" << endl;
break;
}
// Now it's the other player's turn
if (curPlayer == PLAYER1_PIECE)
curPlayer = PLAYER2_PIECE;
else
curPlayer = PLAYER1_PIECE;
}
else
{
cout << "Column is full, pick another." << endl;
}
}
}
return 0;
}
@itsjohncs
Copy link
Author

Here is make2dVector:

vector<vector<char> > make2dVector(unsigned int zwidth,
                                   unsigned int zheight,
                                   char zvalue)
{
    // Create a single row which we will then duplicate later
    vector<char> row;
    for (int i = 0; i < zwidth; ++i)
        row.push_back(zvalue);

    vector<vector<char> > v;
    for (int i = 0; i < zheight; ++i)
        v.push_back(row);

    return v;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment