If ignores my == sign - c++

I'm trying to make a game (simple 2d platformer).
The program runs as it should, but an if statement doesn't work correctly.
I have this function:
int Collision::platformCollision(SDL_Rect *hitbox, SDL_Rect plat) {
if (checkCollision(*hitbox, plat)) {
//X
//LEFT SIDE
if (hitbox->x + hitbox->w > plat.x && hitbox->x + hitbox->w < plat.x + 5) {
hitbox->x = plat.x - hitbox->w;
return 1;
}
//RIGHT SIDE
if (hitbox->x < plat.x + plat.w && hitbox->x > plat.x + plat.w - 5) {
hitbox->x = plat.x + plat.w;
return 2;
}
//Y
//UPPER SIDE
if (hitbox->y + hitbox->h > plat.y && hitbox->y + hitbox->h < plat.y + 10) {
hitbox->y = plat.y - hitbox->h;
return 3;
}
//BOTTOM SIDE
if (hitbox->y < plat.y + plat.h && hitbox->y > plat.y + plat.h - 10) {
hitbox->y = plat.y + plat.h;
return 4;
}
}
//NOT COLLIDING
return -1;
}
So I have this function return an int whenever it collides with a certain part of the platform.
Then I have this function:
void Player::playerCheckPlatCollision(SDL_Rect rect) {
if (platformCollision(p_hitboxPTR, rect) == 3) {
setGravityF(0.0);
}
if (platformCollision(p_hitboxPTR, rect) == 4) {
p_space = false;
}
return;
}
The problem should be easy to fix.
When I debug the program it gets to return 4; in the platformCollision function, but when I do
if (platformCollision(p_hitboxPTR, rect) == 4) {
p_space = false;
}
It doesn't put p_space as false, it just ignores the == 4 and when I debugged, I saw it got to that if statement.
Can someone please help.
Thanks.

If platformCollision returns 4 on the first call, it alters state, and will not return 4 on the second call.
void Player::playerCheckPlatCollision(SDL_Rect rect) {
int bang = platformCollision(p_hitboxPTR, rect);
if (bang == 3) {
setGravityF(0.0);
} else if (bang == 4) {
p_space = false;
}
}

Related

Tic tac toe Minimax Algorithm Having Weird Behavior (C++)

The other day, I wrote a console game of Tic-Tac-Toe in c++ for my son. He wanted me to add a computer, and I ended us using the minimax algorithm for the first time. I did some quick testing, but really just gave my laptop to my son as soon as it was printing stuff, who played with it for a couple minuets. I looked over his sholder once or twice, and noticed that it wasn't playing optimally, iv'e been trying to debug it, but I can't see where it goes wrong. I tried getting rid of alpha beta prunning, but that did not change anything.
For context, on the board the computer is -1, blank is 0, and the player is 1.
Here is the minimax function:
int minimax(int board[9], int depth, int alpha, int beta, bool isMaxizimaizingPlayer)
{
bool found = false;
for (int i = 0; i < 9; i++)
{
if (board[i] == 0)
{
found = true;
}
}
if (!found)
{
return eval(board);
}
if (depth == 0 || eval(board) != 0)
{
return eval(board);
}
if (isMaxizimaizingPlayer)
{
int maxEval = -2;
for (int spot = 0; spot < 9; spot++)
{
if (board[spot] == 0)
{
board[spot] = 1;
int e = minimax(board, depth - 1, alpha, beta, false);
if (e > maxEval)
{
maxEval = e;
}
//if (beta < alpha)
//{
// break;
//}
board[spot] = 0;
}
}
return maxEval;
}
else {
int minEval = 2;
for (int spot = 0; spot < 9; spot++)
{
if (board[spot] == 0)
{
board[spot] = -1;
int e = minimax(board, depth - 1, alpha, beta, true);
if (e < minEval)
{
minEval = e;
}
//if (beta < alpha)
//{
// break;
//}
board[spot] = 0;
}
}
return minEval;
}
}
To be compleate, here is my eval function:
int eval(int board[9])
{
/*horizontial*/
for (int i = 0; i < 3; i++)
{
if (board[i * 3] == board[i * 3 + 1] && board[i * 3 + 2] == board[i * 3] && board[i * 3] != 0)
{
return board[i * 3];
}
}
/*vertical*/
for (int i = 0; i < 3; i++)
{
if (board[i] == board[i + 3] && board[i] == board[i + 6] && board[i] != 0)
{
return board[i];
}
}
/*Both diags*/
if (board[4] != 0) {
if (board[0] == board[4] && board[0] == board[8])
{
return board[4];
}
if (board[2] == board[4] && board[4] == board[6])
{
return board[4];
}
}
return 0;
}
And here is the inital call:
int spot = 0;
int minEval = 2;
for (int i = 0; i < 9; i++)
{
if (board[i] == 0)
{
board[i] = -1;
int score = minimax(board, 3, -2, 2, false);
if (score < minEval) {
minEval = score;
spot = i;
}
board[i] = 0;
}
}
std::cout << "The computer went in spot " << spot + 1 << std::endl;
board[spot] = -1;
printBoard(board);
It looks like you only call minimax with a depth of three, so the algorithm will only look up to three moves ahead, if you want optimal play you need to set the depth to > 9, so that the agent is always looking ahead to the end of the game.

