Created
March 16, 2012 19:53
-
-
Save itsjohncs/2052214 to your computer and use it in GitHub Desktop.
Connect 4 Game for CS 10 SI Lab
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here is make2dVector: