Mouse events not working as they should in functions - c++

I am displaying a card stack and need to know the exact pinpoints of the pixels so I mapped out a function that should return whatever LMB location was at pressed time. The issue with this is that for some reason I can no longer see the cards.
I tried making the function a class member of Game, but then the mouse logic doesn't work at all. I still had MyMouse M; declared but its like the code was just ignored completely. I know how to overload functions and yet this just seems to defy logic.
Function for MouseLogic();
void MouseLogic() {
Game G;
Coordinates C;
MyMouse M;
G.PrintLL(10, 25, G.start_user);
G.PrintLL(10, 10, G.start_cpu);
while (1) {
M.ReadMouseInput();
switch (M.InputRecord.EventType)
{
case MOUSE_EVENT: // mouse input
if (M.InputRecord.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
int x = M.InputRecord.Event.MouseEvent.dwMousePosition.X;
int y = M.InputRecord.Event.MouseEvent.dwMousePosition.Y;
cout << GetCardNumber(x, y);
}
}
}
}
Function for GetCardNumber
int GetCardNumber(int x, int y)
{
if ((x >= 10 && x <= 23) && (y >= 10 && y <= 25))
return 1;
else if ((x >= 41 && x <= 54) && (y >= 10 && y <= 25))
return 2;
else if ((x >= 72 && x <= 85) && (y >= 10 && y <= 25))
return 3;
else if ((x >= 45 && x <= 60) && (y >= 10 && y <= 25))
return 4;
else if ((x >= 78 && x <= 91) && (y >= 10 && y <= 25))
return 5;
else if ((x >= 10 && x <= 23) && (y >= 25 && y <= 40))
return 6;
else if ((x >= 41 && x <= 54) && (y >= 25 && y <= 40))
return 7;
else if ((x >= 72 && x <= 85) && (y >= 25 && y <= 40))
return 8;
else if ((x >= 45 && x <= 60) && (y >= 25 && y <= 40))
return 9;
else if ((x >= 78 && x <= 91) && (y >= 25 && y <= 40))
return 10;
else
return 0;
}

This seemed to work for anyone wondering! I just had to pass the class as an argument for some reason. Would still love an explanation for the logic behind this.
void MouseLogic(Game G) {
Coordinates C;
MyMouse M;
G.PrintLL(10, 25, G.start_user);
G.PrintLL(10, 10, G.start_cpu);
while (1) {
M.ReadMouseInput();
switch (M.InputRecord.EventType)
{
case MOUSE_EVENT: // mouse input
if (M.InputRecord.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
int x = M.InputRecord.Event.MouseEvent.dwMousePosition.X;
int y = M.InputRecord.Event.MouseEvent.dwMousePosition.Y;
cout << GetCardNumber(x, y);
}
}
}
}

Related

Simplifying a code snippet - vector rotation in a circle

Given the following code pattern, wherein I am trying to state a vector direction in increments of 45 degrees over the integers int x and int y, inside of a circle positioned at the origin
// x == 0 && y == 0 case is already taken cared of
if(x > 1) {
if(y == 0) {
// horizontal right
m_rotation = 0;
}else if(y < 1) {
// diagonal down right
m_rotation = 315;
} else if(y > 1) {
// diagonal up right
m_rotation = 45;
}
} else if(x == 0) {
if(y < 1) {
// vertical down
m_rotation = 270;
} else if(y > 1) {
// vertical up
m_rotation = 90;
}
} else if(x < 1){
if(y == 0) {
// horizontal left
m_rotation = 180;
}else if(y < 1) {
// diagonal down left
m_rotation = 225;
} else if(y > 1) {
// diagonal up left
m_rotation = 135;
}
}
I am looking for an elegant way to make this compact. I know there's the spaceship operator <=>, but I need to restrict myself to C++17.
Things I have tried
Nesting ternary operators with m_rotation = x > 1? (y < 1? (y == 0? 0: 315): 45): (x == 0? (y < 1? 270: 90): (y < 1? (y == 0? 180: 225): 135));, but this looks weird
I tried putting the x == 0 case inside x < 1 case and transform the later into else, but that does not simplify enough the code
Using absolute values to compare x and y, but I quickly get lost
Nothing else really, I don't know what else to try
Something like
constexpr int rotation[3][3] = {
{225, 180, 135},
{270, 0, 90},
{315, 0, 45},
};
if (x != 0 || y != 0) // if (!(x == 0 && y == 0))
m_rotation = rotation[1 + sign(x)][1 + sign(y)];
There is a closed form:
// standard sign functions
int xs = x < 0 ? -1 : x > 0;
int ys = y < 0 ? -1 : y > 0;
return 180 - 45 * (xs + 2) * ys + 90 * (xs * xs + xs) * (ys * ys - 1);
or shorter
return 180 * (x < 0 || y) - 45 * (xs + 2) * ys;

