Why doesn't this output "Please try again" when loop runs again? - c++

Hello I am trying to learn c++ and I wanted to give a little practice with a program. However I'm having trouble using cout within the loop.
This is the loop I'm trying to output text from. When the user enters a number that isn't valid it is supposed to say "Sorry try again!"
while (datecheck)
{
bool check(false);
if (check)
std::cout<<"Sorry try again!"<<std::endl;
std::cin>>c;
if (c >= 1)
{
if (b == 2 && c <= 28)
datecheck = false;
if (b == 2 && a % 4 == 0 && c <= 29)
datecheck = false;
if (b == 4 || b == 6 || b == 9 || b == 11 && c <= 30)
datecheck = false;
if (c <= 31)
datecheck = false;
}
check = true;
}
When it outputs and I purposely keep myself in the loop it doesn't output anything
Year: -20
-20
-20

You declare a fresh new variable check at every iteration. And you initialize that variable to false every time. So move that declaration before the while loop.
Change this:
while (datecheck)
{
bool check(false);
...
check = true;
}
to this:
bool check(false);
while (datecheck)
{
...
check = true;
}

The problem is with declaration of bool check(false);. This keeps on re-assigning value to false at beginning of each iteration.
A simple fix could be to get-rid of use of check variable and use only datecheck.
bool datecheck(true);
while (true)
{
std::cin>>c;
if (c >= 1)
{
if (b == 2 && c <= 28)
datecheck = false;
if (b == 2 && a % 4 == 0 && c <= 29)
datecheck = false;
if (b == 4 || b == 6 || b == 9 || b == 11 && c <= 30)
datecheck = false;
if (c <= 31)
datecheck = false;
}
if (datecheck)
{
std::cout<<"Sorry try again!"<<std::endl;
}
else
{
break;
}
}

Related

how to get rid of warning: control reaches end of non-void function c++

I wrote this code and don't understand why there´s a warning, as far as I can tell every branch has a return value. How could I fix this?
bool ValidDate(int d, int m, int a) {
if ((m < 1) || (m > 12)) {
return false;
} else {
if ((m == 1) || (m == 3) || (m == 5) || (m == 7) || (m == 8) || (m == 10) || (m == 12)) {
if (d >= 1 && d <= 31) {
return true;
} else {
return false;
}
} else if ((m == 4) || (m == 6) || (m == 9) || (m == 11)) {
if (d >= 1 && d <= 30) {
return true;
} else {
return false;
}
} else if (m == 2) {
if (a % 4 == 0) {
if (d >= 1 && d <= 29) {
return true;
} else {
return false;
}
} else {
if (d >= 1 && d <= 28) {
return true;
} else {
return false;
}
}
}
}
}
I undestand what the error means but can´t find where the problem is.
The warning arises because the compiler does not know that the else if (m == 2) condition will always be true when that condition is checked, as all other possibilities must have been exhausted. Since the compiler does not perform this kind of analysis, you as the programmer might as well help the compiler by explicitly saying so by just removing that check. You can still leave in a comment saying "m must be 2" to help human readers of the code.
The nested if-else branches can also be simplified considerably by noting the following equivalent constructs:
A check like
if (expr)
return true;
else
return false;
can always be replaced by
return expr;
Similarly, if you're returning at the end of a branch, the subsequent else is redundant. i.e.
if (expr1) {
// ...
return // ...;
}
else if (expr2) {
// ...
return // ...;
}
can be replaced by
if (expr1) {
// ...
return // ...;
}
if (expr2) { // the else is redundant here
// ...
return // ...;
}
Applying these transformations give a cleaner function:
bool ValidDate2(int d, int m, int a) {
if ((m < 1) || (m > 12))
return false;
if ((m == 1) || (m == 3) || (m == 5) || (m == 7) || (m == 8) || (m == 10) || (m == 12))
return d >= 1 && d <= 31;
if ((m == 4) || (m == 6) || (m == 9) || (m == 11))
return d >= 1 && d <= 30;
// Now m must be 2
return a % 4 == 0 ?
d >= 1 && d <= 29 :
d >= 1 && d <= 28;
}
Note that I've replaced the last if-else by a ternary operator ?:, though whether this makes the code more readable is subjective. Certainly nesting multiple ?: can make it harder to see the structure of the branches.
Here's a demo.
Another way of restructuring the code is to use a switch statement for all the different values of m. This reduces the complexity of the if conditionals, and can make the code easier to read:
bool ValidDate2(int d, int m, int a) {
switch(m) {
case 1: [[fallthrough]];
case 3: [[fallthrough]];
case 5: [[fallthrough]];
case 7: [[fallthrough]];
case 8: [[fallthrough]];
case 10: [[fallthrough]];
case 12: return d >= 1 && d <= 31;
case 4: [[fallthrough]];
case 6: [[fallthrough]];
case 9: [[fallthrough]];
case 11: return d >= 1 && d <= 30;
case 2: return a % 4 == 0 ?
d >= 1 && d <= 29 :
d >= 1 && d <= 28;
default: return false; // m < 1 or m > 12
}
}
Here's a demo.

