Moving Boolean Values to Another Function C++ - c++

I need to move the value isAMFut and isAM into the function computeDifference()
cout<<"Is it AM or PM?"<<endl;
cin>>amOrPMFut;
transform(amOrPMFut.begin(), amOrPMFut.end(), amOrPMFut.begin(), ::toupper);
//Checking if user enters am or pm
while ((amOrPMFut != "AM") && (amOrPMFut != "PM")){
cout<<"Is it AM or PM?"<<endl;
cin>>amOrPMFut;
transform(amOrPMFut.begin(), amOrPMFut.end(), amOrPMFut.begin(), ::toupper);
}
if (amOrPMFut == "AM"){
isAMFut = true;
}
else {
isAMFut = false;
}
I would like to accomplish this by using pointers if that is possible. Otherwise I was thinking I could create the two booleans as global scope variables, but I don't feel like that is the most practical. Any insight would be much appreciated, please let me know if I can clear anything up.
Thanks!
int computeDifference(int& hours, int& minutes, int& hourFut, int& minFut){
//Calculations
//NEED TO TRANSFER VALUES OF BOOLEANS FROM MAIN FUNCTION INTO THIS FUNCTION
if ((isAM == true) && (isAMFut == true) {
if (hours > hourFut) {
diffHr = abs((hours - hourFut - 24));
diffMin = abs((minutes - minFut));
}
}
}

Related

return does not stop function, Recursive function issue? (programming exercise, Dynamic Programming, Levenshtein Back-trace)

the printOptimalAlignment function is misbehaving. goto and return will not exit when the function reaches location (1,1)... where it should end, no crash and it stops at seemingly an arbitrary location of (6,6)... because for some reason it increments at the end of the function even though there is no increment-er for the values int yL, int xL, (but I don't follow why it calls itself if it gets to the end of the function without any "hits" on the if statements.
Full code:
https://repl.it/#fulloutfool/Edit-Distance
void printOptimalAlignment(int** arr, string y, string x,int yL, int xL){
int I_weight=1, D_weight=1, R_weight=1;
bool printinfo_allot = 1,printinfo = 1;
if(printinfo_allot){
cout<<"Location: "<<"("<<xL<<","<<yL<<")"<<"-------------------------------\n";
cout<<"Same check Letters: "<<x[xL-2]<<","
<<y[yL-2]<<"("<<(x[xL-2] == y[yL-2])<<")"<<"\n";
cout<<"LL: "<<"("<<xL-1<<","<<yL<<")"
<<":"<<arr[yL][xL-1]
<<":"<<(arr[yL][xL-1]+I_weight)
<<":"<<(arr[yL][xL])
<<":"<<(((arr[yL][xL-1]+I_weight) == arr[yL][xL])==1)
<<":"<<(yL>=1 && xL>=1)<<"\n";
cout<<"xL state:"<<((&x[xL]))<<":"<<(x[xL-1])<<"\n";
cout<<"yL state:"<<((&y[yL]))<<":"<<(y[yL-1])<<"\n";
string tx = &x[xL];
cout<<x.length()<<","<<(tx.length()+1)<<"\n";
}
string tx = &x[xL]; // slopy hotfix
if(x.length()==(tx.length()+1)){
cout<<"return functionality not working?-=-=-=-=-=-=-=-=\n";
cout<<"-> Prep last, current distance = "<<arr[yL][xL] <<"\n";
return;
//printOptimalAlignment(arr,y,x,yL-1,xL-1);
//cant use this goto... but where does it go?
//goto because_Im_a_terrible_person;
throw "how?... breaking rules... make it stop";
}
if(yL>=1 && xL>=1 && (x[xL-2] == y[yL-2]) == 1){
if(printinfo){
cout<<"-> Same (same char), current distance = "<<arr[yL][xL] <<"\n";
}
printOptimalAlignment(arr,y,x,yL-1,xL-1);
}
if(yL>=1 && xL>=1 && (arr[yL-1][xL-1] == arr[yL][xL])){
if(printinfo){
cout<<"-> Swap (same int), current distance = "<<arr[yL][xL] <<"\n";
if(arr[yL-1][xL-1]==0)cout<<"---this is last---\n";
}
printOptimalAlignment(arr,y,x,yL-1,xL-1);
}
if(yL>0 && xL>0 && (arr[yL-1][xL]+D_weight == arr[yL][xL])){
if(printinfo){
cout<<"-> Delete, current distance = "<<arr[yL][xL]<<"\n";
}
printOptimalAlignment(arr,y,x,yL-1,xL);
}
//really weird ((yL>1 && xL>1) && (((arr[yL][xL-1]+I_weight) == arr[yL][xL])==1))
//not true if it is?
bool seperate = (((arr[yL][xL-1]+I_weight) == arr[yL][xL])==1);
if(yL>=1 && xL>=1){
if((((arr[yL][xL-1]+I_weight) == arr[yL][xL])==1) && (true)){
if(printinfo){
cout<<"-> Insert, current distance = "<<arr[yL][xL]<<"\n";
cout<<"Next Location1: "<<"("<<xL-1<<","<<yL<<")"<<"\n";
}
printOptimalAlignment(arr,y,x,yL,xL-1);
return;
//how does it get here... also return gets ignored... prob another stack issue
cout<<"insert function broke?????? # (1,1) ???????????????\n";
//return;
}
}
return;
cout<<"END... Hopefully.. if you see this Something went wrong\n";
because_Im_a_terrible_person:
cout<<"QUIT\n";
}
I suspect your problem is that your function calls itself and you don't appear to be taking into account what should happen next after that call to itself finishes. So you get to your finish condition where you say the return doesn't work, but it does... it just returns to where you left off in the previous call to printOptimalAlignment, which still might do something before returning to its caller, and so on. You have three different sites where you recursively call printOptimalAlignment that aren't immediately followed by a return statement, and at any of these it might be that the code will continue and trigger another of your conditional blocks.

Testing multiple boolean values in a single IF statement

I a newbie C++ programmer trying to test aruments/parameters passed to a program.
Multiple arguments can be passed to the program, however I want to test that if certain arguments are passed then other arguments become invalid.
e.g. PGM accepts arg(1) arg(2) arg(3) arg(4) arg(5) etc...
if arg(1) and arg(2) are supplied then arg(3), arg(4) and arg(5) etc... are invalid and the program should terminate with an error message if they are also supplied along with arg(1) and arg(2).
I've thought that using boolean IF tests would be a good way to check if certain values are true/false.
I searched on stackoverflow but not found an answer that encompasses exactly what i'm trying to do. If someone can point me in the right direction or suggest a far more efficient way of doing this I would be very grateful.
My code currently looks like this:
bool opt1 = false;
bool opt2 = false;
bool opt3 = false;
bool opt4 = false;
bool opt5 = false;
for(int i=1; i<argc; i++) {
char *str = argv[i];
if (strcmp (str, "-opt1:")==0) {opt1 = true;}
else if (strcmp (str, "-opt2:")==0) {opt2 = true;}
else if (strcmp (str, "-opt3:")==0) {opt3 = true;}
else if (strcmp (str, "-opt4:")==0) {opt4 = true;}
else if (strcmp (str, "-opt5:")==0) {opt5 = true;}
}
if((opt1) && (opt2) && (~(opt3)) && (~(opt4)) && (~(opt5)) {
** DO SOMETHING **
} else {
** DISPLAY ERROR MESSAGE AND USAGE TEXT **
}
A good solution would be using operands ! and &&
! denotes "not" (or in such case "not true") while && combines two different logical comparisons (in such case, "logic test 1" and "logic test 2")
Here's an example to do it:
if((opt1 && opt2)&&(!(opt3||opt4||opt5))){
/*
Do something if opt1 and opt2 are true and others are false
*/
}
This is practically the same as #Fareanor's solution above (first solution)
A possible fix could be (if I have well understood your problem):
if(opt1 && opt2) // opt3, opt4 and opt5 are invalid
{
if(!(opt3 || opt4 || opt5))
{
// Do something
}
else
{
// Display error message because at least opt3 or opt4 or opt5 is provided and not requested
}
}
else // opt3, opt4 and opt5 are valid
{
// Do something
}
But I think it could be better to just ignore the obsolete parameters instead of display an error while you can still run your process with only opt1 and opt2. Which could lead us to the simpler code:
if(opt1 && opt2)
{
// Do something without using opt3, opt4 and opt5
}
else
{
// Do something taking into account opt3, opt4 and opt5
}
I hope it is what you was looking for.

Exception Handling with Multiple Variables

I'm trying to learn more about exception handling while working on my program. I have multiple test variables I want to test and make sure it is within range with:
public bool IsWithinRange(TextBox textbox, string name, int min, int max)
{
double number = double.Parse(textbox.Text);
if (number < min || number > max)
{
MessageBox.Show(name + " must be between " + min.ToString() + " and " + max.ToString() + ".", "Entry Error");
textbox.Focus();
return false;
}
else { return true; }
}
And calling the method using:
bool condition;
condition = CheckAll();
if (condition == true) { condition = IsWithinRange(txtVar1, "Var1", 1, 50); }
if (condition == true) { condition = IsWithinRange(txtVar2, "Var2", -100, 100); }
if (condition == true) { condition = IsWithinRange(txtVar3, "Var3", 100, 200); }
This logic works, but I was curious to see if there was a more concise, better looking way of writing some form of systematic checking of variables one by one?
You can take advantage of a few things:
Are you able to assign meaningful names to the TextBox.Name properties? If so, you can omit the second parameter in "IsWithinRange" and simply call "Textbox.Name".
As of C# 6.0, there is now a syntax to interpolate strings. So the string passed into your your MessageBox.Show syntax can be made shorter and prettier.
You can immediately assign to "condition", and you can convert your "if" statements to combined "and" statements.
All together, your code can look like this:
bool condition =
CheckAll()
&& IsWithinRange(txtVar1, 1, 50)
&& IsWithinRange(txtVar2, -100, 100)
&& IsWithinRange(txtVar3, 100, 200);
// Some other code here
With your method looking like this:
public bool IsWithinRange(TextBox textbox, int min, int max) {
double number = double.Parse(textbox.Text);
if (number < min || number > max) {
MessageBox.Show($"{textbox.Name} must be between {min} and {max}.", "Entry Error");
textbox.Focus();
return false;
}
else
return true;
}
This is assuming you actually use "condition". If not, you can omit "bool condition = " and the code runs just the same.
But there are a few things to note. Your code will continue to run even if "CheckAll" is false or any "IsWithinRange" is false. This is true in my version above or in your own version. Yes, your user will get a message, but after he clicks "okay", the remaining code will run even if the checks fail.
Also, "IsWithinRange" might be misinterpreted by a teammate or even by yourself in the future. This is because it does more than just return true/false: it sends a message if false. This violates the principle of command-query separation.
An approach to these issues ignores brevity, as that is desired but never the highest goal. What you can do is create a class that validates, whose methods separate the tasks:
class Validator {
public bool isValid = true;
public List<string> messages = new List<string>();
public Validator CheckAll() {
// Whatever your logic is for this.
return this; // Return the instance of "Validator" that called this method
}
public Validator CheckRange (TextBox textbox, int min, int max) {
double number = double.Parse(textbox.Text);
if (number < min || number > max) {
messages.Add($"{textbox.Name} must be between {min} and {max}.");
isValid = false;
}
return this;
}
public void ShowErrorsToUser () =>
MessageBox.Show(string.Join(Environment.NewLine, messages));
}
Which you would use like this:
var validator =
new Validator()
.CheckAll()
.CheckRange(txtVar1, 1, 50)
.CheckRange(txtVar2, -100, 100)
.CheckRange(txtVar3, 100, 200);
if (!validator.isValid) {
validator.ShowErrorsToUser();
txtVar1.Focus();
return; // Stop code execution!
}
// Continue with your normal logic that utilizes your textbox values.
I'll leave it to you to decide whether the class-based approach is worth your time. But I present it to you as a different way to think.

About the random number in snake games

#include <iostream>
#include <string>
#include <windows.h>
#include <conio.h>
#include <time.h>
using namespace std;
int map_height=22;
int map_width=22;
string border="ùþ";
int snakeheadX=map_width/2-1;
int snakeheadY=map_height/2;
string head_symbol="¡·";
int snakesize;
bool gameover=false;
enum action{up, down, right1, left1, stop};
action moving=stop;
int foodx;
int foody;
void food();
void draw(){
system("cls");
food();
for(int i=0;i<map_width;i++){ // Game frame
cout<<border;
}
cout<<endl;
for(int i=0;i<map_height;i++){
cout<<border;
for(int j=0;j<map_width-2;j++){
if(i==snakeheadY && j==snakeheadX){
cout<<head_symbol;
}
else if(i==foody && j==foodx){
cout<<"¡¯";
}
else
cout<<" ";
}
cout<<border;
cout<<endl;
}
for(int i=0;i<map_width;i++){
cout<<border;
}
}
void running(int moving){
if(moving==up){ //Up
snakeheadY--;
}
if(moving==down){ //Down
snakeheadY++;
}
if(moving==left1){ //Left
snakeheadX--;
}
if(moving==right1){ //Right
snakeheadX++;
}
if(moving==stop){
snakeheadX=snakeheadX;
snakeheadY=snakeheadY;
}
}
void food(){
int prev_foodx=foodx;
int prev_foody=foody;
int a=rand()%(map_width-3)+1;
int b=rand()%(map_height-1)+1;
if(foodx==snakeheadX && foody==snakeheadY){
if(prev_foodx==a && prev_foody==b){
foodx=rand()%(map_width-3)+1;
foody=rand()%(map_height-1)+1;
}
else{
foodx=a;
foody=b;
}
}
}
void move_logic(int getkeyboarddown){
if(getkeyboarddown=='w'){ //Up
snakeheadY--;
moving=up;
}
if(getkeyboarddown=='s'){ //Down
snakeheadY++;
moving=down;
}
if(getkeyboarddown=='a'){ //Left
snakeheadX--;
moving=left1;
}
if(getkeyboarddown=='d'){ //Right
snakeheadX++;
moving=right1;
}
}
void game_logic(){
if (snakeheadX>=map_width || snakeheadX<=0 || snakeheadY<=0 || snakeheadY>=map_height){
cout<<endl<<"Game over!";
gameover=true;
}
}
int main()
{
srand(time(0));
foodx=rand()%(map_width-3)+1;
foody=rand()%(map_height-1)+1;
while(!gameover){
Sleep(50);
cout<<foodx<<" "<<foody;
running(moving);
draw();
game_logic();
if(kbhit()){
move_logic(getch());
}
}
return 0;
}
The code above is my code of snake game in C++. Although the game is not finished, I found the food may sometimes appear in same location after the snake ate. Therefore, in the function food(), I add a script of code below to prevent this state.
if(foodx==snakeheadX && foody==snakeheadY){
if(prev_foodx==a && prev_foody==b){
foodx=rand()%(map_width-3)+1;
foody=rand()%(map_height-1)+1;
cout<<"ok";
}
else{
foodx=a;
foody=b;
}
But I still found the food sometimes appear in same location after the snake ate that means the code I wrote is useless. How can I solve this problem?
The problem is in your move_logic and running functions. You aren't generating the food in the same position twice in a row by chance, what is actually happening is that when the player changes direction the snake actually moves twice, causing it to jump over a position. If you are passing by the food and change direction to get the food, you will actually jump over the food instead.
E.g. Starting with snakeheadX = 2, snakeheadY = 5 and moving = left1, say the player presses s to change direction. move_logic() increments snakeheadY to 6, then running() increments snakeheadY to 7, and only after that are draw() and food() called, so if the food was in position (2,6), then it was missed, and it looks like the snake went right through it, or like new food was generated in the same position.
To fix this, function move_logic() should not modify snakeheadX or snakeheadY. Only the running() function should modify them.
Aside from that, it looks like it should work, but there's a lot that could be cleaned up. E.g. You should use chained else if statements in functions running() and move_logic(). In function food(), prev_foodx and prev_foody aren't actually doing anything useful, because foodx and foody haven't changed at the time when prev_foodx and prev_foody are checked. food() also generated the random positions every time it is called, rather than only when necessary, and does allow food to be generated twice in the same position, albeit only with a chance of 1/22^4. So the randomness could be better implemented using a loop, like this:
void food() {
if (foodx == snakeheadX && foody == snakeheadY) {
int new_foodx;
int new_foody;
do
{
new_foodx = rand() % (map_width - 3) + 1;
new_foody = rand() % (map_height - 1) + 1;
} while (new_foodx == foodx && new_foody == foody);
foodx = new_foodx;
foody = new_foody;
}
}
I don't see what's causing you're issue, but one change you can make to prevent the code from randomly generating the same x and y coordinates two times in a row is to replace the code
if(prev_foodx==a && prev_foody==b){
foodx=rand()%(map_width-3)+1;
foody=rand()%(map_height-1)+1;
}
with
if(prev_foodx==a && prev_foody==b){
food();
}
The food function would then keep calling itself until it comes up with new x and y coordinates for the food. You can also optimize the function so it is not generating random numbers every time the screen is drawn by moving the if statement above the variables you're declaring like so.
void food(){
if(foodx==snakeheadX && foody==snakeheadY){
int prev_foodx=foodx;
int prev_foody=foody;
int a=rand()%(map_width-3)+1;
int b=rand()%(map_height-1)+1;
if(prev_foodx==a && prev_foody==b){
food();
} else{
foodx=a;
foody=b;
}
}
}
Also the name food does not tell me what is going on at all. Perhaps in the draw function you could say
if(foodx==snakeheadX && foody==snakeheadY){
changeFoodPos();
}`
and then instead of your food function, you have a changeFoodPos function. It's always better to have functions that are for one specific purpose like changing the position of food, than to you have a function that could be doing anything with food. Also, you don't need the prev_foodx and prev_foody variables. You could just do
void changeFoodPos(){
if(foodx==snakeheadX && foody==snakeheadY){
int newX = rand()%(map_width-3)+1;
int newY = rand()%(map_height-1)+1;
if(foodx==newX && foody==newY){
changeFoodPos();
} else{
foodx = newX;
foody = newY;
}
}
}
Anyhow, I know this doesn't directly answer you're question. It looks like David Scarlett was able to figure out what the issue was, but I hope this helps you out as you're learning to code.

check if a value belongs to a certain object

I have a map with two different kinds of objects: deposit account and checking account. I want to write a money transfer methode to transfer money between two checking accounts only. Is there a way to check if both account numbers belong to the same checking account object?
bool Bank::moneyTransfer(long fromAccount,long toAccount, double amount)
{
map<long, account*>::iterator iterFrom;
map<long, account*>::iterator iterTo;
iterFrom = m_accountList.find(fromAccount);
if (iterFrom == m_accountList.end()) {
return false;
}
iterTo = m_account.find(toAccount);
if (iterFrom == m_accountList.end()) {
return false;
}
Konto *fromAccount = iterFrom->second;
Konto *toAccount = iterTo->second;
if (!fromAccount->drawMoney(amount)) {
return false;
}
toAccount->payIn(amount);
return true;
}
Q. Is there a way to check if both account numbers belong to the same checking account object?
A. Yes
As Shaktal says you're passing in the account numbers just compare them.
There are a couple things that need to be cleaned up in your code:
The fact that you're asking this question indicated that the you think that you could have the same Key in a map with 2 Values. This is not the case, this code will result in the Key 13 mapping to only a DepositAccount:
m_accountList[13] = CheckingAccount();
m_accountList[13] = DepositAccount();
Please use auto to declare your variables, especially instead of map<long, account*>::iterator aside from being easier to read, you wont have to come back and edit your logic when you change m_accountList's type, for more information on auto I believe the definitive article is: https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/
After making these corrections, your code should look something like:
bool Bank::moneyTransfer(long fromAccount, long toAccount, double amount)
{
if(fromAccount != toAccount) {
auto iterFrom = m_accountList.find(fromAccount);
if (iterFrom != m_accountList.end()) {
auto iterTo = m_account.find(toAccount);
if (iterFrom != m_accountList.end() && iterFrom->second->drawMoney(amount)) {
iterTo->second->payIn(amount);
return true;
}
}
}
return false;
}