RushHour program in C
Write a program to play the game of RushHour, such as shown on this page . Running your program should look like the following, where user input is shown in bold:
Welcome to the traffic game!
Move the vehicles so that the Red car (RR) can
exit the board to the right. Each move should be
of the form: CDN where C is the vehicle to
be moved, D is the direction (u for up, d for down,
l for left or r for right), and N is the number of
squares to move it. For example GR2 means move the
G vehicle to the right 2 squares. Lower-case input
such as gr2 is also accepted. Enter x to exit the
program.
- - - - - - - -
| G G . . . Y |
| P . . B . Y |
| P R R B . Y >
| P . . B . . |
| O . . . T T |
| O . F F F . |
- - - - - - - -
Your move -> gr1
- - - - - - - -
| . G G . . Y |
| P . . B . Y |
| P R R B . Y >
| P . . B . . |
| O . . . T T |
| O . F F F . |
- - - - - - - -
Your move ->
Thank you for playing. Exiting...
Press any key to continue . . .
1. Information on placement of pieces to be used for the board is read in from a file called board.txt. The format of information should be just like the board that is displayed initially, except without the extra spaces, so for the sample board shown above it would look like:
--------
|GG...Y|
|P..B.Y|
|PRRB.Y>
|P..B..|
|O...TT|
|O.FFF.|
--------
2. You may assume the user enters either upper-case or lower-case input, with or without intervening spaces.
3. The program ends when the red car touches the '>' character to the right of it.
When making a move for program 3, we want to accept input in lower-case, upper-case, and with various options of spacing. The key here is to ignore leading space when reading character input. This will skip over blanks, tabs, and even carriage-return characters. The code for this is something like the following:
char vehicle;
char direction;
char distance;
char distanceValue;
printf("Enter your move (e.g. ar2): ");
// skip leading spaces by putting a space in front of the %c in the format string
scanf(" %c %c %c", &vehicle, &direction, &distance);
// Now convert the distance char into a numerical value
distanceValue = distance - '0';
I'm using a 2D array for this project (i.e.board[8][8]). I am not finished with my code, but I've made substantial progress. With that said, if you have a question on how to implement a 2D array (issues with printing the board and null overriding), feel free to ask.
I won't give code, but I will give hints and suggestions. One of my group's problems yesterday was that the printed version had shifted characters from board[0][0] through [0][8] over to the right most side of the printed outcome. It is important to know that in the initial printf statement of board (as a nested for loop), that the rows iterate through 8, and the columns iterate through 9.
Keep in mind that is only true if you treat those special border characters as part of the read-in. Another small hint those read through values will change for different functions (i.e. when you want to read through the file to determine valid car movement).
Reading from board.txt
See the code samples covered in class to read in characters from a file, such as MacbethCount.c
The main loop
From within main you should have a loop with the main components of your program, each of which is in a function that gets called. It should look something like:
// display id info
// display instructions
// loop while program is not done
// display board
// prompt for and get user input for move
// make move
Breaking down the problem into smaller, more easily solvable pieces.
If figuring out how to make a move is giving you trouble, break down that problem into successively simpler but related ideas, then build up your solution one step at a time. For instance you could solve that bigger problem by solving each of the following in turn:
1. Figure out how to "make a move" on a tiny board of only two squares, such as:
2. 0 1 <-array index
3. ---------
4. | G | |
---------
Think of the instructions required to move 'G' from square 0 to square 1. The instructions should be something like:
board[ 1] = board[ 0];
board[0] = ' ';
5. Next consider a larger board, where again there is only a single 'G' somewhere, to be moved to the right a single square. First you would have to write the code to find the 'G' in the array, and store that location. Then again make the move, as in the previous step.
6. Now go back to the simple case, but this time consider how you might "make a move" where the vehicle is either a single 'G' or two letters "GG" to be moved one position to the right:
7. 0 1 2 <-array index
8. -------------
9. | G | G | |
-------------
Here consider how to write the code to move both 'G' characters one square to the right. Merge this with your previous code so that it works for either case, where your code figures out if there is a single 'G' or two 'G' characters. While you are at it, consider handling vehicles up to 3 characters long, which is the maximum we need for this game.
10. Once again think about how to solve this so that it is again a one or two character vehicle, but this time found anywhere on the board, again thinking only about moving that vehicle one character to the right.
11. Once you have the above done, think about how to move a vehicle up to 4 characters to the right. Add the code to make sure there are no other vehicles in the way and that it doesn't go off the edge of the board.
12. Now think about how you can make your code general, so that instead of adding 1 to the position of a character, you add n to it, where n could be 1 (to move right) or -1 (to move left).
13. Now do something similar to the previous step, but handle vehicles that move up and down rather than left and right.
14. To move a vehicle n multiple squares, consider writing code to move it only 1 square, then repeat that n times. Each time you make the move you should make sure the move is valid, that is to say it is not off the end of the board and does not go into a square that is already occupied. One way to handle this is to make a copy of the board and then attempt to make the move. If the move is successful on the copy of the board, then copy that new board back on top of the original board. If the move is invalid, the original board is still there, unchanged.