我正在开发一个基于用户输入值创建第4版DnD角色的程序,我想知道在继续我之前是否有更简单的方法继续我正在做的事情。我正在处理的程序的当前部分是让用户为他们的技能分配预先选择的值。我测试这部分的代码是:
import java.util.Scanner;
public class testCodeThree{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
standardArray(scan);
}
public static void standardArray(Scanner scan) {
System.out.println("----------------------------------------------------------");
System.out.println("Assign the numbers \"16\", \"14\", \"13\", \"12\", \"11\", and \"10\" to your skills.");
System.out.print("Enter your desired Str stat: ");
int userStr = scan.nextInt();
int strMod = 0;
int conMod = 0;
int dexMod = 0;
int intMod = 0;
int wisMod = 0;
int chaMod = 0;
if (userStr == 16 || userStr == 14 || userStr == 13 || userStr == 12 || userStr == 11 || userStr == 10) {
switch (userStr) {
case 16: // 16 Str, -- Con, -- Dex, -- Int, -- Wis, -- Cha
strMod = 3;
System.out.print("Enter your desired Con stat: ");
int userCon = scan.nextInt();
if (userCon == 14 || userCon == 13 || userCon == 12 || userCon == 11 || userCon == 10) {
switch (userCon) {
case 14: // 16 Str, 14 Con, -- Dex, -- Int, -- Wis, -- Cha
conMod = 2;
System.out.print("Enter your desired Dex stat: ");
int userDex = scan.nextInt();
if (userDex == 13 || userDex == 12 || userDex == 11 || userDex == 10) {
switch (userDex) {
case 13: // 16 Str, 14 Con, 13 Dex, -- Int, -- Wis, -- Cha
dexMod = 1;
System.out.print("Enter your desired Int stat: ");
int userInt = scan.nextInt();
if (userInt == 12 || userInt == 11 || userInt == 10) {
switch (userInt) {
case 12: // 16 Str, 14 Con, 13 Dex, 12 Int, -- Wis, -- Cha
intMod = 1;
System.out.print("Enter your desired Wis stat: ");
int userWis = scan.nextInt();
if (userWis == 11 || userWis == 10) {
switch (userWis) {
case 11: // 16 Str, 14 Con, 13 Dex, 12 Int, 11 Wis, 10 Cha
int userCha = 10;
System.out.println("Your Charisma stat is "+ userCha);
break;
default: // 16 Str, 14 Con, 13 Dex, 12 Int, 10 Wis, 11 Cha
userCha = 11;
System.out.println("Your Charisma stat is "+ userCha);
break;
}
} else {
System.out.println("----------------------------------------------------------");
System.out.println("Invalid input. Please try again.");
standardArray(scan);
}
break;
case 11:
break;
default:
break;
}
} else {
System.out.println("----------------------------------------------------------");
System.out.println("Invalid input. Please try again.");
standardArray(scan);
}
break;
case 12:
dexMod = 1;
break;
case 11:
// dexMod does not get updated here because the
// modifier is zero.
break;
default:
// dexMod does not get updated here because the
// modifier is zero.
break;
}
} else {
System.out.println("----------------------------------------------------------");
System.out.println("Invalid input. Please try again.");
standardArray(scan);
}
break;
case 13:
conMod = 1;
break;
case 12:
conMod = 1;
break;
case 11:
// conMod does not get updated here because the modifier
// is zero.
break;
default:
// conMod does not get updated here because the modifier
// is zero.
break;
}
} else {
System.out.println("----------------------------------------------------------");
System.out.println("Invalid input. Please try again.");
standardArray(scan);
}
break;
case 14:
strMod = 2;
break;
case 13:
strMod = 1;
break;
case 12:
strMod = 1;
break;
case 11:
// strMod does not get updated here because the modifier is
// zero.
break;
default:
// strMod does not get updated here because the modifier is
// zero.
break;
}
} else {
System.out.println("----------------------------------------------------------");
System.out.println("Invalid input. Please try again.");
standardArray(scan);
}
}
}
我最初的想法是要求用户为他们的Str stat输入他们想要的号码,然后使用嵌套的if语句/ switch语句来确定他们为以下统计信息输入的内容。我不想这样做的原因是因为我必须考虑所输入数字的每个可能顺序(16,14,13,12,11,10或16,13,14,11,10,12)等...),总共有很多if和case语句。有没有办法做到这一点,需要更少的线?
编辑:用户不能为多种技能输入相同的号码。
如果你有问题,请随时提问。
答案 0 :(得分:1)
是的,有很多方法可以做到这一点。
这是一种方法,使用Set来查看值是否唯一,并使用函数来避免重复代码。
private static boolean isValidStat(int userStat) {
return userStat >= 10 && userStat <= 16 && userStat != 15;
}
private static int readStat(Scanner scan, String stat, Set<Integer> seenStats) {
System.out.println("Enter your desired "+stat+" stat: ");
while(true) {
int userStat = scan.nextInt();
if(!isValidStat(userStat))
System.out.println("Not a valid choice - please try again:");
else if(seenStats.contains(userStat))
System.out.println("Already used that number - please try again:");
else {
seenStats.add(userStat);
return userStat;
}
}
}
private static int getMod(int userStat) {
switch(userStat) {
case 16: return 3;
case 14: return 2;
case 13: return 1;
case 12: return 1;
case 11: return 0;
case 10: return 0;
default: throw new RuntimeException("invalid userStat "+userStat); // shouldn't happen
}
}
public static void standardArray(Scanner scan) {
System.out.println("----------------------------------------------------------");
System.out.println("Assign the numbers \"16\", \"14\", \"13\", \"12\", \"11\", and \"10\" to your skills.");
Set<Integer> seenStats = new HashSet<Integer>();
int userStr = readStat(scan, "Str", seenStats);
int userCon = readStat(scan, "Con", seenStats);
int userDex = readStat(scan, "Dex", seenStats);
int userInt = readStat(scan, "Int", seenStats);
int userWis = readStat(scan, "Wis", seenStats);
int userCha = readStat(scan, "Cha", seenStats);
int strMod = getMod(userStr);
int conMod = getMod(userCon);
int dexMod = getMod(userDex);
int intMod = getMod(userInt);
int wisMod = getMod(userWis);
int chaMod = getMod(userCha);
/* do something with all these numbers, of course */
}
答案 1 :(得分:0)
你应该使用比较运算符来做一件事,即:
if(userStr <= 16 && userStr >= 10) {
而不是
if(userStr == 16 || userStr == 14 || userStr == 13 || userStr == 12 || userStr == 11 || userStr == 10)
答案 2 :(得分:0)
就我个人而言,我认为通过使用数组输入可以更有条理:
int[] stats = new int[6];
int current = 0;
for (;;) {
System.out.print("Enter your desired Str stat: ");
stats[current] = scan.nextInt();
然后你可以在循环中相互验证它们:
if (dndValidStarterStats(stats, current)) {
break;
} else {
System.out.println(
"Stats must be 10, 11, 12, 13, 14, or 16 and unique."
);
}
}
for (current++; ;) {
System.out.print("Enter your desired Con stat: ");
stats[current] = scan.nextInt();
...
}
public static boolean dndValidStarterStats(int[] stats, int current) {
if ( stats[current] > 16 ||
stats[current] == 15 ||
stats[current] < 10 ) {
return false;
}
/* specifically you get to do this */
for (int eval = 0; eval < current; eval++) {
if (stats[eval] == stats[current]) return false;
}
return true;
}
如果您为此创建了基本数据结构,则可以将条目逻辑缩短为单个循环:
public class Stat {
public final String name;
public int val = 0;
private Stat(String name) {
this.name = name;
}
public static final int STR = 0;
public static final int CON = 1;
public static final int DEX = 2;
public static final int INT = 3;
public static final int WIS = 4;
public static final int CHA = 5;
public static List<Stat> createStats() {
Stat[] stats = new Stat[6];
stats[STR] = new Stat("Strength");
stats[CON] = new Stat("Constitution");
stats[DEX] = new Stat("Dexterity");
stats[INT] = new Stat("Intelligence");
stats[WIS] = new Stat("Wisdom");
stats[CHA] = new Stat("Charisma");
return Collections.unmodifiableList(Arrays.asList(stats));
}
}
现在你可以这样做:
List<Stat> stats = Stat.createStats();
Stat entry;
for (int current = 0; current < stats.size();) {
entry = stats.get(current);
System.out.print(
"Enter your desired " + stats.get(current).name + " stat: "
);
stats[current].val = scan.nextInt();
if (dndValidStarterStats(stats, current)) {
current++;
} else {
System.out.println(
"Stats must be 10, 11, 12, 13, 14, or 16 and unique."
);
}
}
为每个索引定义一个常量,使您可以像stats.get(Stat.STR).val++;
一样从类似地图的O(1)中的数组中访问它们。我真的没有理由让现有的地图参与其中,因为你事先知道它究竟发生了什么,只有6个元素,你不需要在创建后修改它们。