俄罗斯方块游戏阵列问题

时间:2015-05-07 02:40:25

标签: c++ arrays pointers tetris

所以我正在尝试制作俄罗斯方块游戏而且我遇到了一些我不确定的奇怪事物。

我有一个名为bottom的数组,用于存储最低块的值 - 因此,如果第一列中没有块,则“bottom”将为20。

如果有一个方块占用第一列,则底部为18.奇怪的是,当我在代码中设置断点以尝试查看底部的值时,它表示数组中只有一个值。另外,我的电路板是一个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;
    }
}

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

2 个答案:

答案 0 :(得分: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.
}

答案 1 :(得分: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之类的容器,那么如果您使用这样的调试器,它将使您的调试生活更轻松。