I have a simple class:
public class NPP {
// inputs
public int m__water_pressure = 0;
public boolean m__blockage_button = false;
public boolean m__reset_button = false;
public int old_m__pressure_mode = 0;
public boolean old_m__reset_button = false;
public boolean old_m__blockage_button = false;
public int old_m__water_pressure = 0;
// outputs
public int c__pressure_mode = 0;
public boolean c__the_overriden_mode = false;
public int c__the_safety_injection_mode = 0;
public int p__pressure_mode = 0;
public boolean p__the_overriden_mode = false;
public int p__the_safety_injection_mode = 0;
public void method__c__pressure_mode() {
if ( m__water_pressure >= 9 && old_m__water_pressure < 9 && c__pressure_mode == 0 ) {
p__pressure_mode = 1;
} else if ( m__water_pressure >= 10 && old_m__water_pressure < 10 && c__pressure_mode == 1 ) {
p__pressure_mode = 2;
} else if ( m__water_pressure < 9 && old_m__water_pressure >= 9 && c__pressure_mode == 1 ) {
p__pressure_mode = 0;
} else if ( m__water_pressure < 10 && old_m__water_pressure >= 10 && c__pressure_mode == 2 ) {
p__pressure_mode = 1;
}
}
public void method__c__the_overriden_mode() {
if ( m__blockage_button == true && old_m__blockage_button == false && m__reset_button == false && !(c__pressure_mode==2) ) {
p__the_overriden_mode = true;
} else if ( m__reset_button == true && old_m__reset_button == false && !(c__pressure_mode==2) ) {
p__the_overriden_mode = false;
} else if ( c__pressure_mode==2 && !(old_m__pressure_mode==2) ) {
p__the_overriden_mode = false;
} else if ( !(c__pressure_mode==2) && old_m__pressure_mode==2 ) {
p__the_overriden_mode = false;
}
}
public void method__c__the_safety_injection_mode() {
if ( c__pressure_mode == 0 && c__the_overriden_mode == true ) {
p__the_safety_injection_mode = 0;
} else if ( c__pressure_mode == 0 && c__the_overriden_mode == false ) {
p__the_safety_injection_mode = 1;
} else if ( c__pressure_mode == 1 || c__pressure_mode == 2 ) {
p__the_safety_injection_mode = 0;
}
}
}
And i've wrote this junit class:
import static org.junit.Assert.*;
import org.junit.Test;
public class NPPTest {
#Test
public void testMethod__c__pressure_mode() {
NPP npp = new NPP();
npp.m__water_pressure = 3;
npp.old_m__water_pressure = 5;
npp.c__pressure_mode = 2;
npp.method__c__pressure_mode();
assertEquals(1, npp.p__pressure_mode);
}
#Test
public void testMethod__c__the_overriden_mode() {
NPP npp = new NPP();
npp.m__blockage_button = false;
npp.old_m__blockage_button = true;
npp.m__reset_button = false;
npp.method__c__the_overriden_mode();
assertFalse(npp.p__the_overriden_mode);
}
#Test
public void testMethod__c__the_safety_injection_mode() {
NPP npp = new NPP();
npp.c__pressure_mode = 2;
npp.c__the_overriden_mode = false;
npp.method__c__the_safety_injection_mode();
assertEquals(1, npp.p__the_safety_injection_mode);
}
}
I've been asked to write some tests and to cover 100% of code coverage. But what exactly does it mean? How can i achieve this? I've ran Eclemma and i've got only 46%.
100% code coverage means that every line of code is covered by a test.
In other words, your test code should call and go through everything that has been written and make sure it works as expected.
In your case, it means that all the methods must be called and every if-else if case must be tested.
Even though 100% code coverage is very sexy, what matters most is the quality of your test suite.
85% code coverage might be near perfect if all the 15% left is some getters/setters, call to external APIs that is useless to check, glue code that is very very difficult to test and so on. It is up to you to realize what code can and should be tested and what code can be left without knowing that you are leaving holes (and bombs?) in your app.
Related
I am trying to solve this CSES problem: Grid Paths. You are given a string of length 48, and you have to find the amount of paths such that you traverse all of the grid and end up at the lower left corner.
I believe I have pruned the search to the best of my ability, as according to this book: CP Handbook (Look in the pruning the search category), the best optimization for this type of problem is to prevent your path from closing yourself off, and I have already implemented this. The time limits for this specific problem are tight, and although I have basically solved this problem, I am still failing 1-2 test cases because my solution takes around 1.01 seconds instead of being below the 1 second time limit.
Finally, I just wanted to know if there were any cool micro-optimizations I could use to marginally enhance the speed of my java code, so I could actually pass all of the test cases for this problem.
import java.io.*;
public class GridPaths {
public static class FastIO {
InputStream dis;
byte[] buffer = new byte[1 << 17];
int pointer = 0;
public FastIO(String fileName) throws Exception {
dis = new FileInputStream(fileName);
}
public FastIO(InputStream is) {
dis = is;
}
int nextInt() throws Exception {
int ret = 0;
byte b;
do {
b = nextByte();
} while (b <= ' ');
boolean negative = false;
if (b == '-') {
negative = true;
b = nextByte();
}
while (b >= '0' && b <= '9') {
ret = 10 * ret + b - '0';
b = nextByte();
}
return (negative) ? -ret : ret;
}
long nextLong() throws Exception {
long ret = 0;
byte b;
do {
b = nextByte();
} while (b <= ' ');
boolean negative = false;
if (b == '-') {
negative = true;
b = nextByte();
}
while (b >= '0' && b <= '9') {
ret = 10 * ret + b - '0';
b = nextByte();
}
return (negative) ? -ret : ret;
}
Integer[] readArray(int n) throws Exception {
Integer[] a = new Integer[n];
for (int i = 0; i < n; i++) a[i] = nextInt();
return a;
}
byte nextByte() throws Exception {
if (pointer == buffer.length) {
dis.read(buffer, 0, buffer.length);
pointer = 0;
}
return buffer[pointer++];
}
String next() throws Exception {
StringBuilder ret = new StringBuilder();
byte b;
do {
b = nextByte();
} while (b <= ' ');
while (b > ' ') {
ret.appendCodePoint(b);
b = nextByte();
}
return ret.toString();
}
}
static char[] board;
static boolean[][] visited = new boolean[7][7];
static int ans = 0;
public static boolean works(int i, int j) {
//makes sure that current spot is on the 7x7 grid and is not visited
return (i >= 0 && i<=6 && j>=0 && j<=6 && !visited[i][j]);
}
public static void solve(int i, int j, int steps) {
if (i == 6 && j == 0) {
if (steps == 48) ans++; //all spots of the grid have to be visited in order to be counted as part of the answer
return;
}
visited[i][j] = true;
//you are given ? characters in the input string, and those mean that you have to try out all 4 combinations (U,D,L,R)
if (board[steps] == '?' || board[steps] == 'L') {
//second condition of the second if statement checks if the spot directly ahead of the current spot is blocked, and if it is, the left and right spots cannot both be unvisited or else you will not continue searching
if (works(i,j-1) && !(!works(i,j-2) && works(i+1,j-1) && works(i-1,j-1))) {
solve(i, j - 1, steps + 1);
}
}
if (board[steps] == '?' || board[steps] == 'R') {
if (works(i,j+1) && !(!works(i,j+2) && works(i+1,j+1) && works(i-1,j+1))) {
solve(i, j + 1, steps + 1);
}
}
if (board[steps] == '?' || board[steps] == 'U') {
if (works(i-1,j) && !(!works(i-2,j) && works(i-1,j+1) && works(i-1,j-1))) {
solve(i - 1, j, steps + 1);
}
}
if (board[steps] == '?' || board[steps] == 'D') {
if (works(i+1,j) && !(!works(i+2,j) && works(i+1,j+1) && works(i+1,j-1))) {
solve(i + 1, j, steps + 1);
}
}
visited[i][j] = false;
}
public static void main(String[] args) throws Exception {
FastIO in = new FastIO(System.in);
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
board = in.next().toCharArray();
solve(0,0,0);
out.println(ans);
out.close();
}
}
Note: I am already using one of the fastest, if not the fastest, ways to receive input in Java, so I do not believe I can actually improve upon that.
I've been playing around with this. In addition to using a standard mechanism for reading the input file (which I suggested in a comment), you can gain a little time in the search alg itself by doing two things:
Break the case board[steps] == '?' off from the other cases. So check for board[steps] == '?' first, and just try all four directions in that case. Otherwise (the else case for if (board[steps] == '?'), just check for U/D/L/R. Since for most steps, the character will be '?', you save having to make the U/D/L/R tests most of the time.
Look up the character to be tested once, with c = board[steps],and then use c in each test instead of board[steps].
Doing these two things saved about 5% it seems. I was doing 100 reps of the solve and timing with System.currentTimeMillis(). I know there are more accurate ways of timing, but this was good enough to see a definite improvement even though the times jumped around quite a bit trial to trial. The best I ever saw in each case was 3600 millis for 100 iterations as originally written vs 3400 millis with the improvements.
My guess is that it's mostly the first change that matters. I'd expect the compiler to be doing the second already, but I didn't try the two optimizations independently.
I also solved this problem in java (AC), and here is how I did it
public static char[] defaultPath;
public static boolean[][] isUsed;
public static int counter = 0;
public static void solve(int indexChar, int indexRow, int indexColumn) {
if (indexRow == 8 && indexColumn == 2) {
if (indexChar == 48) {
counter++;
}
}else {
// Find correct way: 'D', 'U', 'L', 'R'
char correctWay = '?';
// (1) (1)
// 0 1 or 1 0
// 1 1
if ((isUsed[indexRow+1][indexColumn+1] || isUsed[indexRow+1][indexColumn-1])
&& isUsed[indexRow+2][indexColumn] && !isUsed[indexRow+1][indexColumn]) {
correctWay = 'D';
}
// 1 1
// 0 1 or 1 0
// (1) (1)
else if ((isUsed[indexRow-1][indexColumn+1] || isUsed[indexRow-1][indexColumn-1])
&& !isUsed[indexRow-1][indexColumn] && isUsed[indexRow-2][indexColumn]) {
correctWay = 'U';
}
// 1 0 (1) or 1
// 1 1 0 (1)
else if ((isUsed[indexRow+1][indexColumn-1] || isUsed[indexRow-1][indexColumn-1])
&& !isUsed[indexRow][indexColumn-1] && isUsed[indexRow][indexColumn-2]) {
correctWay = 'L';
}
//(1) 0 1 or 1
// 1 (1) 0 1
else if ((isUsed[indexRow+1][indexColumn+1] || isUsed[indexRow-1][indexColumn+1])
&& !isUsed[indexRow][indexColumn+1] && isUsed[indexRow][indexColumn+2]) {
correctWay = 'R';
}
// Check input path (default path)
char c = defaultPath[indexChar];
if (c == '?') {
if (correctWay == '?') {
// 'D'
if (!isUsed[indexRow+1][indexColumn]) {
isUsed[indexRow+1][indexColumn] = true;
solve(indexChar+1, indexRow+1, indexColumn);
isUsed[indexRow+1][indexColumn] = false;
}
// 'U'
if (!isUsed[indexRow-1][indexColumn]) {
isUsed[indexRow-1][indexColumn] = true;
solve(indexChar+1, indexRow-1, indexColumn);
isUsed[indexRow-1][indexColumn] = false;
}
// 'L'
if (!isUsed[indexRow][indexColumn-1]) {
isUsed[indexRow][indexColumn-1] = true;
solve(indexChar+1, indexRow, indexColumn-1);
isUsed[indexRow][indexColumn-1] = false;
}
// 'R'
if (!isUsed[indexRow][indexColumn+1]) {
isUsed[indexRow][indexColumn+1] = true;
solve(indexChar+1, indexRow, indexColumn+1);
isUsed[indexRow][indexColumn+1] = false;
}
}else {
if (correctWay == 'D') {
isUsed[indexRow+1][indexColumn] = true;
solve(indexChar+1, indexRow+1, indexColumn);
isUsed[indexRow+1][indexColumn] = false;
}else if (correctWay == 'U') {
isUsed[indexRow-1][indexColumn] = true;
solve(indexChar+1, indexRow-1, indexColumn);
isUsed[indexRow-1][indexColumn] = false;
}else if (correctWay == 'L') {
isUsed[indexRow][indexColumn-1] = true;
solve(indexChar+1, indexRow, indexColumn-1);
isUsed[indexRow][indexColumn-1] = false;
}else if (correctWay == 'R') {
isUsed[indexRow][indexColumn+1] = true;
solve(indexChar+1, indexRow, indexColumn+1);
isUsed[indexRow][indexColumn+1] = false;
}
}
}else {
if (c == correctWay || correctWay == '?') {
if (c == 'D' && !isUsed[indexRow+1][indexColumn]) {
isUsed[indexRow+1][indexColumn] = true;
solve(indexChar+1, indexRow+1, indexColumn);
isUsed[indexRow+1][indexColumn] = false;
}else if (c == 'U' && !isUsed[indexRow-1][indexColumn]) {
isUsed[indexRow-1][indexColumn] = true;
solve(indexChar+1, indexRow-1, indexColumn);
isUsed[indexRow-1][indexColumn] = false;
}else if (c == 'L' && !isUsed[indexRow][indexColumn-1]) {
isUsed[indexRow][indexColumn-1] = true;
solve(indexChar+1, indexRow, indexColumn-1);
isUsed[indexRow][indexColumn-1] = false;
}else if (c == 'R' && !isUsed[indexRow][indexColumn+1]) {
isUsed[indexRow][indexColumn+1] = true;
solve(indexChar+1, indexRow, indexColumn+1);
isUsed[indexRow][indexColumn+1] = false;
}
}
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
defaultPath = scanner.next().toCharArray();
isUsed = new boolean[11][11];
for (int i = 0; i < 11; i++) {
isUsed[0][i] = true;
isUsed[1][i] = true;
isUsed[9][i] = true;
isUsed[10][i] = true;
isUsed[i][0] = true;
isUsed[i][1] = true;
isUsed[i][9] = true;
isUsed[i][10] = true;
}
isUsed[2][2] = true;
isUsed[8][1] = false;
isUsed[9][2] = false;
solve(0, 2, 2);
System.out.println(counter);
scanner.close();
}
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)
}
};
I have a program grabbing a password from the user, then it checks if the conditions are met or not then outputs "Valid Password" or "Invalid Password". This works, and I was able to turn the verification aspect into a method in the same program and it works, but I want to make it into a class where I can just say if( validate(pw) == true ) ... or at least if( v.getValidation() == true ) ... in any program and it will test my conditions. I've used custom classes before but for some reason everything I try does not work on this one, I've been at it for days.
Here's my method:
public boolean validate( String pw )
{
boolean l = false, u = false, lo = false, d = false, r = true;
if( pw.length() >= 6 )
{ l = true; }
for( int i = 0; i < pw.length(); i++ )
{
if( Character.isUpperCase( pw.charAt(i) ) )
{ u = true; }
if( Character.isLowerCase( pw.charAt(i) ) )
{ lo = true; }
if( Character.isDigit( pw.charAt(i) ) )
{ d = true; }
}
if( l == false || u == false || lo == false || d == false )
{ r = false; }
return r;
}
Edit:
Thank you all for your input, this is what it came out to in the end:
public class Password
{
public static boolean validate( String pw )
{
boolean result = false;
int upper = 0, lower = 0, digit = 0;
if( pw.length() >= 6 )
{
for( int i = 0; i < pw.length(); i++ )
{
if( Character.isUpperCase( pw.charAt(i) ) )
{ upper++; }
if( Character.isLowerCase( pw.charAt(i) ) )
{ lower++; }
if( Character.isDigit( pw.charAt(i) ) )
{ digit++; }
}
}
if( upper >= 1 && lower >= 1 && digit >= 1 )
{ result = true; }
return result;
}
}
You do not need to make a whole class for this. You can do something like:
public static void main(String[] args) {
boolean valid = validate("PassWord22");
}
public static boolean validate( String pw ) {}
Also some notes on your method:
You don't need to do l == true or l == false in your if statement. You can simply do:
if( !l || !u || !lo || !d )
{ r = false; }
In fact you can just return
return l && u && lo && d;
If the length is not 6 or greater, simply return false. This will save checking all the letters in the String
I would come up with better variable names. Single/two letter variable names makes it very hard to tell what they represent, and easy to mix up. (instead of l you could have length and instead of u you could have upper)
Also this can be easier solved with regex and String.matches():
public static boolean validate(String pw) {
String pattern = "^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).+$";
return (pw.length() > 5 && pw.matches(pattern));
}
I got it working, turned out to be an error in the code that the compiler was not picking up. I wanted to delete the question but they wont let me for some reason. So in case you're curious this is what my class looks like functioning:
public class Password
{
private String pw;
public Password()
{
pw = "";
}
public Password( String pw )
{
this.pw = pw;
}
public boolean getPassword( String pw )
{
boolean l = false, u = false, lo = false, d = false, r = true;
if( pw.length() >= 6 )
{ l = true; }
for( int i = 0; i < pw.length(); i++ )
{
if( Character.isUpperCase( pw.charAt(i) ) )
{ u = true; }
if( Character.isLowerCase( pw.charAt(i) ) )
{ lo = true; }
if( Character.isDigit( pw.charAt(i) ) )
{ d = true; }
}
if( l == false || u == false || lo == false || d == false )
{ r = false; }
return r;
}
I hope someone can help me with an IndexOutOfBoundsException error.
I can set the amount of units within a territory, and I can set the owner of the territory however the defend function is causing a problem.
Trace:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at stackOverflow.Territory.calculateLoses(Territory.java:136)
at stackOverflow.Territory.defend(Territory.java:95)
at stackOverflow.Territory.defend(Territory.java:40)
at stackOverflow.Territory.main(Territory.java:155)
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public enum Territory {
// Europe
GREATBRITAIN("Great Britain"), ICELAND("Iceland");
private final String name;
private int numberOfUnits;
private Player player;
private int ad = 0, dd = 0;
private Territory(String name) {
this.name = name;
this.numberOfUnits = 0;
this.player = null;
}
public void setOwner(Player p) {
this.player = p;
}
public Player getOwner() {
return this.player;
}
public int getNumberUnits() {
return this.numberOfUnits;
}
public void setNumberUnits(int units) {
this.numberOfUnits = units;
}
public boolean defend(Territory attacker) throws Exception {
return defend(attacker, attacker.numberOfUnits - 1);
}
public boolean defend(Territory attacker, int attackingUnits)
throws Exception {
if (attackingUnits > (attacker.getNumberUnits() - 1)) {
throw new Exception("Invalid number of units");
}
attacker.setNumberUnits(attacker.numberOfUnits - attackingUnits);
Player defender = this.player;
this.player = null;
int defendingUnits = this.numberOfUnits;
this.numberOfUnits = 0;
if (this.numberOfUnits >= 3 && defendingUnits >= 2) {
ad = 3;
dd = 2;
}
if (this.numberOfUnits >= 3 && defendingUnits == 1) {
ad = 3;
dd = 1;
}
if (this.numberOfUnits == 2 && defendingUnits >= 2) {
ad = 2;
dd = 2;
}
if (this.numberOfUnits == 2 && defendingUnits == 1) {
ad = 2;
dd = 1;
}
if (this.numberOfUnits == 1 && defendingUnits >= 2) {
ad = 1;
dd = 2;
}
if (this.numberOfUnits == 1 && defendingUnits == 1) {
ad = 1;
dd = 1;
}
if (this.name == "Great Britan" || this.name == "Central America"
|| this.name == "Argentina" || this.name == "Egypt"
|| this.name == "Western Australia" || this.name == "India") {
dd++;
}
List<Die> attackerDice = createDice(ad);
List<Die> defenderDice = createDice(dd);
System.out.printf("Attacker: %d \tDefender: %d\n", attackingUnits,
defendingUnits);
while (attackingUnits > 0 && defendingUnits > 0) {
roll(attackerDice);
System.out.println(attackerDice);
roll(defenderDice);
System.out.println(defenderDice);
attackingUnits -= calculateLoses(attackerDice, defenderDice, false);
defendingUnits -= calculateLoses(defenderDice, attackerDice, true);
System.out.printf("Attacker: %d \tDefender: %d\n", attackingUnits,
defendingUnits);
}
if (defendingUnits > 0) {
this.player = defender;
this.numberOfUnits = defendingUnits;
return true;
} else if (attackingUnits > 0) {
this.numberOfUnits = attackingUnits;
this.player = attacker.player;
return false;
} else {
// No one owns the territory as all units died
return false;
}
}
private List<Die> createDice(int number) {
List<Die> dice = new ArrayList<Die>();
for (int i = 0; i < number; i++) {
dice.add(new Die());
}
roll(dice);
return dice;
}
private void roll(List<Die> dice) {
for (Die d : dice) {
d.roll();
}
Collections.sort(dice);
}
private int calculateLoses(List<Die> diceOne, List<Die> diceTwo,
boolean defender) {
int number = 0;
for (int i = 0; i < 2; i++) {
int comparison = diceOne.get(i).compareTo(diceTwo.get(i));
if (comparison > 0 || (!defender && comparison == 0)) {
number++;
}
}
return number;
}
String units()
{
return "" + numberOfUnits;
}
public static void main(String[] args) throws Exception
{
Territory.GREATBRITAIN.setNumberUnits(5);
System.out.println(Territory.GREATBRITAIN.getNumberUnits());
Territory.ICELAND.setNumberUnits(5);
System.out.println(Territory.ICELAND.getNumberUnits());
Territory.GREATBRITAIN.defend(Territory.ICELAND);
}
}
It looks like either ad or dd or both are 0.
That makes sense, given this code:
this.numberOfUnits = 0;
// Lots of these, all requiring numberOfUnits to be greater than 0
if (this.numberOfUnits >= 3 && ...)
{
ad = ...;
dd = ...;
}
How do you ever expect to get into any of those if blocks, when you've just set numberOfUnits to 0?
This is only one of the problems in your code. Others have pointed out other aspects of either style or correctness. I'm not going to try to fix all of your code here - but you should analyze how you could have diagnosed this yourself. Did you try stepping through the code in a debugger, for example?
This code is wrong:
if (this.name == "Great Britan" || this.name == "Central America"
|| this.name == "Argentina" || this.name == "Egypt"
|| this.name == "Western Australia" || this.name == "India") {
dd++;
}
Use this.name.equals("Great Britain") to test if strings contain the same characters, rather than whether they are stored at the same location in memory.
Also, your many separate if statements look like bad practice; use else or something to check you hit at least one case - you clearly don't hit any of the this.numberOfUnits >= [stuff] cases after setting this.numberOfUnits = 0;.
Well been working for hours today so i might be missing something silly, but, at this point I'm kinda blind with this and looking for an explanation for this behaviour
i made an example of the problem I'm having and the solution i found is not quite a solution.
The Problem: to the following function I pass 1 as shotCount and 9 as Countdown
the result when i debug, i see the first if run, and run the return 2, but then also the else decides to run to and finally return -1
public int getNextShot(int shotCount, int Countdown)
{
if ((shotCount == 1) && (Countdown != 10)) return 2;
else if (shotCount == 0) return 1;
else return -1;
}
BUT if i do this (same parameters) it works:
public int getNextShot(int shotCount, int Countdown)
{
int res = -2;
if ((shotCount == 1) && (Countdown != 10)) res = 2;
else if (shotCount == 0) res = 1;
else res = -1;
return res;
}
Am I missing something here?
Thanks :)
I think you are mistaken.
Sometimes the debugger in Eclipse acts like its jumping to the last line of the method call but then does return the correct value.
For example, I just copied and pasted your code and it ran fine for me. The below code prints 2.
public class AA {
public static void main(String[] args) {
System.out.println(getNextShot(1, 9));
}
public static int getNextShot(int shotCount, int Countdown)
{
if ((shotCount == 1) && (Countdown != 10)) return 2;
else if (shotCount == 0) return 1;
else return -1;
}
}
This code is OK. When I run this:
public static int getNextShot1(int shotCount, int Countdown) {
if ((shotCount == 1) && (Countdown != 10)) {
return 2;
} else if (shotCount == 0) {
return 1;
} else {
return -1;
}
}
public static int getNextShot2(int shotCount, int Countdown) {
int res = -2;
if ((shotCount == 1) && !(Countdown == 10)) {
res = 2;
} else if (shotCount == 0) {
res = 1;
} else {
res = -1;
}
return res;
}
public static void main(String[] args) throws KeyStoreException, ParseException {
System.out.println(getNextShot1(1, 9));
System.out.println(getNextShot2(1, 9));
}
I get
2
2
on console :)
Second function could look like this (final keyword):
public static int getNextShot2(int shotCount, int Countdown) {
final int res;
if ((shotCount == 1) && !(Countdown == 10)) {
res = 2;
} else if (shotCount == 0) {
res = 1;
} else {
res = -1;
}
return res;
}