c++arrayspointerstetris

Tetris Game array issue


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

Solution

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