How to Find All TRUE Conditions and Concatenate Corresponding Variables into New Variable?

a = 4
b = 5
c = 7
if (a >= 4){
text1 = “a is high”;
}
if (b >= 8){
text2 = “b is high”;
}
if (c >= 6){
text3 = “c is high”;
}
In C or C++, how would I find which of these statements are true (a & c) and create a new variable that concatenates their accompanying variables containing text to produce a result like “a is high and c is high”? The next time the code executes it may find that only a is high, or whatever the case may be. How would I go about doing this?
Use a single variable and keep on appending as you get the required information.
string text1;
if (a >= 4)
text1.append("a is high");
if (b >= 8)
{
if(text1.length()!=0)
text1.append(" and ");
text1.append("b is high");
}
if (c <= 6)
{
if(text1.length()!=0)
text1.append(" and ");
text1.append("c is high");
}
The answer of Gaurav Sehgal is elegant. Here is another way of writing it-
C++
string text = "";
if (a >= 4)
text += "a is high";
if (b >= 8)
{
if(text.size() > 0)
text += " and ";
text += "b is high";
}
if (c <= 6)
{
if(text.size() > 0)
text += " and ";
text += "c is high";
}
C
char text[buf_size] = {'\0'};
if (a >= 4)
strcat(text, "a is high");
if (b >= 8)
{
if(strlen(text) > 0)
strcat(text, " and ");
strcat(text, "b is high");
}
if (c <= 6)
{
if(strlen(text) > 0)
strcat(text, " and ");
strcat(text, "c is high");
}
create a temporary variable as result.
a = 4
b = 5
c = 7
result="";
if (a >= 4){
result += “a is high”;
}
if (b >= 8){
if(result==""){
result += “b is high”;
}else{
result += “and b is high”;
}
}
if (c <= 6){
if(result==""){
result += “c is high”;
}else{
result += “and c is high”;
}
}
text1=result
Using numeric comparison operators as well as logical AND ("&&"), the following C code finds all true conditions while obviating the need for a new variable as it efficiently uses text1, text2 and text3. Note, the result avoids any duplicate output:
#include <stdio.h>
#include <string.h>
int main(void) {
int a = 4;
int b = 5;
int c = 7;
char text1[] = "a is high";
char text2[] = "b is high";
char text3[] = "c is high";
if ( a >= 4 && c < 6){
puts(text1);
}
if (b >= 8){
puts(text2);
}
if (c >= 6 && a < 4) {
puts(text3);
}
if( ( a >= 4 ) && ( c >= 6 ) ) {
strcat(text1," and ");
strcat(text1,text3);
puts(text1);
}
return 0;
}
See demo

Conditioning for the four cases of the signs of two numbers

I have two numbers A and B. I would like to condition for the four cases of the signs of these two numbers. We could do
if ((A >= 0) && (B >= 0)){
// Do something
};
if ((A >= 0) && (B < 0)){
// Do something
};
if ((A < 0) && (B >= 0)){
// Do something
};
if ((A < 0) && (B < 0)){
// Do something
};
One could produce a function that outputs different values in each case and then use a switch{ case:} statement. For the functions I have thought this doesn't improve the number of comparisons, so there is no much gain.
Which way is recommended for doing this conditioning?
Well, I guess some of those if-s could be put inside else-s of the others so that not all the conditions have to be evaluated always.
if (A >= 0)
{
if (B >= 0)
{
}
else // B < 0
{
}
}
else // A < 0
{
if (B >= 0)
{
}
else // B < 0
{
}
}

C++ Multiple Logical Operator

