Search code examples
arrayscfunctionmultidimensional-arrayscope

3D array manipulation from within a function


So, I am trying to create a mini chess simulator for a project. In the project, I decided to use a 3D array to represent the chess board, with the dimensions representing X, Y, and Piece Data.

My problem is that the system refuses to edit the passed array within the "playerMove" function. So, I think it is a variable scope issue. I don't know how to apply the solutions to 3D arrays though.

Sorry for the huge block of code.

#define _CRT_SECURE_NO_WARNINGS 1 //this is because my pc normally forces scanf_s and similar "safe" functions instead of the simple ones

//includes stuff
#include <stdio.h>
#include <stdlib.h>

#define chessBoardSize 8
#define chessDataSize 2


//predefinitions and global variables
void setupNewBoard(char board[chessBoardSize][chessBoardSize][chessDataSize], char setupOrganization);
void printBoard(char board[chessBoardSize][chessBoardSize][chessDataSize], char highlightColor, char highlightPiece);
int printBoardSpecific(char board[chessBoardSize][chessBoardSize][chessDataSize], char highlightColor, char highlightPiece, int xCoord, int yCoord);
int printBoardLegalMoves (char board[chessBoardSize][chessBoardSize][chessDataSize], char pieceType, int xCoord, int yCoord, int endXCoord, int endYCoord);
void playerMove(char playBoard[chessBoardSize][chessBoardSize][chessDataSize], char playTurnColor);



//Main function
int main()
{
    char chessSquare[chessBoardSize][chessBoardSize][2]; //create chess board for pieces
    for (int yCounter = 0; yCounter < chessBoardSize; yCounter++) {
        for (int xCounter = 0; xCounter < chessBoardSize; xCounter++) {
            chessSquare[xCounter][yCounter][0] = '_';
            chessSquare[xCounter][yCounter][1] = 'f';
        }
        printf("\n");
    }

    setupNewBoard(chessSquare, 'b');

    printBoard(chessSquare, 'x', 'x');//prints a board with no highlighted pieces to start the game

    playerMove(chessSquare, 'R');
    
        
    for (int yCounter = 0; yCounter < chessBoardSize; yCounter++) {
        for (int xCounter = 0; xCounter < chessBoardSize; xCounter++) {
            printf("%c", chessSquare[xCounter][yCounter][0]);
            //printf("%c",chessSquare[xCounter][yCounter][1]);
        }
        printf("\n");
    }

    //printBoard(chessSquare, 'x', 'x');

    return 0;
}

//setup the board funciton defenition
void setupNewBoard(char board[chessBoardSize][chessBoardSize][chessDataSize], char setupOrganization) {
    if (setupOrganization == 'b') {
        //setupBlue
            //blue rook, left side
            board[0][0][0] = 'R';
            board[0][0][1] = 'B';
            //blue knight, left side
            board[1][0][0] = 'N';
            board[1][0][1] = 'B';
            //blue bishop, left side
            board[2][0][0] = 'B';
            board[2][0][1] = 'B';
            //blue queen
            board[3][0][0] = 'Q';
            board[3][0][1] = 'B';
            //blue king
            board[4][0][0] = 'K';
            board[4][0][1] = 'B';
            //blue bishop, right side
            board[5][0][0] = 'B';
            board[5][0][1] = 'B';
            //blue knight, right side
            board[6][0][0] = 'N';
            board[6][0][1] = 'B';
            //blue rook, right side
            board[7][0][0] = 'R';
            board[7][0][1] = 'B';
            //blue pawns
            for (int counter = 0; counter < chessBoardSize; counter++) {
                board[counter][1][0] = 'P';
                board[counter][1][1] = 'B';
            }

            //setupRed
                //red rook, left side
                board[0][7][0] = 'R';
                board[0][7][1] = 'R';
                //red knight, left side
                board[1][7][0] = 'N';
                board[1][7][1] = 'R';
                //red bishop, left side
                board[2][7][0] = 'B';
                board[2][7][1] = 'R';
                //red queen
                board[3][7][0] = 'Q';
                board[3][7][1] = 'R';
                //red king
                board[4][7][0] = 'K';
                board[4][7][1] = 'R';
                //red bishop, right side
                board[5][7][0] = 'B';
                board[5][7][1] = 'R';
                //red knight, right side
                board[6][7][0] = 'N';
                board[6][7][1] = 'R';
                //red rook, right side
                board[7][7][0] = 'R';
                board[7][7][1] = 'R';
                //blue pawns
                for (int counter = 0; counter < chessBoardSize; counter++) {
                    board[counter][6][0] = 'P';
                    board[counter][6][1] = 'R';
                }
    }
}

