Thread: Hanoi Game in C on LINUX

  1. #1
    Registered User
    Join Date
    Mar 2013
    Posts
    4

    Hanoi Game in C on LINUX

    I need to write a C game Towers of Hanoi. Everything works well, the discs are drawn but I can't seem to get them moving like I need. Can someone take a look at the code and help me find what can be wrong with it?

    Code:
    #include "primlib.h"  
    #include <stdlib.h>  
    #include <stdio.h>
    #include <math.h>
    /** number of pegs*/
    #define n 3
    /**number of disks*/
    #define d 3
     
     
    int towers[n][d];                               /*initialization of the array (pegs x disks) */
    int x,i,j,choice,disknum,mem,A,B;              
    /*declaration of variables
    x - piece of the screen, dependent on the peg number, used to place the pegs in the equidistant way
    i,i - loop variables
    choice - typed peg (shifted by 1, in the function shift_key, so that the index starts from 0)
    disknum - number of disks on the peg
    mem - auxiliary variable, used to store the disks during the operation of moving between pegs
    A, B - replacements of choice and disknum-1, to simplify further uses of the array
    */
     
    void pegdraw(void)              /**function drawing the pegs*/
    {
            int i=1;
            while (i<=n)
            {
                    filledRect(i*((screenWidth())/(n+1))-15/n, screenHeight()-(20*d+20),i*((screenWidth()/(n+1)))+15/n, screenHeight()-21, RED);
                    updateScreen();                        
                    i++;
            }
    }
     
     
    void diskdraw(void)             /**function drawing the disks*/
    {
            x=screenWidth()/(n+1);
            for (i=0;i<n;i++)
            {
                    for(j=0;j<d;j++)
                    {
                            if (towers[i][j]==0)
                            {}
                            else
                            {
                                    filledRect((i+1)*x-(30*towers[i][j])/(n+1),screenHeight()-37-20*j,(i+1)*x+(30*towers[i][j])/(n+1), screenHeight()-21-20*j,GREEN);
                            }
                    }      
            }
    }
                           
     
    void shift_key(void)                    /**function assigning the typed key to the actual posision in the array*/
    {
            if (isKeyDown(SDLK_1)) choice=0;
            if (isKeyDown(SDLK_2)) choice=1;
            if (isKeyDown(SDLK_3)) choice=2;
            if (isKeyDown(SDLK_4)) choice=3;
            if (isKeyDown(SDLK_5)) choice=4;
            if (isKeyDown(SDLK_6)) choice=5;
            if (isKeyDown(SDLK_7)) choice=6;
            if (isKeyDown(SDLK_8)) choice=7;
            if (isKeyDown(SDLK_9)) choice=8;
            if (isKeyDown(SDLK_0)) choice=9;        
    }
     
     
    int disk_amount(int choice)             /**function reading the number of disks, which are present on the peg*/
    {
            disknum=0;
            for (i=0;i<d;i++)
            {
                    if(towers[choice][i]==0)
                    {
                    break;
                    }
                    else
                    {
                    disknum=disknum+1;
                    }
            }
            return disknum;
    }
     
     
    int main(int argc, char* argv[])
    {      
            int i,j;
            if (initGraph())
            exit(3);       
            filledRect(0,screenHeight()-20,screenWidth()-1,screenHeight()-1,                                YELLOW);/* drawing the ground for the pegs*/
            textout((screenWidth()/2)-40,50,"Instructions",WHITE); /*instructions*/
            textout(30,70,"The objective is to move all the disks from the initial stack to the other",WHITE);
            textout(30,90,"one.You can only move a disk on an empty peg, or on a bigger disk (not on a",WHITE);
            textout(30,110,"smaller).To move, type the number of the source peg (from the left), and",WHITE);
            textout(30,130,"then the number of the destination peg.",WHITE);
            for (i=0;i<n;i++)
            {
                    for(j=0;j<d;j++)
                    {
                            if(i==0)
                            {
                                    towers[i][j]=d-j;
                            }
                            else towers [i][j]=0;
                    }
            }              
            pegdraw();
            diskdraw();
           
            do
            {
                    if(isKeyDown(SDLK_ESCAPE))
                    {
                            break;                          /*optional closing the program*/
                    }
                    fflush(stdin);                                 
                    getkey();                               /*choice of source peg*/
                    shift_key();                            /*assigning the typed key to the actual posision in the array*/
                    disk_amount(choice);
     
     
                    mem=towers[choice][disknum-1];          /*auxiliary variable 'mem', used to store the user's peg choice and number of disks*/
                    A=choice;
                    B=disknum-1;
     
                                                    /*protection from typing keys too fast (otherwise the program could store two keys together */
     
                    getkey();                               /*choice of destination peg*/
                    shift_key();                            /*assigning the typed key to the actual posision in the array*/
                    disk_amount(choice);
     
                    if(A==choice)
                    {
                            continue;                       /*if both pegs choosen are the same, nothing happens*/
                    }
     
                    if(choice>n-1)
                    {
                            continue;                       /*if a chosen peg has a greater number, than the total amount of pegs, nothing happens. subtraction of 1 indicates, that the peg table index is                                 shifted by 1*/
                    }
     
                    if(towers[choice][0]!=0 && mem>towers[choice][disknum-1])
                    {
                            continue;                       /*if the chosen disk is bigger, than the disk on the top of the destination peg, nothing happens*/
                    }
                    towers[A][B]=0;                         /*clearing the variable, so that next execution can be performed from the beginning*/
     
                    towers[choice][disknum]=mem;            /*moving the disk to the destination peg, above the last disk on it*/
                    updateScreen();
     
                    if(towers[n-1][d-1]>0)
                    {      
                            textout(screenWidth()/2, 50, "YOU WIN", BLUE);
                            break;                          /*all disks are on the last peg - program terminates*/
                    }
                   
                   
            }while(1);
            updateScreen();
            getkey();                      
            return 0;
    }

  2. #2
    young grasshopper jwroblewski44's Avatar
    Join Date
    May 2012
    Location
    Where the sidewalk ends
    Posts
    294
    IsKeyDown()
    Is this C#?

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > Everything works well, the discs are drawn but I can't seem to get them moving like I need.
    But you don't tell us what that "need" is.

    Is it a simple up, left/right then down again?

    I suggest you create a separate program which just animates an example disk from one peg to another, without all the baggage of the whole ToH program as well.
    Most of the code you posted had no relevance to the immediate problem of getting a disk to animate.

    Once you understand your simple example (or get stuck and post it here), you can then merge the idea with your main code and have the whole program working.

    > #include "primlib.h"
    We don't have that, so we can't build your code.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Mar 2013
    Posts
    4
    Quote Originally Posted by Salem View Post
    >
    Is it a simple up, left/right then down again?
    so the discs should be controlled with number keys. 1 should be assigned to the first peg so for example if I would like to move a disc from peg 1 to 3 I should press 1 and the 3.

    Do you have any proposition for a function that could animate the movement of the discs from one peg to another?primlib.h
    I attached my primlib.h file for the visualisations. Thanks for the previous suggestions.

  5. #5
    Registered User
    Join Date
    Mar 2013
    Posts
    4
    but still first I just want them to jump from one peg to another without animations...

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I'm not familiar with primlib.h, but I've done it with conio.h - so I'm sure that curses, Ncurses, or other console oriented lib file could do it as well.

    I must say, it's can be a BEAUTIFUL console game, with animations.

  7. #7
    Registered User
    Join Date
    Mar 2013
    Posts
    4
    Take a look at primlib.h I included it in an above post. I'm sure it can be beautiful. But I'm still a novice to C and I'm just trying for it to work first without animations like in the code above, but I can't seem to understand why it's not working.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by Adam Stolarek View Post
    Take a look at primlib.h I included it in an above post. I'm sure it can be beautiful. But I'm still a novice to C and I'm just trying for it to work first without animations like in the code above, but I can't seem to understand why it's not working.
    I agree. Don't put in animations first - get the core logic working, first. You need a very simple way to place SOMETHING so you know where the discs are currently.

    You have some program logic to work the discs that I don't grok. This is a naturally recursive problem, and the code to move the discs is about 8 lines or so.

    Next to factorials, I would say Towers of Hanoi is THE perfect example of why recursion is so great, sometimes.

    Of course, you still need to get the user's input, etc - and that takes more code.

    To start out, I'd just use a simple numbering system for the discs, just to do that simple display of where the disc is currently.

    That other logic to solve the Tower, I'd delete and think recursively. There is also a number trick that can be used iteratively. I can't remember it atm, it's been a LONG time.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. simple snake game under linux
    By newbie0101 in forum Linux Programming
    Replies: 5
    Last Post: 10-02-2011, 11:33 AM
  2. C++ game programming on Linux?
    By arya6000 in forum C++ Programming
    Replies: 12
    Last Post: 10-30-2008, 05:20 PM
  3. Linux game(uses python)
    By ichijoji in forum A Brief History of Cprogramming.com
    Replies: 2
    Last Post: 09-05-2007, 01:39 PM
  4. windows game programming on Linux?
    By 124 in forum Linux Programming
    Replies: 18
    Last Post: 03-23-2006, 05:14 PM
  5. Best Linux Game?
    By Troll_King in forum Linux Programming
    Replies: 7
    Last Post: 09-14-2002, 05:11 AM

Tags for this Thread