Saturday 30 November 2013

The Old Snake Game

This is actually an edited post. Been thinking of posting 4 times at least, in a month. I didn't want November to slip by, so I quickly posted a random song on the last night of November, to save the spot.

Anyway, this is a crude recreation of the old snake game. The game was invented by Scott McCarthy and was first published in 1976.

I'm still working on the database for the doctor. Hit some glitches that have been giving me sleepless nights. So I decided to take a break and try to write the snake game we used to play on our B&W Nokias.

The fact that the food may appear within the body of the snake sometimes is NOT A BUG, it's sheer laziness.
Besides that it's sure to have some bugs, I haven't played it much, if you find some let me know in the comments section.

I have set the variable 'speed' to 5000 (If you copy paste this into C:B, it should be line 14). Decreasing this number will speed the game up, increasing this will slow the game down.

If you don't already have the include file myconstdwin.h, click HERE to find out how to create it yourself.

The snake is controlled with the arrow keys, hitting Esc will exit the game or if you say 'No' to "Play Again?".

If you are new to earth, welcome to the planet and here are the game instructions :P
The objective of the game is to "eat" as many of the food as you can without hitting the borders, and without crashing into your own body as you coil around. 'Eating', here, means crashing head-long into the food, the snake will keep moving in the direction you point it in.
When you eat one, another piece of food appears in a random spot. Every piece of food you eat increases the snakes length.

Nothing else I can think of saying, so here's the code:


#include <myconstdwin.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>

void time_seed(void); //seed randomizer from the clock
int random(int range); //this generates a random number. The "range" is how big you want the number to be
int get_key(void); //detect keys

void draw_box(void);
void food(int x,int y); //displays food
void snake(int *sxt,int *syt,int *sxh,int *syh); //sxt= snake x coordinate of tail

int pause,direction=3; //direction, counting from left, clockwise: left=1,up=2,right=3,down=4
int len=2,speed=5000,redo=0; //len (length of snake is actually 3 in the beginning, but we are counting from 0.

int main(void)
{
    int i,sx[500],sy[500],key,points=0;
    /**co-ordinates sx[0],sy[0] will always be the tail, sx[len],sy[len] the head**/
    sx[0]=23,sx[1]=24,sx[2]=25,sy[0]=7,sy[1]=7,sy[2]=7;
    int foodx,foody;
    int again=1,game;
    char c;

    while(again)
    {

        system("cls");
        gotoxy(1,17);
        printf("Points: %i",points);
        game=1;
        draw_box();
        /**Snake**/
        for(i=0;i<len;++i)
        {
            gotoxy(sx[i],sy[0]);
            printf("%c",15);
        }

        time_seed();
        foodx=random(43);
        foody=random(14);

        food(foodx+1,foody+1);

        while(game)
        {
            if(sx[len]==foodx+1 && sy[len]==foody+1) //if the head and food are at the same spot
            {
                food(foodx+1,foody+1);
                printf("\b \b%c",15);
                /**create new food**/
                time_seed(); //seed randomizer with clock
                foodx=random(43); //create a random number range upto 43
                foody=random(13); //create a random number range 13

                food(foodx+1,foody+1); //the +1 prevent the food from appearing at the lines
                len++; //increase length
                if(direction==1 || direction==3)
                {
                    if(direction==1)
                        sx[len]=sx[len-1]-1;
                    else if(direction==3)
                        sx[len]=sx[len-1]+1;

                    sy[len]=sy[len-1];
                }
                else
                {
                    if(direction==2)
                        sy[len]=sy[len-1]-1;
                    else if(direction==4)
                        sy[len]=sy[len-1]+1;
                    sx[len]=sx[len-1];
                }
                points+=10;
                gotoxy(1,17);
                printf("Points: %i",points);
            }

            snake(&sx[0],&sy[0],&sx[len],&sy[len]);

            if(redo==1)
            {
                /**if the food appears within the snakes body, the next line prevents the food
                   from disappearing when the snake has finished passing through it**/
                food(foodx+1,foody+1);

                for(i=0;i<len-1;i++)
                {
                    if((sx[len]==sx[i] && sy[len]==sy[i]) || (sx[len]==46) || (sy[len]==15) || (sx[len]==0) || (sy[len]==0))
                    {
                        gotoxy(19,17);
                        printf("OOPS!!! Play Again(Y/N): ");
                        while(1)
                        {
                            c=toupper(getch());
                            if(c=='N')
                            {
                                game=0;
                                again=0;
                                system("cls");
                                break;
                            }
                            else if(c=='Y')
                            {
                                game=0;
                                len=2,redo=0,points=0;
                                sx[0]=23,sx[1]=24,sx[2]=25,sy[0]=7,sy[1]=7,sy[2]=7;
                                direction=3;
                                break;
                            }
                        }
                        break;
                    }
                }

                for(i=0;i<len;i++)
                {
                    sx[i]=sx[1+i];
                    sy[i]=sy[1+i];
                }

                if(direction==1) //going left
                {
                    sy[len]=sy[len-1];
                    sx[len]--;
                }
                else if(direction==2) //going up
                {
                    sy[len]--;
                }
                else if(direction==3) //going right
                {
                    sy[len]=sy[len-1];
                    sx[len]++;
                }
                else if(direction==4) //going down.
                {
                    sy[len]++;
                }
                redo=0;
            }

            if(kbhit())
            {
                key=get_key();

                if(key==584) //up
                {
                    if(direction==1 || direction==3)
                    {
                        direction=2;
                    }
                }
                else if(key==592) //down
                {
                    if(direction==1 || direction==3)
                    {
                        direction=4;
                    }
                }
                else if(key==587) //left
                {
                    if(direction==2 || direction==4)
                    {
                        direction=1;
                    }
                }
                else if(key==589) //right
                {
                    if(direction==2 || direction==4)
                    {
                        direction=3;
                    }
                }
                else if(key==27) //esc
                {
                    exit(0);
                }
            }
        }
    }

    return 0;
}

