commenting out cout statement causes different (and incorrect) output - c++

I have never experienced anything like this. I was using a cout statement to help me debug a small program, and once I was satisfied with my code I commented out the cout. Now, the code no longer works. Below is the code with the cout commented out.
The intent of this program is to test the two hard coded boolean two dimensional arrays for having an odd number of true statements on each row. Thus, the first array should return true and the second array should return false. With the cout statement commented out both instead return false.
#include <iostream>
using namespace std;
template <size_t size_y>
bool findEvenDegrees(bool mapArray[][size_y])
{
bool returnValue;
for (int x=0; x<size_y; x++)
{
int result = 0;
for (int y=0; y<size_y; y++)
{
result = result + mapArray[x][y];
//the line below causes the problem
cout << mapArray[x][y] << "\t" << result << "\t" << x << endl;
}
if (result%2 == 1)
{
returnValue = false;
break;
}
}
if (returnValue== false)
{
return returnValue;
}
else
{
return true;
}
}
int main()
{
bool array1[][6] =
{
{false,true,true,false,false,false},
{true,false,false,true,false,false},
{true,false,false,true,false,false},
{false,true,true,false,true,true},
{false,false,false,true,false,true},
{false,false,false,true,true,false}
};
bool array2[][8] =
{
{false,true,true,false,false,false,false,false},
{true,false,false,true,false,false,false,false},
{true,false,false,true,false,false,false,false},
{false,true,true,false,true,false,false,false},
{false,false,false,true,false,true,true,false},
{false,false,false,false,false,true,false,true},
{false,false,false,false,true,false,false,true},
{false,false,false,false,false,true,true,false}
};
bool answer1 = findEvenDegrees(array1);
bool answer2 = findEvenDegrees(array2);
if (answer1 == true)
{
cout << "Array 1 has a even degree for every switch." << endl;
}
else
{
cout << "Array 1 has a odd degree for at least one switch." << endl;
}
if (answer2 == true)
{
cout << "Array 2 has a even degree for every switch.";
}
else
{
cout << "Array 2 has a odd degree for at least one switch.";
}
return 0;
}

You never initialize returnValue. If it happens to start out as false it will stay that way and the function will return false.

First, I cleaned up your code a little, and arrived at:
#include <iostream>
template <size_t S>
bool findEvenDegrees(bool (&themap)[S][S]) {
for( bool(&row)[S]: themap ) {
bool is_degree_odd = false;
for( auto col: row )
is_degree_odd ^= col;
if( is_degree_odd )
return false;
}
return true;
}
int main()
{
using std::cout;
using std::endl;
bool array1[6][6] = {
{false,true,true,false,false,false},
{true,false,false,true,false,false},
{true,false,false,true,false,false},
{false,true,true,false,true,true},
{false,false,false,true,false,true},
{false,false,false,true,true,false}
};
cout << "Array 1 has an "
<< (findEvenDegrees(array1) ? "even degree for every" : "odd degree for at least one")
<< " switch." << endl;
bool array2[8][8]= {
{false,true,true,false,false,false,false,false},
{true,false,false,true,false,false,false,false},
{true,false,false,true,false,false,false,false},
{false,true,true,false,true,false,false,false},
{false,false,false,true,false,true,true,false},
{false,false,false,false,false,true,false,true},
{false,false,false,false,true,false,false,true},
{false,false,false,false,false,true,true,false}
};
cout << "Array 2 has an "
<< (findEvenDegrees(array2) ? "even degree for every" : "odd degree for at least one")
<< " switch." << endl;
return 0;
}
In the process of cleaning it up, I eliminated the if(result%2 == 1) { resultValue = true; break; }, by effectively returning when I found the first odd-degree row. As I eliminated the resultValue variable, I also killed the "unitialized" bug mentioned by #sth.

Related

c++ (Compare all spaces with Pawns )

