Jump to content

Idk what to do in C

goatedpenguin

So I have been making a snake and ladders game but I am very confused on how to switch turns between players and I need some help in general with my code. Code is below: 

Btw Ik that from my previous post that I can generate a random dice but I did not know how to do that so I instead figured out how to give it a predefined vals when the program gets executed each time. Thanks in advance 🙂 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define ARRAY_SIZE 100
#define DICE_PS 100

//function prototypes

    //function for random dice
    int dice();
    
    //function for 2 players switching turns and adding the logic && make sure to add logic for if the player gets a six
    //so he gets a another turn
    void users();
    
        
//driver code

int main(){
    srand(time(NULL));
    users();
    return 0;
}

 
    int dice(){
        int dice_roll = rand() % 6 + 1;
        return dice_roll;
        // printf("%d", dice_roll);
    }
    
    
    void users(){
        char player_1[30] = {""};
        char player_2[30] = {""};
        int first_turn_counter[100];
        int validate_won_player;
        int get_square_player_1;
        int get_square_player_2;
        int dice_1[ARRAY_SIZE] = {0};
        int dice_2[ARRAY_SIZE] = {0};
        int snakes[8][2] = {{98, 79}, {95, 75}, {93, 73}, {87, 36}, {64, 60}, {62, 19}, {54, 34}, {17, 7}};
        int ladders[8][2] = {{1, 38}, {4, 14}, {9, 31}, {21, 42}, {28, 84}, {51, 67}, {72, 91} , {80, 100}};

        //user name input
        printf("Player 1 enter your name: ");
        scanf("30%s", player_1);
        printf("Player 2 enter your name: ");
        scanf("30%s", player_2);

        for (int i = 0; i < DICE_PS; i++){
            dice_1[i] = dice();
            dice_2[i] = dice();
        }

        for (int j = 0; j < 100; j++){
            first_turn_counter[j] = j + 1;
            
            if(first_turn_counter[100] % 2 == 0){
                
            }
            else if(first_turn_counter[100] % 2 != 0){

            }

            else if(first_turn_counter[j] == first_turn_counter[100]){
                printf("");
            }
        }

        
            

            
            
        }

        
    
    
    
    
    
    
    

 

Link to comment
Share on other sites

Link to post
Share on other sites

One simple way to switch turns is to keep a turn counter - if it's even then it's player 1's turn, and if it's odd then it's player 2's turn. It kind of looks like that's what you were going for.

 

What's the purpose of first_turn_counter? You declare it as an array of 100 ints but access one element past the end, which is out of bounds. Remember that arrays start at index 0 in C, so your valid indices are 0 through 99.

 

I think it would be easiest to have your loop variable be the turn counter. Something like this:

Spoiler
for (int turn_counter = 0; turn_counter < 100; turn_counter++) {
    if (turn_counter % 2 == 0) {
    	// Player 1's turn
    } else {
    	// Player 2's turn
    }
}

 

 

Computer engineering grad student, cybersecurity researcher, and hobbyist embedded systems developer

 

Daily Driver:

CPU: Ryzen 7 4800H | GPU: RTX 2060 | RAM: 16GB DDR4 3200MHz C16

 

Gaming PC:

CPU: Ryzen 5 5600X | GPU: EVGA RTX 2080Ti | RAM: 32GB DDR4 3200MHz C16

Link to comment
Share on other sites

Link to post
Share on other sites

Thanks for the help, if you see any improvements I can make elsewhere I will appreciate it. I will make sure to post the finished code on this thread 🙂 

Link to comment
Share on other sites

Link to post
Share on other sites

Here's something to get you started. What makes C powerful is that it's an object oriented language, and structs are a fundamental tool in that. In this example, I'm utilizing structs in a stateful way to keep track of the game.

 

As an exercise to expand your skill, you can add your logic to climb ladders and slide down snakes. As a further exercise, consider converting my structs into full-fledged classes.

 

#include <time.h>
#include <string.h>
#include <iostream>
#include <array> 
using namespace std;

#define PLAYER_COUNT 2
#define BOARD_SIZE 100

struct player {
    string name;
    int position;
};

struct {
    int turnNumber = 0;
    array<player,PLAYER_COUNT> players; // You can use a Vector of player to make this array dynamic and support an arbitrary number of players
} gameState;

void setupPlayers() {
    
    int playerCount = PLAYER_COUNT;
    // cout << "How many players? "; // TODO: support arbitrary number of players
    // cin >> playerCount;
    
    for (int i = 0; i < playerCount; i++) {
        player p;
        cout << "Enter Player " << i+1 << "'s name: ";
        cin >> p.name;
        gameState.players[i] = p;
    }
    
    cout << "Players:" << endl;
    cout << gameState.players.size();
    for (int i = 0; i < gameState.players.size(); i++) {
        cout << gameState.players[i].name << endl;
    }
    
    return;
}

bool hasWinner() {
    
    // iterate through the players to check if any have reached the end
    for (int i = 0; i < gameState.players.size(); i++) {
        if (gameState.players[i].position >= BOARD_SIZE) {
            return true;
        }
        else {
            continue;
        }
    }
    return false;
}

