Stupid behavior of multi dimensional array - c++
The problem is simple. I made a 3X3 tictactoe game with 3X3 arrays. But the problem is:
array[0][3] = array[1][0]
Which is strange because first of all, the array I made didn't have a fourth column. So array[0][3] doesn't even exist! And to make matters complicated, it takes the value of [1][0]
I'm having problems when I input co ordinates of my move as: 0 2
void displayBoard(int tictac[3][3])
{
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
cout << tictac[i][j] << " ";
} cout << "\n" ;
} cout << "\n";
}
int Horizontal(int x, int y, int tictac[3][3])
{
if(tictac[x][y+1]==0)
{
tictac[x][y+1]=2;
return 1;
}
if(tictac[x][y-1]==0)
{
tictac[x][y-1]=2;
return 1;
}
if(tictac[x][y-2]==0)
{
tictac[x][y-2]=2;
return 1;
}
if(tictac[x][y+2]==0)
{
tictac[x][y+2]=2;
return 1;
}
return 0;
}
int Vertical(int x, int y, int tictac[3][3])
{
if(tictac[x+1][y]==0)
{
tictac[x+1][y]=2;
return 1;
}
if(tictac[x-1][y]==0)
{
tictac[x-1][y]=2;
return 1;
}
if(tictac[x-2][y]==0)
{
tictac[x-2][y]=2;
return 1;
}
if(tictac[x+2][y]==0)
{
tictac[x+2][y]=2;
return 1;
}
return 0;
}
void AI(int X,int Y,int tictac[3][3])
{
int done = 0;
cout << "\n-------------------------\nComputer plays: \n";
done = Horizontal(X,Y,tictac);
if(done == 0)
{
done = Vertical(X,Y,tictac);
}
}
int main()
{
int tictac[3][3] = {{0,0,0},{0,0,0}, {0,0,0} };
int X, Y;
for(int r=1; r<100; r++)
{
cout << "\n-------------------------\nPlayer play a move: \n";
cin >> X;
cin >> Y;
if(tictac[X][Y]==0)
{
tictac[X][Y] = 1;
displayBoard(tictac);
AI(X,Y,tictac);
displayBoard(tictac);
}
else
{
cout << "Space occupied. Try different cell." << endl;
}
}
}
You need to add bounds checking. For instance when the user inputs the move coordinates you need to ensure they are within the range of 0 to 2. The example below validates the input to ensure only numbers are entered, that both X and Y coordinates are entered on a single line and that the coordinates are within range. It uses std::stringstream to parse the coordinates instead of having to deal with checking and clearing the fail bits on std::cin
#include <string> // at top of your .cpp file
#include <sstream>
// in main()
// Get en entire input line so we can skip extra characters
// after the cell coordinates
string inputLine;
std::getline(cin, inputLine);
stringstream inputStream(inputLine);
if(!(inputStream >> X) || !(inputStream >> Y))
{
cout << "Please enter the cell coordinates in the form of # #" << endl;
continue;
}
bool invalidCoordinates = false;
if(X < 0 || X > 2)
{
cout << "invalid X location" << endl;
invalidCoordinates = true;
}
if(Y < 0 || Y > 2)
{
cout << "invalid Y location" << endl;
invalidCoordinates = true;
}
// check for invalid input
if(invalidCoordinates) continue;
You also need to do the same thing in your Vertical and Horizontal functions when checking if a valid move is possible. For instance if x is 2 and y is 2 the following lines from Vertical will access data outside the bounds of the array.
if(tictac[x+1][y]==0)
{
tictac[x+1][y]=2;
return 1;
}
This is because you are actually accessing the forth element with x+1. This element technically doesn't exist but with a multi-dimensional array you end up accessing tictac[0][y+1] instead.
You can get around the bounds checking in Vertical and Horizontal by adding some padding around the edges and fill them with a value that indicates they are unusable. In your case increase the size by 3 in each direction.
int tictac[9][9] = {
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,0,0,0,3,3,3},
{3,3,3,0,0,0,3,3,3},
{3,3,3,0,0,0,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
};
You will need to make adjustments to X and Y appropriately so they point to the correct location.
X += 3; // Adjust for padding
Y += 3; // Adjust for padding
if(tictac[X][Y]==0)
{
tictac[X][Y] = 1;
displayBoard(tictac);
AI(X,Y,tictac);
displayBoard(tictac);
}
You may need to make adjustments in other parts of your code but the above example should get your started.
There is also a problem in your displayBoard function. When it prints out the elements of the array i and j are reversed so the board appears rotated 90 degrees. Change the following line
cout << tictac[i][j] << " ";
to
cout << tictac[j][i] << " ";
Another problem is that you are using \n at the end of each line you output without using std::flush to ensure the line is sent to the console. You can either put << flush; after those lines or remove the \n and put << endl; at the end of the line.
cout << "\n-------------------------\nComputer plays: \n" << flush;
or
cout << "\n-------------------------\nComputer plays: " << endl;
The code below is a complete update of the original code included in your question. It incorporates the above suggestions and makes a couple of other changes. I've also added an endgame check to determine if there are any moves left.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
static const int BoardSize = 3;
static const int BoardPadding = BoardSize;
static const int ArraySize = BoardSize + (BoardPadding * 2);
void displayBoard(int tictac[ArraySize][ArraySize])
{
for(int y = 0; y < BoardSize; y++)
{
for(int x = 0; x < BoardSize; x++)
{
cout << tictac[BoardPadding + x][BoardPadding + y] << " ";
}
cout << endl ;
}
cout << endl;
}
int Horizontal(int x, int y, int tictac[ArraySize][ArraySize])
{
if(tictac[x][y+1]==0)
{
tictac[x][y+1]=2;
return 1;
}
if(tictac[x][y-1]==0)
{
tictac[x][y-1]=2;
return 1;
}
if(tictac[x][y-2]==0)
{
tictac[x][y-2]=2;
return 1;
}
if(tictac[x][y+2]==0)
{
tictac[x][y+2]=2;
return 1;
}
return 0;
}
int Vertical(int x, int y, int tictac[ArraySize][ArraySize])
{
if(tictac[x+1][y]==0)
{
tictac[x+1][y]=2;
return 1;
}
if(tictac[x-1][y]==0)
{
tictac[x-1][y]=2;
return 1;
}
if(tictac[x-2][y]==0)
{
tictac[x-2][y]=2;
return 1;
}
if(tictac[x+2][y]==0)
{
tictac[x+2][y]=2;
return 1;
}
return 0;
}
void AI(int X,int Y,int tictac[ArraySize][ArraySize])
{
int done = 0;
cout << "\n-------------------------\nComputer plays: " << endl;
done = Horizontal(X,Y,tictac);
if(done == 0)
{
done = Vertical(X,Y,tictac);
}
}
// Check if all moves have been made
bool isEndGame(int tictac[ArraySize][ArraySize])
{
int count = 0;
for(int y = 0; y < BoardSize; y++)
{
for(int x = 0; x < BoardSize; x++)
{
count += tictac[BoardPadding + x][BoardPadding + y] ? 1 : 0;
}
}
return count == (BoardSize * BoardSize);
}
int main()
{
int tictac[ArraySize][ArraySize] = {
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,0,0,0,3,3,3},
{3,3,3,0,0,0,3,3,3},
{3,3,3,0,0,0,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3},
};
int X, Y;
while(isEndGame(tictac) == false)
{
cout << "\n-------------------------\nPlayer play a move: " << flush;
// Get en entire input line so we can skip extra characters
// after the cell coordinates
string inputLine;
std::getline(cin, inputLine);
stringstream inputStream(inputLine);
if(!(inputStream >> X) || !(inputStream >> Y))
{
cout << "Please enter the cell coordinates in the form of # #" << endl;
continue;
}
bool invalidCoordinates = false;
if(X < 0 || X >= BoardSize)
{
cout << "invalid X location" << endl;
invalidCoordinates = true;
}
if(Y < 0 || Y >= BoardSize)
{
cout << "invalid Y location" << endl;
invalidCoordinates = true;
}
// check for invalid input
if(invalidCoordinates) continue;
// adjust the coordinates and do our thing
X += BoardPadding;
Y += BoardPadding;
if(tictac[X][Y]==0)
{
tictac[X][Y] = 1;
displayBoard(tictac);
AI(X,Y,tictac);
displayBoard(tictac);
}
else
{
cout << "Space occupied. Try different cell." << endl;
}
}
cout << "game finished...check for winner" << endl;
}
Note: It's a bad idea to use using namespace std;. It pulls everything from the std namespace into the current scope (in this case the global namespace) and can cause conflicts. It's best to use fully qualified names such as std::cout instead to avoid this.
In case of this array
int array[3][3];
the following statement is valid
array[0][3] == array[1][0]
because:
C/C++ does not perform any boundary checks.
3x3 array is stored as a 1D array. When you specify the 2D indices, the compiler transforms them to 1D index: [j][i] becomes [j * width + i].
Thus, array[0][3] points to 0 * 3 + 3 (third) cell in a memory, but array[1][0] points to 1 * 3 + 0 (also third!) cell of the memory, starting from the start of your 2D array.
Related
Travelling Sales Man: Finding Total Shortest Distance Travelled To All Points Without Going Back To Origin (C++)
This is a school project, where we are supposed to find the total shortest distance travelled to all points once, without going back to the origin. I have solved this using the nearest neighbour method, however, sometimes it will not give the fastest route. Is there any algorithms I can use to solve this? I wanted to try using 2-Opt Swap however that requires all points to be connected. Here is my main code: // Mini Proj.cpp : This file contains the 'main' function. Program execution begins and ends there. #include <iostream> #include <list> #include <iterator> #include <vector> #include <fstream> #include <algorithm> #include <string> // #pragma warning(disable : 4996) // turn off warnings for error code using namespace std; int numArr[20]; // Set to 20 for redundancy, in case there's a lot of locations // Display Code Keilaash int rack_length; int rack_height; int id = 49; // typedef for easier use. typedef vector<vector<char>> Matrix; typedef vector<char> Row; // Class to hold Location's X and Y value class Location { public: int m_x; int m_y; Location() { m_x = -1; m_y = -1; }; Location(int x, int y) { m_x = x; m_y = y; }; }; /* Make matrix of all 0s. */ void setup_matrix(Matrix &matrix) // Matrix is access matrix[y][x] { // asigning values, I suppose this is done allready. for ( int y = rack_height-1 ; y >= 0 ; y-- ) // start from top left { vector<char> row(rack_length); for (int x = 0; x < rack_length; x++) { row[x] = '0'; } matrix.push_back(row); } } /* Initialise matrix with home and points */ void preset_matrix(int x, int y, Matrix &matrix) // Set X then set Y { matrix[0][0] = 'H'; matrix[y][x] = 'X'; } /* mark location as being visited. */ void update_matrix(int x, int y, Matrix &matrix) // Set X then Set Y { matrix[y][x] = id ; id++; } /* display the matrix on the screen */ void display_matrix(Matrix &matrix) { // matrix is accessed as matrix[y][x] cout << "\nMatrix Output:" << endl; for (int y = rack_height-1 ; y >= 0 ; y--) // loop 3 times for three lines { for (int x = 0 ; x < rack_length ; x++) // loop for the three elements on the line { cout << matrix[y][x]; // display the current element out of the array } cout << endl; // when the inner loop is done, go to a new line } cout << endl; } int main() { int numElements; ifstream readIn; string fileName; for (int i = 0; i <= 20; i++) { numArr[i] = i; } cout << "What is the name of the file you would like to open (please include the .txt extension): "; cin >> fileName; readIn.open(fileName.c_str()); // Open text file for subsequent information retrieval // Error check, to notify the user if there was trouble opening the file if (!readIn) { cout << "There was an error opening the file you wanted" << endl; } else { int inputCount = 0; for (int i = 0; i < 20; i++) { readIn >> numArr[i]; if (readIn) { inputCount++; } } inputCount -= 2; // cout << inputCount << endl; // Count the number of individual co-ordinates that were put into the text file (Xi, Yi) cout << "Total X length: " << numArr[0] << endl; cout << "Total Y length: " << numArr[1] << endl; int y = 2, z = 3; for (int i = 0; i < inputCount; i++) { if (i < inputCount / 2) { cout << "Location " << i + 1 << ": " << numArr[y] << ", " << numArr[z] << endl; y += 2; z += 2; } } // Save data into variables rack_length = numArr[0]; rack_height = numArr[1]; numElements = inputCount; } /* List of Location */ list<Location> locationList, sortedLocationList; list<Location>::iterator it, iteratorShortest; /* Create list of locations */ vector<int> xCoordinates; vector<int> yCoordinates; // Transfer xy from array to vectors for (int i = 2; i < numElements + 2; i++) { if (i % 2 == 0) // even { xCoordinates.push_back(numArr[i]); } else // odd { yCoordinates.push_back(numArr[i]); } } /* Safety Checks */ // ensure proper tally of x and y coordinates if ( xCoordinates.size() != yCoordinates.size() ) { cout << "\nNumber of x and y coordinates do not match" << endl; return -1; } // ensure rack size larger than points in rack. double maxXCoordinate = *max_element(xCoordinates.begin(), xCoordinates.end()); // max element returns iterator double maxYCoordinate = *max_element(yCoordinates.begin(), yCoordinates.end()); // max element returns iterator if (maxXCoordinate > rack_length || maxYCoordinate > rack_height) { cout << "\nYour xy coordinate is not in rack_length or rack_height" << endl; return -1; } int numberOfLocations = xCoordinates.size(); Matrix matrix; setup_matrix(matrix); // initialise Location nodes for algorthim and display for (int i = 0; i < numberOfLocations; i++) { Location location(xCoordinates[i], yCoordinates[i]); locationList.push_back(location); preset_matrix(xCoordinates[i], yCoordinates[i], matrix); } /* Greedy Algorithm */ int currentX = 0; int currentY = 0; int listSize = locationList.size(); for (int i = 0; i < listSize; i++) { int shortestDistance = -1; // -1 indicates undefined // reset iterator iteratorShortest = locationList.begin(); // Loops through location list, finding the shortest distance from start location to next location. for (it = locationList.begin(); it != locationList.end(); it++) { // Find Difference in X and Y coordinates int xDiff = abs((*it).m_x - currentX); int yDiff = abs((*it).m_y - currentY); int distance = xDiff + yDiff; if (distance < shortestDistance || shortestDistance == -1) { //cout << "new shortest distance found " << distance << endl; //DEBUG shortestDistance = distance; // save shortest element's iterator iteratorShortest = it; } else { //cout << "not longer" << endl; //DEBUG } } // add location to sorted list sortedLocationList.push_back(*iteratorShortest); /* Reset algortihm to find next closest node*/ // set new value for current x and y currentX = (*iteratorShortest).m_x; currentY = (*iteratorShortest).m_y; // Remove found element from list locationList.erase(iteratorShortest); } /* Display list of locations */ display_matrix(matrix); for (it = sortedLocationList.begin(); it != sortedLocationList.end(); it++) { update_matrix( (*it).m_x , (*it).m_y , matrix); display_matrix(matrix); } return 0; } And this is my text file named rack1.txt: 10 10 6 0 2 3 4 1 4 4 6 7 6 1 7 1 Any Help Would Be Appreciated! 😛😌
C++ Tic Tac toe game not showing X character
Novice programmer here. Trying to make a tic tac toe game. Everything so far works, except the character X doesn't appear. In the for loop is where I believe I have a problem but I cant seem to find anything wrong. Please help, any criticism is greatly appreciated. Good and bad. Thanks. void playgame() { std::string input; while (true) { std::cout << "Go player one" << std::endl; getline (std::cin, input); if (input != " ") { char entered = input.c_str ()[0]; if (entered >= '1' && entered <= '9') { int entered_num = entered - 0; int index = entered_num - 1; int row = index / 3; int col = index % 3; char grid_position = map[row][col]; if (grid_position == 'X' || grid_position == 'O') { std::cout << "Space taken. Try again" << std::endl; } else { map[row][col] = (char) 'X'; break; } } else { std::cout << "Only numbers 1 - 9" << std::endl; } } else { std::cout << "Have to enter something, try again" << std::endl; } } } void generateGrid() { int number = 1; for (int x = 0; x < GRID_SIZE; x++) { for (int y = 0; y < GRID_SIZE; y++) { map[x][y] = std::to_string (number).c_str ()[0]; number += 1; } } } void tictacToeMap() { std::cout << std::endl; for (int x = 0; x < GRID_SIZE; x++) { for (int y = 0; y < GRID_SIZE; y++) { std::printf (" %c ", map[x][y]); } std::cout << std::endl; } } TicTacToe() { generateGrid (); while (true) { tictacToeMap (); playgame (); } } }; int main() { TicTacToe tic; return 0; }
int entered_num = entered - 0; Should be: int entered_num = entered - '0'; To convert a '1' into a 1, you need to subtract '0' (the character we use to represent the digit zero), not 0 (the number zero). Subtracting zero doesn't do anything.
For loop repetition drawing trouble
I'm trying to get a loop to draw a Christmas tree but the output is wrong, I've tried searching for the answer but i can't seem to find it and I'm stumped. The answer may be obvious but I've missed a lot and any help's greatly appreciated! #include <iostream> #include <assert.h> #include <iomanip> using namespace std; const char blank = ' '; const char leaf = '#'; const char wood = '|'; const int minSize = 4; const int maxSize = 20; int treeHeight; int& getValidHeight(int&); void drawALineOfFoliage(int); void drawFoliage(int); void drawTrunk(int); void drawAXmasTree(int); void drawAXmasTree(int treeHeight) { getValidHeight(treeHeight); drawFoliage(treeHeight); drawTrunk(treeHeight); } int& getValidHeight(int& treeHeight) { cout << ("Please enter the size of the tree (4-20):\n"); cin >> treeHeight; while ((treeHeight < minSize) || (maxSize < treeHeight)) { cout << "ERROR: Invalid height! Enter the size of the tree (4-20):\n"; cin >> treeHeight; return treeHeight; } } void drawALineOfFoliage(int treeHeight) { for (int x = 0; x < treeHeight; ++x){ for (int y = treeHeight; y > x; --y){ cout << blank;} for (int y = 0; y < x; ++y){ cout << leaf;}}} void drawFoliage(int treeHeight) { int branchLine = 1; do { drawALineOfFoliage(treeHeight); branchLine += 1; } while (branchLine <= (treeHeight - 2));} void drawTrunk(int treeHeight) { int trunkLine(1), spaces; while (trunkLine <= 2) { spaces = 1; while (spaces <= (treeHeight - 3)) { cout << blank; spaces += 1;} cout << wood << "\n"; trunkLine += 1; } } int main() { drawAXmasTree(treeHeight); system("pause");} the output is just the Christmas tree deconstructed so all the levels are on the same line and repeated several times
So I took your sample code and gave it a run. First of all, your styling and tabbing is inconsistent which can make the code really hard to read. Next, your drawALineOfFoliage is actually drawing the entire tree without the trunk instead of just a line. Therefore you were missing a cout << endl; inside the main for loop after the other 2 nested for loop. Begin edit: EDIT: I forgot to talk about the half tree. So in your existing code, it only prints half the tree. Something like this... # ## ### #### Which is half a Christmas tree. To make it look similar to an actual tree, all I did was adding *2 to the for loop that is responsible for printing the leaf. (You can also do cout << leaf << leaf; instead) for (int y = 0; y < x*2; ++y) { cout << leaf; } End edit. Since your drawALineOfFoliageis printing the tree already, in drawFoliage, do { drawALineOfFoliage(treeHeight); branchLine += 1; } while (branchLine <= (treeHeight - 2)); this do while loop is looping the amount of trees (again, without trunk) so it should be removed. Now that we got the top part done, let's take a look at the trunk. while (spaces <= (treeHeight - 3)) The - 3 seems to came out of nowhere. And it is only printing one | per row which looks kinda weird so I removed the - 3 and make it print 2 woods instead. Now the output looks somewhat like this... Please enter the size of the tree (4-20): 6 ## #### ###### ######## ########## || || Its alright but still weird. TLDR, I did some tweaking and got an end result like this... Please enter the size of the tree (4-20): 7 # ### ##### ####### ######### ########### ############# ||| ||| Full code as follows: #include <iostream> #include <assert.h> #include <iomanip> using namespace std; const char blank = ' '; const char leaf = '#'; const char wood = '|'; const int minSize = 4; const int maxSize = 20; int treeHeight; int& getValidHeight(int&); void drawALineOfFoliage(int); void drawFoliage(int); void drawTrunk(int); void drawAXmasTree(int); void drawAXmasTree(int treeHeight) { getValidHeight(treeHeight); drawFoliage(treeHeight); drawTrunk(treeHeight); } int& getValidHeight(int& treeHeight) { cout << ("Please enter the size of the tree (4-20):\n"); cin >> treeHeight; while ((treeHeight < minSize) || (maxSize < treeHeight)) { cout << "ERROR: Invalid height! Enter the size of the tree (4-20):\n"; cin >> treeHeight; } return treeHeight; } void drawALineOfFoliage(int treeHeight) { for (int x = 0; x < treeHeight; ++x) { for (int y = treeHeight; y > x; --y) { cout << blank; } for (int y = 0; y < x*2; ++y) { cout << leaf; } cout << endl; } } void drawALineOfFoliageOdd(int treeHeight) { for (int x = 0; x < treeHeight; ++x) { for (int y = treeHeight; y > x; --y) { cout << blank; } cout << leaf; for (int y = 0; y < x*2; ++y) { cout << leaf; } cout << endl; } } void drawFoliage(int treeHeight) { int branchLine = 1; drawALineOfFoliageOdd(treeHeight); do { branchLine += 1; } while (branchLine <= (treeHeight - 2)); } void drawTrunk(int treeHeight) { int trunkLine(1), spaces; while (trunkLine <= 2) { spaces = 1; while (spaces <= (treeHeight - 1)) { cout << blank; spaces += 1; } cout << wood << wood << wood << endl; trunkLine += 1; } } int main() { drawAXmasTree(treeHeight); system("pause"); } Note: I did not do any sort of cleanup so there are a lot of unnecessary codes in it. I just worked on top of what you have to provide you the best solution I got.
Your lineOfFoliage seems to do lines for all x < height. It seems to me that the basic structure of the foliage drawing code would be: drawFoliage(height) { for(width = 0..height) cout << centeredLine(width); } drawCenteredLine(width) { return blanks + leafs; }
Input/Output file (Sudoku Solver)
First, I am a beginner coder and I have tried to tackle and solve parts of my problem for hours and can not figure it out. I have done all the task except for two tasks: 1.) I can not figure out how to use input and outfile mechanism of ifstream and ofstream to get my .txt file to set my values for my sudoku board. 2.) I cannot seem to figure out how to print out a sudoku board for each "possible values" for each xyposition in the cells. I am trying to implement a text file that reads: puzzle.setBoardValue(0,0,1); puzzle.setBoardValue(1,1,3); puzzle.setBoardValue(2,2,9); puzzle.setBoardValue(3,2,6); puzzle.setBoardValue(4,1,2); puzzle.setBoardValue(5,0,7); puzzle.setBoardValue(6,2,5); puzzle.setBoardValue(7,0,9); puzzle.setBoardValue(8,1,8); puzzle.setBoardValue(0,5,6); puzzle.setBoardValue(1,4,1); puzzle.setBoardValue(2,3,5); puzzle.setBoardValue(3,3,3); puzzle.setBoardValue(4,4,8); puzzle.setBoardValue(5,5,4); puzzle.setBoardValue(6,3,9); puzzle.setBoardValue(8,4,2); puzzle.setBoardValue(0,6,3); puzzle.setBoardValue(1,7,4); puzzle.setBoardValue(2,8,7); puzzle.setBoardValue(6,8,3); puzzle.setBoardValue(7,6,1); puzzle.setBoardValue(8,7,7); ` and basically use that to and automatically direction my program to the function void setBoardValue(); All I have figured out was in my int main(); where I put cout << "Enter filename:" << endl; cin >> filename; in.open(filename); while(getline(in,line)){ ... Secondly, I just can not figure out how to print all the possible values for each number cells. Here is my entire program code: #include <iostream> #include <fstream> #include <vector> using namespace std; class SudokuPuzzle{ private: unsigned short board[9][9]; char BlankChar; bool debug; void printTracerTryingValue(int xpos, int ypos); bool solve(int xpos, int ypos); bool verifyValue(int xpos, int ypos); public: SudokuPuzzle(); void print(); void setBoardValue(int xpos, int ypos, int value); int getBoardValue(int xpos, int ypos); bool solve(); }; SudokuPuzzle::SudokuPuzzle(){ debug = false; for (int i = 0; i < 9; ++i){ for (int j = 0; j < 9; ++j){ board[j][i] = 0; } } } void SudokuPuzzle::print(){ for (int y = 0; y < 9; y++){ if (y % 3 == 0){ cout << "-------------------------------" << endl; } for (int x = 0; x < 9; x++){ if (x % 3 == 0){ cout << "|"; } if (board[x][y] != 0){ cout << " " << board[x][y] << " "; } else{ cout << " . "; } } cout << "|" << endl; } cout << "-------------------------------" << endl; } void SudokuPuzzle::setBoardValue(int xpos, int ypos, int value){ board[xpos][ypos] = value; } void SudokuPuzzle::setBoardValue(int xpos, int ypos, int value){ board[xpos][ypos] = value; } bool SudokuPuzzle::solve(){ return solve(0,0); } void SudokuPuzzle::setBoardValue(int xpos, int ypos, int value){ board[xpos][ypos] = value; } bool SudokuPuzzle::solve(){ return solve(0,0); } int SudokuPuzzle::getBoardValue(int xpos, int ypos){ return board[xpos][ypos]; } bool SudokuPuzzle::solve(int xpos, int ypos){ if (board[xpos][ypos] != 0){ if (verifyValue(xpos, ypos)){ if (xpos == 8 && ypos == 8){ return true; } int next_x = xpos+1; int next_y = ypos; if (next_x >= 9){ next_x = 0; next_y++; } return solve(next_x, next_y); } else{ return false; } } for(int value = 1; value < 10; value++){ setBoardValue(xpos, ypos, value); if (verifyValue(xpos, ypos)){ if (xpos == 8 && ypos == 8){ return true; } int next_x = xpos+1; int next_y = ypos; if (next_x >= 9){ next_x = 0; next_y++; } if (solve(next_x, next_y)){ return true; } } } board[xpos][ypos] = 0; return false; } bool SudokuPuzzle::verifyValue(int xpos, int ypos){ printTracerTryingValue(xpos, ypos); int value = board[xpos][ypos]; for (int x_verify = 0; x_verify < 9; x_verify++){ if (x_verify == xpos){ continue; } int verifyValue = board[x_verify][ypos]; if (verifyValue == value){ return false; } } for (int y_verify = 0; y_verify < 9; y_verify++){ if (y_verify == ypos){ continue; } int verifyValue = board[xpos][y_verify]; if (verifyValue == value){ return false; } } int box_x = xpos / 3; int box_y = ypos / 3; for (int y_verify = box_y * 3; y_verify < box_y * 3 + 3; y_verify++){ for (int x_verify = box_x * 3; x_verify < box_x * 3 + 3; x_verify++){ if (x_verify == xpos && y_verify == ypos){ continue; } int verifyValue = board[x_verify][y_verify]; if (verifyValue == value){ return false; } } } return true; } void SudokuPuzzle::printTracerTryingValue(int xpos, int ypos){ if(debug){ for (int i = 0; i < xpos+ypos; i++){ cout << " "; } cout << "Trying value " << board[xpos][ypos] << " at board[" << xpos << "][" \ << ypos <<"]" << endl; } } int main(int argc, char *const argv[]){ SudokuPuzzle puzzle; string filename; string line; ifstream in; ofstream out; cout << "Enter filename:" << endl; cin >> filename; in.open(filename); while(getline(in, line)){ puzzle.line.print() } cout << endl; if(puzzle.solve()){ cout << "Solution:" << endl; puzzle.print(); } else{ cout << "Puzzle is not solvable."; } cout << endl; return 0; }
Your question is written a bit confusingly, but I'll try to answer it as I've understood it. Firstly, I hope you don't have the actual function calls in your text file - there's no way to call a function directly like that from a text file. Also, in your while statement in main(), calling puzzle.line.print() doesn't make sense, because print() is not a method of std::string and your 'line' is not a member of the SudokuPuzzle type. So, if you're just interested in storing and reading positions on a grid where you expect the input to be regular, you might have a file that simply looks like this: 0 0 1 1 1 3 2 2 9 ...(etc) From there, without concern for input or error checking, we might have some code like this, to read from the file: std::ifstream readFile("Text.txt"); //construct ifstream object from text file std::vector<int> vec; int file_input; //temporary variable to hold input while(readFile >> file_input) { vec.push_back(file_input); }; readFile.close(); working with filestreams is just like working with std::cin or std::cout; You use the stream operators << and >> to carry information between streams and other data. Now, we can do whatever processing we need to on the data structure (in this case std::vector but it could be anything). When we need to write it back, we can use this kind of code: std::ofstream writeFile("Text.txt"); //overwrites contents! for(unsigned i = 0; i < vec.size(); ++i) { //this is just to format the text output to the same way it came in writeFile << vec[i] << ' '; if ((i + 1) % 3 == 0) writeFile << '\n'; } writeFile.close(); In the block of code where you format the text for output is where you may want to do something like using characters like | and _ to create some grid pattern. You should have some idea of how to go about that (think about where they need to be inserted, they should come in predictable places). Here's some example code as well.
why increment variable changing the value of the array when they have different names
Can someone please help me. I am struggling to find in my code why the last value in column B always gets incremented by one. I have written some code since its an assignment due today. I also cant figure out why the last value in column B is not equal to 196 because in the reset function it sets all the values in the array to 196 . Any suggestion would be appreciated. Thank you in advance #include <iostream> //includes cin cout #include <iomanip> using namespace std; //setting up the environment const int NUMBER_OF_ROWS = 3; const int NUMBER_OF_COLUMNS = 3; void printAllSeats(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]); void reset(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]); void askForUsersSeat(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS], int &SeatCountNumber, bool &anyFreeSeats); bool isFull(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]); bool isEmpty(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]); int main() { //main starts int maxSeats; int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]; int SeatCountNumber = 0; bool anyFreeSeats; reset(seats); anyFreeSeats = true; SeatCountNumber = 0; while (anyFreeSeats) { printAllSeats(seats); askForUsersSeat(seats, SeatCountNumber, anyFreeSeats); } system("pause"); return 0; } //main ends void printAllSeats(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]) { cout << endl; cout << setw(10) << " - = Available R = Reserved\n\n"; for (int i = 0; i <= NUMBER_OF_ROWS; i++) { cout << setw(15) << i << " "; for (int j = 0; j < NUMBER_OF_COLUMNS; j++) { if (i == 0) { cout << " " << static_cast<char>(j + 65) << " "; } else { cout << " " << static_cast<char>(seats[i][j]) << " "; } } cout << endl; } cout << endl; } void reset(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]) { //set all values in array to 196 for (int i = 0; i <= NUMBER_OF_ROWS; i++) { for (int j = 0; j <= NUMBER_OF_COLUMNS; j++) { seats[i][j] = 196; } } } void askForUsersSeat(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS], int &SeatCountNumber, bool &anyFreeSeats) { int seatChoiceNumber; char seatChoiceLetter; int letter; int maxSeats = NUMBER_OF_ROWS * NUMBER_OF_COLUMNS; cout << "Seat (Row, Column): "; cin >> seatChoiceNumber >> seatChoiceLetter; letter = static_cast<int>(toupper(seatChoiceLetter)); if (((letter >= 65) && (letter < (65 + NUMBER_OF_COLUMNS))) && ((seatChoiceNumber > 0) && (seatChoiceNumber <= NUMBER_OF_ROWS))) { if (seats[(seatChoiceNumber)][(letter - 65)] == 82) { } else { seats[(seatChoiceNumber)][(letter - 65)] = 82; SeatCountNumber++; //this changes last value in column B for some reason if (SeatCountNumber < maxSeats) { anyFreeSeats = true; } else if (SeatCountNumber > maxSeats) { printAllSeats(seats); anyFreeSeats = false; } } } else { } }
I kind of cleaned up the code a bit. It seems you found your answer in the comments, so I just did some indentation. Try and eliminate whitespaces in your code (mind you, the one I am putting here is not perfect either, but you get the point). Clean and easy to read code doesn't only make it better for you, but as you get higher up in the industry and other people begin reading and working on your code, having clean and easy to read code really helps :) #include <iostream> //includes cin cout #include <iomanip> using namespace std; //setting up the environment const int NUMBER_OF_ROWS = 3; const int NUMBER_OF_COLUMNS = 3; void printAllSeats(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]); void reset(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]); void askForUsersSeat(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS], int &SeatCountNumber, bool &anyFreeSeats); bool isFull(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]); bool isEmpty(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]); int main() { int maxSeats; int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]; int SeatCountNumber = 0; bool anyFreeSeats; reset(seats); anyFreeSeats = true; SeatCountNumber = 0; while (anyFreeSeats) { printAllSeats(seats); askForUsersSeat(seats, SeatCountNumber, anyFreeSeats); } system("pause"); return 0; } //main ends void printAllSeats(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]) { cout << endl; cout << setw(10) << " - = Available R = Reserved\n\n"; for (int i = 0; i <= NUMBER_OF_ROWS; i++) { cout << setw(15) << i << " "; for (int j = 0; j < NUMBER_OF_COLUMNS; j++) { if (i == 0) { cout << " " << static_cast<char>(j + 65) << " "; } else { cout << " " << static_cast<char>(seats[i][j]) << " "; } } cout << endl; } cout << endl; } void reset(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]) { //set all values in array to 196 for (int i = 0; i <= NUMBER_OF_ROWS; i++) { for (int j = 0; j <= NUMBER_OF_COLUMNS; j++) { seats[i][j] = 196; } } } void askForUsersSeat(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS], int &SeatCountNumber, bool &anyFreeSeats) { int seatChoiceNumber; char seatChoiceLetter; int letter; int maxSeats = NUMBER_OF_ROWS * NUMBER_OF_COLUMNS; cout << "Seat (Row, Column): "; cin >> seatChoiceNumber >> seatChoiceLetter; letter = static_cast<int>(toupper(seatChoiceLetter)); if (((letter >= 65) && (letter < (65 + NUMBER_OF_COLUMNS))) && ((seatChoiceNumber > 0) && (seatChoiceNumber <= NUMBER_OF_ROWS))) { if (seats[(seatChoiceNumber)][(letter - 65)] == 82) { } else { seats[(seatChoiceNumber)][(letter - 65)] = 82; SeatCountNumber++; //this changes last value in column B for some reason if (SeatCountNumber < maxSeats) { anyFreeSeats = true; } else if (SeatCountNumber > maxSeats) { printAllSeats(seats); anyFreeSeats = false; } } } else { } } Note: Some more whitespaces could even come out but I generally like to have spaces after certain statements (personal preference).