//print the board function defenition
void printBoard(char board[chessBoardSize][chessBoardSize][chessDataSize], char highlightColor, char highlightPiece) {
    
    printf(" 01234567\n");
    for (int yCounter = 0; yCounter < chessBoardSize; yCounter++) {
        printf("%d", yCounter);
        for (int xCounter = 0; xCounter < chessBoardSize; xCounter++) {
            if ((xCounter + yCounter) % 2 == 1) {
                char currentPiece = board[xCounter][yCounter][0];
                char currentColor = board[xCounter][yCounter][1];
                if (board[xCounter][yCounter][1] == 'R') {
                    if ((currentPiece == highlightPiece) && (currentColor == highlightColor)) {
                        printf("\033[31m\033[43m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                    else {
                        printf("\033[31m\033[107m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                }
                else if (board[xCounter][yCounter][1] == 'B') {
                    if ((currentPiece == highlightPiece) && (currentColor == highlightColor)) {
                        printf("\033[34m\033[43m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                    else {
                        printf("\033[34m\033[107m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                }
                else {
                    printf("\033[30m\033[107m%c\033[0m", board[xCounter][yCounter][0]);
                }
            }
            else {
                char currentPiece = board[xCounter][yCounter][0];
                char currentColor = board[xCounter][yCounter][1];
                if (board[xCounter][yCounter][1] == 'R') {
                    if ((currentPiece == highlightPiece) && (currentColor == highlightColor)) {
                        printf("\033[31m\033[43m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                    else {
                        printf("\033[31m\033[100m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                }
                else if (board[xCounter][yCounter][1] == 'B') {
                    if ((currentPiece == highlightPiece) && (currentColor == highlightColor)) {
                        printf("\033[34m\033[43m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                    else {
                        printf("\033[34m\033[100m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                }
                else {
                    printf("\033[30m\033[100m%c\033[0m", board[xCounter][yCounter][0]);
                }
            }
        }
        printf("\033[0m\n");
    }
}

//print the board with a specific piece selected
int printBoardSpecific(char board[chessBoardSize][chessBoardSize][chessDataSize], char highlightColor, char highlightPiece, int xCoord, int yCoord) {
    
    int connect = 0;
    printf(" 01234567\n");
    for (int yCounter = 0; yCounter < chessBoardSize; yCounter++) {
        printf("%d", yCounter);
        for (int xCounter = 0; xCounter < chessBoardSize; xCounter++) {
            if ((xCounter + yCounter) % 2 == 1) {
                char currentPiece = board[xCounter][yCounter][0];
                char currentColor = board[xCounter][yCounter][1];
                if (board[xCounter][yCounter][1] == 'R') {
                    if ((currentPiece == highlightPiece) && (currentColor == highlightColor) && (xCoord == xCounter) && (yCoord == yCounter)) {
                        printf("\033[31m\033[43m%c\033[0m", board[xCounter][yCounter][0]);
                        connect = 1;
                    }
                    else {
                        printf("\033[31m\033[107m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                }
                else if (board[xCounter][yCounter][1] == 'B') {
                    if ((currentPiece == highlightPiece) && (currentColor == highlightColor) && (xCoord == xCounter) && (yCoord == yCounter)) {
                        printf("\033[34m\033[43m%c\033[0m", board[xCounter][yCounter][0]);
                        connect = 1;
                    }
                    else {
                        printf("\033[34m\033[107m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                }
                else {
                    printf("\033[30m\033[107m%c\033[0m", board[xCounter][yCounter][0]);
                }
            }
            else {
                char currentPiece = board[xCounter][yCounter][0];
                char currentColor = board[xCounter][yCounter][1];
                if (board[xCounter][yCounter][1] == 'R') {
                    if ((currentPiece == highlightPiece) && (currentColor == highlightColor) && (xCoord == xCounter) && (yCoord == yCounter)) {
                        printf("\033[31m\033[43m%c\033[0m", board[xCounter][yCounter][0]);
                        connect = 1;
                    }
                    else {
                        printf("\033[31m\033[100m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                }
                else if (board[xCounter][yCounter][1] == 'B') {
                    if ((currentPiece == highlightPiece) && (currentColor == highlightColor) && (xCoord == xCounter) && (yCoord == yCounter)) {
                        printf("\033[34m\033[43m%c\033[0m", board[xCounter][yCounter][0]);
                        connect = 1;
                    }
                    else {
                        printf("\033[34m\033[100m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                }
                else {
                    printf("\033[30m\033[100m%c\033[0m", board[xCounter][yCounter][0]);
                }
            }
        }
        printf("\033[0m\n");
    }
    return connect;
}

//print the board with legal moves displayed
int printBoardLegalMoves (char board[chessBoardSize][chessBoardSize][chessDataSize], char pieceType, int xCoord, int yCoord, int endXCoord, int endYCoord) {
    system("cls");
    int connect = 0;
    char legalMovesChart[chessBoardSize][chessBoardSize];
    
    //resets the legal moves for new call
    for (int yCounter = 0; yCounter < chessBoardSize; yCounter++) {
        for (int xCounter = 0; xCounter < chessBoardSize; xCounter++) {
            legalMovesChart[xCounter][yCounter] = 0;
        }
    }

    //decides correct "legal" moves based on piece type and environment
    switch (pieceType){
        case 'P':
            if (board[xCoord][yCoord][1] == 'B') {
                //move forward one space if not occupied
                if (board[xCoord][(yCoord + 1)][0] == '_') {
                    legalMovesChart[xCoord][(yCoord + 1)] = 1;
                }
                if ((xCoord > 0) && (board[(xCoord - 1)][(yCoord + 1)][1] == 'R')) {
                    legalMovesChart[(xCoord - 1)][(yCoord + 1)] = 1;
                }
                if ((xCoord < 7) && (board[(xCoord + 1)][(yCoord + 1)][1] == 'R')) {
                    legalMovesChart[(xCoord + 1)][(yCoord + 1)] = 1;
                }
                if ((yCoord == 6) && (board[xCoord][(yCoord + 1)][0] == '_') && board[xCoord][(yCoord + 2)][0] == '_') {
                    legalMovesChart[xCoord][(yCoord + 2)] = 1;
                }
            }
            else if(board[xCoord][yCoord][1] == 'R') {
                //move forward one space if not occupied
                if (board[xCoord][(yCoord - 1)][0] == '_') {
                    legalMovesChart[xCoord][(yCoord - 1)] = 1;
                }
                if ((xCoord > 0) && (board[(xCoord - 1)][(yCoord - 1)][1] == 'B')) {
                    legalMovesChart[(xCoord - 1)][(yCoord - 1)] = 1;
                }
                if ((xCoord < 7) && (board[(xCoord + 1)][(yCoord - 1)][1] == 'B')) {
                    legalMovesChart[(xCoord + 1)][(yCoord - 1)] = 1;
                }
                if ((yCoord == 6) && (board[xCoord][(yCoord - 1)][0] == '_') && board[xCoord][(yCoord - 2)][0] == '_') {
                    legalMovesChart[xCoord][(yCoord - 2)] = 1;
                }
            }
            break;

        default:
            printf("not a pawn");
            break;
    }
    
    printf(" 01234567\n");
    for (int yCounter = 0; yCounter < chessBoardSize; yCounter++) {
        printf("%d", yCounter);
        for (int xCounter = 0; xCounter < chessBoardSize; xCounter++) {
            if ((xCounter + yCounter) % 2 == 1) {
                //SELECTED PIECE
                if ((xCounter == xCoord) && (yCounter == yCoord)) {
                    if (board[xCounter][yCounter][1] == 'R') {
                        printf("\033[31m\033[43m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                    else {
                        printf("\033[34m\033[43m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                }
                else if (legalMovesChart[xCounter][yCounter]) { //ALL LEGAL MOVES
                    if (board[xCounter][yCounter][1] == 'R') {
                        printf("\033[31m\033[42m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                    else {
                        printf("\033[34m\033[42m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                }
                else { //everything else
                    if (board[xCounter][yCounter][1] == 'R') {
                        printf("\033[31m\033[107m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                    else if (board[xCounter][yCounter][1] == 'B') {
                        printf("\033[34m\033[107m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                    else {
                        printf("\033[30m\033[107m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                }
            }
            else {
                //SELECTED PIECE
                if ((xCounter == xCoord) && (yCounter == yCoord)) {
                    if (board[xCounter][yCounter][1] == 'R') {
                        printf("\033[31m\033[43m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                    else {
                        printf("\033[34m\033[43m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                }
                else if (legalMovesChart[xCounter][yCounter]) { //ALL LEGAL MOVES
                    if (board[xCounter][yCounter][1] == 'R') {
                        printf("\033[31m\033[42m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                    else {
                        printf("\033[34m\033[42m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                }
                else { //everything else
                    if (board[xCounter][yCounter][1] == 'R') {
                        printf("\033[31m\033[100m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                    else if (board[xCounter][yCounter][1] == 'B') {
                        printf("\033[34m\033[100m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                    else {
                        printf("\033[30m\033[100m%c\033[0m", board[xCounter][yCounter][0]);
                    }
                }
            }
        }
        printf("\n");
    }

    if (legalMovesChart[endXCoord][endYCoord] == 1) {
        connect = 1;
    }
    else {
        connect = 0;
    }


    return connect;
}

//playerMove funciton defenition
void playerMove (char playBoard[chessBoardSize][chessBoardSize][chessDataSize], char playTurnColor) {
    char startP; //type of piece
    int startCX; //x coordinate of piece
    int startCY; //y coordinate of piece

    int endCX; //end x coordinate
    int endCY; //end y coordinate

    int itemLocatedBool = 0;
    int endLocatedBool = 0;
    
    startP = getche();
    printf("\n");

    system("cls");
    
    printBoard(playBoard, playTurnColor, startP);

    while (itemLocatedBool != 1) {
        printf("(");
        startCX = getche();
        printf(",");
        startCY = getche();
        printf(")\n");

        system("cls");

        itemLocatedBool = printBoardSpecific(playBoard, playTurnColor, startP, (startCX - '0'), (startCY - '0'));
    }

    printBoardLegalMoves(playBoard, startP, (startCX - '0'), (startCY - '0'), 0, 0);
    
    while (endLocatedBool != 1) {
        printf("(");
        endCX = getche();
        printf(",");
        endCY = getche();
        printf(")\n");

        system("cls");

        endLocatedBool = printBoardLegalMoves(playBoard, startP, (startCX - '0'), (startCY - '0'), (endCX - '0'), (endCY - '0'));
    }

    playBoard[startCX][startCY][0] = '_';
    playBoard[startCX][startCY][1] = 'f';

    playBoard[endCX][endCY][0] = startP;
    playBoard[endCX][endCY][1] = playTurnColor;

    //printf("\n%c,%c", startP, playTurnColor);
    //printf("::%c,%c\n", playBoard[endCX][endCY][0], playBoard[endCX][endCY][1]);

    //swap turns
    /*
    if (playTurnColor == 'B') {
        playTurnColor = 'R';
    }
    else {
        playTurnColor = 'B';
    }
    */
}


//green: 42 (this is for legal moves)

I am trying to get the "playerMove" function to edit the array "chessSquare" from main. I tried changing the calls and definitions to pointers, but it returns an error about illegal memory access violation.

I may just be misunderstanding how pointers and arrays work, but after looking through multiple tutorials, I couldn't solve the issue.


Solution

  • I found my own problem. The access violation was caused by an improper translation. I forgot to translate the characters 0-8 into their actual decimal form, and was trying to write to their ASCI number of the array instead of their decimal number.

    change:

        playBoard[startCX][startCY][0] = '_';
        playBoard[(startCX][startCY][1] = 'f';
    
        playBoard[endCX][endCY][0] = startP;
        playBoard[endCX][endCY][1] = playTurnColor;
    

    To this:

        playBoard[(startCX - '0')][(startCY - '0')][0] = '_';
        playBoard[(startCX - '0')][(startCY - '0')][1] = 'f';
    
        playBoard[(endCX - '0')][(endCY - '0')][0] = startP;
        playBoard[(endCX - '0')][(endCY - '0')][1] = playTurnColor;