Tetris Game array issue - c++
So I'm trying to make a Tetris game and I've come across something odd that I'm unsure about.
I have an array called bottom which stores the value of the lowest block - so, if there is no block in the first column, "bottom" will be 20.
If there's a square block occupying that first column, bottom would be 18. The weird thing is, when I set a breakpoint in my code to try to view the values for bottom, it says there is only one value in the array. In addition, my board, which is a 25 by 10 array, has the same problem, it only displays one dimension.
It seems the problem has to do with some kind of pointer issue, because it says (int (*)[10]) and (int *), where I think it should be a (int [25][10]) and (int [10]). I tried looking up array pointers and references, but the main thing I found was how to make an array of pointers and I'm not really quite sure how to word my searches.
If someone might know what's going wrong please let me know!
main.cpp
#include <chrono>
#include "makeboard.h"
int main() {
//declares and defines board
int board[24][10];
for (int y = 0; y < 24; y++) {
for (int x = 0; x < 10; x++) {
board[y][x] = 0;
}
}
makeboard(board);
}
tiles.h
#ifndef tiles_h
#define tiles_h
class O {
int board[24][10];
int x, y;
public:
void set_O (int[24][10], int, int);
};
void O::set_O (int board[24][10], int y, int x) {
board[y][x] = 1;
board[y][x+1] = 1;
board[y-1][x] = 1;
board[y-1][x+1] = 1;
}
class I {
int board[24][10];
int x, y, d;
public:
void set_I (int[24][10], int, int, int);
};
void I::set_I (int board[24][10], int d, int y, int x) {
if (d == 1 || d == 3) {
board[y-3][x] = 1;
board[y-2][x] = 1;
board[y-1][x] = 1;
board[y][x] = 1;
}
if (d == 2 || d == 4) {
board[y][x-1] = 1;
board[y][x] = 1;
board[y][x+1] = 1;
board[y][x+2] = 1;
}
}
class S {
int board[24][10];
int x, y, d;
public:
void set_S (int[24][10], int, int, int);
};
void S::set_S (int board[24][10], int d, int y, int x) {
if (d == 1 || d == 3) {
board[y-1][x] = 1;
board[y-1][x+1] = 1;
board[y][x] = 1;
board[y][x-1] = 1;
}
if (d == 2 || d == 4) {
board[y-2][x] = 1;
board[y-1][x] = 1;
board[y-1][x+1] = 1;
board[y][x+1] = 1;
}
}
class Z {
int board[24][10];
int x, y, d;
public:
void set_Z (int[24][10], int, int, int);
};
void Z::set_Z (int board[24][10], int d, int y, int x) {
if (d == 1 || d == 3) {
board[y][x] = 1;
board[y][x-1] = 1;
board[y+1][x] = 1;
board[y+1][x+1] = 1;
}
if (d == 2 || d == 4) {
board[y-1][x+1] = 1;
board[y][x+1] = 1;
board[y][x] = 1;
board[y+1][x] = 1;
}
}
class T {
int board[24][10];
int d, x, y;
public:
void set_T (int[24][10], int, int, int);
};
void T::set_T (int board[24][10], int d, int y, int x) {
if (d == 1 && (board[y+1][x-1] != 1 || board[y+1][x] != 1 || board[y+1][x+1] != 1)) {
board[y-1][x] = 1;
board[y][x-1] = 1;
board[y][x] = 1;
board[y][x+1] = 1;
}
if (d == 2 && (board[y+2][x] != 1 || board[y+1][x+1] != 1)) {
board[y-1][x] = 1;
board[y][x] = 1;
board[y][x+1] = 1;
board[y+1][x] = 1;
}
if (d == 3 && (board[y+1][x-1] != 1 || board[y+2][x] != 1 || board[y+1][x+1] != 1)) {
board[y][x-1] = 1;
board[y][x] = 1;
board[y][x+1] = 1;
board[y+1][x] = 1;
}
if (d == 4 && (board[y+1][x-1] != 1 || board[y+2][x] != 1)) {
board[y-1][x] = 1;
board[y][x-1] = 1;
board[y][x] = 1;
board[y+1][x] = 1;
}
}
class J {
int board[24][10];
int d, x, y;
public:
void set_J (int[24][10], int, int, int);
};
void J::set_J (int board[24][10], int d, int y, int x) {
if (d == 1) {
board[y-1][x-1] = 1;
board[y-1][x] = 1;
board[y-1][x+1] = 1;
board[y][x+1] = 1;
}
if (d == 2) {
board[y-2][x] = 1;
board[y-1][x] = 1;
board[y][x] = 1;
board[y][x-1] = 1;
}
if (d == 3) {
board[y][x-1] = 1;
board[y][x] = 1;
board[y][x+1] = 1;
board[y-1][x-1] = 1;
}
if (d == 4) {
board[y-2][x] = 1;
board[y-2][x+1] = 1;
board[y-1][x] = 1;
board[y][x] = 1;
}
}
class L {
int board[24][10];
int d, x, y;
public:
void set_L (int[24][10], int, int, int);
};
void L::set_L (int board[24][10], int d, int y, int x) {
if (d == 1) {
board[y-1][x-1] = 1;
board[y-1][x] = 1;
board[y-1][x+1] = 1;
board[y][x-1] = 1;
}
if (d == 2) {
board[y-2][x] = 1;
board[y-1][x] = 1;
board[y][x] = 1;
board[y][x-1] = 1;
}
if (d == 3) {
board[y-1][x-1] = 1;
board[y-1][x] = 1;
board[y-1][x+1] = 1;
board[y][x+1] = 1;
}
if (d == 4) {
board[y-2][x] = 1;
board[y-1][x] = 1;
board[y][x] = 1;
board[y][x+1] = 1;
}
}
#endif
makeboard.cpp
#include <iostream>
#include <limits>
#include <thread>
#include "makeboard.h"
#include "clearscreen.h"
#include "isBottom.h"
#include "isPressed.h"
#include "tiles.h"
using namespace std;
string icon[3] = { " ", " o ", " o " };
void makeboard(int board[24][10]) {
time_t srand( time(NULL) );
int block = srand % 7 ;
block = 3;
//declares pieces
O o;
I i;
S s;
Z z;
T t;
J j;
L l;
//declares and defines initial bottom
int bottom[10];
for (int i = 0; i < 10; i++) bottom[i] = 23;
//declares and defines initial block position
int y = 3;
int x = 4;
int d = 1;
while (!isBottom(board, block, y, x, d, bottom)) {
if (isPressed(0) && x > 0) {
x--;
}
if (isPressed(2) && x < 10) {
x++;
}
if (isPressed(1)) {
d += 1;
if (d == 4) {
d = 1;
}
}
//moves tile down
y++;
//clears screen
clearscreen();
//clears non set pieces
for (int i = 0; i < 24; i++) {
for (int j = 0; j < 10; j++) {
if (board[i][j] == 1) {
board[i][j] = 0;
}
}
}
//adds blocks to board
switch (block) {
case 1:
o.set_O(board, y, x);
break;
case 2:
i.set_I(board, d, y, x);
break;
case 3:
s.set_S(board, d, y, x);
break;
case 4:
z.set_Z(board, d, y, x);
break;
case 5:
t.set_T(board, d, y, x);
break;
case 6:
j.set_J(board, d, y, x);
break;
case 7:
l.set_L(board, d, y, x);
break;
}
//builds board
cout << "╔══════════════════════════════╗" << endl;
for (int i = 4; i < 24; i++) {
cout << "║";
for (int j = 0; j < 10; j++) {
cout << icon[board[i][j]] ;
}
cout << "║" << endl;
}
cout << "╚══════════════════════════════╝" << endl;
cout << " 0 1 2 3 4 5 6 7 8 9 " << endl;
//resets initial tile position
if (isBottom(board, block, y, x, d, bottom)) {
y = 2;
//block = srand % 7;
}
//ends game
if (isBottom(board, block, 3, x, d, bottom)) {
cout << "You lose!";
return;
}
//delay
this_thread::sleep_for (chrono::milliseconds(100));
}
return;
}
clearscreen.cpp
#include <unistd.h>
#include <term.h>
#include <stdlib.h>
#include "clearscreen.h"
void clearscreen()
{
if (!cur_term)
{
void *a;
int result;
setupterm( NULL, STDOUT_FILENO, &result );
a = malloc(sizeof(int) *result);
free (a);
if (result <= 0) free (a); return;
}
putp( tigetstr( "clear" ) );
}
isBottom.cpp
#include "isBottom.h"
bool isBottom(int board[24][10], int block, int y, int x, int d, int bottom[10]) {
switch (block) {
case 1:
if (y == bottom[x] || y == bottom[x+1]) {
board[y][x] = 2;
board[y][x+1] = 2;
board[y-1][x] = 2;
board[y-1][x+1] = 2;
bottom[x] -= 2;
bottom[x+1] -= 2;
return true;
}
return false;
break;
case 2:
if (d == 1 || d == 3) {
if (y == bottom[x]) {
board[y-3][x] = 2;
board[y-2][x] = 2;
board[y-1][x] = 2;
board[y][x] = 2;
bottom[x] -= 4;
return true;
}
return false;
break;
}
if (d == 2 || d == 4) {
if (y == bottom[x-1] || y == bottom[x] || y == bottom[x+1] || y == bottom[x+2]) {
board[y][x-1] = 2;
board[y][x] = 2;
board[y][x+1] = 2;
board[y][x+2] = 2;
bottom[x-1]--;
bottom[x]--;
bottom[x+1]--;
bottom[x+2]--;
return true;
}
return false;
break;
}
case 3:
if (d == 1 || d == 3) {
if (y == bottom[x-1] || y == bottom[x] || y == bottom[x+1]) {
board[y-1][x] = 2;
board[y-1][x+1] = 2;
board[y][x] = 2;
board[y][x-1] = 2;
bottom[x-1] = 23 - y;
bottom[x] -= 2;
bottom[x+1] -= 2;
return true;
break;
}
return false;
break;
}
if (d == 2 || d == 4) {
if (y == bottom[x-1] || y == bottom[x]) {
board[y-2][x] = 2;
board[y-1][x] = 2;
board[y-1][x+1] = 2;
board[y][x+1] = 2;
bottom[x-1]--;
bottom[x] -= 1;
return true;
break;
}
return false;
break;
}
/*
case 3:
s.set_S(board, d, y, x);
break;
case 4:
z.set_Z(board, d, y, x);
break;
case 5:
t.set_T(board, d, y, x);
break;
case 6:
j.set_J(board, d, y, x);
break;
case 7:
l.set_L(board, d, y, x);
break;
*/
}
return true;
}
isPressed.cpp
#include <Carbon/Carbon.h>
#include "isPressed.h"
bool isPressed( unsigned short inKeyCode )
{
unsigned char keyMap[16];
GetKeys((BigEndianUInt32*) &keyMap);
return (0 != ((keyMap[ inKeyCode >> 3] >> (inKeyCode & 7)) & 1));
}
It depends on the scope of your array. For example:
int GetBottom(int* bottom);
int GetBottom2(const int (&bottom)[20]);
int main()
{
int localArray1d[20] = {};
int localArray2d[10][25] = {};
// putting a breakpoint here will allow you to see the full dimensions of the array because this function KNOWS what the object is (e.g. a 1d and 2d array respectively)
int lastBrick = GetBottom(localArray1d);
// When the array is passed to GetBottom, it's passed just as a pointer. Although it IS an array, the function GetBottom doesn't know that. We could just as simply pass it a single int*
int n = 0;
GetBottom(&n); // here we are only passing a single int pointer. GetBottom has no idea that your object is an array, it only knows it has an int*
lastBrick = GetBottom2(localArray1d);
// GetBottom2 only takes an array of 20 elements, so inspecting the object in that function allows you to see all the elements.
return 0;
}
int GetBottom(int* bottom)
{
// Having a breakpoint here will not allow you to see all the elements in an array since this function doesn't even know bottom IS an array.
}
int GetBottom2(const int (&bottom)[20])
{
// A breakpoint here will allow you to fully inspect bottom.
}
It's a little tricky when you refer to arrays the way you do, but an array like int array[5] degrades to int* array when you branch outside the scope in which it is defined. It's because arrays are r-values and need to degrade into a reference or pointer l-value (which lacks that info about how many elements there are) to pass them around. The gotcha part here is that you can still write a function which accepts int parameter[5] and the compiler will accept it, but will silently treat it like int* parameter. The same goes for the debugger.
So depending on your debugger, there's different ways to look at all the elements through a pointer anyway. For example, with this code:
int* ptr = some_array;
... in MSVC, I can only see the first element pointed to by ptr in the watch window. However, if I know that some_array has 10 elements, I can type ptr,10 in the watch window and it'll show me all 10 elements.
Also, again this is debugger-specific, but some debuggers are conveniently programmed to show the contents of standard containers no matter what in a beautifully-readable format. So if you can use contaners like std::vector, it'll make your debugging life easier if you're using such a debugger.
Related
How can I get the common digits of two int in C++? Example: (1234, 41567) --> 1 4
Given two int I want to get all the common digits and print out them separated by spaces. So for example, if int x=1234; int y=41567; then I want to print out: 1 4. This is my code. It does not work properly. When I run it, it prints 0 1 2 3 4 5 then stops. I don't want to use vector nor arrays. void problema3() { int x, y, kX=0, kY=0; cout << "x="; cin >> x; cout << "y="; cin >> y; int cx = x; int cy = y; for (int i = 0; i < 10; i++) { kX = 0; kY = 0; x = cx; y = cx; while (x != 0 || kX==0) { if (x % 10 == i) kX=1; x /= 10; } while (y != 0 || kY == 0) { if (y % 10 == i) kY=1; y /= 10; } if (kX == 1 && kY == 1) cout << i << ' '; } } int main() { problema3(); return 0; }
If you're allowed to use std::set then you can do what you want as follows: #include <iostream> #include <set> void print(int x, int y) { int individual_number1 = 0, individual_number2 = 0; std::set<int> myset; int savey = y;//this will be used to reset y when the 2nd do while loop finishes do { individual_number1 = x % 10; do { individual_number2 = y % 10; if(individual_number1 == individual_number2) { myset.insert(individual_number1); break; } y = y / 10; }while( y > 0); y = savey; x = x / 10; } while (x > 0); //print out the element of the set for(int i: myset) { std::cout<<i<<" "; } } int main() { int x = 1234, y = 41567; print(x, y); return 0; } The output of the above program is as follows: 1 4 which can be seen here.
Your main bug is when assigning copies of cy. //... for (int i = 0; i < 10; i++) { //... x = cx; y = cx; // <-- BUG! should read y = cy; But that's not the only bug in your program. Your digit detection logic is wrong. In particular, zero is not handled correctly, and since you did not put that reusable code in a function, your program is way more complex than it needs. Here's the corrected logic for digit detection. // checks if base 10 representation of a positive integer contains a certain digit (0-9) bool hasDigit(int x, int d) { do { if (x % 10 == d) return true; x /= 10; } while (x != 0); return false; } Your main loop then becomes: // assuming int x, y as inputs. // ... for (int i = 0; i < 10; ++i) { if (hasDigit(x, i) && hasDigit(y, i)) std::cout << i << ' '; } Which leaves very little room for bugs. You can play with the code here: https://godbolt.org/z/5c5brEcEq
Printing 2D array in full ignores edited values, prints initialised values
beginner to C++ and attempting a dungeon crawler beginner task, upon testing one of the classes I found that printing the 2D array works, however if it is edited and printed, it resets and prints original values it was initialised with. InitGrid is used to initialize the array. class MAP { public: /* Difficulty used in number of enemies and traps created. 1-5 Difficulty | 1 - Too easy | 2 - Easy | 3 - Normal | 4 - Hard | 5 - Insane | */ int Difficulty = Hard; //### Temporary, user selection needs implemented ### int SpawnPos; int TPosX; //Treasure Postion, used to checkwinstate. int TPosY; //Treasure Postion, used to checkwinstate. char Grid[MAPHeight][MAPWidth]; void InitGrid() { for (int y = 0; y < 9; y++) //Row loop { for (int x = 0; x < 14; x++) //Column loop { Grid[y][x] = { '.' }; } } } void PrintMap() { for (int y = 0; y < 9; y++) //This loops on the rows. { for (int PrintX = 0; PrintX < 14; PrintX++) //This loops on the columns { cout << Grid[y][PrintX] << " "; } cout << endl; } } void GenerateEnemies() { for (int i = 0; i < Difficulty; i++) { int TotEnemies = (Difficulty * 1.5); for (TotEnemies; TotEnemies == 0; TotEnemies--) { int x = rand() % (MAPWidth - 1); int y = rand() % (MAPHeight - 1); if (Grid[y][x] == '.') { Grid[y][x] = '#'; } else { GenerateEnemies(); } } } } // Generate Enemies void GenerateTraps() { for (int i = 0; i < Difficulty; i++) { int TotTraps = (Difficulty * 1.5); for (TotTraps; TotTraps == 0; TotTraps--) { int x = rand() % (MAPWidth - 1); int y = rand() % (MAPHeight - 1); if (Grid[y][x] == '.') { Grid[y][x] = 'T'; } else { GenerateTraps(); } } } } void GenerateTreasure() { int x = rand() % MAPWidth; int y = rand() % MAPHeight; /* Randomly selects spawn location uses tmp variables to overwrite that grid location. */ if (Grid[y][x] == '.') { Grid[y][x] = 'X'; } else { GenerateTreasure(); } TPosX = x; TPosY = y; } }; //PLAYER CLASS class PLAYER : public MAP { public: int Health = (Difficulty * 1.5); int PPosX; int PPosY; char Direction; //Use cin to get user input after map is updated, used in switch case to move player. void GenerateSpawn() { int x = rand() % (MAPWidth - 1); int y = rand() % (MAPHeight - 1); /* Randomly selects spawn location uses tmp variables to overwrite that grid location. */ Grid[y][x] = 'P'; PPosX = x; PPosY = y; } void AllowMove(int y, int x) { if (Grid[y][x] == '.') { Grid[y][x] = '#'; } else if (Grid[y][x] == 'X') { //GameWin(); } else if (Grid[y][x] == '#') { //DamagePlayer(); } else {} } void MovePlayer() { switch (Direction) { case 'w': { int x = PPosX; int y = (PPosY + 1); void AllowMove(int y, int x); } break; case 'a': { int x = (PPosX - 1); int y = PPosY; void AllowMove(int y, int x); } break; case 's': { int x = (PPosX); int y = PPosY; void AllowMove(int y, int x); } break; case 'd': { int x = (PPosX + 1); int y = PPosY; void AllowMove(int y, int x); } break; default: cout << "invalid character, try again." << endl; Sleep(5000); //Call function to retry } } }; //######### End ######### //Main Function int main() { srand(time(NULL)); //Used to seed rand() values. SetConsoleTitle(TEXT("Dungeon Crawler")); //Objects MAP Map; PLAYER Player; Map.InitGrid(); Player.GenerateSpawn(); //Map.GenerateTreasure(); //Map.GenerateEnemies(); //Map.GenerateTraps(); Map.PrintMap(); cout << endl; } However, when I run these, I get the following image: I've attempted debugging in visual studio using breakpoints and at some point it does set the grid value to 'P' but I couldn't find where I gets 'reset' for lack of a better term.
char Grid[MAPHeight][MAPWidth]; needs to be moved outside of the class as a global variable. Currently as the PLAYER class inherits from the MAPS class, when GenerateSpawn() edits the Grid that is created specific to the object linked to PLAYER. When it is a global variable, it is separate, then when edited by GenerateSpawn() and called by void PrintMap() they both use the same Grid. That way when it is printed to console it correctly prints out the map. Answered my own question in case someone else stumbles upon this.
Run-Time Check Failure #2 Stack around the variable 'maze' were corrupted
Run-Time Check Failure #2 Stack around the variable 'maze' were corrupted. Whenever I compile and run my program, I receive this error whenever the program finishes running. I believe the problem is happening in my addPaths function in my implementation. I posted all my code just in case. This program is creating a maze and the addPaths function is "digging" the paths for the user to move through. The path direction is chosen at random and the paths are only drawn at even number spaces on the maze. HEADER: const int HEIGHT = 3; const int WIDTH = 5; class Coordinate { public: int row, column; }; class Maze { public: Maze(); ~Maze(); void buildMaze(); void displayMaze(); void addPaths(); void startGame(); void movePlayer(int); bool solved(); int getKey(); void addDestinationToGrid(); private: char grid[WIDTH][HEIGHT]; Coordinate player; const static char PLAYER = 'P'; const static char DESTINATION = 'X'; const static char START = 'S'; const static char PATH = ' '; const static char WALL = (char)219; }; IMPLEMENTATION: #include <iostream> #include "maze.h" #include <windows.h> #include <stack> using std::cout; using std::endl; Maze::Maze() { buildMaze(); } Maze::~Maze() { cout << "yay"; } void Maze::buildMaze() { for (int x = 0; x <= HEIGHT-1; x++) { for (int y = 0; y <= WIDTH-1; y++) { grid[x][y] = WALL; //SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4); } } } void Maze::displayMaze() { for (int x = 0; x <= HEIGHT-1; x++) { for (int y = 0; y <= WIDTH-1; y++) { cout << grid[x][y]; } cout << endl; } } void Maze::startGame() { int input; do { input = getKey(); movePlayer(input); } while (!solved()); } bool Maze::solved() { return true; } void Maze::movePlayer(int direction) { if (direction == VK_UP || direction == VK_DOWN || direction == VK_LEFT || direction == VK_RIGHT) { COORD newCoord = { player.column + 1, player.row + 1 }; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), newCoord); if (grid[player.row][player.column] == START) { cout << START; } else { cout << PATH; } } } int Maze::getKey() { int result = 0; while (!solved() && result == 0) { short MAX_SHORT = 0x7FFF; //111111111111111 if (GetAsyncKeyState(VK_LEFT) & MAX_SHORT) { result = VK_LEFT; } else if (GetAsyncKeyState(VK_UP) & MAX_SHORT) { result = VK_UP; } else if (GetAsyncKeyState(VK_RIGHT) & MAX_SHORT) { result = VK_RIGHT; } else if (GetAsyncKeyState(VK_DOWN) & MAX_SHORT) { result = VK_DOWN; } } return result; } void Maze::addPaths() { Coordinate currentLocation; Coordinate startLocation; //Coordinate endLocation; //not used yet std::stack<Coordinate> myStack; currentLocation.row = (((rand() % HEIGHT) / 2) * 2); currentLocation.column = (((rand() % WIDTH) / 2) * 2); startLocation = currentLocation; grid[currentLocation.row][currentLocation.column] = START; player = currentLocation; do { bool canMoveUp = !(currentLocation.row == 0 || grid[currentLocation.row - 2][currentLocation.column] != WALL); bool canMoveDown = !(currentLocation.row == HEIGHT - 1 || grid[currentLocation.row + 2][currentLocation.column] != WALL); bool canMoveLeft = !(currentLocation.column == 0 || grid[currentLocation.row][currentLocation.column - 2] != WALL); bool canMoveRight = !(currentLocation.column == WIDTH - 1 || grid[currentLocation.row][currentLocation.column + 2] != WALL); if (canMoveUp || canMoveDown || canMoveLeft || canMoveRight) { myStack.push(currentLocation); //choose random location to dig bool moveFound = false; while (moveFound != true) { int direction = rand() % 4; if (direction == 0 && canMoveUp) { moveFound = true; grid[currentLocation.row - 2][currentLocation.column] = PATH; grid[currentLocation.row - 1][currentLocation.column] = PATH; currentLocation.row -= 2; } else if (direction == 1 && canMoveDown) { moveFound = true; grid[currentLocation.row + 2][currentLocation.column] = PATH; grid[currentLocation.row + 1][currentLocation.column] = PATH; currentLocation.row += 2; } else if (direction == 2 && canMoveLeft) { moveFound = true; grid[currentLocation.row][currentLocation.column - 2] = PATH; grid[currentLocation.row][currentLocation.column - 1] = PATH; currentLocation.column -= 2; } else if (direction == 3 && canMoveRight) { moveFound = true; grid[currentLocation.row][currentLocation.column + 2] = PATH; grid[currentLocation.row][currentLocation.column - 2] = PATH; currentLocation.column += 2; } } } else if (!myStack.empty()) { currentLocation = myStack.top(); myStack.pop(); } } while (!myStack.empty()); addDestinationToGrid(); } void Maze::addDestinationToGrid() { int randomRow = rand() % HEIGHT; int randomColumn = rand() % WIDTH; while (grid[randomRow][randomColumn] != PATH) { randomRow = rand() % HEIGHT; randomColumn = rand() % WIDTH; } grid[randomRow][randomColumn] = DESTINATION; } MAIN: #include <iomanip> #include <iostream> #include "maze.h" using namespace std; int main() { Maze maze; maze.addPaths(); maze.displayMaze(); maze.startGame(); /*if (maze.solved()) { cout << " You Win!"; }*/ }
There are two problems. One is that you are not consistent in the order you access elements of grid. It is declared grid[WIDTH][HEIGHT] but most (but not all) accesses use a HEIGHT based index first. This isn't causing your problems since WIDTH is greater than HEIGHT and you stay within the object's memory when doing normal accesses to it. The problem is this line: grid[currentLocation.row][currentLocation.column - 2] = PATH; in the moveRight handler. The column offset should be + 1, not - 2. The way it is can cause you to write to memory before the first element of grid.
C++ Not Counting white beands
I need some help. I'm writing a code in C++ that will ultimately take a random string passed in, and it will do a break at every point in the string, and it will count the number of colors to the right and left of the break (r, b, and w). Here's the catch, the w can be either r or b when it breaks or when the strong passes it ultimately making it a hybrid. My problem is when the break is implemented and there is a w immediately to the left or right I can't get the program to go find the fist b or r. Can anyone help me? #include <stdio.h> #include "P2Library.h" void doubleNecklace(char neck[], char doubleNeck[], int size); int findMaxBeads(char neck2[], int size); #define SIZE 7 void main(void) { char necklace[SIZE]; char necklace2[2 * SIZE]; int brk; int maxBeads; int leftI, rightI, leftCount = 0, rightCount=0, totalCount, maxCount = 0; char leftColor, rightColor; initNecklace(necklace, SIZE); doubleNecklace(necklace, necklace2, SIZE); maxBeads = findMaxBeads(necklace2, SIZE * 2); checkAnswer(necklace, SIZE, maxBeads); printf("The max number of beads is %d\n", maxBeads); } int findMaxBeads(char neck2[], int size) { int brk; int maxBeads; int leftI, rightI, leftCount = 0, rightCount=0, totalCount, maxCount = 0; char leftColor, rightColor; for(brk = 0; brk < 2 * SIZE - 1; brk++) { leftCount = rightCount = 0; rightI = brk; rightColor = neck2[rightI]; if(rightI == 'w') { while(rightI == 'w') { rightI++; } rightColor = neck2[rightI]; } rightI = brk; while(neck2[rightI] == rightColor || neck2[rightI] == 'w') { rightCount++; rightI++; } if(brk > 0) { leftI = brk - 1; leftColor = neck2[leftI]; if(leftI == 'w') { while(leftI == 'w') { leftI--; } leftColor = neck2[leftI]; } leftI = brk - 1; while(leftI >= 0 && neck2[leftI] == leftColor || neck2[leftI] == 'w') { leftCount++; leftI--; } } totalCount = leftCount + rightCount; if(totalCount > maxCount) { maxCount = totalCount; } } return maxCount; } void doubleNecklace(char neck[], char doubleNeck[], int size) { int i; for(i = 0; i < size; i++) { doubleNeck[i] = neck[i]; doubleNeck[i+size] = neck[i]; } }
I didn't study the code in detail, but something is not symmetric: in the for loop, the "left" code has an if but the "right" code doesn't. Maybe you should remove that -1 in the for condition and add it as an if for the "right" code: for(brk = 0; brk < 2 * SIZE; brk++) { leftCount = rightCount = 0; if (brk < 2 * SIZE - 1) { rightI = brk; rightColor = neck2[rightI]; //... } if(brk > 0) { leftI = brk - 1; leftColor = neck2[leftI]; //... } //... Just guessing, though... :-/ Maybe you should even change those < for <=.
Pacman Game stuff not declared?
I am getting these two errors while compiling but i dont understand what i didnt do right. main.cpp|107|error: 'sqrt' was not declared in this scope| main.cpp|107|error: 'pow' was not declared in this scope| #include <iostream> #include <Windows.h> using namespace std; struct Player { int x, y; Player() { x = -1; y = -1; } }; struct Ghost { int x, y, direction; Ghost() { x = -1; y = -1; direction = 1; } }; const char SYMBOL_EMPTY = ' '; const char SYMBOL_PLAYER = '#'; const char SYMBOL_GHOST = 'G'; const char SYMBOL_WALL = '#'; const int MapDx = 10; const int MapDy = 20; const int GameSpeed = 100; const int LEFT = 1; const int RIGHT = 2; const int UP = 3; const int DOWN = 4; int direction = RIGHT; char map[10][20] = { "###################", "# #", "# #", "# #", "# #", "# #", "# #", "# #", "###################" }; bool isValidPos(int x, int y) { return (x >= 0 && x < MapDx && y >= 0 && y < MapDy); } bool movePlayer(Player &player, int x, int y) { if (!isValidPos(x, y)) { return false; } char ch = map[x][y]; if(ch != SYMBOL_EMPTY) { return false; } if (isValidPos(player.x, player.y)) { map[player.x][player.y] = SYMBOL_EMPTY; } player.x = x; player.y = y; map[player.x][player.y] = SYMBOL_PLAYER; return true; } bool moveGhost(Ghost &ghost, int x, int y) { if (!isValidPos(x, y)) { return false; } char ch = map[x][y]; if (ch != SYMBOL_EMPTY) { return false; } if (isValidPos(ghost.x, ghost.y)) { map[ghost.x][ghost.y] = SYMBOL_EMPTY; } ghost.x = x; ghost.y = y; map[ghost.x][ghost.y] = SYMBOL_GHOST; return true; } void GhostAI(Ghost &ghost, Player &player) { double a = sqrt((pow((double) (ghost.x - 1) - player.x, 2)) + pow((double) ghost.y - player.y, 2)); //UP double b = sqrt((pow((double) (ghost.x + 1) - player.x, 2)) + pow((double) ghost.y - player.y, 2)); //DOWN double c = sqrt((pow((double) (ghost.y - 1) - player.x, 2)) + pow((double) ghost.x - player.y, 2)); //RIGHT double d = sqrt((pow((double) (ghost.y + 1) - player.x, 2)) + pow((double) ghost.x - player.y, 2)); //LEFT if(a < b && a <= c && a <= d && ghost.direction != DOWN) ghost.direction = UP; else if(b <= c && b <= d && ghost.direction != UP) ghost.direction = DOWN; else if(c < d && ghost.direction != LEFT) ghost.direction = RIGHT; else if(ghost.direction != RIGHT) ghost.direction = LEFT; } void showMap() { for (int x = 0; x < MapDx; x++) { cout << map[x] << endl; } } void showPlayer(Player &player) { cout << "\nPlayerX: " << player.x << endl; cout << "PlayerY: " << player.y << endl; } void gameLoop() { Player player; Ghost ghosts[3]; movePlayer(player, 1, 2); moveGhost(ghosts[0], 5, 2); moveGhost(ghosts[1], 5, 5); moveGhost(ghosts[2], 5, 8); while (true) { system("cls"); showMap(); showPlayer(player); if (GetAsyncKeyState(VK_UP)) { direction = UP; } else if (GetAsyncKeyState(VK_DOWN)) { direction = DOWN; } else if (GetAsyncKeyState(VK_LEFT)) { direction = LEFT; } else if (GetAsyncKeyState(VK_RIGHT)) { direction = RIGHT; } switch (direction) { case UP: movePlayer(player, player.x-1, player.y); break; case DOWN: movePlayer(player, player.x+1, player.y); break; case LEFT: movePlayer(player, player.x, player.y-1); break; case RIGHT: movePlayer(player, player.x, player.y+1); break; } for (int ghost = 0; ghost < 3; ghost++) { GhostAI(ghosts[ghost], player); switch (ghosts[ghost].direction) { case UP: moveGhost(ghosts[ghost], ghosts[ghost].x-1, ghosts[ghost].y); break; case DOWN: moveGhost(ghosts[ghost], ghosts[ghost].x+1, ghosts[ghost].y); break; case LEFT: moveGhost(ghosts[ghost], ghosts[ghost].x, ghosts[ghost].y-1); break; case RIGHT: moveGhost(ghosts[ghost], ghosts[ghost].x, ghosts[ghost].y+1); break; } } Sleep(GameSpeed); } } int main() { gameLoop(); return 0; }
You need to #include <cmath> It's the header that declares those functions.
sqrt and pow functions are declared in the Math Library. Make sure to include them in your program at gloal scope like this. #include <cmath>