void food(int x,int y)
{
    gotoxy(x,y);
    printf("%c",219);
}

void snake(int *sxt,int *syt,int *sxh,int *syh)
{
    pause++;

    if(pause==speed) //this controls game speed
    {
        redo=1;
        gotoxy(*sxt,*syt);
        printf(" ");
        gotoxy(*sxh,*syh);
        printf("%c",15);

        pause=0;
    }
}

void draw_box(void)
{
    int i;

    /**Draw Box**/
    gotoxy(0,0);
    printf("%c",218);
    for(i=0;i<45;i++)
    {
        printf("%c",196);
    }
    printf("%c",191);
    for(i=0;i<15;i++)
    {
        gotoxy(0,1+i);
        printf("%c",179);
        gotoxy(46,1+i);
        printf("%c",179);
    }
    gotoxy(0,15);
    printf("%c",192);
    for(i=0;i<45;i++)
    {
        printf("%c",196);
    }
    printf("%c",217);
}

int random(int range)
{
    int y;
    y=rand()%range;
    return(y);
}

void time_seed(void)
{
    srand((unsigned)time(NULL));
}

int get_key()
{
    int c=getch();
    switch(c)
    {
      case 0:   return getch()+256;
      case 224: return getch()+512;
    }
    return c;
}

Monday 25 November 2013

Sort 5 Names According To The First Character

This was a LOT harder than I thought it would be.

I want to be able to sort a list of names. I have been trying to do this and this is possibly the hardest problem I've had to solve.

I have heard of functions that can sort stuff for you, maybe library functions or maybe functions off of the internet, but I was adamant on writing my own with no help.

It took me a couple of days to get this right. Even then, it can only compare the first characters and sort accordingly.

If I can muster up the courage I'll try to make it so that it can sort the rest of the letters too; 'dictionary entry' like. But for now, this will have to do, because it represents a lot of hard work for me :).

It accepts 5 names and sorts them according to the first character. There is no check to ensure small letters or big letters, so THE PROGRAM WILL ALWAYS CONSIDER SMALL LETTERS TO BE HIGHER THAN BIG LETTERS: Eg. 'banana' will figure as higher than 'Zebra', so on the list 'banana' will be below 'Zebra', because to the program, small letter 'b' is larger than big letter 'Z'.

#include <stdio.h>
#include <strings.h>

int main()
{
    int a,b=0,found=0;;
    char names1[5][21],names2[5][21],sorted[5][21];

    printf("Enter 5 names:\n");
    for(a=0;a<5;a++)
    {
        gets(names1[a]);
    }

    /**Make a copy of the original array so as not to lose
    the original input order**/
    for(a=0;a<5;a++)
    {
        strcpy(names2[a],names1[a]);
    }

    /**Sort Here**/
    while(b<5)
    {
        for(a=b;a+1<5;a++)
        {
            if(names1[b][0]>names1[a+1][0])
            {
                strcpy(sorted[b],names1[a+1]); //copy the smaller in order into sorted.
                strcpy(names1[a+1],names1[b]); //copy what was being compared into the one already saved in sorted
                strcpy(names1[b],sorted[b]); //start comparing the smaller one
                found=1; //so that we know a smaller character has been found
            }
        }

        if(found==0) //nothing was found
        {
            strcpy(sorted[b],names1[b]); //what was being compared is the smallest, copy into sorted
        }
        b++; //go on to the next item
        found=0; //reset found
    }

    system("cls");

    for(a=0;a<5;a++)
    {
        printf("\n%s\t%s",names2[a],sorted[a]);
    }
    return 0;
}