I have a board game that has spaces (has numeral values 1,2,3, etc.) starting from 1 and 16 pieces of pawns; four for each player.
I want to show the result of my board game at some point. I tried the method below but that will make my code extremely long.
i have 16 pieces and 100 spaces that i have to repeat that code with 100 space that would take forever. the code below is just for one space (the first space)
Any idea how to show my result in a short way? Thanks in advance!
Here is my old-fashioned way:
//space 1
if (bpiece1->value == 1)
{
cout << " bpiece1";
}
else if (bpiece2->value == 1)
{
cout << " bpiece2";
}
else if (bpiece3->value == 1)
{
cout << " bpiece3";
}
else if (bpiece4->value == 1)
{
cout << " bpiece4";
}
else if (gpiece1->value == 1)
{
cout << " gpiece1";
}
else if (gpiece2->value == 1)
{
cout << " gpiece2";
}
else if (gpiece3->value == 1)
{
cout << " gpiece3";
}
else if (gpiece4->value == 1)
{
cout << " gpiece4";
}
else if (ypiece1->value == 1)
{
cout << " ypiece1";
}
else if (ypiece2->value == 1)
{
cout << " ypiece2";
}
else if (ypiece3->value == 1)
{
cout << " ypiece3";
}
else if (y4->value == 1)
{
cout << " y4";
}
else if (rpiece1->value == 1)
{
cout << " rpiece1";
}
else if (rpiece2->value == 1)
{
cout << " rpiece2";
}
else if (rpiece3->value == 1)
{
cout << " rpiece3";
}
else if (rpiece4->value == 1)
{
cout << " rpiece4";
}
else
{
cout << " 01";
}
C++ is an object-oriented language. Therefore, we start by creating a class that stores your board and implements all functions on it. Like
//Board.h
#include <array>
using std::array;
enum class Figure { None, Pawn };
class Board {
private:
array<array<Figure, 8>, 8> fields; //8x8 if it was a chess board
public:
void print() const;
};
//Board.cpp
#include "Board.h"
#include <iostream>
using std::cout;
using std::endl;
#include <string>
using std::string;
inline string to_string(const Figure figure){
switch(figure){
case Figure::None:
return " ";
case Figure::Pawn:
return "p";
}
//throw error here
return "";
}
void Board::print() const {
for(size_t i = 0; i < fields.size(); i++){
for(size_t j = 0; j < fields[i].size(); j++){
cout << to_string(fields[i][j]);
}
cout << endl;
}
cout << endl;
}
If this is new to you, you should really read the basic tutorials first and make sure that you understand each line I wrote in the end.
Important here is: Representation, represenation, representation. Don't think in "1 is a pawn", think in "a pawn is a pawn". Everything that has a function which you can think of should probably be a class, a structure or an enum.

Negative value not being added to Array

Problem
I have 2 arrays, one for positive numbers, one for negative numbers. For some reason, if the first number to be added is a negative number, it creates the array space to add the number yet the number inserted will always be 0.
Code for adding
Here is my add method, it determines if the value is negative or positive and adds the value to the appropriate array:
bool MyClass::addInt(int valueToBeInserted){
if (valueToBeInserted >= 0){
if (posArrayIterator >= sizeOfMyArray){
return false;
} else {
cout << "added " << valueToBeInserted << "\n" << endl;
myPArray[posArrayIterator] = valueToBeInserted;
posArrayIterator ++;
return true;
}
} else {
if (negArrayIterator >= sizeOfMyArray){
return false;
} else {
cout << "added " << valueToBeInserted << "\n" << endl;
myNarray[negArrayIterator] = valueToBeInserted;
negArrayIterator ++;
return true;
}
}
}
Output
With the following test:
b.addInt(-1);
b.addInt(-3);
b.addInt(-9);
The expected output would be
[-1, -3, -9]
but output is
[-3, -9, 0].
Any help is much appreciated.
Since you are not posting the whole class I can only guess where the problem is.
1) Are posArrayIterator and negArrayIterator initialized to 0? They should be!
2) What is a value of sizeOfMyArray?
There is nothing wrong with your bool MyClass::addInt(int valueToBeInserted)
See example below:
class MyClass
{
private:
int sizeOfMyArray;
int posArrayIterator;
int negArrayIterator;
int myNarray[20];
int myPArray[20];
public:
MyClass(){
sizeOfMyArray = 20;
posArrayIterator = 0;
negArrayIterator = 0;
};
bool addInt(int value);
void printNArray()
{
cout << "[ ";
for (int i=0; i<negArrayIterator; i++)
{
cout << myNarray[i];
if ( (i+1) < negArrayIterator )
{
cout << ", ";
}
}
cout << "]";
}
};
bool MyClass::addInt(int valueToBeInserted){
if (valueToBeInserted >= 0){
if (posArrayIterator >= sizeOfMyArray){
return false;
} else {
cout << "added " << valueToBeInserted << "\n" << endl;
myPArray[posArrayIterator] = valueToBeInserted;
posArrayIterator ++;
return true;
}
} else {
if (negArrayIterator >= sizeOfMyArray){
return false;
}
else {
cout << "added " << valueToBeInserted << "\n" << endl;
myNarray[negArrayIterator] = valueToBeInserted;
negArrayIterator ++;
return true;
}
}
}
int main()
{
MyClass b;
b.addInt(-1);
b.addInt(-3);
b.addInt(-9);
b.printNArray();
return 0;
}
Output:
added -1
added -3
added -9
[ -1, -3, -9]

