text-based chess (with cursor selection feature)

This is a discussion on text-based chess (with cursor selection feature) within the C++ Programming forums, part of the General Programming Boards category; ok, it's quite crude because i haven't added anything in the way of rules governing legality of moves, turn system, ...

  1. #1
    Registered User
    Join Date
    Aug 2006
    Posts
    6

    text-based chess (with cursor selection feature)

    ok, it's quite crude because i haven't added anything in the way of rules governing legality of moves, turn system, and game-deciding factors such as checkmate, check, or castling.

    i'm a real newb to this stuff (i learned this stuff like... two days ago... i only know the syntax for for loops, if statements, cout and cin (the getch thing included in the code had been a remedy to constantly having to press enter all the time), arrays and arrays within arrays (i'm guessing you can make multidimensional arrays with something like... array[n(1)][n(2)][n(3)]...[n(n-1)][n(n)]???), declaring variable of different types (char for letters and int for numbers... and i also know that the declaration double or float makes non-integer numbers) and.. making functions outside the main thing...

    to be frank, i'm actually a little proud of the approach i took in making this lil proggy. i thought about it for a large portion of yesterday, mulling over if it was actually even possible to begin with (which eventually led me to taking this approach).

    so basically what happens:

    i have this char-based 8x8 matrix called board[8][8] that's filled in using a populator function.

    i also have a char-based variable cursor_storage that "stores" the value currently holding the cursor.

    by "holding" i mean that the cursor can "pick up" items on the board, and the item that had been on the board is replaced by a blank space (represented by a period). you'll see this in the function void movement().

    look at the functions display() and movement() to see exactly how i made the cursor possible...

    anyway on to the main code:

    Code:
    #include <iostream.h>
    #include <conio.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    //let us write a single matrix chess program.
    
    int i;
    int j;
    char command;
    char board[7][7];
    int xpos;
    int ypos;
    int pickupstate;
    char cursor_storage;
    
    void populator()
    {
         for (i=0;i<8;i++)
         {
             for(j=0;j<8;j++)
             {
             board[i][j]='.';
             }
         } //seeds the board with periods as placeholders
         
         //the following is the specific placement of pieces; capital letters
         //represent white pieces, while the lowercase letters represent white
         //pieces.
         board[0][0]='r';
         board[0][1]='n';
         board[0][2]='b';
         board[0][3]='q';
         board[0][4]='k';
         board[0][5]='b';
         board[0][6]='n';
         board[0][7]='r';
         
         board[7][0]='R';
         board[7][1]='N';
         board[7][2]='B';
         board[7][3]='Q';
         board[7][4]='K';
         board[7][5]='B';
         board[7][6]='N';
         board[7][7]='R';
         
         for(i=0;i<8;i++)
         {
                         board[1][i]='p';
                         board[6][i]='P';
         }
         
         xpos=0;
         ypos=0;
         cursor_storage='*';
         pickupstate=0;
         //these are simply initial values.
    }
    
    void display()
    {
         for(i=0;i<8;i++)
         {
                         for(j=0;j<8;j++)
                         {
                                         if(i!=ypos || j!=xpos)
                                         cout<<board[i][j];
                                         if(i==ypos && j==xpos)
                                         cout<<cursor_storage;
                         }
                         cout<<endl; 
                         //displays the board if the current coordinates
                         //being represented (i,j) are not in accordance with the
                         //'real coordinates' of where the cursor currently 'is'
                         //(ypos,xpos). if i and j are both equal to ypos/xpos 
                         //respectively, the character currently stored as the 
                         //cursor marker is displayed instead of board[i][j].
         }
         
    }
    
    void movement()
    {
         command=getch();
         
         if(command=='w')//northward cursor movement
         {
                         ypos=ypos-1;
         }
         if(command=='s')//southward cursor movement
         {
                         ypos++;
         }                
         if(command=='a')//westward cusor movement
         {
                         xpos=xpos-1;
         }
         if(command=='d')//eastward cursor movement
         {
                         xpos++;
         }
         if(command=='k')//'k' is the button to pickup/release pieces currently on
                         //the board.
         {
                         if(pickupstate==0)//pickupstate of 0 indicates no piece
                                           //currently 'held' by the cursor
                         {
                                          cursor_storage=board[ypos][xpos];
                                          board[ypos][xpos]='.';
                                          pickupstate=1;
                         }
                         if(pickupstate==1)//pickupstate of 1 indicates a piece
                                           //is currently being held by cursor   
                         {
                                           board[ypos][xpos]=cursor_storage;
                                           cursor_storage='*';
                                           pickupstate=0;
                         }
         }
         system("cls"); //clears the after images to make it look like asingleboard
    }
         
         int main()//now i just call in the three functions in an infinte loop.
                   //press ctrl+c to terminate the program.
         {
             populator();
             for(;;)
             {
                    display();
                    movement();
             }
         
             return 0;
         }
    if you compile and run this prog, you'll find a gross bug/error that i have no idea on how to circumvent. first of all, it doesn't properly display the board matrix... it seems that a portion of the board is warped on the right side, making for a "protruding" pawn line and rear ranks. secondly, half the rear rank for the white side, the right side of this rank, does not display correctly and instead shows some eerie lines that i know must not be "real" computer letters like abc's, 123's, and !@#$%^&*() etc. also the computer makes a beeping noise whenever the the cursor is sent to the right-most column (therefore, whenever xpos=7, i guess... but then again maybe not because of that "protrusion" phenomenon that i mentioned earlier). thirdly, the cursor just won't pick items on the board up. refer to the lines in movement() to see... i mean, i'm just so sure it should work, but it doesn't. but then again that's what bugs are, heh.

    oh, and use wasd keys to move the thing around. "k" is supposed to pick stuff up, but like i said... it doesn;t work. oh and another thing is not to move past the boundaries. i haven;t yet implemented any counter measures for that :P and, sorry for the ;'s instead of apostrophes, i broke my right hand (the pinky... like not the actual finger but the bone actually "in the palm", according to the doctor) yesterday when i punched my wall... ring finger's been real busy since yesterday hehe.

    please help!~ i'm really desperate after sitting here for three hours to no avail.
    Last edited by swbang86; 08-14-2006 at 01:35 PM.

  2. #2
    Registered User
    Join Date
    Aug 2002
    Location
    Hermosa Beach, CA
    Posts
    446
    Your array bounds are wrong. You use board[7], which means your valid array indices are 0-6. You need board[8][8], which gives you valid elements from 0-7. There may be other problems, that was only what I saw with a quick glance.
    The crows maintain that a single crow could destroy the heavens. Doubtless this is so. But it proves nothing against the heavens, for the heavens signify simply: the impossibility of crows.

  3. #3
    Registered User
    Join Date
    Aug 2006
    Posts
    6

    ah... did it, now it works

    thanks alot. here's the new code (only modification is changing board[7][7] declaration to board[8][8].

    Code:
    #include <iostream.h>
    #include <conio.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    //let us write a single matrix chess program.
    
    int i;
    int j;
    char command;
    char board[8][8];
    int xpos;
    int ypos;
    int pickupstate;
    char cursor_storage;
    
    void populator()
    {
         for (i=0;i<8;i++)
         {
             for(j=0;j<8;j++)
             {
             board[i][j]='.';
             }
         } //seeds the board with periods as placeholders
         
         //the following is the specific placement of pieces; capital letters
         //represent white pieces, while the lowercase letters represent white
         //pieces.
         board[0][0]='r';
         board[0][1]='n';
         board[0][2]='b';
         board[0][3]='q';
         board[0][4]='k';
         board[0][5]='b';
         board[0][6]='n';
         board[0][7]='r';
         
         board[7][0]='R';
         board[7][1]='N';
         board[7][2]='B';
         board[7][3]='Q';
         board[7][4]='K';
         board[7][5]='B';
         board[7][6]='N';
         board[7][7]='R';
         
         for(i=0;i<8;i++)
         {
                         board[1][i]='p';
                         board[6][i]='P';
         }
         
         xpos=0;
         ypos=0;
         cursor_storage='*';
         pickupstate=0;
         //these are simply initial values.
    }
    
    void display()
    {
         for(i=0;i<8;i++)
         {
                         for(j=0;j<8;j++)
                         {
                                         if(i!=ypos || j!=xpos)
                                         cout<<board[i][j];
                                         if(i==ypos && j==xpos)
                                         cout<<cursor_storage;
                         }
                         cout<<endl; 
                         //displays the board if the current coordinates
                         //being represented (i,j) are not in accordance with the
                         //'real coordinates' of where the cursor currently 'is'
                         //(ypos,xpos). if i and j are both equal to ypos/xpos 
                         //respectively, the character currently stored as the 
                         //cursor marker is displayed instead of board[i][j].
         }
         
    }
    
    void movement()
    {
         command=getch();
         
         if(command=='w')//northward cursor movement
         {
                         ypos=ypos-1;
         }
         if(command=='s')//southward cursor movement
         {
                         ypos++;
         }                
         if(command=='a')//westward cusor movement
         {
                         xpos=xpos-1;
         }
         if(command=='d')//eastward cursor movement
         {
                         xpos++;
         }
         if(command=='k')//'k' is the button to pickup/release pieces currently on
                         //the board.
         {
                         if(pickupstate==0)//pickupstate of 0 indicates no piece
                                           //currently 'held' by the cursor
                         {
                                          cursor_storage=board[ypos][xpos];
                                          board[ypos][xpos]='.';
                                          pickupstate=1;
                         }
                         if(pickupstate==1)//pickupstate of 1 indicates a piece
                                           //is currently being held by cursor   
                         {
                                           board[ypos][xpos]=cursor_storage;
                                           cursor_storage='*';
                                           pickupstate=0;
                         }
         }
         system("cls"); //clears the after images to make it look like asingleboard
    }
         
         int main()//now i just call in the three functions in an infinte loop.
                   //press ctrl+c to terminate the program.
         {
             populator();
             for(;;)
             {
                    display();
                    movement();
             }
         
             return 0;
         }
    y et i still can't get the "picking stuff up" to work...

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,318
    First you check if(pickupstate==0), and inside that block you set pickupstate to 1. Then you check to see if pickupstate is 1. That will execute also. Perhaps you intended an else if or a plain old else.

    BTW, your code won't compile on several modern compilers. You should switch from iostream.h to iostream, and make sure to account for the std namespace (a simple search of posts or the FAQ should give the details). Also, conio.h is non-standard, although there really isn't an alternative that does exactly what you want, so at this point you might as well leave it there. Finally, stdlib.h and stdio.h are standard C++ headers, but they don't look like they are needed in your program.

  5. #5
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,262
    >> ypos=ypos-1;
    ypos--; is a popular alternative


    In your global declarations, I'd say initialise them all first, makes for safer and less undefined behaviour (look for Salem's sig). Most importantly say - int pickupstate=0;, I think, because it's undefined, so when you check to see if it's in the pick up state, it will more than likely not be what you want it to me. But it's always good practise to initialise variables anyways.


    >> if(i!=ypos || j!=xpos)
    >> cout<<board[i][j];
    >> if(i==ypos && j==xpos)
    >> cout<<cursor_storage;
    why not just have it as -

    if ( i==ypos && j==xpos ) cout<< whatever;
    else cout<< the other alternative;

    achieves the same end.

  6. #6
    Registered User
    Join Date
    Aug 2006
    Posts
    6

    wow... thank you, daved~!!

    ahh... i overlooked the fact that the code "executes" from top-down and that the if pickupstate=1 conditional statement will be checked right after the if pickupstate=0 condition a few lines above it... thank you! i'll get to fixing that, then i'll write in some rules (limitations to movements of pieces and such... can;t have knights moving all over the board and crap! heh)

    ty very much daved.

  7. #7
    Registered User
    Join Date
    Aug 2006
    Posts
    6

    finally! i got it!

    ok now one can play against another human! no rules have been yet implemented though

    wasd= movement arrows
    j = select piece/drop piece

    Code:
    #include <iostream.h>
    #include <conio.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    //let us write a single matrix chess program.
    
    int i;
    int j;
    char command;
    char board[8][8];
    int xpos=0;
    int ypos=0;
    int pickupstate=0;
    char cursor_storage='*';
    
    void populator()
    {
         for (i=0;i<8;i++)
         {
             for(j=0;j<8;j++)
             {
             board[i][j]='.';
             }
         } //seeds the board with periods as placeholders
         
         //the following is the specific placement of pieces; capital letters
         //represent white pieces, while the lowercase letters represent white
         //pieces.
         board[0][0]='r';
         board[0][1]='n';
         board[0][2]='b';
         board[0][3]='q';
         board[0][4]='k';
         board[0][5]='b';
         board[0][6]='n';
         board[0][7]='r';
         
         board[7][0]='R';
         board[7][1]='N';
         board[7][2]='B';
         board[7][3]='Q';
         board[7][4]='K';
         board[7][5]='B';
         board[7][6]='N';
         board[7][7]='R';
         
         for(i=0;i<8;i++)
         {
                         board[1][i]='p';
                         board[6][i]='P';
         }
    }
    
    void display()
    {
         for(i=0;i<8;i++)
         {
                         for(j=0;j<8;j++)
                         {
                                         if(i!=ypos || j!=xpos)
                                         cout<<board[i][j];
                                         if(i==ypos && j==xpos)
                                         cout<<cursor_storage;
                         }
                         cout<<endl; 
                         //displays the board if the current coordinates
                         //being represented (i,j) are not in accordance with the
                         //'real coordinates' of where the cursor currently 'is'
                         //(ypos,xpos). if i and j are both equal to ypos/xpos 
                         //respectively, the character currently stored as the 
                         //cursor marker is displayed instead of board[i][j].
         }
         
    }
    
    void movement()
    {
         command=getch();
         switch(command)
         {
         case 'w'://northward cursor movement
                         ypos=ypos-1;
                         break;
         case 's'://southward cursor movement
                         ypos++;
                         break;             
         case 'a'://westward cusor movement
                         xpos=xpos-1;
                         break;
         case 'd'://eastward cursor movement
                         xpos++;
                         break;
         case 'j'://'k' is the button to pickup/release pieces currently on
                         //the board.             
                         switch(pickupstate)
                         {
                         case 1://pickupstate of 1 indicates a piece
                                           //is currently being held by cursor   
                                           board[ypos][xpos]=cursor_storage;
                                           cursor_storage='*';
                                           pickupstate=0;
                                           break;
                         case 0://pickupstate of 0 indicates no piece
                                           //currently 'held' by the cursor
                                          cursor_storage=board[ypos][xpos];
                                          board[ypos][xpos]='.';
                                          pickupstate=1;
                                          break;
                         default:
                         break;
                         }
         default:
                 break;
         }
         system("cls"); //clears the after images to make it look like asingleboard
    }
         
         int main()//now i just call in the three functions in an infinte loop.
                   //press ctrl+c to terminate the program.
         {
             populator();
             for(;;)
             {
                    display();
                    movement();
             }
         
             return 0;
         }

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,318
    >> In your global declarations, I'd say initialise them all first, makes for safer and less undefined behaviour.
    Global variables are initialized for you, there is no undefined behavior. Although explicitly doing so might make the code clearer.

    >> finally! i got it!
    Nice work. If you're trying to learn C++, consider first passing values to your functions instead of having them be global. Then, once you get the hang of that you can try writing a class that encapsulates the chess board and game play.

  9. #9
    C / C++
    Join Date
    Jan 2006
    Location
    The Netherlands
    Posts
    312
    If you want to get experienced in arrays and for loops, code a validation function!
    Operating Systems:
    - Ubuntu 9.04
    - XP

    Compiler: gcc

  10. #10
    Registered User
    Join Date
    Aug 2006
    Posts
    6

    a what?

    what's a validation function?

  11. #11
    Registered User
    Join Date
    Aug 2006
    Posts
    6

    sorry...

    i don;t understand alot of the jargon being thrown around... passing values to the functions? classes? i've heard of these but i haven;t the slightest when it comes to actually understanding what they mean.. could you explain (at least briefly)? if it's too complicated or something, you could just tell me to read up on them, but i'd rather someone tell it to me thanks.

    oh, and i've heard somewhere that i shouldn;t use global variables and initializations... why? too clunky and un-fancy? just wondering

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,318
    You'll learn the jargon over time. Global variables are not the best idea for several reasons. One is that they make it harder to re-use code. Your code doesn't have any great examples yet, but if you wanted to have two chessboards visible for some reason, your functions would have to be changed. If you actually sent the data for a board to the function, then you could call the function once for the first board and then again for the second board, and you wouldn't have to change the function code.

    What I meant by passing values to functions was the use of function arguments. If you haven't learned about them yet, don't worry about it, but when you do (which should be soon) then try to use them instead of global variables.

    As I look at your code I see you aren't using any local variables. When you only use a variable in a single function, you can create that variable inside that function. That will reduce the name clutter and help reduce programmer errors. For example, you don't use the command variable anywhere but inside of movement, so you could remove the char command; from the top of the file and change the first line of movement to be char command = getch();.

    These are all somewhat minor details that you'll pick up as you go along, so don't worry too much about it.

  13. #13
    C++No0b!!!
    Join Date
    Jul 2005
    Location
    penn
    Posts
    66
    nice program

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Gearing up for Firefox 3
    By stevesmithx in forum A Brief History of Cprogramming.com
    Replies: 150
    Last Post: 06-20-2008, 06:10 AM
  2. A begginer writing a text based dungeon game.
    By deadherorising in forum C Programming
    Replies: 55
    Last Post: 11-10-2007, 05:16 PM
  3. Text Based RPG & AI?
    By TylerMoyer in forum General AI Programming
    Replies: 4
    Last Post: 10-12-2007, 06:40 AM
  4. pull out data frm a text file based on a condition
    By nirmala.s in forum C Programming
    Replies: 21
    Last Post: 11-26-2006, 11:56 PM
  5. Outputting String arrays in windows
    By Xterria in forum Game Programming
    Replies: 11
    Last Post: 11-13-2001, 06:35 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21