I'm writing a section of code for a Rock, Paper, Scissors game. I am writing a method that returns 1, 0 or -1 depending on wether the computer wins, it's a tie, or the user wins, respectively. I have this code so far:
private int nextPlay(char computerMove, char playerMove) {
switch (playerMove) {
case 'R': switch (computerMove) {
case 'R': return 0;
case 'P': return 1;
case 'S': return -1;
}
case 'P': switch (computerMove) {
case 'R': return -1;
case 'P': return 0;
case 'S': return 1;
}
case 'S': switch (computerMove) {
case 'R': return 1;
case 'P': return -1;
case 'S': return 0;
}
}
}
It throws a "Missing Return Statement" at me at the last bracket. Any suggestions?
P.S. the only options available for both computerMove and playerMove are R, P and S!
Others are telling you to add default to your switch statements. Not needed at all in this case, though it's a good general rule to follow.
However, you need to consider what should happen if playerMove and/or computerMove doesn't have one of the 3 expected values ('R', 'P', or 'S').
If computerMove doesn't, you'd want the logic flow to exit the outer switch statement, rather than fall through to the next case (though technically they'd all just fall through then, but still), so add a break in each outer case.
If that breaks out, or if playerMove doesn't have valid value, then logic flow gets to end of method, and there is no return statement there. That is your compilation error.
Best solution here, since you hopefully can't get into that situation, is to declare that to be exceptional, i.e. throw an Exception.
You code could be:
private int nextPlay(char computerMove, char playerMove) {
switch (playerMove) {
case 'R':
switch (computerMove) {
case 'R': return 0;
case 'P': return 1;
case 'S': return -1;
}
break;
case 'P':
switch (computerMove) {
case 'R': return -1;
case 'P': return 0;
case 'S': return 1;
}
break;
case 'S':
switch (computerMove) {
case 'R': return 1;
case 'P': return -1;
case 'S': return 0;
}
break;
}
throw new IllegalStateException("Oops! I messed up!!");
}
But it's better with more descriptive error messages:
private int nextPlay(char computerMove, char playerMove) {
switch (playerMove) {
case 'R':
switch (computerMove) {
case 'R': return 0;
case 'P': return 1;
case 'S': return -1;
}
throw new IllegalArgumentException("Invalid computer move: " + computerMove);
case 'P':
switch (computerMove) {
case 'R': return -1;
case 'P': return 0;
case 'S': return 1;
}
throw new IllegalArgumentException("Invalid computer move: " + computerMove);
case 'S':
switch (computerMove) {
case 'R': return 1;
case 'P': return -1;
case 'S': return 0;
}
throw new IllegalArgumentException("Invalid computer move: " + computerMove);
}
throw new IllegalArgumentException("Invalid player move: " + playerMove);
}
Now, you could add those throw statements in a default clause instead. Same result.
private int nextPlay(char computerMove, char playerMove) {
switch (playerMove) {
case 'R':
switch (computerMove) {
case 'R': return 0;
case 'P': return 1;
case 'S': return -1;
default: throw new IllegalArgumentException("Invalid computer move: " + computerMove);
}
case 'P':
switch (computerMove) {
case 'R': return -1;
case 'P': return 0;
case 'S': return 1;
default: throw new IllegalArgumentException("Invalid computer move: " + computerMove);
}
case 'S':
switch (computerMove) {
case 'R': return 1;
case 'P': return -1;
case 'S': return 0;
default: throw new IllegalArgumentException("Invalid computer move: " + computerMove);
}
default: throw new IllegalArgumentException("Invalid player move: " + playerMove);
}
}
my suggestion
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
int x=nextPlay('R','P');
System.out.println(x);
}
private static int nextPlay(char computerMove, char playerMove)
{
if(playerMove=='R')
{
if(computerMove=='R')
return 0;
else if(computerMove=='P')
return 1;
else
return -1;
}
else if(playerMove=='P')
{
if(computerMove=='R')
return -1;
else if(computerMove=='P')
return 0;
else
return 1;
}
else
{
if(computerMove=='R')
return 1;
else if(computerMove=='P')
return -1;
else
return 0;
}
}
Thanks so much everyone! I decided to simply set one of the cases in each switch statement to default (keeping track of which char it is of course) and it resolved the issue.
I know this can cause some issues if the char is anything but the intended one, but my teacher says it is ok and I would use a different method (as suggested) next time!
Related
I want to convert bytecode type to java using an api instead of manually coding for it, Is there any api for that? Since the requirement goes high I have to keep adding the convertion type manually which is bit tedious.
[Ljava/lang/StackTraceElement;
J[Ljava/lang/StackTraceElement;
Ljava/util/Map;
Ljava/util/LinkedList;
Ljava/lang/String;
Ljava/net/URL;
Z
Ljava/lang/String;
[Ljava/net/URL;
Previously I used code it manually as below.
private static Type getType(final char[] buf, final int off) {
int len;
switch (buf[off]) {
case 'V':
return VOID_TYPE;
case 'Z':
return BOOLEAN_TYPE;
case 'C':
return CHAR_TYPE;
case 'B':
return BYTE_TYPE;
case 'S':
return SHORT_TYPE;
case 'I':
return INT_TYPE;
case 'F':
return FLOAT_TYPE;
case 'J':
return LONG_TYPE;
case 'D':
return DOUBLE_TYPE;
}
}
And when I used asm library for this,
Type.getArgumentTypes(desc);
it showed me an error as below.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 44
at org.objectweb.asm.Type.getArgumentTypes(Unknown Source)
I would add a method getTypeLength:
private static int getTypeLength(final char[] buf, final int off) {
switch (buf[off]) {
case 'V':
case 'Z':
case 'C':
case 'B':
case 'S':
case 'I':
case 'F':
case 'J':
case 'D':
return 1;
case 'L':
{
int i = offs+1;
while (buf[i] != ';') {
++i;
}
return i-offs+1;
}
case '[':
return getTypeLength(buf, off+1)+1;
}
}
And then:
private static Type getType(final char[] buf, final int off) {
int len;
switch (buf[off]) {
case 'V':
return VOID_TYPE;
case 'Z':
return BOOLEAN_TYPE;
case 'C':
return CHAR_TYPE;
case 'B':
return BYTE_TYPE;
case 'S':
return SHORT_TYPE;
case 'I':
return INT_TYPE;
case 'F':
return FLOAT_TYPE;
case 'J':
return LONG_TYPE;
case 'D':
return DOUBLE_TYPE;
case 'L':
{
int len = getTypeLength(buf, offs);
String name = new String(buf, offs+1, len-2).replace('/', '.');
return Class.forName(name);
}
case '[':
int len = getTypeLength(buf, offs);
return Class.forName(new String(buf, offs, len));
}
}
If you are using asm it would be like this,
Type.getType(desc).getClassName();
Type class from asm library and its static method getType which accepts a string will convert bytecode type to java type.
I have to create a scrabble word search for my data structures class. I haven't reached the actual search yet. First, I need to create a bag of scrabble tiles. However, I keep getting errors when trying to add ScrabbleTile objects to my bag.
I have four classes: ScrabbleTile, ScrabbleBag, ScrabbleHand, and WordFinder.
Here is ScrabbleTile:
public class ScrabbleTile {
private char letter;
private int points;
ScrabbleTile (char letter)
{
this.letter = letter;
switch (letter)
{
case '_':
points = 0;
case 'e':
case 'a':
case 'i':
case 'o':
case 'n':
case 'r':
case 't':
case 'l':
case 's':
case 'u':
points = 1; break;
case 'd':
case 'g':
points = 2; break;
case 'b':
case 'c':
case 'm':
case 'p':
points = 3; break;
case 'f':
case 'h':
case 'v':
case 'w':
case 'y':
points = 4; break;
case 'k':
points = 5; break;
case 'j':
case 'x':
points = 8; break;
case 'q':
case 'z':
points = 10; break;
default: System.out.println("Incorrect character. Please enter a lowercase letter, a-z.");
break;
}
}
public char getLetter()
{
return letter;
}
public int getPoints()
{
return points;
}
}
Here is my ScrabbleBag class:
import DSLib.*;
public class ScrabbleBag {
private BagADT<ScrabbleTile> letterBag;
ScrabbleBag()
{
letterBag = new Bag<>();
for (int i = 0; i < 12; i++) {letterBag.add(ScrabbleTile('e'));}
}
}
In the ScrabbleBag constructor, I'm trying to add the correct number of each letter tile, starting with "e". Netbeans had a few suggestions which I tried, but then it was telling me the line syntax was wrong, after creating a few more instance variables in the ScrabbleBag class. How can I properly add ScrabbleTile objects to the bag?
My professor was very clear that we cannot use methods ahead of what we've gone over in class. Thanks in advance!
I think you missed new when create ScrabbleTitle object
for (int i = 0; i < 12; i++) {
letterBag.add(new ScrabbleTile('e'));
}
To create a ScrabbleTile you need the new keyword:
for (int i = 0; i < 12; i++) {
ScrabbleTile tile = new ScrabbleTile('e');
letterBag.add(tile);
}
Im trying to replace each letter with a digit using the international standard letter/number mapping. I got my output to run correctly however, how do get the dashes in the phone number to appear automatically in the output? For example, if I enter 1800Flowers it prints out as 18003569377. How do I get it to print out as 1-800-3569377 without using regular expressions?
import java.util.Scanner;
public class PhoneKeypad {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
//while loop keeps the program running until the user enters quit
while (true) {
System.out.println("\nEnter a phone number or quit to exit:");
String phoneNumber = input.next();
if (phoneNumber.equalsIgnoreCase("quit")) {
System.out.print("\nProgrammed by me");
return;
}
//checks if the phone number entered is at least 8 digits
if (phoneNumber.length() < 8) {
System.out.println("Invalid Phone Number");
} else {
System.out.println(getNumber(phoneNumber));
}
}
}
//method converts all letters in the phone number to digits
public static String getNumber(String phoneNumber) {
int keypadNum = 0;
for (int i = 0; i < phoneNumber.length(); i++) {
char letter = phoneNumber.charAt(i);
if (Character.isAlphabetic(letter)) {
letter = Character.toUpperCase(letter);
switch (letter) {
case 'A':
case 'B':
case 'C':
keypadNum = 2;
break;
case 'D':
case 'E':
case 'F':
keypadNum = 3;
break;
case 'G':
case 'H':
case 'I':
keypadNum = 4;
break;
case 'J':
case 'K':
case 'L':
keypadNum = 5;
break;
case 'M':
case 'N':
case 'O':
keypadNum = 6;
break;
case 'P':
case 'Q':
case 'R':
case 'S':
keypadNum = 7;
break;
case 'T':
case 'U':
case 'V':
keypadNum = 8;
break;
case 'W':
case 'X':
case 'Y':
case 'Z':
keypadNum = 9;
break;
default:
System.out.println("Invalid phone number");
}
phoneNumber = phoneNumber.substring(0, i) + keypadNum + phoneNumber.substring(i + 1);
}
}
return phoneNumber;
}
}
Expected Output:
You could use a regular expression with String.replaceAll. Remove the leading one, group the first three digits, the second three digits and the final group of digits. Something like
public static String formatNumber(String phoneNumber) {
if (phoneNumber.startsWith("1")) {
phoneNumber = phoneNumber.substring(1);
}
return phoneNumber.replaceAll("(\\d{3})(\\d{3})(\\d+)", "1-$1-$2-$3");
}
or
public static String formatNumber(String phoneNumber) {
return phoneNumber.replaceAll("1(\\d{3})(\\d{3})(\\d+)", "1-$1-$2-$3");
}
And then call it like
System.out.println(formatNumber(getNumber(phoneNumber)));
I ran it with 1800flowers and got (as expected)
1-800-356-9377
or without regular expressions like
public static String formatNumber(String phoneNumber) {
if (phoneNumber.startsWith("1")) {
phoneNumber = phoneNumber.substring(1);
}
return "1-".concat(phoneNumber.substring(0, 3)) //
.concat("-").concat(phoneNumber.substring(3, 6)) //
.concat("-").concat(phoneNumber.substring(6));
}
Before calling formatNumber, you can remove the dashes to normalize it with something like
public static String removeDashes(String phoneNumber) {
StringBuilder sb = new StringBuilder();
for (char ch : phoneNumber.toCharArray()) {
if (ch != '-') {
sb.append(ch);
}
}
return sb.toString();
}
Then
System.out.println(formatNumber(removeDashes(getNumber(phoneNumber))));
I'm solving the next technical question (Q1): http://blog.sdeskills.com/qotd-2016-oct-17-resistance-is-futile/
It's almost done, just one task is pending. Evaluate if the input is balanced or not. Checking if parenthesis are in order, that's done, but not to evaluate the tokens.
In a given sub-network cannot have a mix of series / parallel
connections, so (500+200|300) is not allowed.
This is my current code: https://repl.it/EC3i/2 Any idea about how to evaluate the previous expression as wrong?
Try this. This code checks operator sereis and also balanced parentheses.
static boolean isBalanced(String s) {
Deque<Character> operators = new LinkedList<>();
operators.push('#');
for (int i = 0; i < s.length(); ++i) {
if (operators.isEmpty()) return false;
char ch = s.charAt(i);
switch (ch) {
case '(': operators.push('#'); break;
case ')': operators.pop(); break;
case '+':
switch (operators.peek()) {
case '#': operators.pop(); operators.push(ch); break;
case '+': break;
default: return false;
}
break;
case '|':
switch (operators.peek()) {
case '#': operators.pop(); operators.push(ch); break;
case '|': break;
default: return false;
}
break;
}
}
return operators.size() == 1;
}
And JUnit test codes.
#Test
public void testIsBalanced() {
assertTrue(isBalanced("(2)"));
assertTrue(isBalanced("(2+3+3)"));
assertTrue(isBalanced("2+3+3"));
assertTrue(isBalanced("2+(4|5|5)+3"));
assertTrue(isBalanced("2+(4|(2+3+4)|5)+3"));
assertTrue(isBalanced("(2)+3()"));
assertFalse(isBalanced("(2"));
assertFalse(isBalanced("(2))"));
assertFalse(isBalanced("((2)"));
assertFalse(isBalanced("2|3+3"));
assertFalse(isBalanced("2+(4|5+5)+3"));
assertFalse(isBalanced("2+3|3"));
}
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
public int alphCheck(char check){
switch(check){
case 'a':
return 1;
break;
case 'b':
return 2;
break;
case 'c':
return 3;
break;
case 'd':
return 4;
break;
case 'e':
return 5;
break;
case 'f':
return 6;
break;
case 'g':
return 7;
break;
case 'h':
return 8;
break;
case 'i':
return 9;
break;
case 'j':
return 10;
break;
case 'k':
return 11;
break;
case 'l':
return 12;
break;
case 'm':
return 13;
break;
case 'n':
return 14;
break;
case 'o':
return 15;
break;
case 'p':
return 16;
break;
case 'q':
return 17;
break;
case 'r':
return 18;
break;
case 's':
return 19;
break;
case 't':
return 20;
break;
case 'u':
return 21;
break;
case 'v':
return 22;
break;
case 'w':
return 23;
break;
case 'x':
return 24;
break;
case 'y':
return 25;
break;
case 'z':
return 26;
break;
}
}
PS.This was done in another class
I want to be able to use this method in the main class, to input a letter, and return a number/index for that letter.
But I kept getting: this method must return a result of type int.
Very Confused. Please help. Thx.
Here's a question to consider: What happens if the inputted letter isn't one of the cases you described?
While you may know that you're only feeding in letters, the compiler doesn't know that, and because it can't figure out what to return if one of the cases you defined isn't hit, emits an error as a result. You'll need to put in a default case, so the compiler knows that the method is guaranteed to return something:
switch(check) {
case 'a':
...
default:
// return something or maybe print/throw an error
}
A better solution for this may be to use the fact that chars are just numbers in a different form. For example, 'a' is equivalent to the integer 97 (check out the table here for a table of characters and their ASCII numerical equivalents). So you can do a math trick to get equivalent results:
public int alphCheck(char check) {
return check - 'a' + 1;
}
you have to provide return type like return 0; at the end of your switch statement.or in default: case
switch(check) {
..
default:
return 0;
}