For loop not accessing and performing check

I am having some troubles with one of my for loops not executing correctly. I have stepped through my code to try and see what's going on but it just seems to skip the for loop completely therefore giving the incorrect output.
My for loop looks like this:
for (auto &link : p1links){
if (link->accessTransportType() != type){
continue;
}
if ((p1->accessReference() == link->accessReferenceNumber1() && p2->accessReference() == link->accessReferenceNumber2()) || (p1->accessReference() == link->accessReferenceNumber2() && p2->accessReference() == link->accessReferenceNumber1()))
{
anyPASS = true;
}
}
if (anyPASS){
m_outFile << p1->accessReference() << "," << p2->accessReference() << "," << "PASS" << endl;
return true;
}
else{
m_outFile << p1->accessReference() << "," << p2->accessReference() << "," << "FAIL" << endl;
return true;
break;
}
}
m_outFile << endl;
And these are the methods its trying to access when I say accessTransportType() etc.
class Links
{
public:
Links(int, int, const string&, bool);
~Links();
int accessReferenceNumber1()const{ return referenceNumber1; }
int accessReferenceNumber2()const{ return referenceNumber2; }
string accessTransportType()const{ return transportType; }
bool accessHasBeenSearched()const{ return hasBeenSearched; }
private:
int referenceNumber1 = 0;
int referenceNumber2 = 0;
string transportType = "";
bool hasBeenSearched = false;
};
My output is currently returning the FAIL every time but I am looking to return PASS for my first check and then a FAIL when it does the second check.

Program soft-locking when calling second* function