Thursday 21 November 2013

Programmers & Programming Windows (Contains no code)

In my C learning crusade, I have traveled at light speeds across many forums, write-ups and e-books (Well, the loading takes a while though considering my internet speed, but the data is still sent at light speed anyways, no matter how small the chunks are). I have lurked in the shadows, reading, scrolling, judging lines and lines of text; I have chuckled, smirked and been relieved many a time.

I have come to the one, inevitable, conclusion: Programmers are dicks!

Not all of them, but many of them. A lot of them take the "If I tell you everything, you'll never learn" thing too far. No, nobody has ever done that to me. As far as I can remember, the only post I made in a public forum regarding programming was at the Code Blocks forums asking about a feature which was promptly resolved in their nightly releases. I only judge what I read...hehe!

Sometimes, even a simple question like "How do I draw a circle?" is responded with "How much are you paying?".

Well, it only strengthens my resolve to be nice. If I ever get to the level of expertise where I am able to help out people, I will go out of my way to be nice & will never be the first one to cast the first crap.


In other news:
I have been trying hard to understand Programming Windows by Charles Petzold. This is supposedly THE book to learn Windows Programming. But it is beyond my comprehension. It was written for people who can speak 'tech' much better than I do.
Not to be undone, I e-mailed Dan Gookin. Gookin is the author of 'C For Dummies' and a host of other books. If I'm not mistaken, it was his book "DOS for Dummies" that birthed the whole "For Dummies" series. Legend.
I asked him if he could do a book on Windows Programming for laymen...well...for 'Dummies', in his unmistakable, humorous and understandable style. It would help someone like me, who wants to learn, but have no good resource or teacher, to get started.
He was very kind and forwarded my e-mail to his publisher to see if they were willing to accommodate a new book.
The publisher's money making instincts did a quick calculation and the returns didn't seem appealing, so they refused. Not their fault, profit is what they are in the business for, they are not a charity. They already did some books on it and those never sold well.

Mr. Gookin told me he is swamped with work at the moment but he will try to introduce a new segment in his blog to introduce us to Windows Programming very soon. Apparently Programming Windows by Charles Petzold is the only book on Windows Programming he has ever bought. And he uses Java to program Windows.
Regardless, I am very eagerly looking forward to his posts on the subject. His C Programming blog is a goldmine. Check this out: A few days back, I dusted off my old book on games programming Game Programming On PC by Diana Gruber. I cannot use the book to program games because the code will not work on Windows 7 (Which is what I use), but I thought maybe I can pick up a few things from scanning the code (FYI, I didn't learn anything, not because the book is hard, but because I'm too dumb). There is a part where she says about a memory location "There is something in there, I don't know what it is, but there is something" (may not be the exact words, but it was the same idea). This was written in the early 90's so she very likely has learnt what is in there since.
I KNEW WHAT WAS THERE....yup I did! I had picked it up from Gookin's blog. :) Knowing is always an ego boost.

If you want to follow his blog here it is: http://www.c-for-dummies.com/cfordummies/
Go there and click on "C Blog" on the left pane.

See you soon.

Getting File Path From The User/Adding User Entered String As Part Of A Longer String

Here is a program to get a text file path and name from the user. These are then saved as a single string into another char variable. Then the file is opened and displayed.


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

int main()
{
    char path[100],fname[100],complete[200],ch;
    FILE *fp;

    printf("Please enter the path to the text file (eg: c:\\users\\johnsmith\\: ");
    gets(path);
    printf("Enter the name of the file (eg:MyText.txt): ");
    gets(fname);

    sprintf(complete,"%s%s",path,fname); //this works exactly like printf, except the output is sent to the 'complete' variable.

    fp=fopen(complete,"r");
    if(fp==NULL)
    {
        printf("Cannot open file. Sorry :(");
        getch();
        exit(0);
    }

    while(ch!=EOF)
    {
        ch=fgetc(fp);
        printf("%c",ch);
    }
    fclose(fp);

    return 0;
}


Sprintf is important to me because I need it to run user defined commands in the DOS command line. Eg:
If I want to delete a file the user names, I prompt for the file and get its name:

printf("Enter filename: ");
gets(filename); //assume the user enters 'MyFile.exe'

sprintf(command,"delete %s",filename);

If the user entered 'MyFile.exe', the variable 'command' now contains the string 'delete MyFile.exe'. Now I can delete this file by saying:
system(command);

It comes in really handy sometimes.