Sunday, 1 February 2015

C Program fo games

This is a discussion on Gaming in c within the C Programming forums, part of the General Programming Boards category; I have learned basic c now.But i want to move further and i want to create simple games using C.But ...

/ * =========================================================
 * This program implements the game Mines Sweeper. Its user 
 * can perform the following actions:
 * 1. choose board size
 * 2. place mines
 * 3. remove mines
 * 4. show mines
 * 5. start the game
 * 0. exit
 * ========================================================= */

// preprocessing
#include <stdio.h>

#define TRUE 1
#define FALSE 0

#define N 9

// for uncoverMine() return value
#define EMPTY 1
#define MINE 0

// for printType parameter in printBoard()
#define MENU_PRINT 0    // main menu board print
#define GAME_PRINT 1    // print board after square is checked
#define WON_PRINT 2     // print board after win
#define LOST_PRINT 3    // print board after mine hit - like MENU_PRINT?

// global Var decl
    //! not alowed !//

// global function decl
int mainPlayGame(char board[N][N]);
void mainProgram(char board[N][N]);
void printBoard(char board[N][N],int size, int printType);
void mainMenu();
int insertMine(char board[N][N],char mines[],int size);
int removeMine(char board[N][N],int size,int x,int y);
int unCover(char board[N][N],int size,int x,int y);
int checkEndOfGame(char board[N][N],int size);
int playGame(char board[N][N],int size) ;

int main()
{
    char board[N][N];

    mainProgram (board);
    printf("press ENTER to EXIT\n");
    getchar();
    return 0;
}

void mainProgram(char board[N][N])
{
    //char* test_char_gil;

    int size_defined = FALSE;
    int size, i,  row, col, menu_choice, x, y, lost;
    int lost_times = 0;
    int won_times = 0;
    char menu_choice_buf[346], mines[40];
    char coordinates[346];
    char nothing[346];
    //
    while (TRUE)
    {
        mainMenu();

        gets(menu_choice_buf);
        // test input is ok
        if (menu_choice_buf[0] < '0' || '5' < menu_choice_buf[0])
            continue;
        if (menu_choice_buf[1] != '\0')
            continue;

        // convert char to ints
        menu_choice = menu_choice_buf[0] - 48;

        // exit
        if (menu_choice == 0)
        {
            if (won_times+lost_times == 0)
                printf("you didn't play\n");
            else
            {
                printf("you played %d game(s):\n", won_times+lost_times);
                printf("you won %d\n", won_times);
                printf("you lost %d\n", lost_times);
            }
            printf("bye!\n");
            // print num of games
            return;
        }

        // choose board size
        if (menu_choice == 1)
        {
            size_defined = FALSE;
            printf("enter board size [1..9] (no input control is needed):\n");
            scanf ("%d", &size);
            gets(nothing);  // consuming the rest of the stdin buffer
            if (0 < size && size < 10)
            {
                // initializing board
                for (row = 0; row < size; row++)
                    for (col = 0; col < size; col++)
                        board[row][col] = ' ';

                size_defined = TRUE;
            }
            continue;
        }

        // place mines
        if (menu_choice == 2)
        {
            if (size_defined == FALSE)
            {
                printf("you must choose board size first!\n");
                continue;
            }
            printf ("enter x,y of the new mines (x1,y1)(x2,y2)...(xn,yn):\n");

            // initialize mins[]
            for (i=0; i<40; i++)
                mines[i]=' ';

            // user inputs mine/s coordinates
            gets(mines);

            // testing user input and applying it to the board array
            if (insertMine (board, mines, size) == FALSE)
                printf("wrong input\n");

            continue;
        }

        // remove mines
        if (menu_choice == 3)
        {
            if (size_defined == FALSE)
            {
                printf("you must choose board size first!\n");
                continue;
            }

            printf("enter x,y of the mine to remove (no input control is needed):\n");

            // get coordinates and test input
            gets(coordinates);
            if ((coordinates[0] < '0') || ('9' < coordinates[2]))
                continue;
            if (coordinates[1] != ',')
                continue;
            if ((coordinates[2] < '0') || ('9' < coordinates[2]))
                continue;

            x = coordinates[0]-48;
            y = coordinates[2]-48;

            // remove if possible
            if(removeMine(board, size, x, y) == FALSE)
                printf("wrong input or no mine\n");
            else
                printf("mine removed\n");

            // if not, print err msg

            continue;
        }

        // show mines
        if (menu_choice == 4)
        {
            if (size_defined == FALSE)
            {
                printf("you must choose board size first!\n");
                continue;
            }
            printBoard(board, size, MENU_PRINT);

            continue;
        }

        // start the game
        if (menu_choice == 5)
        {
            if (size_defined == FALSE)
            {
                printf("you must choose board size first!\n");
                continue;
            }
            lost = playGame(board, size);
            if (lost == TRUE)
                lost_times++;
            else
                won_times++;

            // make sure new game is to start
            size_defined = FALSE;

            continue;
        }
    }
}


void mainMenu()
{
    printf("--------------------------\n");
    printf("welcome to the game\n");
    printf("1. choose board size\n");
    printf("2. place mines\n");
    printf("3. remove mines\n");
    printf("4. show mines\n");
    printf("5. start the game\n");
    printf("0. exit\n");
    printf("please enter your choice (input control is needed):\n");
}



/* printType can have one of the following macros:
 * MENU_PRINT  - main menu board print
 * GAME_PRINT  - print board after square is checked
 * WON_PRINT   - print board after win
 * LOST_PRINT - print board after mine hit
 */