So, I'm practising my C++ code by writing a program that creates a matching-pairs game out of a grid with user-specified size. To do this I've separated each action (initialising the grid, drawing the grid, hiding the pairs and finding the pairs from user input) into a function.
Unfortunately, at some point - I can't tell when or how - the program began failing to call the second* and subsequent functions. After calling drawGrid, it should move on to hidePairs immediately - however, it just stops at that step. The cursor in the command window keeps blinking, so the program's running just fine, but nothing I can do will make it progress.
I've checked via debugging, and it does successfully execute drawGridand moves on to the next line in main, but then no more code gets executed. What am I doing wrong?
*EDIT: third function, it successfully draws the grid, THEN stops before hiding the pairs. Unnecessary calls-by-reference removed and all functions added for clarity. My bad :P
#include <iostream>
#include <random>
#include <algorithm>
void drawGrid(int gridX, int gridY, char gridArray[][30]);
void hidePairs(int gridX, int gridY, char pairsArray[][30], int *numPairs);
void findPairs(int gridX, int gridY, char gridArray[][30], char pairsArray[][30], int *numPairs);
void initialiseGrid(int gridX, int gridY, char gridArray[][30], char pairsArray[][30]);
int main()
{
int gridX, gridY, numPairs;
//Ask user for gridX(width) and gridY(height)
std::cout << "Please enter the width and height of the grid you want to use." << std::endl;
bool gridIsNotEven = true;
while (gridIsNotEven == true)
{
std::cin >> gridX >> gridY;
if ((gridX*gridY) % 2 == 0)
{
gridIsNotEven = false;
}
else
{
std::cout << std::endl << "The grid produced by these two numbers has an odd number of spaces." << std::endl;
}
}
if (gridX*gridY > 30)
{
std::cout << "This grid is larger than recommended." << std::endl;
}
gridX++;
gridY++;
char gridArray[30][30];
char pairsArray[30][30];
numPairs = ((gridX*gridY) / 2);
//Func : initialiseGrid
initialiseGrid(gridX, gridY, gridArray, pairsArray);
//Func : drawGrid
drawGrid(gridX, gridY, gridArray);
//Func : hidePairs
hidePairs(gridX, gridY, pairsArray, &numPairs);
//Func : findTreasure
findPairs(gridX, gridY, gridArray, pairsArray, &numPairs);
system("Pause");
return 0;
}
void drawGrid(int gridX, int gridY, char gridArray[][30])
{
int printX, printY;
//For(printX = 0, printX < gridX, printX++)
for (printY = 0; printY < gridY; printY++)
{
//For(printY = 0, printY < gridY, printY++)
for (printX = 0; printX < gridX; printX++)
{
std::cout << gridArray[printX][printY] << " ";
}
//END FOR
//Print new line
std::cout << std::endl;
}
//END FOR
}
void hidePairs(int gridX, int gridY, char pairsArray[][30], int *numPairs)
{
int pairsMade, halfPair, curPairX = 0, curPairY = 0;
char pairSymbol = '!';
for (pairsMade = 0; pairsMade < *numPairs; pairsMade++)
{
halfPair = 0;
while (halfPair < 2)
{
curPairX = rand() % gridX;
curPairY = rand() % gridY;
if (pairsArray[curPairX][curPairY] == '?')
{
pairsArray[curPairX][curPairY] = pairSymbol;
halfPair++;
}
}
pairSymbol++;
}
}
void findPairs(int gridX, int gridY, char gridArray[][30], char pairsArray[][30], int *numPairs)
{
int guess1X = 0, guess1Y = 0, guess2X, guess2Y, printChar, pairsFound = 0;
//Display pairs
char pairSymbol = '!';
printChar = 0;
std::cout << std::endl << "The following symbols will be used in the grid:" << std::endl << std::endl;
while (printChar < *numPairs)
{
std::cout << pairSymbol << std::endl;
pairSymbol++;
printChar++;
}
//while ((guessX != treasureX) OR(guessY != treasureY))
while (pairsFound != *numPairs)
{
// User input : guessX and guessY
std::cout << std::endl << "Please enter the co-ordinates of your first guess (e.g. 'X Y')" << std::endl << std::endl;
std::cin.clear();
std::cin >> guess1X >> guess1Y;
gridArray[guess1X][guess1Y] = pairsArray[guess1X][guess1Y];
drawGrid(gridX, gridY, gridArray);
std::cout << std::endl << "Please enter the co-ordinates of your second guess (e.g. 'X Y')" << std::endl << std::endl;
std::cin.clear();
std::cin >> guess2X >> guess2Y;
gridArray[guess2X][guess2Y] = pairsArray[guess2X][guess2Y];
drawGrid(gridX, gridY, gridArray);
if (guess1X > gridX || guess1X < 1 || guess1Y > gridY || guess1Y < 1)
{
std::cout << std::endl << guess1X << ", " << guess1Y << " does not lie inside the grid. Try again." << std::endl;
continue;
}
else if (gridArray[guess1X][guess1Y] == gridArray[guess2X][guess2Y])
{
pairsFound++;
}
else
{
std::cout << std::endl << "Pair not matching" << std::endl << std::endl;
gridArray[guess1X][guess1Y] = '?';
gridArray[guess2X][guess2Y] = '?';
}
// END IF
}
//Print ‘Success! etc.’
std::cout << std::endl << "Success! You found all the pairs!" << std::endl << std::endl;
}
void initialiseGrid(int gridX, int gridY, char gridArray[][30], char pairsArray[][30])
{
int printX, printY;
for (printY = 0; printY < gridY; printY++)
{
for (printX = 0; printX < gridX; printX++)
{
if ((printX == 0))
{
gridArray[0][printY] = printY + '0';
pairsArray[0][printY] = printY + '0';
}
else if ((printY == 0))
{
gridArray[printX][0] = printX + '0';
pairsArray[printX][0] = printX + '0';
}
else
{
gridArray[printX][printY] = '?';
pairsArray[printX][printY] = '?';
}
}
}
}
You initialised the number of pairs to numPairs = gridX * gridY / 2, but that size (gridX, gridY) contains also the header column and row, that do not play a role in the pairing.
So to fix this, your numPairs should be (gridX-1) * (gridY-1) / 2.
Else, the pairs will have been exhausted, but the pairing function is still looking! This is your infinite loop.
I also advise you to find a better name for gridX and gridY to indicate that the headers are counted, or to be very careful in the rest of your code that you understand what gridX and gridY mean and that the grid only starts being an actual thing at index 1 rather than index 0.
It seams it fails only if you add numbers 30 and higher caused by array size
I dont know your settings but ensure you have compiler setting of language standard like GNU C++11
it should work
Turns out there's an infinite loop in the hidePairs function. It's not reading the correct co-ordinates in the pairsArray, so there are spaces it never fills in. And since the loop is only set to end when all unused spaces are filled, it never stops.
Advice for others: always sanity-check your loops!