I'm rather new to C/C++. I have a segment of my application which doesn't seem to work as I'd want but I cannot understand why.
What I'm looking to do is when the 4 key is in the status of down, I'd like it to carry out the 'idle' function. I'd like the idle function to have 2 outcomes.
If the Up OR Down OR Left OR Right OR LMouse AND RButton then carry out the 'movement rotation operation' code else just carry out the standard idle function.
However within my code, it'll loop this while it's down but the moving() will only ever return 0
I've been messing with it for some time and trying to look on google for answers but I cannot understand why.
Here's my segment of code:
int moving()
{
int u = GetAsyncKeyState(VK_UP);
int d = GetAsyncKeyState(VK_DOWN);
int l = GetAsyncKeyState(VK_LEFT);
int r = GetAsyncKeyState(VK_RIGHT);
int mr = GetAsyncKeyState(VK_RBUTTON);
int ml = GetAsyncKeyState(VK_LBUTTON);
if(u == 1 || d == 1 || l == 1 || r == 1 || mr == 1 && ml == 1)
{
return 1;
}
}
void idle()
{
cout << "moving = " << moving() << endl;
if(moving() == 1)
{
cout << "Movement rotation operating." << endl;
}
else
{
cout << "This is the idle statement" << endl;
}
}
int main()
{
while(1)
{
if(GetAsyncKeyState('4'))
{
cout << "4 Pressed" << endl;
idle();
}
}
}
Thank you in advance.
Your logic to determine the button combination needs an extra set of parentheses.
if(u == 1 || d == 1 || l == 1 || r == 1 || (mr == 1 && ml == 1))
Also, 1 will evaluate to true so you can say
if(u || d || l || r || (mr && ml))
You could also make the function return a bool since that is really what you're after.
bool moving()
{
// ...
// code for getting button states
// ...
return (u || d || l || r || (mr && ml))
}

Sudoku solving algorithm C++

