aboutsummaryrefslogtreecommitdiffstats
path: root/2048 Game/Game.cpp
diff options
context:
space:
mode:
authorzedarider <ymherklotz@gmail.com>2016-02-24 01:12:05 +0000
committerzedarider <ymherklotz@gmail.com>2016-02-24 01:12:05 +0000
commit08fdf56e21bcd9fe77508e98c9f65b9847d538ac (patch)
tree0fa4a49c7e796f3bff3729204249087e13e1012e /2048 Game/Game.cpp
downloadimperial_2015-08fdf56e21bcd9fe77508e98c9f65b9847d538ac.tar.gz
imperial_2015-08fdf56e21bcd9fe77508e98c9f65b9847d538ac.zip
final changes to game done
Diffstat (limited to '2048 Game/Game.cpp')
-rw-r--r--2048 Game/Game.cpp268
1 files changed, 268 insertions, 0 deletions
diff --git a/2048 Game/Game.cpp b/2048 Game/Game.cpp
new file mode 100644
index 0000000..f2ddf44
--- /dev/null
+++ b/2048 Game/Game.cpp
@@ -0,0 +1,268 @@
+/*
+ * includes necessary libraries
+ */
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <sstream>
+#include <cstdlib>
+#include <ctime>
+
+/*
+ * defines names for the constants we want to use
+ * this is to make the code more readable
+ */
+#define GRIDSIZE 4
+#define BASE 2
+#define UP 'w'
+#define DOWN 's'
+#define RIGHT 'd'
+#define LEFT 'a'
+
+using namespace std;
+
+// declares the functions
+void printGrid(int(&) [GRIDSIZE][GRIDSIZE]);
+void moveGrid(int(&) [GRIDSIZE][GRIDSIZE], char&);
+void mergeArray(int*&, int&);
+void placeBase(int (&) [GRIDSIZE][GRIDSIZE]);
+
+bool checkGridChange(int (&) [GRIDSIZE][GRIDSIZE], int (&) [GRIDSIZE][GRIDSIZE]);
+bool checkGameOver(int(&) [GRIDSIZE][GRIDSIZE]);
+
+/*
+ * main function that handles all the i/o except for printing the grid
+ * as this is easier done by a seperate function
+ */
+int main(int argc, char* argv[]) {
+ // defines the 2D and tmp array that is used to check change
+ int grid[GRIDSIZE][GRIDSIZE];
+ int before[GRIDSIZE][GRIDSIZE];
+ // defines tmp string file name to check if file exists
+ string fileName;
+ char usrInput;
+ // defines input filestream for configFile
+ ifstream configFile;
+
+ // set random seed to be the current time
+ srand(time(NULL));
+
+ // gets the input from the user for the input file
+ cout << "Enter initial configuration file name:" << endl;
+ cin >> fileName;
+
+ // opens the user defined file
+ configFile.open(fileName.c_str());
+
+ // enters the integers from the file into the array if file is correct
+ if(configFile.is_open()) {
+ for(int i = 0; i < GRIDSIZE; ++i) {
+ for(int j = 0; j < GRIDSIZE; ++j) {
+ configFile >> grid[i][j];
+ }
+ }
+ configFile.close();
+ } else {
+ // if the file is not valid it will enter the default values of 0 and 2 in the
+ // bottom right
+ cout << "The file doesn't exist, using default start" << endl;
+ // creates default grid
+ for(int i = 0; i < GRIDSIZE; ++i) {
+ for(int j = 0; j < GRIDSIZE; ++j) {
+ grid[i][j] = 0;
+ }
+ }
+ grid[GRIDSIZE-1][GRIDSIZE-1] = BASE;
+ }
+ printGrid(grid);
+
+ /*
+ * executes this loop while the game isn't over, which means that the user can
+ * still have turns and there are zero's left, as well as adjacent equivalent
+ * numbers that can be added
+ */
+ while(!checkGameOver(grid)) {
+ // gets user input
+ cin >> usrInput;
+ // copies the grid into the before grid
+ for(int i = 0; i < GRIDSIZE; ++i) {
+ for(int j = 0; j < GRIDSIZE; ++j) {
+ before[i][j] = grid[i][j];
+ }
+ }
+ // moves grid in correct direction
+ moveGrid(grid, usrInput);
+ // check if grid has changed which means that the movement was valid
+ if(checkGridChange(grid, before)){
+ cout << endl;
+ // places the random number in the correct base defined above
+ placeBase(grid);
+ // prints the grid
+ printGrid(grid);
+ }
+ }
+ cout << "game over" << endl;
+ return 0;
+}
+
+/*
+ * prints the contents a 2D array with a constant size
+ * so that the user can see the result of their input
+ */
+void printGrid(int (&gridArray)[GRIDSIZE][GRIDSIZE]) {
+ for(int i = 0; i < GRIDSIZE; ++i) {
+ for(int j = 0; j < GRIDSIZE; ++j) {
+ cout << gridArray[i][j] << '\t';
+ }
+ cout << endl;
+ }
+ cout << endl;
+}
+
+/*
+ * handles the inputs of UP, DOWN, LEFT and RIGHT by the user and
+ * sends them to the merge algorithm in the correct order
+ */
+void moveGrid(int (&gridArray)[GRIDSIZE][GRIDSIZE], char &movDir) {
+ // pointer that will point towards first element in array
+ int* elementPtr;
+ // defines the separation to the next element which
+ // says if it moves in rows or columns
+ int separation;
+
+ // if statements to find what direction the user wants to move the grid
+ if(movDir == UP) {
+ // separation set so that it goes up in rows
+ separation = GRIDSIZE;
+ for(int i = 0; i < GRIDSIZE; ++i) {
+ // set elementpointer to be the first element in the rows
+ elementPtr = &gridArray[0][i];
+ // calls merge function
+ mergeArray(elementPtr, separation);
+ }
+ } else if(movDir == DOWN) {
+ separation = -GRIDSIZE;
+ for(int i = 0; i < GRIDSIZE; ++i) {
+ elementPtr = &gridArray[GRIDSIZE-1][i];
+ mergeArray(elementPtr, separation);
+ }
+ } else if(movDir == LEFT) {
+ // set separation to increment in columns
+ separation = 1;
+ for(int i = 0; i < GRIDSIZE; ++i) {
+ elementPtr = gridArray[i];
+ mergeArray(elementPtr, separation);
+ }
+ } else if(movDir == RIGHT) {
+ separation = -1;
+ for(int i = 0; i < GRIDSIZE; ++i) {
+ elementPtr = &gridArray[i][GRIDSIZE-1];
+ mergeArray(elementPtr, separation);
+ }
+ }
+}
+
+/*
+ * merges arrays together depending on the input
+ */
+void mergeArray(int* &arrayPointer, int &addrSep) {
+ // defines array of one size larger so that all elements are moved correctly
+ int nonZeroRow[GRIDSIZE+1];
+ // sets all elements to 0
+ for(int i = 0; i < GRIDSIZE+1; ++i) {
+ nonZeroRow[i] = 0;
+ }
+ // sets the counter to 0
+ int nonZeroCounter = 0;
+ // sets all the elements in the array to be the nonzero elements
+ // pointed to by the pointer
+ for(int i = 0; i < GRIDSIZE; ++i) {
+ if(*(arrayPointer+addrSep*i) != 0) {
+ nonZeroRow[nonZeroCounter++] = *(arrayPointer+addrSep*i);
+ }
+ }
+ for(int i = 0; i < nonZeroCounter; ++i) {
+ // if two adjacent cells are equal multiply by the base
+ if(nonZeroRow[i] == nonZeroRow[i+1]) {
+ nonZeroRow[i] *= BASE;
+ // then move all the other elements up
+ for(int j = i+1; j < GRIDSIZE; ++j) {
+ nonZeroRow[j] = nonZeroRow[j+1];
+ }
+ }
+ }
+ // set all the pointer locations to be equal to the elements in the array
+ for(int i = 0; i < GRIDSIZE; ++i) {
+ *(arrayPointer+addrSep*i) = nonZeroRow[i];
+ }
+}
+
+/*
+ * adds a base num at a random location where a zero was
+ */
+void placeBase(int (&gridArray)[GRIDSIZE][GRIDSIZE]) {
+ // 2D array that will hold locations of the zeros
+ int zeroArray[GRIDSIZE*GRIDSIZE][2];
+ // sets the 0 counter
+ int zeroCount = 0;
+ for(int i = 0; i < GRIDSIZE; ++i) {
+ for(int j = 0; j < GRIDSIZE; ++j) {
+ if(gridArray[i][j] == 0) {
+ // sets the x and y values in the zero array
+ zeroArray[zeroCount][0] = i;
+ zeroArray[zeroCount++][1] = j;
+ }
+ }
+ }
+ // gets a random number
+ int randomLoc = rand() % zeroCount;
+ // sets the random location in the grid to equal that value
+ gridArray[zeroArray[randomLoc][0]][zeroArray[randomLoc][1]] = BASE;
+}
+
+/*
+ * checks if the two grids are the same
+ * if they are this means it will not add the random 2
+ * and not print the grid
+ */
+bool checkGridChange(int (&gridArray)[GRIDSIZE][GRIDSIZE], int (&beforeGrid)[GRIDSIZE][GRIDSIZE]) {
+ for(int i = 0; i < GRIDSIZE; ++i) {
+ for(int j = 0; j < GRIDSIZE; ++j) {
+ if(gridArray[i][j] != beforeGrid[i][j]) {
+ // if it finds a value that doesn't match, grid must have changed hence return true
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+/*
+ * checks if the game is over by checking if 0's are present
+ * or if there are equal numbers side by side
+ */
+bool checkGameOver(int (&gridArray)[GRIDSIZE][GRIDSIZE]) {
+ // uses two for loops to go through all boxes in the grid
+ for(int i = 0; i < GRIDSIZE; ++i) {
+ for(int j = 0; j < GRIDSIZE; ++j) {
+ // checks if the current box is a 0
+ if(gridArray[i][j] == 0) {
+ // returns false as this means the game isn't over
+ return false;
+ }
+ // if not it checks if there are any repeating numbers around
+ // it as this means they can add
+ else if(i > 0 && gridArray[i][j] == gridArray[i-1][j]) {
+ return false;
+ } else if(i < GRIDSIZE-1 && gridArray[i][j] == gridArray[i+1][j]) {
+ return false;
+ } else if(j > 0 && gridArray[i][j] == gridArray[i][j-1]) {
+ return false;
+ } else if(j < GRIDSIZE-1 && gridArray[i][j] == gridArray[i][j+1]) {
+ return false;
+ }
+ }
+ }
+ // if none of the if statements is true it will end the games
+ return true;
+}