/** * Play the triangular peg-jumping game * * Class: CS 107, Spring 2009 * Lab: Billie Joe Armstrong, Wed. 6:00 AM * System: BlueJ 2.1.1, jsdk 1.5, Windows XP * * @author Dale Reed * @version January 30, 2009 * * Running the program looks like: Author: Dale Reed Program: #2, PegJump TA: Englebert Humberdink, T 4-5 Jan 30, 2009 This program represents the peg jumping puzzle. The board starts out with a single blank position, represented by the 'o'. To make a move, select the letter of the peg to be moved, then the letter of the destination position. (e.g. the first move might be: d a, meaning we move peg 'd' into blank position 'a'.) A peg must be able to jump over an adjacent peg into a blank for a move to be valid. The jumped peg is then removed from the board. The game is over when there are no valid moves left to be made, or when there is a single peg left. At any point enter 'x' to exit the program. ----------------------- Board Positions o A + + B C + + + D E F + + + + G H I J + + + + + K L M N O 1. Enter your move: d a ----------------------- Board Positions + A o + B C o + + D E F + + + + G H I J + + + + + K L M N O 2. Enter your move: f d . . . */ // Import libraries needed by the program import java.util.Scanner; // used for console input // Declare the class public class PegJump { // Fields that can be accessed anywhere in the class go here Scanner keyboard = new Scanner( System.in); // used to read user input //---------------------------------------------------------------------------------------- // main() - startup main loop. It is necessary to create an instance of this class // and then call a method from that instance, otherwise there are all kinds // of error messages having to do with non-static objects (e.g. keyboard) // being called from a static context (e.g. main). By creating the instance // and *then* using keyboard, it is not longer being called from a static // context. Don't worry about understanding all this right now. public static void main(String[] args) { // create an instance of this class PegJump thePegJumpInstance = new PegJump(); // call a non-static method to do everything else thePegJumpInstance.mainLoop(); } //---------------------------------------------------------------------------------------- // mainLoop() - display identifying information and run main loop. // In your program, you will only add code inside this method. You don't need to // change anything above except for the comments at the top of the program. // void mainLoop() { // Display identifying information System.out.println( "Author: Dale Reed \n" + "Program: #2, PegJump \n" + "TA: Englebert Humberdink, T 4-5 \n"+ "Jan 30, 2009"); System.out.println(); // Display Instructions System.out.println( "This program represents the peg jumping puzzle. \n" + "The board starts out with a single blank position, represented by \n" + "the 'o'. To make a move, select the letter of the peg to be moved, \n" + "then the letter of the destination position. (e.g. the first move \n" + "might be: d a, meaning we move peg 'd' into blank position 'a'.) \n" + "A peg must be able to jump over an adjacent peg into a blank for a \n" + "move to be valid. The jumped peg is then removed from the board. \n" + "The game is over when there are no valid moves left to be made, or \n" + "when there is a single peg left. \n" + "At any point enter 'x' to exit the program. \n"); // Playing pieces char p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15; // Initialize peg (playing pieces) values to all be '+' except for the top one, which is a blank p1='o'; p2=p3=p4=p5=p6=p7=p8=p9=p10=p11=p12=p13=p14=p15='+'; // move number int moveNumber = 1; int numberOfPegs = 14; // initial value, used to detect when program is done String userInput = ""; // stores user input, which is then parsed into the "from" and "to" peg positions char movingFrom = ' '; // letter position ('A'..'O') where we are moving from char movingTo = ' '; // letter position ('A'..'O') where we are moving to char pieceBeingJumped = ' '; // letter position ('A'..'O') of the piece being jumped char charAtMovingFromPosition = ' '; // character at the position we are moving from char charAtMovingToPosition = ' '; // character at the position we are moving to char charAtPositionBeingJumped = ' '; // character at the position being jumped do { // Display Board System.out.println(); System.out.println(); System.out.println("----------------------- \n" + " Board Positions \n" + " " + p1 + " A \n" + " " + p2 + " " + p3 + " B C \n" + " " + p4 + " " + p5 + " " + p6 + " D E F \n" + " " + p7 + " " + p8 + " " + p9 + " " + p10 + " G H I J \n" + p11 + " " + p12 + " " +p13 + " " +p14 + " " + p15 + " K L M N O \n"); // break out of loop if there is only 1 peg left if( numberOfPegs == 1) { break; } // Get user input. Put a loop around this to allow repeat prompts when input is invalid boolean verifyingUserInput = true; // after input passes all checks, this is set to false while( verifyingUserInput) { System.out.print(moveNumber + ". Enter your move: "); userInput = keyboard.nextLine(); // convert to upper case to simplify comparisons later userInput = userInput.toUpperCase(); // check for exit if( userInput.charAt(0) == 'X') { break; // break out of the user input loop } // extract where we are moving from and where we are moving to movingFrom = userInput.charAt( 0); movingTo = userInput.charAt( 2); // Calculate which piece is being jumped by using character arithmetic, finding the character // that is in between the source and destination positions. Below at left are the positions: // A For example, 'A' is represented internally by the value 65, 'B' is 66, // B C 'C' is 67, 'D' is 68, and so on. When moving from 'D' to 'A' (68 to 65) // D E F we need to find the middle position (66). // G H I J To do this we find the halfway point between the starting and ending position: // K L M N O (68 + 65) / 2, which is: 133/2 which is: 66 (the remainder is truncated // because we are doing integer division.) We then cast this value back to a char // which gives us 'B'. This works the same for any other valid moves. pieceBeingJumped = (char) ((movingFrom + movingTo) / 2); // Do error checking on user input. Note that input was changed to all upper-case already. // There are 5 conditions to check: // 1. Verify destination is in range if( (movingTo < 'A') || (movingTo > 'O')) { // destination is out of range 'A'..'O' System.out.println("*** Invalid destination. Please retry ****"); continue; // go back up to reprompt for user input }//end if( (movingTo... // 2. Verify source is in range if( (movingFrom < 'A') || (movingFrom > 'O')) { // source is out of range 'A'..'O' System.out.println("*** Invalid source. Please retry ****"); continue; // go back up to reprompt for user input }//end if( (movingFrom... // 3. Verify position being jumped has a peg. First find which character is at that position. switch( pieceBeingJumped) { case 'A': charAtPositionBeingJumped = p1; break; case 'B': charAtPositionBeingJumped = p2; break; case 'C': charAtPositionBeingJumped = p3; break; case 'D': charAtPositionBeingJumped = p4; break; case 'E': charAtPositionBeingJumped = p5; break; case 'F': charAtPositionBeingJumped = p6; break; case 'G': charAtPositionBeingJumped = p7; break; case 'H': charAtPositionBeingJumped = p8; break; case 'I': charAtPositionBeingJumped = p9; break; case 'J': charAtPositionBeingJumped = p10; break; case 'K': charAtPositionBeingJumped = p11; break; case 'L': charAtPositionBeingJumped = p12; break; case 'M': charAtPositionBeingJumped = p13; break; case 'N': charAtPositionBeingJumped = p14; break; case 'O': charAtPositionBeingJumped = p15; break; default: // sanity check, should never get to this code System.out.println("*** Invalid middle position character calculated. Exiting..."); System.exit( -1); // exit the program break; // keep compiler happy for this switch-case condition }//end switch( movingFrom) if( charAtPositionBeingJumped != '+') { // piece being jumped is not a peg though it should be System.out.println("*** Must jump a piece. Please retry ****"); continue; // go back up to reprompt for user input }//end if( (charAtPositionBeingJumped... // 4. Verify source has a piece. First find which character is at that position switch( movingFrom) { case 'A': charAtMovingFromPosition = p1; break; case 'B': charAtMovingFromPosition = p2; break; case 'C': charAtMovingFromPosition = p3; break; case 'D': charAtMovingFromPosition = p4; break; case 'E': charAtMovingFromPosition = p5; break; case 'F': charAtMovingFromPosition = p6; break; case 'G': charAtMovingFromPosition = p7; break; case 'H': charAtMovingFromPosition = p8; break; case 'I': charAtMovingFromPosition = p9; break; case 'J': charAtMovingFromPosition = p10; break; case 'K': charAtMovingFromPosition = p11; break; case 'L': charAtMovingFromPosition = p12; break; case 'M': charAtMovingFromPosition = p13; break; case 'N': charAtMovingFromPosition = p14; break; case 'O': charAtMovingFromPosition = p15; break; default: // sanity check, should never get to this code System.out.println("*** Invalid movingFrom character calculation. Exiting..."); System.exit( -1); // exit the program break; // keep compiler happy for this switch-case condition }//end switch( movingFrom) if( charAtMovingFromPosition != '+') { // position we are moving from is not a peg though it should be System.out.println("*** Source must have a piece. Please retry ****"); continue; // go back up to reprompt for user input }//end if( (charAtMovingFromPosition... // 5. Verify destination is empty. First find which character is at that position switch( movingTo) { case 'A': charAtMovingToPosition = p1; break; case 'B': charAtMovingToPosition = p2; break; case 'C': charAtMovingToPosition = p3; break; case 'D': charAtMovingToPosition = p4; break; case 'E': charAtMovingToPosition = p5; break; case 'F': charAtMovingToPosition = p6; break; case 'G': charAtMovingToPosition = p7; break; case 'H': charAtMovingToPosition = p8; break; case 'I': charAtMovingToPosition = p9; break; case 'J': charAtMovingToPosition = p10; break; case 'K': charAtMovingToPosition = p11; break; case 'L': charAtMovingToPosition = p12; break; case 'M': charAtMovingToPosition = p13; break; case 'N': charAtMovingToPosition = p14; break; case 'O': charAtMovingToPosition = p15; break; default: // sanity check, should never get to this code System.out.println("*** Invalid destination position character calculated. Exiting..."); System.exit( -1); // exit the program break; // keep compiler happy for this switch-case condition }//end switch( movingTo) if( charAtMovingToPosition != 'o') { // position we are moving to is not blank though it should be System.out.println("*** Destination must be empty. Please retry ****"); continue; // go back up to reprompt for user input }//end if( (charAtMovingToPosition... // if we got to here that means we passed all user input verification steps, so exit the loop verifyingUserInput = false; // forces loop to exit on next iteration }//end while( verifyingUserInput // check for exit. If 'X' to exit was entered, the above user input loop was already exited if( userInput.charAt(0) == 'X') { break; // break out of the main loop } // Make move. If we got to this point, we can assume it is a valid move. Make a move in 3 steps: // 1. Blank out the peg where we are moving from // 2. Blank out the peg being jumped // 3. Place a peg in the position we are moving to, and decrement the number of pegs // // Step 1. Blank out the peg where we are moving from. Check each of 15 possible positions switch( movingFrom) { case 'A': p1 = 'o'; break; case 'B': p2 = 'o'; break; case 'C': p3 = 'o'; break; case 'D': p4 = 'o'; break; case 'E': p5 = 'o'; break; case 'F': p6 = 'o'; break; case 'G': p7 = 'o'; break; case 'H': p8 = 'o'; break; case 'I': p9 = 'o'; break; case 'J': p10 = 'o'; break; case 'K': p11 = 'o'; break; case 'L': p12 = 'o'; break; case 'M': p13 = 'o'; break; case 'N': p14 = 'o'; break; case 'O': p15 = 'o'; break; default: // sanity check, should never get to this code System.out.println("*** Invalid source position calculated. Exiting..."); System.exit( -1); // exit the program break; // keep compiler happy for this switch-case condition }//end switch( movingFrom) // Step 2. Blank out the peg being jumped. switch( pieceBeingJumped) { case 'A': p1 = 'o'; break; case 'B': p2 = 'o'; break; case 'C': p3 = 'o'; break; case 'D': p4 = 'o'; break; case 'E': p5 = 'o'; break; case 'F': p6 = 'o'; break; case 'G': p7 = 'o'; break; case 'H': p8 = 'o'; break; case 'I': p9 = 'o'; break; case 'J': p10 = 'o'; break; case 'K': p11 = 'o'; break; case 'L': p12 = 'o'; break; case 'M': p13 = 'o'; break; case 'N': p14 = 'o'; break; case 'O': p15 = 'o'; break; default: // sanity check, should never get to this code System.out.println("*** Invalid middle position calculated. Exiting..."); System.exit( -1); // exit the program break; // keep compiler happy for this switch-case condition }//end switch( movingFrom) // Step 3. Place a peg in the position we are moving to and // decrement number of pegs switch( movingTo) { case 'A': p1 = '+'; break; case 'B': p2 = '+'; break; case 'C': p3 = '+'; break; case 'D': p4 = '+'; break; case 'E': p5 = '+'; break; case 'F': p6 = '+'; break; case 'G': p7 = '+'; break; case 'H': p8 = '+'; break; case 'I': p9 = '+'; break; case 'J': p10 = '+'; break; case 'K': p11 = '+'; break; case 'L': p12 = '+'; break; case 'M': p13 = '+'; break; case 'N': p14 = '+'; break; case 'O': p15 = '+'; break; default: // sanity check, should never get to this code System.out.println("*** Invalid destination position calculated. Exiting..."); System.exit( -1); // exit the program break; // keep compiler happy for this switch-case condition }//end switch( movingTo) // decrement the number of pegs numberOfPegs--; // increment move number moveNumber++; } while (numberOfPegs >= 1); // Display a message, depending on the number of pegs left System.out.println("# left Rating \n" + "------ ---------------\n" + " >4 Dufus \n" + " 4 Poor \n" + " 3 Mediocre \n" + " 2 Good Job \n" + " 1 Awesome Genius!\n"); System.out.print("You had " + numberOfPegs + " left. "); // and print the customized message switch( numberOfPegs) { case 1: System.out.println(" Awesome Genius!"); break; case 2: System.out.println(" Good Job."); break; case 3: System.out.println(" Mediocre."); break; case 4: System.out.println(" Poor."); break; default: System.out.println(" Dufus."); break; }//end switch( numberOfPegs) System.out.println(); System.out.println("Thanks for playing. Exiting... \n"); }//end mainLoop() }//end class PegJump