Implementing a collision in 2D platform game ( Icy Tower )

I'm fighting with this for like few days, and I have no idea, how to do that, so I'd like to ask you for help. I've got no idea how collision should look like right here, so player could jump through 'down zone' of the block, and stay right on the block.
block.cpp
bool block::CollidingWithPlayer(character& player) {
for (int i = 1; i < MAX_BLOCKS; i++) {
if (player.x + player.width >= coordinateX[i] && player.x <= coordinateX[i] + width[i] && player.y + player.height >= coordinateY[i] && player.y <= coordinateY[i] + block_height) {
player.onGround = true;
return true;
}
}
}
character.cpp
void character::startJump(map& Map, character& player) {
if (onGround)
{
vel[1] = -11.0;
onGround = false;
}
}
void character::updateJump(block& Block, character& player) {
if (!onGround) {
Block.CollidingWithPlayer(player);
vel[1] += 0.5;
y += vel[1];
x += vel[0];
}
if (y > 460){
y = 460;
vel[1] = 0.0;
onGround = true;
vel[0] = 0.0;
}
if ((x + width >= START_OF_RIGHT_WALL && x <= WALL_WIDTH + START_OF_RIGHT_WALL) || (x + width >= START_OF_LEFT_WALL &&x <= START_OF_LEFT_WALL + WALL_WIDTH)){
vel[0] *= -1;
bound = true;
if (direction == 1)
direction = 2;
else if (direction == 2)
direction = 1;
}
}

Recursively mapping mines on a minesweeper board