void gameLoop() {
    
    cout << "Starting game" << endl;
    while (!hasWinner()) {
        // run game logic...
        
        // Using the turn number to decide whose turn it is. This is done by taking the modulus of the player count.
        // Notice, we're getting a pointer to the player so that we can access and modify that struct
        player* p = &gameState.players[gameState.turnNumber % 2];
        
        // make a dice roll
        int roll = rand() % 6 + 1;
        cout << p->name << " rolled a " << roll << endl;
        
        // move the player
        p->position += roll;
        
        // This is where you would slide down snakes/climb ladders (pseudo code)
        // if (is on snake/ladder) { p->position += snake/ladder end square };
        
        cout << p->name << " is on square " << min(p->position, BOARD_SIZE) << endl;
        
        // increase turn counter
        gameState.turnNumber++;
    }
    cout << "Game Over";
}

int main()
{
    // seed random number generator
    srand(time(NULL));
    
    setupPlayers();
    
    gameLoop();
    
    return 0;
}

 

Link to comment
Share on other sites

Link to post
Share on other sites

I think you mean that C++ is a OOP lang and not C? And btw using namespace std; is not valid C code its C++ there is also no iostream in C.

Link to comment
Share on other sites

Link to post
Share on other sites

Sorry, I tend to assume when someone says C, they mean C++. You are correct, C is not object oriented and has no understanding of classes.

 

Here's the equivalent code in C.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define PLAYER_COUNT 2
#define BOARD_SIZE 100

// returns the smaller of either a or b
#define MIN(a,b) ((a) < (b) ? (a) : (b))

struct Player {
    char name[50];
    int position;
};

struct GameState {
    int turnNumber;
    struct Player players[PLAYER_COUNT];
};

struct GameState gameState;

void setupPlayers() {
    int playerCount = PLAYER_COUNT;
    // TODO: make playerCount configurable
    // printf("Enter number of players");
    // scanf("%d", playerCount);
  
    for (int i = 0; i < playerCount; i++) {
        printf("Enter Player %d's name: ", i + 1);
        scanf("%s", gameState.players[i].name);
        gameState.players[i].position = 0;
    }

    printf("Players:\n");
    for (int i = 0; i < playerCount; i++) {
        printf("%s\n", gameState.players[i].name);
    }
}

int hasWinner() {
    for (int i = 0; i < PLAYER_COUNT; i++) {
        if (gameState.players[i].position >= BOARD_SIZE) {
            return 1;
        }
    }
    return 0;
}

void gameLoop() {
    printf("Starting game\n");

    // Consider declaring currentPlayer outside of this loop and using condition (currentPlayer->position <= BOARD_SIZE)
    // then you can easily output the winning player's name.
    while (!hasWinner()) {
        struct Player* currentPlayer = &gameState.players[gameState.turnNumber % PLAYER_COUNT];

        // make a dice roll
        int roll = rand() % 6 + 1;
        printf("%s rolled a %d\n", currentPlayer->name, roll);

        // move the player
        currentPlayer->position += roll;

        // This is where you would slide down snakes/climb ladders (pseudo code)
        // if (is on snake/ladder) { currentPlayer->position = snake/ladder end square };

        printf("%s is on square %d\n", currentPlayer->name, MIN(currentPlayer->position, BOARD_SIZE));

        // increase turn counter
        gameState.turnNumber++;
    }

    printf("Game Over\n");
}

int main() {
    // seed random number generator
    srand(time(NULL));

    // set the game state
    gameState.turnNumber = 0;

    setupPlayers();

    gameLoop();

    return 0;
}

 

Link to comment
Share on other sites

Link to post
Share on other sites

On 1/29/2024 at 2:24 AM, goatedpenguin said:

I think you mean that C++ is a OOP lang and not C? And btw using namespace std; is not valid C code its C++ there is also no iostream in C.

Probably not really what you are after, but it is actually possible to implement classes into C, I believe parts of the linux kernel were written in "object oriented C".

 

The idea is basically implement some of the features C++ has, by hand. You'd just use a struct to store your data, if you want to have inheritance, you just have to make sure, that the parent class takes up the first part of the memory in the struct and functions can be handled via virtual function tables.

 

If you are at all interested in that, let me know. It's pretty neat to learn what OOP languages are actually doing in the background. On the other hand, it's probably more useful to learn C++.

Link to comment
Share on other sites

Link to post
Share on other sites

6 hours ago, adm0n said:

Probably not really what you are after, but it is actually possible to implement classes into C, I believe parts of the linux kernel were written in "object oriented C".

 

The idea is basically implement some of the features C++ has, by hand. You'd just use a struct to store your data, if you want to have inheritance, you just have to make sure, that the parent class takes up the first part of the memory in the struct and functions can be handled via virtual function tables.

 

If you are at all interested in that, let me know. It's pretty neat to learn what OOP languages are actually doing in the background. On the other hand, it's probably more useful to learn C++.

I find C++ too complicated and my goals are to be doing embedded system and kernel programming stuff(ik I am far from it now) so I thought C might be better here. Not to mention I find C simple & easy to understand.

Link to comment
Share on other sites

Link to post
Share on other sites

4 hours ago, goatedpenguin said:

I find C++ too complicated and my goals are to be doing embedded system and kernel programming stuff(ik I am far from it now) so I thought C might be better here. Not to mention I find C simple & easy to understand.

I see, if embedded is your goal, then C is indeed the best choice. Then you'll probably stumble upon on of those object oriented C approaches at some point anyway. At least I've seen some people talk about their approaches. Good luck anyway!

Link to comment
Share on other sites

Link to post
Share on other sites

Thanks for the insight I will be sure to check out "OOP C" when I get to that level 😉

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×