samedi 13 mars 2021

C++: My Connect 4 game board will not update in my game

I have provided my code below. I used comments to try to help make sense of what is going on. Basically, in my function check_row, it doesn't seem like it is checking for whether or not there is a game piece (X for player one and O for player two) in the space it is supposed to look at. The function check_row should check if the column that the user inputed in the function get_int has any free row spaces for the game piece to go. Please let me know if you either can alter my current solution to make it work correctly or provide a new solution to that problem. Thank you for your help!

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>

void get_int(int&, int&, int&);
void check_row(char**, int&, int&, int&, int&, int&);
void player_swap(int&);
void print_board(char **, int, int);
void initialize_board(char **, int, int);
void update_board(char**, int, int, int&, int&, int&);
void check_win();
void delete_board(char**, int);
void check_args(int, char**, int&, int&, int&);
void reprompt_args(int&, int&, int&);
void error();

using namespace std;

//I have been using "a.out 2 7 9" for the sake of simplicity when compiling
int main(int argc, char** argv) {
    int cols, rows, players, player = 1, col, row, play_again = 1;
    
    //checks the arguments for the game
    check_args(argc, argv, cols, rows, players);  

    //initializes connect 4 board
    char** board = new char*[rows];
    for (int i = 0; i < rows; i++)
        board[i] = new char[cols];
        
    //prints out initial board
        initialize_board(board, cols, rows);
    do {
        get_int(col, cols, player); //gets the column from the user
        check_row(board, col, row, cols, rows, player); //checks if row is occupied
        update_board(board, cols, rows, col, row, player); //updates game board and reprints it to user
        player_swap(player); //changes turns for the player
        
        //This is just a temporary way to loop the game
        cout << "Again? (1 - Yes) (0 - No)" << endl;
        cin >> play_again;
    }
    while(play_again == 1);
    delete_board(board, rows); //clears heap

    return 0;
}

void get_int(int& col, int& cols, int& player) {
    cout << "Player " << player << ", Enter a column: ";
    while((!(cin >> col)) || (col > cols)) {
        error();
    }
}

void check_row(char** board, int& col, int& row, int& cols, int& rows, int& player) {
    // this sets the rows of the board equal to the row being used in the for loop
    row = rows;
    
    //I was using these cout statements to check if variable "row" was being updated or not when applicable
    cout << "instance of row 1 = " << row << endl;
   
   
    for(int i = 0; i < rows; i++) {
        //The if and else if shoudl check if the given element in the array have a game piece
        if ((board[col-1][row-1] == 'X') && (row > 0)) {
            row--;
            cout << "instance of row 2 = " << row << endl;
        }
        else if ((board[col-1][row-1] == 'O') && (row > 0)) {
            row--;
            cout << "instance of row 3 = " << row << endl;
        }
        //The else statement is a reprompt if the column inputed by the user is full
        else {
            if (row == 0) {
                cout << "Invalid Row Try Again!" << endl;
                get_int(col, cols, player);
                row = rows;
            }
        }
    }
    cout << "instance of row 4 = " << row << endl;
}
    

//Swaps player after turn is over
void player_swap(int& player) {
    if (player == 1)
        player++;
    else
        player--;
}

void print_board(char ** board, int cols, int rows) {
    //prints out checkered board with contents of array board
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            if (i % 2 == 0 && j % 2 == 0)
                cout << "|\033[30;47m " << board[i][j] << " ";
            else if (i % 2 == 1 && j % 2 == 1)
                cout << "|\033[30;47m " << board[i][j] << " ";
            else
               cout << "|\033[0m " << board[i][j] << " ";
            cout << "\033[0m";
        }   
        cout << endl;
    }
}

void initialize_board(char ** board, int cols, int rows) {
    // provides column numbers for board
    for (int i = 0; i < cols; i++)
        cout << " " << (i + 1) << " ";
    cout << endl;

    //same code fragment for printing out the array onto a checkered board
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            if (i % 2 == 0 && j % 2 == 0)
                cout << "|\033[30;47m " << board[i][j] << " ";
            else if (i % 2 == 1 && j % 2 == 1)
                cout << "|\033[30;47m " << board[i][j] << " ";
            else
                cout << "|\033[0m " << board[i][j] << " ";
            cout << "\033[0m";
        }   
        cout << endl;
    }
    cout << endl;
}

void update_board(char** board, int cols, int rows, int& col, int& row, int& player) {
    // assigns the gamepiece to the appopriate row and col
    if (player == 1) {
        board[row-1][col-1] = 'X';
    }
    if (player == 2) {
        board[row-1][col-1] = 'O';
    }
    print_board(board, cols, rows);
}

//Deletes Board
void delete_board(char** board, int rows) {
    for(int i = 0; i < rows; i++)
        delete[] board[i];
    delete[] board;  
}

void check_args(int argc, char** argv, int& cols, int& rows, int& players) {
    int arg;
    
    //checks for commands that are not of integer type
    for(int i = 1; i < argc; i++) {
        if (atoi(argv[i]) == 0) {
            arg = 0;
        }       
    }
    //Checks argument paramets: argv[1] must be 2 or 1, argv[2]&argv[3] must be less that 20 and at least 2, and there must be 4 total arguments
    if ((atoi(argv[1]) > 2) || (atoi(argv[2]) > 20) || (atoi(argv[3]) > 20) || (atoi(argv[2]) < 2) || (atoi(argv[3]) < 2)|| (argc != 4))
        arg = 0;
    else
        arg = 1;
    
    if (arg == 1) {
        players = atoi(argv[1]);
        rows = atoi(argv[2]);
        cols = atoi(argv[3]);
    }
    else {
        reprompt_args(players, rows, cols);
    }
}
//Takes input for the command line arguments if they were invalid
void reprompt_args(int& players, int& rows, int& cols) {
    cout << "Invalid Command Line Arguments!" << endl << endl;
    cout << "Enter Players: ";
    while((!(cin >> players)) || (players > 2) || (players < 1)) {
        error();
    }
    cout << "Enter rows: ";
    while((!(cin >> rows)) || (rows > 20) || (rows < 2)) {
        error();
    }
    cout << "Enter cols: ";
    while((!(cin >> cols)) || (cols > 20) || (cols < 2)) {
        error();
    }
}

//General Invalid Input function
void error() {
    cout << "Error! Enter a valid input: " << endl;
    cin.clear();
    cin.ignore(1024, '\n');
}

Aucun commentaire:

Enregistrer un commentaire