I have been trying to make a minesweeper game where given coordinates for a cell it will recursively reveal adjacent cells until a cell adjacent to a bomb is found. I have a method that given coordinates x and y calculates how many mines are surrounding it.
// Counts how many mines are adjacent to a given coordinate cell if any
void board::mineCount(int x, int y) {
// North
if (y > 0) {
if (board[x][y - 1].hasMine) {
board[x][y].mineCount++;
}
}
// South
if (y < dimensions[1] - 1) {
if (board[x][y + 1].hasMine) {
board[x][y].mineCount++;
}
}
// East
if (x < dimensions[0] - 1) {
if (board[x + 1][y].hasMine) {
board[x][y].mineCount++;
}
}
// West
if (x > 0) {
if (board[x - 1][y].hasMine) {
board[x][y].mineCount++;
}
}
// North East
if (x < dimensions[0] - 1 && y > 0) {
if (board[x + 1][y - 1].hasMine) {
board[x][y].mineCount++;
}
}
// North West
if (x > 0 && y > 0) {
if (board[x - 1][y - 1].hasMine) {
board[x][y].mineCount++;
}
}
// South East
if (x < dimensions[0] - 1 && y < dimensions[1] - 1) {
if (board[x + 1][y + 1].hasMine) {
board[x][y].mineCount++;
}
}
// South West
if (x > 0 && y < dimensions[1] - 1) {
if (board[x - 1][y + 1].hasMine) {
board[x][y].mineCount++;
}
}
}
Each cell is a struct which has a mineCount field that gets incremented by 1 each time a mine is found adjacent to it. I am having trouble figuring out where my recursion logic would go. I tried doing something like:
// North
if (y > 0) {
if (board[x][y - 1].hasMine) {
board[x][y].mineCount++;
} else {
minecount(x, y-1);
}
}
for each position but to no avail. Any pointers would be appreciated.
The recursion shouldn't be a part of the code that performs the mine count itself. It should be part of the function that's responsible for revealing nearby tiles.
int get_adjacent_mine_count(point p) {
int mine_count = 0;
for(int i = -1; i <= 1; i++) {
for(int j = -1; j <= 1; j++) {
point this_point(p.x + i, p.y + j);
//is_inside_board checks to see if the point's coordinates are less than 0
//or greater than the board size
if(!is_inside_board(board, this_point)) continue;
//We ignore the center tile
if(i == 0 && j == 0) continue;
if(board(this_point).hasMine)
mine_count++;
}
}
return mine_count;
}
void reveal_tiles(point p) {
//We shouldn't throw if the recursion is correct
if(board(p).hasMine) throw Explosion("Stepped on a Mine!");
//Single call to previously defined function
int num_of_adjacent_mines = get_adjacent_mine_count(p);
//I'm assuming this gets initialized to -1 beforehand
board(p).revealed = num_of_adjacent_mines;
if(num_of_adjacent_mines == 0) {
for(int i = -1; i <= 1; i++) {
for(int j = -1; j <= 1; j++) {
point this_point(p.x + i, p.y + j);
if(!is_inside_board(board, this_point)) continue;
if(i == 0 && j == 0) continue;
if(board(this_point).revealed == -1)
reveal_tiles(this_point);
}
}
}
}
I'm going to strongly recommend you write a simple Matrix class to represent board, which my code implies you've done, because that's a much more robust solution than just trying to interact with a 2D array the C-style way you're doing it.

Segmentation fault in recursive backtracking maze generator C++