I'm trying to make a Sudoku Solving program for a couple of days but I'm stuck with the methods. I found this algorithm here but I don't really understand it:
start at the first empty cell, and put 1 in it.
Check the entire board, and see if there are any conflicts
If there are coflicts on the board, increase the number in the current cell by 1 (so change 1 to 2, 2 to 3, etc)
If the board is clean move, start at step one again.
If all nine possible numbers on a given cell cause a conflict in the board, then you set this cell back to empty, go back to the previous cell, and start again from step 3 (this is where the 'backtracking' comes in).
Here is my code. I think something is wrong with my Help_Solve(...) function. Can you help me to identify the problem, please?
#include <iostream>
#include <iomanip>
#include <time.h>
#include <cstdlib>
#include <windows.h>
using namespace std;
class Sudoku
{
private:
int board[9][9];
int change[9][9];
public:
Sudoku();
void Print_Board();
void Add_First_Cord();
void Solve();
void Help_Solve(int i, int j);
bool Check_Conflicts(int p, int i, int j);
};
Sudoku Game;
void setcolor(unsigned short color) //The function that you'll use to
{ //set the colour
HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hcon,color);
}
Sudoku::Sudoku()
{
for(int i = 1; i <= 9; i++)
for(int j = 1; j <= 9; j++)
board[i][j] = 0;
}
void Sudoku::Print_Board()
{
for(int i = 1; i <= 9; i++)
{
for(int j = 1; j <= 9; j++)
{
if(change[i][j] == 1)
{
setcolor(12);
cout << board[i][j] << " ";
setcolor(7);
}
else cout << board[i][j] << " ";
if(j%3 == 0) cout << "| ";
}
cout << endl;
if(i%3 == 0) cout << "------+-------+---------" << endl;
}
}
void Sudoku::Add_First_Cord()
{
board[1][1] = 5; change[1][1] = 1;
board[1][2] = 3; change[1][2] = 1;
board[1][5] = 7; change[1][5] = 1;
board[2][1] = 6; change[2][1] = 1;
board[2][4] = 1; change[2][4] = 1;
board[2][5] = 9; change[2][5] = 1;
board[2][6] = 5; change[2][6] = 1;
board[3][2] = 9; change[3][2] = 1;
board[3][3] = 8; change[3][3] = 1;
board[3][8] = 6; change[3][8] = 1;
board[4][1] = 8; change[4][1] = 1;
board[4][5] = 6; change[4][5] = 1;
board[4][9] = 3; change[4][9] = 1;
board[5][1] = 4; change[5][1] = 1;
board[5][4] = 8; change[5][4] = 1;
board[5][6] = 3; change[5][6] = 1;
board[5][9] = 1; change[5][9] = 1;
board[6][1] = 7; change[6][1] = 1;
board[6][5] = 2; change[6][5] = 1;
board[6][9] = 6; change[6][9] = 1;
board[7][2] = 6; change[7][2] = 1;
board[7][7] = 2; change[7][7] = 1;
board[7][8] = 8; change[7][8] = 1;
board[8][4] = 4; change[8][4] = 1;
board[8][5] = 1; change[8][5] = 1;
board[8][6] = 9; change[8][6] = 1;
board[8][9] = 5; change[8][9] = 1;
board[9][5] = 8; change[9][5] = 1;
board[9][8] = 7; change[9][8] = 1;
board[9][9] = 9; change[9][9] = 1;
}
bool Sudoku::Check_Conflicts(int p, int i, int j)
{
for(int k = 1; k <= 9; k++)
if(board[i][k] == p) return false;
for(int q = 1; q <= 9; q++)
if(board[q][j] == p) return false;
/*
*00
000
000
*/
if((j == 1 || j == 4 || j == 7) && (i == 1 || i == 4 || i == 7))
{
if(board[i][j+1] == p || board[i][j+2] == p || board[i+1][j] == p ||
board[i+2][j] == p || board[i+1][j+1] == p || board[i+1][j+2] == p ||
board[i+2][j+1] == p || board[i+2][j+2] == p)return false;
}
/*
000
000
*00
*/
if((j == 1 || j == 4 || j == 7) && (i == 3 || i == 6 || i == 9))
{
if(board[i-1][j] == p || board[i-2][j] == p || board[i][j+1] == p ||
board[i][j+2] == p || board[i-1][j+1] == p || board[i-1][j+2] == p ||
board[i-2][j+1] == p || board[i-2][j+2] == p)return false;
}
/*
000
*00
000
*/
if((j == 1 || j == 4 || j == 7) && (i == 2 || i == 5 || i == 8))
{
if(board[i-1][j] == p || board[i+1][j] == p || board[i-1][j+1] == p ||
board[i][j+1] == p || board[i+1][j+1] == p || board[i+1][j+2] == p ||
board[i][j+2] == p || board[i+1][j+2] == p)return false;
}
/*
0*0
000
000
*/
if((j == 2 || j == 5 || j == 8) && (i == 1 || i == 5 || i == 7))
{
if(board[i-1][j] == p || board[i+1][j] == p || board[i-1][j+1] == p ||
board[i][j+1] == p || board[i+1][j+1] == p || board[i+1][j+2] == p ||
board[i][j+2] == p || board[i+1][j+2] == p)return false;
}
/*
000
0*0
000
*/
if((j == 2 || j == 5 || j == 8) && (i == 2 || i == 5 || i == 8))
{
if(board[i-1][j] == p || board[i-1][j-1] == p || board[i-1][j+1] == p ||
board[i][j+1] == p || board[i][j-1] == p || board[i+1][j+1] == p ||
board[i][j] == p || board[i+1][j-1] == p)return false;
}
/*
000
000
0*0
*/
if((j == 2 || j == 5 || j == 8) && (i == 3 || i == 6 || i == 9))
{
if(board[i][j-1] == p || board[i][j+1] == p || board[i-1][j] == p ||
board[i-1][j+1] == p || board[i-1][j-1] == p || board[i-2][j] == p ||
board[i-1][j+1] == p || board[i-2][j-1] == p) return false;
}
/*
00*
000
000
*/
if((j == 3 || j == 6 || j == 9) && (i == 1 || i == 4 || i == 7))
{
if(board[i][j-1] == p || board[i][j-2] == p || board[i+1][j] == p ||
board[i+1][j-1] == p || board[i+1][j-2] == p || board[i+2][j] == p ||
board[i+2][j-1] == p || board[i+2][j-2] == p) return false;
}
/*
000
00*
000
*/
if((j == 3 || j == 6 || j == 9) && (i == 2 || i == 5 || i == 8))
{
if(board[i-1][j] == p || board[i-1][j-1] == p || board[i-1][j-2] == p ||
board[i][j-1] == p || board[i][j-2] == p || board[i+1][j] == p ||
board[i+1][j-1] == p || board[i+1][j-2] == p) return false;
}
/*
000
000
00*
*/
if((j == 3 || j == 6 || j == 9) && (i == 3 || i == 6 || i == 9))
{
if(board[i][j-1] == p || board[i][j-1] == p || board[i-1][j] == p ||
board[i-1][j-1] == p || board[i-1][j-2] == p || board[i-2][j] == p ||
board[i-2][j-1] == p || board[i-2][j-2] == p) return false;
}
return true;
}
void Sudoku::Help_Solve(int i, int j)
{
if(j <= 0)
{
i = i-1;
j = 9;
}
if(change[i][j] == 1) return Game.Help_Solve(i, j-1);
for(int p = 1; p <= 9; p++)
if(Game.Check_Conflicts(p, i, j))
{
board[i][j] = p;
return;
}
return Game.Help_Solve(i, j-1);
}
void Sudoku::Solve()
{
for(int i = 1; i <= 9; i++)
{
for(int j = 1; j <= 9; j++)
{
if(board[i][j] == 0 && change[i][j] == 0)
{
Game.Help_Solve(i, j);
}
}
}
for(int i = 1; i <= 9; i++)
for(int j = 1; j <= 9; j++)
if(board[i][j] == 0) Game.Help_Solve(i, j);
}
int main()
{
Game.Add_First_Cord();
Game.Solve();
Game.Print_Board();
system("pause");
return 0;
}
Edit: I need to use recursion right? But maybe the parameters I give to the function are wrong. I really don't know. In Add_First_Cord() I declare the starting values that every sudoku has in the beginning. Here are the values that I use: http://bg.wikipedia.org/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:Sudoku-by-L2G-20050714.gif. I expect to see the solved sudoku as it is shown in wikipedia. But some solved values are right others are not. Here is what I get in the console
Suggested Approach
Implement a generic graph search algorithm
could use either IDFS or A* graph search
I would prefer the second
do this for a general directed graph
node type TNode
node successor function TNode => vector<TNode>
Define your Sudoku states
a state is a 9x9 array with a number 1, 2, ..., or 9 or a blank in each position
Define what a goal Sudoku state is
all 81 cells filled in
all 9 rows have numbers {1, 2, ..., 9} in them
all 9 columns have numbers {1, 2, ..., 9} in them
all 9 3x3 squares have numbers {1, 2, ..., 9} in them
Define your valid Sudoku state successor function
a state S can have number N added at row I, column J if:
cell (I,J) is empty
there is no other N in row I
there is no other N in column J
there is no other N in the 3x3 square containing (I,J)
the state successor function maps a state S to the vector of states that satisfy these rules
Apply your generic graph search algorithm (1) to the Sudoku state graph (2-4)
(optional) If you do choose to use A* graph search, you can also define a heuristic on your Sudoku state space to potentially drastically increase performance
how to design the heuristic is another whole problem, that's more of an art than a science
Current Approach
Your current approach mixes the specification of the graph to be searched and the implementation of the search algorithm. You're going to have a lot of difficulty if you mix those two. This problem naturally separates into two distinct pieces -- the algorithm and the graph -- so you can and should exploit that in your implementation. It will make it much simpler.
The other benefit you get if you go with this separation is that you will be able to reuse your graph search algorithm on a huge number of problems - very cool!
The following assumes you are trying to solve a given board, not generate a puzzle.
Basic (simple) approach
Create a class whose objects can hold a board (here called board_t). This class may internally use array, but must support copying boards.
Have a function void solve(board_t const& board); which repeats the following for each number n:
Copies your input
Enters n in the first empty cell of the copied board
If the copied board is a solution, print the solution and return.
Else If the board is still viable (e.g. no conflicts):
call solve(copied_board)
Performance
This is a recursive backtracking solution, which performs horribly for hard problems. You can significantly speed it up by proper pruning or deductive steps (e.g. if you end up with 8 numbers in a row after inserting one, you can immediately enter the ninth without any kind of search).
Reasoning
While certainly not an impressive technique, it has a high probability of working correctly, since you will only ever be modifying a copy to add a single value. This prevents corruption of your data structures (one problem your idea has is that it will destroy the numbers it finds when backtracking, are not necessarily the ones you just inserted, but may be part of the initial puzzle).
Improving performance is quite simple, once you start picking more intelligent heuristics (e.g. instead of testing the square in order, you could pick the ones with the fewest remaining moves and try to get them out of the way - or do the reverse...) or start doing a bit of deduction and pruning.
Note: The Algorithm Design Manual uses a Soduko solver to show the impact of these techniques on backtracking.
There is one very important modification to recursive algorithms: Use most constrained first approach. This means first to solve a cell with smallest number of possible candidates (when direct row/column/block conflicts are removed).
Another modification is: Change the board in-place; do not copy it. In each recursive call you modify only one cell on the board, and that cell used to be empty. If that call doesn't end up in a solved board somewhere down the recursive call tree, just clear the cell again before returning - this returns the board into original state.
You can find a very short and fast solution in C# on address: Sudoku Solver. It solves arbitrary sudoku board in about 100 steps only, all thanks to the most constrained first heuristic.
This is a classic Constraint Satisfaction Problem. I recommend doing some research on the topic to figure out the successful strategy. You will need to use AC-3 ( Arc Consistency 3) algorithm along with the backtracking techniques to solve the problem.