How can I run multiple functions after an if statement

How can I have a the return and cout both take place as a result of being true or false?
gameState computerMove(gameState state) {
if (sizeOfPile(state,1) > 0)
return removeCoinsFromPile(state,1,1);
cout << "I take 1 coin from Pile 1." << endl;
else
return removeCoinsFromPile(state,1,2);
cout << "I take 1 coin from Pile 2" << endl;
C++ uses the concept of a "compound statement" - a statement made up of multiple sub-statements - denoted by brackets, { and }, just as you used for your function.
gameState computerMove(gameState state) {
}
You can use a compound statement pretty much anywhere you can use a regular statement:
int sum = 0;
for (int i = 0; i < 100; ++i)
sum += i;
or
int sum = 0;
for (int i = 0; i < 100; ++i) {
sum += i;
}
These do the same thing, but if we need to add more instructions inside the for, we add them between the '{'s.
One important thing about this: a compound statement is considered to have "scope"
int i = 1;
{
int i = 2;
std::cout << "inside, i = " << i << '\n';
}
std::cout << "outside, i = " << i << '\n';
Programmers sometimes use this to maintain lifetime of advanced objects. The following code opens a file and releases it as soon as we're done with it - because that's what happens when the 'istream' object goes out of scope.
std::string instructions;
{
std::istream file("instructions.txt");
file >> instructions;
} // <-- 'file' goes away, which closes the file.
However: the return keyword causes a function to end and return a value. So you're going to have to do that after your cout.
if (sizeOfPile(state,1) > 0) {
cout << "I take 1 coin from Pile 1." << endl;
return removeCoinsFromPile(state,1,1);
}
Your function ends after the return statement, so you should prepare what to return in a variable, print it, and then do the return, like this:
int res;
if (sizeOfPile(state,1) > 0) {
res = removeCoinsFromPile(state,1,1);
cout << "I take 1 coin from Pile 1." << endl;
} else {
res = removeCoinsFromPile(state,1,2);
cout << "I take 1 coin from Pile 2" << endl;
}
return res;
However, in your specific case you can rewrite this without an if by using a conditional operator:
int pile = sizeOfPile(state,1) > 0 ? 1 : 2;
res = removeCoinsFromPile(state, 1, pile);
cout << "I take 1 coin from Pile " << pile << endl;
return res;
You could move the return statement to after the cout statement.
gameState computerMove(gameState state) {
int res;
if (sizeOfPile(state,1) > 0) {
cout << "I take 1 coin from Pile 1." << endl;
res = removeCoinsFromPile(state,1,1);
} else {
cout << "I take 1 coin from Pile 2" << endl;
res = removeCoinsFromPile(state,1,2);
}
return res;
}
This website might be helpful when learning about functions in c++.