import java.util.Arrays ;
import java.util.Random ;
import java.util.Scanner ;
/**
* Rock Paper Scissors Lizard Spock
* <p>
* http://e...content-available-to-author-only...a.org/wiki/Rock-paper-scissors-lizard-Spock
* <p>
* Interface for a human to play against the computer.
*/
class Ideone {
/**
* Set up the rules for the game.
* What are the moves, and what beats what!
*/
public enum Move {
Rock,
Paper , Scissors, Lizard, Spock
;
static {
Rock.willBeat ( Scissors, Lizard) ;
Paper .
willBeat ( Rock,Spock
) ; Scissors.
willBeat ( Paper , Lizard
) ; Lizard.
willBeat ( Spock,
Paper ) ; Spock.willBeat ( Rock,Scissors) ;
}
// what will this move beat - populated in static initializer
private Move[ ] ibeat;
private void willBeat( Move...moves ) {
ibeat = moves;
}
/**
* Return true if this Move will beat the supplied move
* @param move the move we hope to beat
* @return true if we beat that move.
*/
public boolean beats( Move move) {
// use binary search in case someone wants to set up crazy rules.
return Arrays .
binarySearch ( ibeat, move
) >= 0 ; }
}
// This is a prompt that is set up just once per JVM
private static final String MOVEPROMPT
= buildOptions
( ) ; private static String buildOptions
( ) { StringBuilder sb = new StringBuilder( ) ;
sb.append ( " -> " ) ;
// go through the possible moves, and make a prompt string.
for ( Move m : Move.values ( ) ) {
sb.append ( m.ordinal ( ) + 1 ) .append ( ") " ) .append ( m.name ( ) ) .append ( " " ) ;
}
// include a quit option.
sb.append ( " q) Quit" ) ;
return sb.toString ( ) ;
}
/**
* get some input from the human.
* @param scanner What we read the input from.
* @param prompt What we prompt the user for.
* @param defval If the user just presses enter, what do we return.
* @return the value the user entered (just the first char of it).
*/
private static final char prompt
( Scanner scanner,
String prompt,
char defval
) { // prompt the user.
System .
out .
print ( prompt
+ ": " ) ; // it would be nice to use a Console or something, but running from Eclipse there isn't one.
String input
= scanner.
nextLine ( ) ; if ( input.isEmpty ( ) ) {
return defval;
}
return input.charAt ( 0 ) ;
}
/**
* Simple conditional that prompts the user to play again, and returns true if we should.
* @param scanner the scanner to get the input from
* @return true if the user wants to continue.
*/
private static boolean playAgain( Scanner scanner) {
return ( 'n' != prompt( scanner, "\n Play Again (y/n)?" , 'y' ) ) ;
}
/**
* Prompt the user for a move.
* @param scanner The scanner to get the move from
* @return the move the user wants to do.
*/
private static Move getHumanMove( Scanner scanner) {
// loop until we get some valid input.
do {
char val = prompt( scanner, MOVEPROMPT, 'q' ) ;
if ( 'q' == val) {
// user does not want to make a move... or just presses enter too fast.
return null ;
}
int num = ( val - '0' ) - 1 ;
if ( num >= 0 && num < Move.values ( ) .length ) {
// we got valid input. Return.
return Move.values ( ) [ num] ;
}
System .
out .
println ( "Invalid move " + val
) ; } while ( true ) ;
}
/**
* Run the game.... Good Luck!
* @param args these are ignored.
*/
public static void main
( String [ ] args
) { final Move[ ] moves = Move.values ( ) ;
final Scanner scanner
= new Scanner
( System .
in ) ; int htotal = 0 ;
int ctotal = 0 ;
do {
System .
out .
println ( "\n Best of 3.... Go!" ) ; int hscore = 0 ;
int cscore = 0 ;
bestofthree: do {
final Move computer = moves[ rand.nextInt ( moves.length ) ] ;
final Move human = getHumanMove( scanner) ;
if ( human == null ) {
System .
out .
println ( "Human quits Best-of-3..." ) ; // quit the best-of-three loop
break bestofthree;
}
if ( human == computer) {
System .
out .
printf ( " DRAW... play again!! (%s same as %s)\n " , human, computer
) ; } else if ( human.beats ( computer) ) {
hscore++;
System .
out .
printf ( " HUMAN beats Computer (%s beats %s)\n " , human, computer
) ; } else {
cscore++;
System .
out .
printf ( " COMPUTER beats Human (%s beats %s)\n " , computer, human
) ; }
// play until someone scores 2....
} while ( hscore != 2 && cscore != 2 ) ;
// track the total scores.
if ( hscore == 2 ) {
htotal++;
} else {
// perhaps the human quit while ahead, computer wins that too.
ctotal++;
}
String winner
= hscore
== 2 ? "Human" : "Computer" ; System .
out .
printf ( "\n %s\n **** %s wins Best-Of-Three (Human=%d, Computer=%d - game total is Human=%d Computer=%d)\n " ,
winner.toUpperCase ( ) , winner, hscore, cscore, htotal, ctotal) ;
// Shall we play again?
} while ( playAgain( scanner) ) ;
System .
out .
printf ( "Thank you for playing. The final game score was Human=%d and Computer=%d\n " , htotal, ctotal
) ;
}
}
aW1wb3J0IGphdmEudXRpbC5BcnJheXM7CmltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOwppbXBvcnQgamF2YS51dGlsLlNjYW5uZXI7CgovKioKICogUm9jayBQYXBlciBTY2lzc29ycyBMaXphcmQgU3BvY2sKICogPHA+CiAqIGh0dHA6Ly9lLi4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5hLm9yZy93aWtpL1JvY2stcGFwZXItc2Npc3NvcnMtbGl6YXJkLVNwb2NrCiAqIDxwPgogKiBJbnRlcmZhY2UgZm9yIGEgaHVtYW4gdG8gcGxheSBhZ2FpbnN0IHRoZSBjb21wdXRlci4KICovCmNsYXNzIElkZW9uZSB7CgogICAgLyoqCiAgICAgKiBTZXQgdXAgdGhlIHJ1bGVzIGZvciB0aGUgZ2FtZS4KICAgICAqIFdoYXQgYXJlIHRoZSBtb3ZlcywgYW5kIHdoYXQgYmVhdHMgd2hhdCEKICAgICAqLwogICAgcHVibGljIGVudW0gTW92ZSB7CiAgICAgICAgUm9jaywgUGFwZXIsIFNjaXNzb3JzLCBMaXphcmQsIFNwb2NrOwoKICAgICAgICBzdGF0aWMgewogICAgICAgICAgICBSb2NrLndpbGxCZWF0KFNjaXNzb3JzLCBMaXphcmQpOwogICAgICAgICAgICBQYXBlci53aWxsQmVhdChSb2NrLFNwb2NrKTsKICAgICAgICAgICAgU2Npc3NvcnMud2lsbEJlYXQoUGFwZXIsIExpemFyZCk7CiAgICAgICAgICAgIExpemFyZC53aWxsQmVhdChTcG9jayxQYXBlcik7CiAgICAgICAgICAgIFNwb2NrLndpbGxCZWF0KFJvY2ssU2Npc3NvcnMpOwogICAgICAgIH0KCiAgICAgICAgLy8gd2hhdCB3aWxsIHRoaXMgbW92ZSBiZWF0IC0gcG9wdWxhdGVkIGluIHN0YXRpYyBpbml0aWFsaXplcgogICAgICAgIHByaXZhdGUgTW92ZVtdIGliZWF0OwogICAgICAgIHByaXZhdGUgdm9pZCB3aWxsQmVhdChNb3ZlLi4ubW92ZXMpIHsKICAgICAgICAgICAgaWJlYXQgPSBtb3ZlczsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiB0cnVlIGlmIHRoaXMgTW92ZSB3aWxsIGJlYXQgdGhlIHN1cHBsaWVkIG1vdmUKICAgICAgICAgKiBAcGFyYW0gbW92ZSB0aGUgbW92ZSB3ZSBob3BlIHRvIGJlYXQKICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgd2UgYmVhdCB0aGF0IG1vdmUuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGJvb2xlYW4gYmVhdHMoTW92ZSBtb3ZlKSB7CiAgICAgICAgICAgIC8vIHVzZSBiaW5hcnkgc2VhcmNoIGluIGNhc2Ugc29tZW9uZSB3YW50cyB0byBzZXQgdXAgY3JhenkgcnVsZXMuCiAgICAgICAgICAgIHJldHVybiBBcnJheXMuYmluYXJ5U2VhcmNoKGliZWF0LCBtb3ZlKSA+PSAwOwogICAgICAgIH0KCiAgICB9ICAgIAoKICAgIC8vIFRoaXMgaXMgYSBwcm9tcHQgdGhhdCBpcyBzZXQgdXAganVzdCBvbmNlIHBlciBKVk0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBNT1ZFUFJPTVBUID0gYnVpbGRPcHRpb25zKCk7CiAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgYnVpbGRPcHRpb25zKCkgewogICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgIHNiLmFwcGVuZCgiICAgICAtPiAiKTsKICAgICAgICAvLyBnbyB0aHJvdWdoIHRoZSBwb3NzaWJsZSBtb3ZlcywgYW5kIG1ha2UgYSBwcm9tcHQgc3RyaW5nLgogICAgICAgIGZvciAoTW92ZSBtIDogTW92ZS52YWx1ZXMoKSkgewogICAgICAgICAgICBzYi5hcHBlbmQobS5vcmRpbmFsKCkgKyAxKS5hcHBlbmQoIikgIikuYXBwZW5kKG0ubmFtZSgpKS5hcHBlbmQoIiAiKTsKICAgICAgICB9CiAgICAgICAgLy8gaW5jbHVkZSBhIHF1aXQgb3B0aW9uLgogICAgICAgIHNiLmFwcGVuZCgiIHEpIFF1aXQiKTsKICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKICAgIH0KCiAgICAvKioKICAgICAqIGdldCBzb21lIGlucHV0IGZyb20gdGhlIGh1bWFuLgogICAgICogQHBhcmFtIHNjYW5uZXIgV2hhdCB3ZSByZWFkIHRoZSBpbnB1dCBmcm9tLgogICAgICogQHBhcmFtIHByb21wdCBXaGF0IHdlIHByb21wdCB0aGUgdXNlciBmb3IuCiAgICAgKiBAcGFyYW0gZGVmdmFsIElmIHRoZSB1c2VyIGp1c3QgcHJlc3NlcyBlbnRlciwgd2hhdCBkbyB3ZSByZXR1cm4uCiAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSB0aGUgdXNlciBlbnRlcmVkIChqdXN0IHRoZSBmaXJzdCBjaGFyIG9mIGl0KS4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhciBwcm9tcHQoU2Nhbm5lciBzY2FubmVyLCBTdHJpbmcgcHJvbXB0LCBjaGFyIGRlZnZhbCkgewogICAgICAgIC8vIHByb21wdCB0aGUgdXNlci4KICAgICAgICBTeXN0ZW0ub3V0LnByaW50KHByb21wdCArICI6ICIpOwogICAgICAgIC8vIGl0IHdvdWxkIGJlIG5pY2UgdG8gdXNlIGEgQ29uc29sZSBvciBzb21ldGhpbmcsIGJ1dCBydW5uaW5nIGZyb20gRWNsaXBzZSB0aGVyZSBpc24ndCBvbmUuCiAgICAgICAgU3RyaW5nIGlucHV0ID0gc2Nhbm5lci5uZXh0TGluZSgpOwogICAgICAgIGlmIChpbnB1dC5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmV0dXJuIGRlZnZhbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGlucHV0LmNoYXJBdCgwKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNpbXBsZSBjb25kaXRpb25hbCB0aGF0IHByb21wdHMgdGhlIHVzZXIgdG8gcGxheSBhZ2FpbiwgYW5kIHJldHVybnMgdHJ1ZSBpZiB3ZSBzaG91bGQuCiAgICAgKiBAcGFyYW0gc2Nhbm5lciB0aGUgc2Nhbm5lciB0byBnZXQgdGhlIGlucHV0IGZyb20KICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdXNlciB3YW50cyB0byBjb250aW51ZS4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBwbGF5QWdhaW4oU2Nhbm5lciBzY2FubmVyKSB7CiAgICAgICAgcmV0dXJuICgnbicgIT0gcHJvbXB0KHNjYW5uZXIsICJcblBsYXkgQWdhaW4gKHkvbik/IiwgJ3knKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm9tcHQgdGhlIHVzZXIgZm9yIGEgbW92ZS4KICAgICAqIEBwYXJhbSBzY2FubmVyIFRoZSBzY2FubmVyIHRvIGdldCB0aGUgbW92ZSBmcm9tCiAgICAgKiBAcmV0dXJuIHRoZSBtb3ZlIHRoZSB1c2VyIHdhbnRzIHRvIGRvLgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBNb3ZlIGdldEh1bWFuTW92ZShTY2FubmVyIHNjYW5uZXIpIHsKICAgICAgICAvLyBsb29wIHVudGlsIHdlIGdldCBzb21lIHZhbGlkIGlucHV0LgogICAgICAgIGRvIHsKICAgICAgICAgICAgY2hhciB2YWwgPSBwcm9tcHQoc2Nhbm5lciwgTU9WRVBST01QVCwgJ3EnKTsKICAgICAgICAgICAgaWYgKCdxJyA9PSB2YWwpIHsKICAgICAgICAgICAgICAgIC8vIHVzZXIgZG9lcyBub3Qgd2FudCB0byBtYWtlIGEgbW92ZS4uLiBvciBqdXN0IHByZXNzZXMgZW50ZXIgdG9vIGZhc3QuCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBpbnQgbnVtID0gKHZhbCAtICcwJykgLSAxOwogICAgICAgICAgICBpZiAobnVtID49IDAgJiYgbnVtIDwgTW92ZS52YWx1ZXMoKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIC8vIHdlIGdvdCB2YWxpZCBpbnB1dC4gUmV0dXJuLgogICAgICAgICAgICAgICAgcmV0dXJuIE1vdmUudmFsdWVzKClbbnVtXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkludmFsaWQgbW92ZSAiICsgdmFsKTsKICAgICAgICB9IHdoaWxlICh0cnVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJ1biB0aGUgZ2FtZS4uLi4gR29vZCBMdWNrIQogICAgICogQHBhcmFtIGFyZ3MgdGhlc2UgYXJlIGlnbm9yZWQuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICBmaW5hbCBSYW5kb20gcmFuZCA9IG5ldyBSYW5kb20oKTsKICAgICAgICBmaW5hbCBNb3ZlW10gbW92ZXMgPSBNb3ZlLnZhbHVlcygpOwogICAgICAgIGZpbmFsIFNjYW5uZXIgc2Nhbm5lciA9IG5ldyBTY2FubmVyKFN5c3RlbS5pbik7CiAgICAgICAgaW50IGh0b3RhbCA9IDA7CiAgICAgICAgaW50IGN0b3RhbCA9IDA7CiAgICAgICAgZG8gewogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuQmVzdCBvZiAzLi4uLiBHbyEiKTsKICAgICAgICAgICAgaW50IGhzY29yZSA9IDA7CiAgICAgICAgICAgIGludCBjc2NvcmUgPSAwOwogICAgICAgICAgICBiZXN0b2Z0aHJlZTogZG8gewogICAgICAgICAgICAgICAgZmluYWwgTW92ZSBjb21wdXRlciA9IG1vdmVzW3JhbmQubmV4dEludChtb3Zlcy5sZW5ndGgpXTsKICAgICAgICAgICAgICAgIGZpbmFsIE1vdmUgaHVtYW4gPSBnZXRIdW1hbk1vdmUoc2Nhbm5lcik7CiAgICAgICAgICAgICAgICBpZiAoaHVtYW4gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiSHVtYW4gcXVpdHMgQmVzdC1vZi0zLi4uIik7CiAgICAgICAgICAgICAgICAgICAgLy8gcXVpdCB0aGUgYmVzdC1vZi10aHJlZSBsb29wCiAgICAgICAgICAgICAgICAgICAgYnJlYWsgYmVzdG9mdGhyZWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaHVtYW4gPT0gY29tcHV0ZXIpIHsKICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50ZigiICBEUkFXLi4uIHBsYXkgYWdhaW4hISAoJXMgc2FtZSBhcyAlcylcbiIsIGh1bWFuLCBjb21wdXRlcik7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGh1bWFuLmJlYXRzKGNvbXB1dGVyKSkgewogICAgICAgICAgICAgICAgICAgIGhzY29yZSsrOwogICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRmKCIgIEhVTUFOIGJlYXRzIENvbXB1dGVyICglcyBiZWF0cyAlcylcbiIsIGh1bWFuLCBjb21wdXRlcik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGNzY29yZSsrOwogICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRmKCIgIENPTVBVVEVSIGJlYXRzIEh1bWFuICglcyBiZWF0cyAlcylcbiIsIGNvbXB1dGVyLCBodW1hbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBwbGF5IHVudGlsIHNvbWVvbmUgc2NvcmVzIDIuLi4uCiAgICAgICAgICAgIH0gd2hpbGUgKGhzY29yZSAhPSAyICYmIGNzY29yZSAhPSAyKTsKCiAgICAgICAgICAgIC8vIHRyYWNrIHRoZSB0b3RhbCBzY29yZXMuCiAgICAgICAgICAgIGlmIChoc2NvcmUgPT0gMikgewogICAgICAgICAgICAgICAgaHRvdGFsKys7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBwZXJoYXBzIHRoZSBodW1hbiBxdWl0IHdoaWxlIGFoZWFkLCBjb21wdXRlciB3aW5zIHRoYXQgdG9vLgogICAgICAgICAgICAgICAgY3RvdGFsKys7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFN0cmluZyB3aW5uZXIgPSBoc2NvcmUgPT0gMiA/ICJIdW1hbiIgOiAiQ29tcHV0ZXIiOwogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50ZigiXG4gJXNcbiAqKioqICVzIHdpbnMgQmVzdC1PZi1UaHJlZSAoSHVtYW49JWQsIENvbXB1dGVyPSVkIC0gZ2FtZSB0b3RhbCBpcyBIdW1hbj0lZCBDb21wdXRlcj0lZClcbiIsCiAgICAgICAgICAgICAgICAgICAgd2lubmVyLnRvVXBwZXJDYXNlKCksIHdpbm5lciwgaHNjb3JlLCBjc2NvcmUsIGh0b3RhbCwgY3RvdGFsKTsKCiAgICAgICAgICAgIC8vIFNoYWxsIHdlIHBsYXkgYWdhaW4/CiAgICAgICAgfSB3aGlsZSAocGxheUFnYWluKHNjYW5uZXIpKTsKCiAgICAgICAgU3lzdGVtLm91dC5wcmludGYoIlRoYW5rIHlvdSBmb3IgcGxheWluZy4gVGhlIGZpbmFsIGdhbWUgc2NvcmUgd2FzIEh1bWFuPSVkIGFuZCBDb21wdXRlcj0lZFxuIiwgaHRvdGFsLCBjdG90YWwpOwoKICAgIH0KCn0=