How to make a loop to determine if 2 numbers belong in a given range

I am having problems making a loop which stops when both x and y are in the range/interval [0,1] in c++.
double x;
double y;
while(condition)
{
if(x < 0)
{
x = -x;
}
else
{
x = 2 - x;
}
if(y < 0)
{
y = -y;
}
else
{
y = 2 - y;
}
}
This method with 2 loops works:
while((x < 0) || (x > 1)) {do sth}
while((y < 0) || (y > 1)) {do sth}
This doesn't work:
while(!((x >= 0) && (x <= 1)) && !((y >= 0) && (y <= 1))) {do sth}
And this doesn't work either:
while(((x < 0) || (x > 1)) && ((y < 0) || (y > 1))) {do sth}
This makes an infinite loop (in my case):
while(((x < 0) || (x > 1)) || ((y < 0) || (y > 1))) {do sth}
Note: {do sth} changes x and y if needed so they will eventually go in that interval (same as in the first block of code).
Note 2: By doesn't work I mean it never goes in the loop when x is in the interval and y < 0 (and some other cases).
while ( !( (x>=0 && x<=1) && (y>=0 && y<=1) ) ) should be the combined conditional check.
I'd go for a dedicated function with a speaking name: so you can still understand your code in a couple of weeks :-), e.g.
auto check_outside_interval_0_1 = [] (double const a) {
return a < 0.0 or 1.0 < a;
};
while( check_outside_interval_0_1(x) or
check_outside_interval_0_1(y) ) {
// ... do your things here
}

