如何更改代码以提高效率



在这段代码中是在电脑和用户之间玩Rock Paper Scissors。我的代码运行得很好,但是,我正在想一个更好的方法让它询问用户是否愿意再次播放。如果是,它将再次启动程序,如果不是,它将停止。我的"是";似乎有效,但"不"会停止,不会一直通过。关于如何做到这一点,有什么建议或提示吗?我会尝试加入一个不同的while循环,但没有成功。do循环对这种情况有好处吗?谢谢

//import scanner
import java.util.Scanner;
import java.util.*;
//declare variables and main methods
class Rock {
Scanner scan = new Scanner(System.in);
Random generator = new Random();
String response, name;
char choice;
int rounds, computerChoice, userScore, computerScore;
boolean playIntro = true;
boolean playGame = true;
//this method will run the entire progrma
public void playRPS(){

//while loop for beginning of game
while(playIntro){
System.out.println("This is a game of Rock Paper Scissors!");
System.out.println("Please enter your name: ");
name = scan.nextLine();
//while loop for the actual part of the game
while(playGame){
System.out.println("Type R (Rock), P (Paper), or S (Scissors): ");
choice = scan.nextLine().charAt(0);
computerChoice = generator.nextInt(3)+1;
//using switch and case for each choice
switch (choice){
//case for Rock
case 'R':
if(computerChoice==1){
System.out.println("Tie between you and the computer! Go again.");
break;
}
else{
if(computerChoice==2){
System.out.println("The computer beat you this round");
computerScore++;
break;
}
else{
System.out.println("You won this round");
userScore++;
break;
}
}
//case for Paper
case 'P':
if(computerChoice==2){
System.out.println("Tie between you and the computer! Go again.");
break;
}
else{
if(computerChoice==3){
System.out.println("The computer beat you this round");
computerScore++;
break;
}
else{
System.out.println("You won this round");
userScore++;
break;
}
}
//case for Scissors
case 'S':
if(computerChoice==3){
System.out.println("Tie between you and the computer! Go again.");
break;
}
else{
if(computerChoice==1){
System.out.println("The computer beat you this round");
computerScore++;
break;
}
else{
System.out.println("You won this round");
userScore++;
break;
}
}
}
System.out.println("You have "+userScore+" points and the computer has "+computerScore+" points");
if (userScore==5){
System.out.println("nOut of 5 rounds, You beat the computer!");
playGame = false;
}
else if (computerScore==5){
System.out.println("nOut of 5 rounds, The computer beat you.");
playGame = false;
}
}
askUser();
}  
}
public void askUser(){
System.out.println("nDo you want to play this Rock Paper Scissors again? Type yes: ");
response = scan.nextLine();
if (response.equalsIgnoreCase("yes")){
playGame = true;
userScore=0;
computerScore=0;
}
else{
playGame = false;
scan.nextLine();
}
}
public static void main() {
Rock prog = new Rock();
prog.playRPS();
}
}

我不会说这一定更高效甚至更好,但它更简洁。它的主要元素是。

  • 使用Lambdas根据选择的动作决定获胜者
  • 使用地图根据用户的移动调用适当的Lambda。lambda然后评估这两个动作以决定结果
  • 为了简单起见,移动是按数字选择的

当然,重要的是你的代码能正常工作。

import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;
import java.util.function.Function;
public class RockPaperScissors {

final static int PAPER = 1;
final static int ROCK = 2;
final static int SCISSORS = 3;

// the next two declarations allows the previous three to take on any values.
private Set<Integer> allowedMoves = Set.of(PAPER, ROCK, SCISSORS);
private List<String> moves = List.of("PAPER", "ROCK", "SCISSORS");
private String ROCK_WINS_MSG = "Rock crushes scissors";
private String SCISSORS_WINS_MSG = "Scissors cuts paper";
private String PAPER_WINS_MSG = "Paper covers rock";
private String COMPUTER_WINS = ", computer wins!";
private String YOU_WIN = ", you win!";

private Function<Integer, String> CHECK_PAPER =
(c) -> c == PAPER ? "It's a tie!" :
c == ROCK ? PAPER_WINS_MSG + YOU_WIN :
SCISSORS_WINS_MSG + COMPUTER_WINS;
private Function<Integer, String> CHECK_ROCK =
(c) -> c == ROCK ? "It's a tie!" :
c == SCISSORS ? ROCK_WINS_MSG + YOU_WIN :
PAPER_WINS_MSG + COMPUTER_WINS;
private Function<Integer, String> CHECK_SCISSORS =
(c) -> c == SCISSORS ? "It's a tie!" :
c == PAPER ? SCISSORS_WINS_MSG + YOU_WIN :
ROCK_WINS_MSG + COMPUTER_WINS;

private Map<Integer, Function<Integer, String>> evalUser =
Map.of(PAPER, CHECK_PAPER, ROCK, CHECK_ROCK, SCISSORS,
CHECK_SCISSORS);

public static void main(String[] args) {
new RockPaperScissors().play();
}

public void play() {
Random r = new Random();
Scanner scan = new Scanner(System.in);

while (true) {
System.out.printf("%n%d : %s%n%d : %s%n%d : %s%n%s%n",
PAPER, "PAPER", ROCK, "ROCK", SCISSORS,
"SCISSORS", "Any other integer to quit.");
System.out.print("Your move! ");
String str = scan.nextLine();
int move;
try {
move = Integer.parseInt(str);
if (!allowedMoves.contains(move)) {
break;
}
} catch (IllegalArgumentException ie) {
System.out.println("Only integers permitted.");
continue;
}
System.out.println("nYou chose " + moves.get(move - 1));
int cmove = r.nextInt(3);

System.out.println(
"The computer chooses " + moves.get(cmove));
System.out.println(evalUser.get(move).apply(cmove + 1));

}
System.out.println("nGame over!");

}
}

对于您的代码,建议您查看切换案例。每个案例的代码实际上是相同的。我会寻找相似之处,并将评估作为一个单一的方法(这是我在代码中没有真正做到的(。然后,在每种情况下,使用适当的参数调用该方法。一个这样的论点是";"计算机";或";你"基于上下文。

没有任何东西会将playIntro设置为false,因此外部循环永远不会终止。

askUser()playGame设置为false时,内部循环终止,并且您陷入了保持循环的外部循环中。

我看不出有任何理由存在外循环。你只需要打印介绍并询问玩家的名字一次。

与其说这是一个"效率"问题,不如说是一个正确性问题。


顺便说一句,最好让askUser()返回true/false值,而不是设置成员变量。然后您可以直接在while表达式中使用它。

playRPS()的整体结构看起来像:

public void playRPS() {
... print intro, ask name ...
do {
... play one game ...
} while (askUser());
}

最新更新