I am trying to create a maze generator using recursive backtracking and have come across a problem that I just can't get my head around. For some reason my move function is returning the value "18446744073709551615". This is (of course) leading to a segmentation fault. Why is my move function returning such a large value when my move function can only increase or decrease the value by 2?
bool maze::generate(size_t x, size_t y) {
//mark the position as visited
labyrinth.s[y][x] = true;
//print to see progress
//this->print();
//if the position is not out of bounds
if (x < 0 || x > labyrinth.MAXWIDTH - 1 || y < 0 || y > labyrinth.MAXHIGHT - 1) {
//if the position is the endpoint return true
if (labyrinth.v[y][x - 1] == 'W' || labyrinth.v[y][x + 1] == 'W' || labyrinth.v[y - 1][x] == 'W' || labyrinth.v[y + 1][x] == 'W') {
return true;
}
}
//pick a random direction
do {
d = size_t(rand() % 4);
} while(!this->pos_test(x, y, d));
std::cout << x << ' ' << y << std::endl;
if (d == UP) {
y = move(x, y, UP);
}
else if (d == DOWN) {
y = move(x, y, DOWN);
}
else if (d == RIGHT) {
x = move(x, y, RIGHT);
}
else if (d == LEFT) {
x = move(x, y, LEFT);
}
else{
}
std::cout << x << ' ' << y << std::endl;
//recursively generate the maze
if (this->generate(x, y)) {
return true;
}
}
void maze::initialize(size_t x, size_t y) {
//set the maxhight and the maxwidth to y and x
labyrinth.MAXHIGHT = y;
labyrinth.MAXWIDTH = x;
//set all elements in the vector to #
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
std::vector<char> temp;
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
temp.push_back(labyrinth.wall);
}
labyrinth.v.push_back(temp);
}
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
if (j % 2 == 1 && i % 2 == 1 && j != labyrinth.MAXWIDTH - 1 && j != 0 && i != labyrinth.MAXHIGHT - 1 && i != 0) {
labyrinth.v[j][i] = labyrinth.path;
}
}
}
//set all posistions to unvisited
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
std::vector<bool> temp2;
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
temp2.push_back(false);
}
labyrinth.s.push_back(temp2);
}
//setup the start point
labyrinth.v[0][1] = 'S';
//setup the endpoint
labyrinth.v[labyrinth.MAXHIGHT - 2][labyrinth.MAXWIDTH - 1] = 'W';
}
//if a position has been visited or if not possible to go to return true
bool maze::pos_test(size_t x, size_t y, size_t d) const {
//if the position is out of bounds return false
if (x < 0 || y < 0 || x > labyrinth.MAXWIDTH - 1 || y > labyrinth.MAXHIGHT - 1) {
return true;
}
else if (x == 1 && d == LEFT) {
return true;
}
else if (y == 1 && d == UP) {
return true;
}
else if (x == labyrinth.MAXWIDTH - 1 && d == RIGHT) {
return true;
}
else if (y == labyrinth.MAXHIGHT - 1 && d == DOWN) {
return true;
}
else if (d == UP) {
return labyrinth.s[y - 2][x];
}
else if (d == DOWN) {
return labyrinth.s[y + 2][x];
}
else if (d == RIGHT) {
return labyrinth.s[y][x + 2];
}
else if (d == LEFT) {
return labyrinth.s[y][x - 2];
}
else {
return true;
}
}
size_t maze::move(size_t x, size_t y, size_t d) {
//if the position is out of bounds return without modifying
if (x < 0 || x > labyrinth.MAXWIDTH - 1) {
return x;
}
else if (y < 0 || y > labyrinth.MAXHIGHT - 1) {
return y;
}
else if (d == UP) {
labyrinth.v[y - 1][x] = labyrinth.path;
return y = y - 2;
}
else if (d == DOWN) {
labyrinth.v[y + 1][x] = labyrinth.path;
return y = y + 2;
}
else if (d == RIGHT) {
labyrinth.v[y][x + 1] = labyrinth.path;
return x = x + 2;
}
else if (d == LEFT) {
labyrinth.v[y][x - 1] = labyrinth.path;
return x = x - 2;
}
else {
}
}
You are underflowing your unsigned 64-bit return type size_t.
You are checking whether x and y are below zero, but that's not enough, because 0 and 1 will still be too low because you are subtracting 2!
The number you get is 0xFFFFFFFFFFFFFFFF in hexadecimal. This is the highest possible value for an unsigned 64-bit integer.
It comes from calculating 1 - 2. Yes, this is supposed to be -1, but because your move function doesn't return a signed number but an unsigned one (check the docs on size_t), it can't be negative! Instead, it wraps around to the highest possible number.
You can imagine this in the same way you would get ...99999999999 when you try to calculate 1 - 2 on paper ignoring the "you can't subtract a higher number from a smaller one on paper" rule.
As a side note: I guess the negative result is undesired anyway, because actually your huge number, once added to a pointer, will in turn overflow back into positive, so basically it will work the same is a real -1 in your case and the segmentation fault comes from accessing something right before the beginning of your buffer, not far beyond it, but it comes down to the same thing.
Apart from that, there is no need to do return y = y - 2 and such. Just return y - 2.

C++ Visual Studio interprets the class method as static