How do i fix this code in random walk problem? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
int main() {
int arr[5][5] = { 0 };
int x =0, y = 0;
int mx,my;
int cnt = 0;
srand(time(NULL));
while(1) {
bool a = true;
int i = rand() % 8;
if (i == 0) {
mx = -1, my = 0;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my] ++;
x += mx;
y += my;
cnt++;
}
if (i == 1) {
mx = 1, my = -1;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my]++;
x += mx;
y += my;
cnt++;
}
if (i == 2) {
mx = 0, my = -1;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my] ++;
x += mx;
y += my;
cnt++;
}
if (i == 3) {
mx = 1, my = 1;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my] ++;
x += mx;
y += my;
cnt++;
}
if (i == 4) {
mx = 1, my = 0;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my] ++;
x += mx;
y += my;
cnt++;
}
if (i == 5) {
mx = 1, my = -1;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my] ++;
x += mx;
y += my;
cnt++;
}
if (i == 6) {
mx = 0, my = -1;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my] ++;
x += mx;
y += my;
cnt++;
}
if (i == 7) {
mx = -1, my = -1;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my]++;
x += mx;
y += my;
cnt++;
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (arr[i][j] == 0) a = false;
}
}
if (a == true)break;
}
cout << cnt;
return 0;
}
I'm solving a random walk algorithm problem, but I don't know where it is wrong.
When I compile, nothing is displayed on the black screen.
It was lengthened by not using functions, but I think there is nothing wrong with it.
If there are any parts that can cause errors, please explain
thanks for reading this post i'm waiting your answer
The problem lies in the fact that your various if do not explore all the possible movements you can do given you are in a position x, y. For example, if you see what you do at i == 2
if (i == 2) {
mx = 0, my = -1;
or, at i == 6
if (i == 6) {
mx = 0, my = -1;
you do the same thing. In particular: look at this:
- - V
V X V
V V V
You miss the two movements going up and up-left.
I would review the various if movements (that you save in those two variables, mx and my)
As an improvement to your code, I'd choose a random move only between the ones you can really do.. it would be more clean.

Code compiles, however crashes after start(rot13) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
So, I have been fiddling around with a code for a ctf competition. However, every time I run the actual console application, it keeps crashing. Could someone please explain to me why. Thank you so much in advance.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int lowerConvert(char x)
{
int y;
if (x == 'a')
y = 1;
if (x == 'b')
y = 2;
if (x == 'c')
y = 3;
if (x == 'd')
y = 4;
if (x == 'e')
y = 5;
if (x == 'f')
y = 6;
if (x == 'g')
y = 7;
if (x == 'h')
y = 8;
if (x == 'i')
y = 9;
if (x == 'j')
y = 10;
if (x =='k')
y = 11;
if (x == 'l')
y = 12;
if (x == 'm')
y = 13;
if (x == 'n')
y = 14;
if (x == 'o')
y = 15;
if (x == 'p')
y = 16;
if (x == 'q')
y = 17;
if (x == 'r')
y = 18;
if (x == 's')
y = 19;
if (x == 't')
y = 20;
if (x == 'u')
y = 21;
if (x == 'v')
y = 22;
if (x == 'w')
y = 23;
if (x == 'x')
y = 24;
if (x == 'y')
y = 25;
if (x == 'z')
y = 26;
return y;
}
int upperConvert(char x)
{
int y;
if (x == 'A')
y = 27;
if (x == 'B')
y = 28;
if (x == 'C')
y = 29;
if (x == 'D')
y = 30;
if (x == 'E')
y = 31;
if (x == 'F')
y = 32;
if (x == 'G')
y = 33;
if (x == 'H')
y = 34;
if (x == 'I')
y = 35;
if (x == 'J')
y = 36;
if (x == 'K')
y = 37;
if (x == 'L')
y = 38;
if (x == 'M')
y = 39;
if (x == 'N')
y = 40;
if (x == 'O')
y = 41;
if (x == 'P')
y = 42;
if (x == 'Q')
y = 43;
if (x == 'R')
y = 44;
if (x == 'S')
y = 45;
if (x == 'T')
y = 46;
if (x == 'U')
y = 47;
if (x == 'V')
y = 48;
if (x == 'W')
y = 49;
if (x == 'X')
y = 50;
if (x == 'Y')
y = 51;
if (x == 'Z')
y = 52;
return y;
}
char lowerBack(int x)
{
char y;
if (x == 1)
y = 'a';
else if (x == 2)
y = 'b';
else if (x == 3)
y = 'c';
else if (x == 4)
y = 'd';
else if (x == 5)
y = 'e';
else if (x == 6)
y = 'f';
else if (x == 7)
y = 'g';
else if (x == 8)
y = 'h';
else if (x == 9)
y = 'i';
else if (x == 10)
y = 'j';
else if (x == 11)
y = 'k';
else if (x == 12)
y = 'l';
else if (x == 13)
y = 'm';
else if (x == 14)
y = 'n';
else if (x == 15)
y = 'o';
else if (x == 16)
y = 'p';
else if (x == 17)
y = 'q';
else if (x == 18)
y = 'r';
else if (x == 19)
y = 's';
else if (x == 20)
y = 't';
else if (x == 21)
y = 'u';
else if (x == 22)
y = 'v';
else if (x == 23)
y = 'w';
else if (x == 24)
y = 'x';
else if (x == 25)
y = 'y';
else if (x == 26)
y = 'z';
return y;
}
char upperBack(int x)
{
char y;
if (x == 27)
y = 'A';
if (x == 28)
y = 'B';
if (x == 29)
y = 'C';
if (x == 30)
y = 'D';
if (x == 31)
y = 'E';
if (x == 32)
y = 'F';
if (x == 33)
y = 'G';
if (x == 34)
y = 'H';
if (x == 35)
y = 'I';
if (x == 36)
y = 'J';
if (x == 37)
y = 'K';
if (x == 38)
y = 'L';
if (x == 39)
y = 'M';
if (x == 40)
y = 'N';
if (x == 41)
y = 'O';
if (x == 42)
y = 'P';
if (x == 43)
y = 'Q';
if (x == 44)
y = 'R';
if (x == 45)
y = 'S';
if (x == 46)
y = 'T';
if (x == 47)
y = 'U';
if (x == 48)
y = 'V';
if (x == 49)
y = 'W';
if (x == 50)
y = 'X';
if (x == 51)
y = 'Y';
if (x == 52)
y = 'Z';
return y;
}
void primaryRot13()
{
cout << "Please enter name of file to be decrypted: ";
string name;
getline(cin, name);
name += ".txt";
ifstream file;
ofstream write;
file.open(name);
string message;
file >> message;
int converted[9999999];
char reconvert[9999999];
for (int i = 0; i < message.length();++i)
{
if (message[i] == 0 || 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9)
message[i] += 53;
if (message[i] == 'a' || 'b' || 'c' || 'd' || 'e' || 'f' || 'g' || 'h' || 'i' || 'j' || 'k' || 'l' || 'm' || 'n' || 'o' || 'p' || 'q' || 'r' || 's' || 't' || 'u' || 'v' || 'w' || 'x' || 'y' || 'z')
converted[i] = lowerConvert(message[i]);
converted[i] += 13;
if (converted[i] > 26)
converted[i] -= 26;
if (message[i] == 'A' || 'B' || 'C' || 'D' || 'E' || 'F' || 'G' || 'H' || 'I' || 'J' || 'K' || 'L' || 'M' || 'N' || 'O' || 'P' || 'Q' || 'R' || 'S' || 'T' || 'U' || 'V' || 'W' || 'X' || 'Y' || 'Z')
converted[i] = upperConvert(message[i]);
converted[i] += 13;
if (converted[i] > 52)
converted[i] -= 26;
}
for (int i = 0; i < message.length(); ++i)
{
if (converted[i] == 52 || 53 || 54 || 55 || 56 || 57 || 58 || 59 || 60 || 61){
reconvert[i] = converted[i] - 53;
continue;
}
if (converted[i] < 27){
reconvert[i] = lowerBack(converted[i]);
continue;
}
if (converted[i] < 51){
reconvert[i] = upperBack(converted[i]);
continue;
}
write.open("decode");
write << reconvert[i];
}
}
EDIT AND FINAL SOLUTION
Several years later, I am here to repost. What I ended up doing was simply adding the desired amount to the character code, then if it is greater than the upper limit for that set, I subtracted 26 in order to reset. I also ended up using the vector instead, which did solve my issue of crashing. Now I can happily rot13 all day long :) All without the myriad of if statements.
Table Lookup
First, an introduction to table or array look ups.
Given a character array:
static const char letters[] = "abcdefghijklmnopqrstuvwxyz";
The index of 'a' is 0, 'b' is 1, ..., 'z' is 25.
The array can be searched for a letter. The index of the letter can be it's number. In your case, it would be the index + 1.
Example:
static const unsigned int letter_quantity = sizeof(letters) / sizeof(letters[0]);
unsigned int index = 0;
for (index = 0; index < letter_quantity; ++i)
{
if (letters[i] == x)
{
break;
}
}
At the end of the loop statement, the index variable will be the position of the character in x or the length of the array (if not found).
Modulo Arithmetic
Modulo arithmetic, using the % operator, returns the remainder. It has the behavior of wrapping around. This can be used with the array.
unsigned int new_char_index = index + 13; // We may have gone past the array.
new_char_index = new_char_index % letter_quantity; // Wrap around.
The New ROT13 Character
The converted character can be found by using the new_char_index as the index into the array.
char rot13 = letters[new_char_index];
Covering all the characters
The remaining uppercase characters can be added to the array to account for all the letters. Other symbols can be added also.
All this without any if statements.
You're allocating two static arrays of 9999999 elements on the stack.
If an int is 32 bits and a char is 8 bits on your system, then that's 48MB of memory. That's simply too much for the stack.
Try allocating your arrays dynamically instead, i.e. using std::vector:
std::vector<int> converted(9999999);
std::vector<char> reconvert(9999999);

Is there a better way of selecting a random element from an array of variable size than this?

I'm very new to C++ and was wondering if if there is a better way of doing this. It's going to run on an Arduino so I can't use ArrayLists or anything.
byte GetFreeCell(short x, short y)
{
byte possibleMoves[4] = {0,0,0,0};
if (y - 2 >= 0 && _grid[y - 2][x] == 0)
possibleMoves[0] = 1;
if (x + 2 < WIDTH && _grid[y][x + 2] == 0)
possibleMoves[1] = 2;
if (y + 2 < HEIGHT && _grid[y + 2][x] == 0)
possibleMoves[2] = 3;
if (x - 2 >= 0 && _grid[y][x - 2] == 0)
possibleMoves[3] = 4;
if (possibleMoves[0] == 0 && possibleMoves[1] == 0 && possibleMoves[2] == 0 && possibleMoves[3] == 0) {
return 0;
}
byte move = 0;
while(move == 0){
move = possibleMoves[random(4)];
}
return move;
}
Thanks,
Joe
byte GetFreeCell(short x, short y)
{
byte possibleMoves[4];
byte index = 0;
if (y - 2 >= 0 && _grid[y - 2][x] == 0)
possibleMoves[index++] = 1;
if (x + 2 < WIDTH && _grid[y][x + 2] == 0)
possibleMoves[index++] = 2;
if (y + 2 < HEIGHT && _grid[y + 2][x] == 0)
possibleMoves[index++] = 3;
if (x - 2 >= 0 && _grid[y][x - 2] == 0)
possibleMoves[index++] = 4;
return index ? possibleMoves[random(index)] : 0;
}
You can do yourself a favor and use this:
https://github.com/maniacbug/StandardCplusplus/#readme
Then you can sanitize your code by using standard containers.
Also, there's no ArrayList in C++. That's Java. With the above library, you can use std::vector instead.