Проблема с массивом игр Tetris

Поэтому я пытаюсь сделать игру в тетрис и наткнулся на что-то странное, в чем я не уверен.

У меня есть массив с именем bottom, в котором хранится значение самого нижнего блока, поэтому, если в первом столбце нет блока, «bottom» будет равен 20.

Если есть квадратный блок, занимающий этот первый столбец, bottom будет равен 18. Странно то, что когда я устанавливаю точку останова в своем коде, чтобы попытаться просмотреть значения для bottom, он говорит, что в массиве есть только одно значение. Кроме того, моя доска, которая является массивом 25 на 10, имеет ту же проблему, она отображает только одно измерение.

Кажется, проблема связана с каким-то указателем, потому что он говорит (int (*)[10]) а также (int *)где я думаю, что это должно быть (int [25][10]) а также (int [10]), Я попытался найти указатели и ссылки на массивы, но главное, что я нашел, было то, как создать массив указателей, и я не совсем уверен, как сформулировать мои поиски.

Если кто-то может знать, что происходит, пожалуйста, дайте мне знать!

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;
}
}

#endifmakeboard.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));
}

0

Решение

Это зависит от объема вашего массива. Например:

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.
}
0

Другие решения

Это немного сложно, когда вы обращаетесь к массивам, как вы делаете, но массив, как int array[5] ухудшается до int* array когда вы переходите за пределы области, в которой он определен. Это связано с тем, что массивы являются r-значениями и должны быть преобразованы в l-значение ссылки или указателя (в котором отсутствует информация о количестве элементов) для их передачи. Здесь есть одна проблема: вы все еще можете написать функцию, которая принимает int parameter[5] и компилятор примет это, но будет молча относиться к этому как int* parameter, То же самое касается отладчика.

Таким образом, в зависимости от вашего отладчика, есть разные способы просмотреть все элементы через указатель в любом случае. Например, с этим кодом:

int* ptr = some_array;

… в MSVC я вижу только первый элемент, на который указывает ptr в окне часов. Однако, если я знаю, что some_array имеет 10 элементов, я могу напечатать ptr,10 в окне просмотра, и он покажет мне все 10 элементов.

Кроме того, опять же, это зависит от отладчика, но некоторые отладчики удобно запрограммированы, чтобы показать содержимое стандартных контейнеров, независимо от того, что в красиво читаемом формате. Так что, если вы можете использовать такие как std::vectorэто сделает вашу отладочную жизнь проще, если вы используете такой отладчик.

0

По вопросам рекламы [email protected]