Visual Studio interprets the class method as static but they are not. I have 110 Errors when i build below code.
Errors: Foto with errors 1. , Foto with errors 2.
It may wrong declares these methods?
//header
class Player {
public:
Player(int x, int y) {
PlayerX = x;
PlayerY = y;
};
void doAction(int input, Mapa *mapa);
int getDirection();
Vector2 getPosition();
int
PlayerX, PlayerY, direction;
void turn(int dir);
void move(int move, Vector2 mapSize, Mapa *mapa);
Vector2 getCordInFrontOfCharacter();
Vector2 getCordBehindCharacter();
};
and cpp file:
#include "Vector2.h"
#include "Player.h"
#include "Mapa.h"
using namespace std;
int PlayerX = 0, PlayerY = 0;
int direction = 0;
void Player::doAction(int input, Mapa *mapa) {
if (input == (char)72)
this->move(1, *mapa->mapSize, mapa);
else if (input == (char)80)
this->move(-1, *mapa->mapSize, mapa);
if (input == (char)75)
this->turn(-1);
else if (input == (char)77)
this->turn(1);
}
void Player::turn(int dir) {
if (dir < 0)
dir = 2 - dir;
direction = (direction + dir) % 4;
}
void Player::move(int move, Vector2 mapSize, Mapa *mapa) {
if (
move = 1
&& getCordInFrontOfCharacter().y - 1 >= 0
&& getCordInFrontOfCharacter().x - 1 >= 0
&& getCordInFrontOfCharacter().y - 1 < mapSize.y
&& getCordInFrontOfCharacter().x - 1 < mapSize.x
&& mapa->_Mapa[getCordInFrontOfCharacter().y - 1][getCordInFrontOfCharacter().x - 1] == '0') {
if (this->direction == 0)
this->PlayerY -= move;
else if (this->direction == 2)
this->PlayerY += move;
else if (this->direction == 1)
this->PlayerX += move;
else if (this->direction == 3)
this->PlayerX -= move;
if (this->PlayerY < 1)
this->PlayerY = 1;
if (this->PlayerX < 1)
this->PlayerX = 1;
if (this->PlayerY > mapSize.y)
this->PlayerY = mapSize.y;
if (this->PlayerX > mapSize.x)
this->PlayerX = mapSize.x;
}
else if (
move = 1
&& this->getCordBehindCharacter().y - 1 >= 0
&& this->getCordBehindCharacter().x - 1 >= 0
&& this->getCordBehindCharacter().y - 1 < mapSize.y
&& this->getCordBehindCharacter().x - 1 < mapSize.x
&& mapa->_Mapa[this->getCordBehindCharacter().y - 1][this->getCordBehindCharacter().x - 1] == '0') {
if (this->direction == 0)
this->PlayerY -= move;
else if (this->direction == 2)
this->PlayerY += move;
else if (this->direction == 1)
this->PlayerX += move;
else if (this->direction == 3)
this->PlayerX -= move;
if (this->PlayerY < 1)
this->PlayerY = 1;
if (this->PlayerX < 1)
this->PlayerX = 1;
if (this->PlayerY > mapSize.y)
this->PlayerY = mapSize.y;
if (this->PlayerX > mapSize.x)
this->PlayerX = mapSize.x;
}
}
int Player::getDirection() {
return this->direction;
}
Vector2 Player::getPosition() {
return Vector2(this->PlayerX, this->PlayerY);
}
Vector2 Player::getCordInFrontOfCharacter() {
if (this->direction == 2)
return Vector2(this->PlayerX, this->PlayerY + 1);
else if (this->direction == 0)
return Vector2(this->PlayerX, this->PlayerY - 1);
else if (this->direction == 3)
return Vector2(this->PlayerX - 1, this->PlayerY);
else if (this->direction == 1)
return Vector2(this->PlayerX + 1, this->PlayerY);
return Vector2(0, 0);
}
Vector2 Player::getCordBehindCharacter() {
if (direction == 2)
return Vector2(this->PlayerX, this->PlayerY - 1);
else if (this->direction == 0)
return Vector2(this->PlayerX, this->PlayerY + 1);
else if (this->direction == 3)
return Vector2(this->PlayerX + 1, this->PlayerY);
else if (this->direction == 1)
return Vector2(this->PlayerX - 1, this->PlayerY);
return Vector2(0, 0);
}
Thanks for help.
The Visual Studio compilater apparently gets confused at this function signature
void Player::move(int move, Vector2 mapSize, Mapa *mapa)
where the same name is used for a parameter and the function itself.
Change that to make them distinct:
void Player::move(int move_, Vector2 mapSize, Mapa *mapa)
// ^
In cpp file i initialize non-static methods with "::"
It's pretty much impossible to initialize method in c++. I you meant class members, well, then that's wrong.
If you have non-static member, you can't do that:
int foo::member = 0; // error, member is non-static
Every foo object has it's own int member, so it's not shared between them. You must set it for every object in constructor (maybe default values are what you are looking for):
foo::foo (int _mem = 0, ... ) : member(_mem) {...}