Building a Guess-the-Number Game in C Without Using the Standard Library

0

 Building a Guess-the-Number Game in C Without Using the Standard Library


If you're up for a programming challenge, creating a C program without relying on the standard library is a great way to explore how low-level programming works. In this post, we’ll build a Guess-the-Number game that uses only Windows system calls for input, output, and random number generation.


Why Avoid the Standard Library?

The C standard library provides functions like printf, scanf, and rand, which make programming easier. However, these are high-level abstractions built on lower-level system calls. By avoiding them, you:

  1. Learn how to work directly with the operating system.
  2. Gain a deeper understanding of how common functions are implemented under the hood.
  3. Explore efficient ways to handle tasks like random number generation, string manipulation, and I/O.

Overview of the Game

The game is simple:

  1. The program generates a random number between 1 and 100.
  2. The player guesses the number.
  3. The program provides hints like "Too low" or "Too high" until the player guesses correctly. 

The Code: A Fully Standard Library-Free Implementation

Here's the complete implementation:


#include <windows.h> // Windows system calls ke liye

// Global seed for random number generation

unsigned int seed = 0;


// Seed initialization using system time

void initialize_seed() {

    SYSTEMTIME st;

    GetSystemTime(&st);

    seed = (unsigned int)(st.wMilliseconds + st.wSecond * 1000);

}


// Custom pseudo-random number generator

int custom_rand() {

    seed = (214013 * seed + 2531011); // Linear Congruential Generator (LCG) formula

    return (seed >> 16) & 0x7FFF;     // Extracting a smaller range

}


// Custom function to calculate string length

int custom_strlen(const char *str) {

    int length = 0;

    while (str[length] != '\0') {

        length++;

    }

    return length;

}


// Custom function to print a string

void custom_print(const char *str) {

    DWORD written;

    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

    WriteConsole(hOut, str, custom_strlen(str), &written, NULL);

}


// Custom function to read input as a string

int custom_read_input() {

    char buffer[16] = {0}; // Fixed size buffer

    DWORD read;

    HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);

    ReadConsole(hIn, buffer, sizeof(buffer) - 1, &read, NULL);


    // Convert string to integer manually

    int num = 0;

    for (int i = 0; buffer[i] != '\0' && buffer[i] != '\n'; i++) {

        if (buffer[i] >= '0' && buffer[i] <= '9') {

            num = num * 10 + (buffer[i] - '0');

        }

    }

    return num;

}


// Main Game Logic

int main() {

    initialize_seed(); // Initialize random seed

    int number_to_guess = custom_rand() % 100 + 1; // Random number between 1 and 100

    int guess;


    custom_print("Welcome to Guess the Number Game!\n");

    custom_print("I have chosen a number between 1 and 100. Try to guess it!\n");


    while (1) {

        custom_print("Enter your guess: ");

        guess = custom_read_input();


        if (guess < number_to_guess) {

            custom_print("Too low! Try again.\n");

        } else if (guess > number_to_guess) {

            custom_print("Too high! Try again.\n");

        } else {

            custom_print("Congratulations! You guessed the number!\n");

            break;

        }

    }

    return 0;

}


Key Features of the Code

1. Custom Random Number Generator

Instead of rand(), we implemented a Linear Congruential Generator (LCG):

 int custom_rand() {

    seed = (214013 * seed + 2531011); // LCG formula

    return (seed >> 16) & 0x7FFF;    // Extract a smaller range

}

This simple formula generates a pseudo-random sequence based on a global seed, initialized using system time.

2. Custom String Length Function

Without strlen, we wrote our own function:


This manually calculates the length of a string by iterating through it.

3. Custom Print Function

To replace printf, we use Windows system calls (WriteConsole):


void custom_print(const char *str) {

    DWORD written;

    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

    WriteConsole(hOut, str, custom_strlen(str), &written, NULL);

}

This function calculates the string length and writes it to the console.

4. Custom Input Reader

Instead of scanf, we use ReadConsole to read user input:

int custom_read_input() {

    char buffer[16] = {0};

    DWORD read;

    HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);

    ReadConsole(hIn, buffer, sizeof(buffer) - 1, &read, NULL);


    // Convert the string to an integer manually

    int num = 0;

    for (int i = 0; buffer[i] != '\0' && buffer[i] != '\n'; i++) {

        if (buffer[i] >= '0' && buffer[i] <= '9') {

            num = num * 10 + (buffer[i] - '0');

        }

    }

    return num;

}

Step-by-Step Execution

  1. The program initializes the random number generator with the current system time.
  2. A random number between 1 and 100 is generated.
  3. The user is prompted to guess the number, with hints provided until they guess correctly.
  4. The game uses only Windows API functions for printing and reading input.

Compiling and Running the Code

You’ll need a Windows compiler like MinGW or Visual Studio. To compile the code:

gcc -o guess_game_no_std guess_game_no_std.c

Run it in a Windows terminal, and enjoy the game.


Why This Approach is Interesting

  1. Deeper Understanding: By removing the standard library, you interact directly with the operating system.
  2. Learning Opportunity: This approach teaches how common C functions like printf and scanf work under the hood.
  3. Portability Awareness: This game is Windows-specific due to its reliance on windows.h. Building a cross-platform version would require different system calls.

Conclusion

Building a game without the standard library is a rewarding experience that sharpens your programming skills and deepens your understanding of system-level operations. Try this project, and take your C programming knowledge to the next level!

Ready to take the challenge? Copy the code, compile it, and start guessing! 😊






Post a Comment

0Comments
Post a Comment (0)