Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 6 years ago.
Improve this question
I'm trying to recreate a printer in java,I'm fairly new to programming so I'm using huge if else blocks inside a single function to dictate the logic of the program, I'm noticing this is creating a mass of code inside the same function, I was wondering if there was a more eloquent/efficient way of doing this, printer class below. Logic for the printer isn't too important, but just to show anyway, one is a double sided printer one isn't, and logic is in charge of checking toner levels and making sure pages printed are in line with printer being double sided or not.
package com.company;
public class Printer {
private String name;
private double tonerLevel = 100;
private int ammountOfPaper;
private int numberOfPagesPrinted;
private boolean isDoubleSided;
public Printer(String name, double tonerLevel, int ammountOfPaper, boolean isDoubleSided) {
this.name = name;
if(tonerLevel >= 0 && tonerLevel <= 100) {
this.tonerLevel = tonerLevel;
}
this.ammountOfPaper = ammountOfPaper;
this.isDoubleSided = isDoubleSided;
}
private boolean isOutOfToner(double numberToPrint) {
if((tonerLevel - (numberToPrint / 2) < 0)) {
return true;
}
else {
return false;
}
}
private boolean isOutOfPaper(double numberToPrint) {
if(((ammountOfPaper - numberToPrint) < 0)) {
return true;
}
else {
return false;
}
}
private boolean twoSideNoPaperEven(double numberToPrint) {
if((ammountOfPaper - ((int) numberToPrint / 2)) < 0 ) {
return true;
}
else {
return false;
}
}
private boolean twoSideNoPaperOdd(double numberToPrint) {
if(((ammountOfPaper - ((int) numberToPrint / 2)) - 1) < 0) {
return true;
}
else {
return false;
}
}
public void printPages(double numberToPrint) {
if(isDoubleSided == false) {
if(tonerLevel == 0) {
System.out.println("Out of toner");
}
if(ammountOfPaper == 0) {
System.out.println("Out of Paper");
}
if(isOutOfToner(numberToPrint) && (tonerLevel != 0)) {
double difference = tonerLevel * 2;
numberToPrint = difference;
ammountOfPaper -= numberToPrint;
System.out.println("Will run out of toner after this print, able to print " + (int) numberToPrint +
" pages");
tonerLevel = 0;
}
if(isOutOfPaper(numberToPrint) && (ammountOfPaper != 0)) {
double different = ammountOfPaper - numberToPrint;
numberToPrint = numberToPrint + different;
System.out.println("Will run out of paper after this print, printing " + (int) numberToPrint + " pages");
ammountOfPaper = 0;
}
else if(!isOutOfToner(numberToPrint) && (!isOutOfPaper(numberToPrint))) {
ammountOfPaper -= numberToPrint;
tonerLevel = tonerLevel - (numberToPrint / 2);
showPages(numberToPrint);
}
}
else if(isDoubleSided = true) {
if (numberToPrint % 2 == 0) {
if(tonerLevel == 0) {
System.out.println("Out of Toner");
}
if(ammountOfPaper == 0) {
System.out.println("Out of Paper");
}
if(twoSideNoPaperEven(numberToPrint) && (ammountOfPaper != 0)) {
ammountOfPaper -= numberToPrint / 2;
System.out.println("There is no Paper");
}
else if(!twoSideNoPaperEven(numberToPrint)) {
tonerLevel = tonerLevel - (numberToPrint / 2);
ammountOfPaper -= numberToPrint / 2;
showPages(numberToPrint);
}
} else {
if(tonerLevel == 0) {
System.out.println("Out of Toner");
}
if(ammountOfPaper == 0) {
System.out.println("Out of Paper");
}
if(twoSideNoPaperOdd(numberToPrint) && (ammountOfPaper != 0)) {
System.out.println("There is no paper");
ammountOfPaper = (ammountOfPaper - ((int) numberToPrint / 2)) - 1;
ammountOfPaper = 0;
}
else if(!twoSideNoPaperOdd(numberToPrint)) {
tonerLevel = tonerLevel - (numberToPrint / 2);
ammountOfPaper = (ammountOfPaper - ((int) numberToPrint / 2)) - 1;
showPages(numberToPrint);
}
}
}
}
public void showPages(double numberToPrint) {
System.out.println("Printing " + (int) numberToPrint + " Pages, paper remaining is: " + this.ammountOfPaper
+ " Toner level is: " + this.tonerLevel);
}
public void refillToner() {
tonerLevel = 100;
}
public void refillPaper(int paper) {
if(paper > 50) {
System.out.println("Cannot put in more paper");
}
else {
this.ammountOfPaper += paper;
}
}
public int getAmmountOfPaper() {
return ammountOfPaper;
}
public double getTonerLevel() {
return tonerLevel;
}
public void setTonerLevel(double tonerLevel) {
this.tonerLevel = tonerLevel;
}
public void setAmmountOfPaper(int ammountOfPaper) {
this.ammountOfPaper = ammountOfPaper;
}
Changing the If Statements To as suggested by nicolas:
public void printPages(double numberToPrint) {
if(tonerLevel == 0) {
System.out.println("Out of toner");
return;
}
if(ammountOfPaper == 0) {
System.out.println("Out of Paper");
return;
}
if(isDoubleSided == false) {
Your if-statements are redundant. You can return directly the boolean value. It saves you 12 lines in your code. For example:
private boolean twoSideNoPaperOdd(double numberToPrint) {
return ((ammountOfPaper - ((int) numberToPrint / 2)) - 1) < 0;
}
There are few conditions repeated often with the same result. Again, it shortens the class by 24 lines.
if (tonerLevel == 0) {
System.out.println("Out of toner");
return; // leave the rest of method
}
if (ammountOfPaper == 0) {
System.out.println("Out of Paper");
return
}
Related
In this program, a randomly generated 2D array is populated with 1's or 0's and I attempt to find a path of 1's (no diagonal movement). I have got the program to work for smaller dimensions of the 2D array, but when the dimensions are too large, the error Exception in thread "main" java.lang.StackOverflowError occurs.
import java.util.Scanner;
import java.util.Random;
public class Daft {
private int counter = 0;
public static void main(String[] args) {
Daft punk = new Daft();
punk.run();
}
public void run() {
int ans;
int[][] array;
int[][] solvedPath;
do {
counter = 1;
array = populate(defineArray(firstDimension(),secondDimension()));
solvedPath = findPath(array);
System.out.println("Times before solvable: " + counter);
print(solvedPath);
ans = continuity();
}while(ans != 0);
}
public int[][] findPath(int[][] array) {
int r = 0, c = 0;
while(true) {
array[0][0] = 7;
if(c == 0 && r == array.length-1) { //reached the bottom left, checks right
if(array[r][c+1] == 1) {
array[r][c+1] = 7;
c+=1;
} else {
array[r][c] = 7;
break;
}
} else if(c == array[0].length-1 && r == array.length-1) { //reached the bottom right, checks left
if(array[r][c-1] == 1) {
array[r][c-1] = 7;
} else {
array[r][c] = 7;
break;
}
} else if(r == array.length-1) { //reached the bottom, checks left/right
if(array[r][c+1] == 1 && array[r][c-1] == 1) {
counter++;
newPath(array);
break;
} else if(array[r][c+1] == 1) { //checks right
array[r][c+1] = 7;
c+=1;
} else if(array[r][c-1] == 1) { //checks left
array[r][c-1] = 7;
c-=1;
} else { //end of path
array[r][c] = 7;
break;
}
} else if(c == 0) { //reached the left, checks right/bottom
if(array[r][c+1] == 1 && array[r+1][c] == 1) { //checks if path is unique
counter++;
newPath(array);
break;
} else if(array[r][c+1] == 1) {
array[r][c+1] = 7;
c+=1;
} else if(array[r+1][c] == 1) {
array[r+1][c] = 7;
r+=1;
} else {
counter++; //path has ended, not solvable
newPath(array);
break;
}
} else if(c == array[0].length-1) { //reached the right, checks left/bottom
if(array[r+1][c] == 1 && array[r][c-1] == 1) { //checks if path is unique
counter++;
newPath(array);
break;
} else if(array[r+1][c] == 1) {
array[r+1][c] = 7;
r+=1;
} else if(array[r][c-1] == 1) {
array[r][c-1] = 7;
c-=1;
} else {
counter++; //path has ended, not solvable
newPath(array);
break;
}
} else if(array[r][c+1] == 1 && array[r+1][c] == 1) { //checks if path is unique
counter++;
newPath(array);
break;
} else if(array[r][c-1] == 1 && array[r+1][c] == 1) { //checks if path is unique
counter++;
newPath(array);
break;
} else if(array[r][c+1] == 1) { //checks right
array[r][c+1] = 7;
c+=1;
} else if(array[r+1][c] == 1) { //checks bottom
array[r+1][c] = 7;
r+=1;
} else if(array[r][c-1] == 1) { //checks left
array[r][c-1] = 7;
c-=1;
} else {
counter++;
newPath(array);
break;
}
}
return array;
}
public int firstDimension() {
Scanner in = new Scanner(System.in);
System.out.println("Size of the first dimension:");
return in.nextInt();
}
public int secondDimension() {
Scanner in = new Scanner(System.in);
System.out.println("Size of the second dimension:");
return in.nextInt();
}
public int[][] defineArray(int firstDimension, int secondDimension) {
return new int[firstDimension][secondDimension];
}
public int[][] populate(int[][] array) {
Random rand = new Random();
for(int i = 0; i < array.length; i++) {
for(int j = 0; j < array[i].length; j++) {
array[i][j] = rand.nextInt(2);
}
}
return array;
}
public int continuity() {
Scanner in = new Scanner(System.in);
System.out.println("Enter a number to continue (0 to quit):");
return in.nextInt();
}
public void print(int[][] array) {
for(int[] ints : array) {
for(int anInt : ints) {
System.out.print(anInt + " ");
}
System.out.println();
}
System.out.println();
}
public void newPath(int[][] array) {
findPath(populate(array));
}
}
I'm trying to change delay of handler in handler.postDelay() but here it works only once then it stops. The crucial method is in the end. I'm thinking how I can make the runnable work in loop of postDelay().
class MyGestureListener implements GestureDetector.OnGestureListener {
#Override
public boolean onSingleTapUp(MotionEvent e) {
column = (int) (e.getX() / cellWidth);
row = (int) (e.getY() / cellHeight);
selectedNode = (6 * row) + column;
if (selectedNode == enemyNode && !atak && GameMovingObject.ableToAttack(chibiAlive, enemyAlive, chibiNode, enemyNode)) {
if (attackOption) {
chibi1.attack(enemies.get(enemyId));
//attackOption=false;
atak = true;
if (!enemyAlive) {
enemyId = enemyId + 1;
enemies.add(new Enemy(enemyId, GameSurface.this, wolf, Enemy.genPosition(getWidth(), getHeight())[0], Enemy.genPosition(getWidth(), getHeight())[1], cellWidth, cellHeight));
enemyAlive = true;
}
}
}
// ...
return true;
}
}
relevant methods
public static boolean ableToAttack(boolean chibiAlive, boolean enemyAlive, int chibiNode, int enemyNode) {
if(!chibiAlive || !enemyAlive)
return false;
boolean able = false;
if (chibiNode > enemyNode)
if (chibiNode - enemyNode == 1 || chibiNode - enemyNode == 5 || chibiNode - enemyNode == 6 || chibiNode - enemyNode == 7)
able = true;
if (enemyNode > chibiNode)
able = enemyNode - chibiNode == 1 || enemyNode - chibiNode == 5 || enemyNode - chibiNode == 6 || enemyNode - chibiNode == 7;
return able;
}
and
public void attack(Enemy enemy) {
if (partOfBody.equals("legs"))
enemy.getLegsDamage(generateDamage());
if (enemy.hp <= 0) {
enemy.hp = 0;
gs.attackOption = false;
gs.setEnemyAlive(false);
addExperience();
dbHelper.setExp("1", exp);
// ...
}
}
and finally
public void getLegsDamage(int legsDamage) {
fullLegsDamage = fullLegsDamage + legsDamage;
hp = hp - legsDamage;
if(fullLegsDamage>50) {
legsDamaged=2;
handler2.removeCallbacksAndMessages(null);
handler2.postDelayed(runnable, 4000);
}
}
runnable looks like this
runnable = new Runnable() {
#Override
public void run() {
hit=true;
//gs.canvas.drawBitmap(bitmap,200,200, null);
cc.setHp(cc.getHp() - generateDamage());
if(cc.getHp() <= 0) {
cc.setHp(0);
gs.setChibiAlive(false);
}
((Gra)gs.getContext()).updateChibiHpMp(cc);
}
};
I've been thinking about this for whole day up until now. Help me please.
Not completely sure what you are asking for but I interpret the question as you want the Runnable to run every 4s and in that case the Runnable needs to post it self at before it's done, like this:
runnable = new Runnable() {
#Override
public void run() {
hit=true;
//gs.canvas.drawBitmap(bitmap,200,200, null);
cc.setHp(cc.getHp() - generateDamage());
if(cc.getHp() <= 0) {
cc.setHp(0);
gs.setChibiAlive(false);
}
((Gra)gs.getContext()).updateChibiHpMp(cc);
// Schedule the runnable again
handler2.postDelayed(this, 4000)
}
};
public class ModFib
{
public static int modFibonacci(int term)
{
if(term == 1)
{
return 3;
}
else if(term == 2)
{
return 5;
}
else
{
return modFibonacci(term - 1) + modFibonacci(term - 2) + modFibonacci(term - 3);
}
}
}
it works fine at only term - 3 but this gives a stack overflow error.
need to add condition like
if(term == 0)
{
return 0;
}
I am working on code for an assignment in which I have to make Wheel of Fortune, I am having trouble with building the string that will be shown to the user after each guess. I have the wheel spin working but I just can't seem to figure how to build the string. I can also answer any questions about this if you have any. Any help will be much appreciated. Here is my code so far:
class WheelOfFortune3 {
public static void main(String[] args) {
int result, location, newLocation, numGuess = 0;
String puzzle, guess;
String sub[] = new String[26];
for (int i = 0; i < sub.length; i++) {
sub[i] = "_";
}
result = wheelResult();
System.out.println("You spun $" + result);
puzzle = getPuzzle();
System.out.println(puzzle);
do {
guess = In.getString();
location = checkGuess(puzzle, guess);
if (location == -1) {
System.out.println("Incorrect guess");
}
if (location >= 0 && location <= 25) {
System.out.println("Correct guess");
newLocation = location + 1;
sub[numGuess] = puzzle.substring(location, newLocation);
for (int i = 0; i <= 10; i++) {
System.out.print(sub[i] + " ");
}
System.out.println("");
numGuess = numGuess + 1;
System.out.println(numGuess);
System.out.println(sub.length);
}
}
while (numGuess < sub.length);
}
public static int checkGuess(String puzzle, String guess) {
String word = puzzle;
int location;
location = word.indexOf(guess);
return location;
}
public static int wheelResult() {
int result;
int[] wheelSpin = new int[1];
wheelSpin[0] = (int)(24 * Math.random());
if (wheelSpin[0] == 1 || wheelSpin[0] == 18 || wheelSpin[0] == 22) {
result = 200;
return result;
} else if (wheelSpin[0] == 2 || wheelSpin[0] == 5) {
result = 900;
return result;
} else if (wheelSpin[0] == 0 || wheelSpin[0] == 3 || wheelSpin[0] == 15) {
result = 250;
return result;
} else if (wheelSpin[0] == 4 || wheelSpin[0] == 6 || wheelSpin[0] == 12 || wheelSpin[0] == 16) {
result = 300;
return result;
} else if (wheelSpin[0] == 7) {
result = 1500;
return result;
} else if (wheelSpin[0] == 9 || wheelSpin[0] == 11) {
result = 700;
return result;
} else if (wheelSpin[0] == 10 || wheelSpin[0] == 14 || wheelSpin[0] == 21) {
result = 500;
return result;
} else if (wheelSpin[0] == 13) {
result = 5000;
return result;
} else if (wheelSpin[0] == 23 || wheelSpin[0] == 19) {
result = 600;
return result;
} else if (wheelSpin[0] == 8 || wheelSpin[0] == 20) {
result = 100;
return result;
} else if (wheelSpin[0] == 17) {
result = 17;
return result;
}
return -1;
}
public static String getPuzzle() {
String puzzle;
//a long ride
return "A long ride";
//01234567890
}
}
This can be done using a List of Characters and the .contains() method like so:
List<Character> guessedCharacters = new ArrayList<>();
each time a player guesses a letter, add that letter to
the guessedCharacters List like this: guessedCharacters.add(char);
Then you can do something like this to generate the String to output to the player:
StringBuilder toShowSB = new StringBuilder();
for(int i=0,n=puzzle.length;i<n;i++){
if(guessedCharacters.contains(puzzle.charAt(i))){
toShowSB.append(puzzel.charAt(i));
}else{
toShowSB.append("_");
}
}
String toShow = toShowSB.toString();
This will create a String that holds all of the guessed letters in their places and an underscore denoting characters that have not been properly guessed yet.
import java.util.ArrayList;
import java.lang.Math;
public class War {
ArrayList deck = new ArrayList(0);
ArrayList player1 = new ArrayList(0);
ArrayList player2 = new ArrayList(0);
int sum1 = 0;
int sum2 = 0;
int count = 0;
private void setup ()
{
for (int x = 1; x <= 13; x++)
{
for (int y = 1; y <= 4; y++)
{
deck.add(x);
}
}
while (deck.size() > 26)
{
double x = Math.random() * deck.size();
int y = (int) x;
player1.add(deck.remove(y));
}
while (deck.size() > 0)
{
double x = Math.random() * deck.size();
int y = (int) x;
player2.add(deck.remove(y));
}
for (int x = 0; x < 26; x++)
{
sum1 += (int) player1.get(x);
sum2 += (int) player2.get(x);
}
System.out.println("Player 1's starting power is " + sum1 + ".");
System.out.println();
System.out.println("Player 2's starting power is " + sum2 + ".");
System.out.println();
if (sum1 == sum2)
{
System.out.println("The two player's starting powers are equal! This'll be a good one, folks!");
}
}
public void play ()
{
if (hasSomeoneWon() || count == 0)
{
setup();
}
while (!player1.isEmpty() && !player2.isEmpty())
{
int a = (int) player1.get(0);
int b = (int) player2.get(0);
if (a > b)
{
player1.add(player1.remove(0)); // The winner's card is re-added to his deck before
player1.add(player2.remove(0)); // the loser's is added to the winner's deck.
}
if (a < b)
{
player2.add(player2.remove(0));
player2.add(player1.remove(0));
}
if (a == b)
{
war();
}
}
victory();
}
private void war ()
{
ArrayList temp1 = new ArrayList(0);
ArrayList temp2 = new ArrayList(0);
temp1.add(player1.remove(0));
temp2.add(player2.remove(0));
int x = 0;
while (!(player1.isEmpty() || player2.isEmpty()) && x < 3)
{
temp1.add(player1.remove(0));
temp2.add(player2.remove(0));
x++;
}
int a = (int) temp1.get(temp1.size() - 1);
int b = (int) temp2.get(temp2.size() - 1);
if (a == b)
{
if (temp1.size() != temp2.size())
{
if (temp1.size() > temp2.size())
{
while (!temp1.isEmpty())
{
player1.add(temp1.remove(0));
}
while (!temp2.isEmpty())
{
player1.add(temp2.remove(0));
}
}
else
{
while (!temp2.isEmpty())
{
player2.add(temp2.remove(0));
}
while (!temp1.isEmpty())
{
player2.add(temp1.remove(0));
}
}
}
else
{
if (player1.isEmpty() || player2.isEmpty())
{
if (player1.isEmpty())
{
while (!temp2.isEmpty())
{
player2.add(temp2.remove(0));
}
while (!temp1.isEmpty())
{
player2.add(temp1.remove(0));
}
}
else
{
while (!temp1.isEmpty())
{
player1.add(temp1.remove(0));
}
while (!temp2.isEmpty())
{
player1.add(temp2.remove(0));
}
}
}
else
{
war();
}
}
}
else
{
if (a > b)
{
while (!temp1.isEmpty())
{
player1.add(temp1.remove(0));
}
while (!temp2.isEmpty())
{
player1.add(temp2.remove(0));
}
}
else
{
while (!temp2.isEmpty())
{
player2.add(temp2.remove(0));
}
while (!temp1.isEmpty())
{
player2.add(temp1.remove(0));
}
}
play();
}
}
private void victory ()
{
if (player1.isEmpty() && sum2 > sum1)
{
System.out.println("Player 2 has won!");
}
if (player1.isEmpty() && sum1 > sum2)
{
System.out.println("Upset! Player 2 has won!");
}
if (player2.isEmpty() && sum1 > sum2)
{
System.out.println("Player 1 has won!");
}
if (player2.isEmpty() && sum2 > sum1)
{
System.out.println("Upset! Player 1 has won!");
}
hasSomeoneWon();
}
private boolean hasSomeoneWon ()
{
if (player1.isEmpty() || player2.isEmpty())
{
count++;
return true;
}
return false;
}
}
Sorry for including all of my code, but I don't know which part is causing the extra printing.
This is the card game War. It's supposed to play out the game between two players on its own and then print the winner. Whenever I've played it, though, the victory message (whichever one gets printed) is printed a variable number of times. I'm guessing this has something to do with either where and how often I've included my calls to some of the methods OR the recursive call to war within the war() method.
My only experience with Java is an AP Computer Science class I took this school year, so I'm for sure a noob by the standards of everyone reading this.
In the war() method you are recursively calling war() and war() will eventually end by recalling play(). So there will be multiple instances executing play(). Eventually when the cards run out for one player all this instances will comeback as the stack is unwound and continue executing play(). And finally of course calling victory() and printing it multiple times (should be the amount of times war() was called).
So each war() may print out a player has won once it reached the bottom of the recursion. I don't think the call to play() in war() is necessary, it will go back to the play() method after it finishes the war() method anyway.