0

There are 5 static variables: countAllGames, countWinCrosses, countWinNoughts, percentageWinCrosses and percentageWinNoughts. Their results are displayed in a "Statistics" window. There is one problem: the first 3 variables are normally their counters are incremented, as was intended, but the last two variables are dropping their result to 0.0. Here is the code:

if (countWinCrosses != 0) {
    percentageWinCrosses = (countWinCrosses / countAllGames) * 100;
}
if (countWinNoughts != 0) {
    percentageWinNoughts = (countWinNoughts / countAllGames) * 100;
}

And this is the code of methods, one of which is executed after winning the x's or o's:

public static void incrementWinCrosses() {
    countWinCrosses++;
    calculatePercentage();
}

public static void incrementWinNoughts() {
    countWinNoughts++;
    calculatePercentage();
}

There is also a method that increases the count of all games played. Why variables percentageCrosses and percentageNoughts become zero after the second call to calculatePercentage()? After the first winning one of them becomes equal to 100%, but after the second game (say, won the other) both variables are equal to 0.0. The first 3 variables retain their values, increasing each time by 1.

  • check this http://stackoverflow.com/questions/7220681/division-of-integers-in-java – Gustek Oct 09 '14 at 09:19
  • 1
    Using statics like this is evil. Why not have member variables on an instance? – lance-java Oct 09 '14 at 09:21
  • @Lance Java, so they reset to zero after each run of the statistics window? –  Oct 09 '14 at 09:25
  • If they were member variables on an instance. You could call instance.reset() or just discard the old instance when it's not needed and create again for a new window (with defaults). Static variables are global and evil and should be avoided most of the time. Mutable static variables are the worst (as you are doing here). – lance-java Oct 09 '14 at 09:27
  • @LanceJava sometimes i wish Java newbies had to donate $1 to charity every time they use "static" ;-) – Gyro Gearless Oct 09 '14 at 09:37
  • @LanceJava Thanks for the advice. I'll deal with this issue. –  Oct 09 '14 at 09:56
  • @LanceJava I don't quite understand how to make the variables worked well, but without making them static. The first thing that came to mind is to create a new constructor to initialize them and use it to create a single object, working with variables (it will store its own copy of variables). Continue to call the same methods (percentageCrosses etc), but not static. This version will come? Or you can implement even better? –  Oct 09 '14 at 10:49
  • @LanceJava Just a Statistics class extends the JFrame class and its default constructor initializes and adds components to the form. Whether it is true logically, if you create a new constructor to initialize variables, working only with them (counters winnings, interest etc)? –  Oct 09 '14 at 10:59
  • Create a Game class which encapsulates all the functionality. It has methods to perform moves and get the current state (and possibly reset). – lance-java Oct 09 '14 at 11:05
  • @LanceJava Ok, I'll try. –  Oct 09 '14 at 11:11

1 Answers1

1

It has not any problem with the static variables. It has the problem that your variables are integers. If you divide an integer with an integer, you will get an integer.

Thus, if you divide 3/5, you will get 0 (as integer), and not 0.6. If you multiply this with 100, you will get 0, too.

The simplest solution were to first multiply with 100 and divide only after that! So:

myPercentValue = quantity1 * 100 / quantity2;

So you will get what you wanted. In my example, first you multiplied 3 with 100, so you got 300, and after you divided that with 5, you will get 60 as you wanted.

Or alternatively, you could use floating point or double types, either by declaring the variables as floating point, or converting them on the fly. This is what @Gustek 's comment suggested, and it can be a good solution, too. But these complex conversions are often practically unneeded. A simple change in the operation ordering will also do what you want.

peterh
  • 11,875
  • 18
  • 85
  • 108
  • I think using float is better than multiplying by hundred and dividing. Because, 2*100/3 = 66.67, If you use integers, then you get 66, but 67 is the correct value in this case – A Nice Guy Oct 09 '14 at 09:34
  • @Arnab I think, it depends on our rounding algorithm. For example, it is possible too, that we want to get 100% only on a perfect match. – peterh Oct 09 '14 at 09:36
  • @Arnab The result of the calculation of the percentage, I assign a variable of type double. –  Oct 09 '14 at 09:47
  • @PeterHorvath Thanks, worked. Next time I will carefully for such calculation. –  Oct 09 '14 at 09:50
  • @PeterHorvath yup, thats why i said "I think it is better" :) – A Nice Guy Oct 09 '14 at 09:50
  • @akhbulatov If you are satisfied with an answer, you can accept that by clicking the green pipe on the left side. It is a good reward to the answering person. – peterh Oct 09 '14 at 09:59