void printBoard(char board[N][N],int size, int printType)
{
    char square;
    int col, row;
    // print top border first row
    for (col = 0; col < size; col++)
        printf("+-");
    printf("+\n");

    for (row = 0; row < size; row++)
    {
        for (col = 0; col < size; col++)
        {
            square = board[row][col];
            if ((printType == MENU_PRINT) || (printType == WON_PRINT) || (printType == LOST_PRINT))
            {
                printf("|%c", square);
            }
            else
                if (printType == GAME_PRINT)
                {
                    if ((square == '*') || (square == ' '))
                        square = '?';
                    printf("|%c", square);
                }
                else
                    printf("something is damn wrong here\n");
        }
        printf("|\n");

        for (col = 0; col < size; col++)
            printf("+-");
        printf("+\n");
    }
}


int insertMine(char board[N][N],char mines[],int size)
{
    int i, input_ok, x, y, y_con, xy_to_input;
    int test_type = 0;

    // test for input ok
    for (i=0; i<40; i++)
    {
        if (mines[i] == '\0')
            break;
        if (mines[i] == ' ')
            continue;
        // '(' test
        if (test_type == 0)
        {
            if (mines[i]!='(')
            {
                input_ok = FALSE;
                return input_ok;
            }
            else // !(mines[i]!='(')
            {
                test_type = (test_type + 1) % 5 ;
                continue;
            }
        }

        // number test
        if ((test_type == 1) || (test_type == 3))
        {
            if ( mines[i] < 48 || 57 < mines[i] )
            {
                input_ok = FALSE;
                return input_ok;
            }
            else
            {
                test_type = (test_type + 1) % 5 ;
                continue;
            }
        }

        // ',' test
        if (test_type == 2)
        {
            if (mines[i]!=',')
            {
                input_ok = FALSE;
                return input_ok;
            }
            else
            {
                test_type = (test_type + 1) % 5 ;
                continue;
            }
        }

        // ')' test
        if (test_type == 4)
        {
            if (mines[i]!=')')
            {
                input_ok = FALSE;
                return input_ok;
            }
            else
            {
                test_type = (test_type + 1) % 5 ;
                continue;
            }
        }
    }

    // test if input is complete
    if (test_type != 0)
    {
        input_ok = FALSE;
        return input_ok;
    }

    // input coordinates to board
    y_con = FALSE;
    xy_to_input = FALSE;
    i = 0;
    while  ( mines[i] != '\0')
    {
        if (48 < mines[i] && mines[i] < 57)
        {
            if (y_con == FALSE)
            {
                x = (mines[i]-48);
                y_con = TRUE;
            }
            else
            {
                y = (mines[i]-48);
                y_con = FALSE;
                xy_to_input = TRUE;
            }
        }
        
        if (xy_to_input == TRUE)
        {
            printf ("(%d,%d)",x,y);
            if ((x > size) || (y > size))
                printf (" is out of range\n");
            else
            {
                if (board[x-1][y-1] == '*')
                    printf (" already full\n");
                else
                {
                    board[x-1][y-1] = '*';
                    printf (" mine inserted\n");
                }
            }
            xy_to_input = FALSE;
        }
        i++;
    }

    return TRUE;
}

int removeMine(char board[N][N],int size,int x,int y)
{
    // test x,y boundaries
    if ( (x<1 || size<x) || (y<1 || size<y))
        return FALSE;
    // test if mine really exists at x,y
    if (board[x][y] != '*')
        return FALSE;

    // remove mine
    board[x][y] = ' ';

    return TRUE;
}


int playGame(char board[N][N],int size)
{
    int x, y, lost = FALSE;
    char coordinates[346] = {0};

    while ( (checkEndOfGame(board, size) == FALSE) && (lost == FALSE))
    {
        // enter x,y
        printf("enter a squre x,y to uncover (no input control is needed):\n");
        
        // get coordinates and test input
        gets(coordinates);
        if ((coordinates[0] < '0') || ('9' < coordinates[2]))
            continue;
        if (coordinates[1] != ',')
            continue;
        if ((coordinates[2] < '0') || ('9' < coordinates[2]))
            continue;

        x = coordinates[0]-48;
        y = coordinates[2]-48;

        // test square
        if (unCover(board, size, x, y) == MINE)
            lost = TRUE;

        // print result
        if (lost == FALSE)
            printBoard(board, size, GAME_PRINT);
    }

    // print win/loose
    if (lost == TRUE)
    {
        printf("you lost\n");
        printBoard(board, size, LOST_PRINT);
    }
    else
    {
        printf("all mines were uncovered - you won\n");
        printBoard(board, size, WON_PRINT);
    }

    return lost;
}

int checkEndOfGame(char board[N][N],int size)
{
    int row, col;

    // counting empty, non checked squares
    int empty_square = 0;
    for (row = 0; row < size; row++)
        for (col = 0; col < size; col ++)
            if (board[row][col] == ' ')
                empty_square++;

    if (empty_square == 0)
        return TRUE;
    else
        return FALSE;
}

int unCover(char board[N][N],int size,int x,int y)
{
    int sum, row, col;

    // turning user input [1..9] to array index compatible [0..8]
    x--;
    y--;

    if (board[x][y] == '*')
    {
        board[x][y] = 'X';
        return MINE;
    }

    // count neighbor squares for mines
    sum = 0;
    for (row = 0; row < size; row++)
        for (col = 0; col < size; col ++)
            if ((x-1 <= col) && (col <= x+1) && (y-1 <= col) && (col <= y+1))
                if (board[row][col] == '*')
                    sum++;

    // put in board
    board[x][y] = sum+48;

    return EMPTY;
}

No comments:

Post a Comment