check of a java awt 2D game, jbutton background update problem - java

i'm posting a simple game code, written in java. It took my hours today to write this but now i'm stuck! The problem is, in the second level of this game (after failure or success) i can't see the red tiles. It works only the first time.
games logic:
it starts up with a 3x3 matrix and rebound the dimension of this matrix in case of success (testing the ability of memory, memorising the coordinates of red tiles in 1200 ms). So we show the red tiles first, than we check the estimations. If there became a wrong try, failure!. If it is a bigger matrix than 3x3, it gets smaller.
the code is a little bit long but just one class, so it is so easy yo execute it. If you have time i would be appreciate.
So there it goes:
package skeleton;
public class Memory extends JFrame implements ActionListener {
private static final long serialVersionUID = 5963518754230629235L;
private static int minDimX = 3, minDimY = 3;
private static int maxDimX = 15, maxDimY = 15;
private static int counter = 13;
private static int memoriseTime = 1200; // milliseconds
private static int memGridWidthX = 60;
private static int memGridWidthY = 60;
private JPanel centerPanel;
private JButton memTile;
private Random generator;
private int memGridDimX, memGridDimY, coef, numberOfMemTilesToGuess;
int[][] memTileCoordinates;
int[] randomNums;
Border grayBorder = LineBorder.createGrayLineBorder();
public Memory(int xDim, int yDim) {
waitALittleBit(1300);
memGridDimX = xDim;
memGridDimY = yDim;
coef = 3;
numberOfMemTilesToGuess = memGridDimX*memGridDimY / coef;
centerPanel = new JPanel();
centerPanel.setLayout(new GridLayout(memGridDimY, memGridDimX, 0, 0));
add(centerPanel, BorderLayout.CENTER);
System.out.println("int[" + memGridDimX + "][" + memGridDimY + "] array is created ");
randomNums = new int[numberOfMemTilesToGuess];
for (int i = 0 ; i < numberOfMemTilesToGuess ; i ++) {
System.out.println("> we are in for the "+ (i+1) +". time!");
int randomNum;
boolean randomNumberAlreadySelected = false;
do {
randomNum = calculateARandomNumber(memGridDimX * memGridDimY);
if (i != 0) { //for the first time, we don't need to compare any numbers
randomNumberAlreadySelected = isThisRandomNumberExistInAlreadyFoundRandomNumbersArray(randomNum, randomNums, i);
if (randomNumberAlreadySelected)
System.out.println("######## RECALCULATING RANDOM NUMBER !! ##########");
else
System.out.println("They are not equal, go on!");
}
} while (randomNumberAlreadySelected);
randomNums[i] = (Integer)randomNum;
}
//show the memory tiles
setMemTiles(randomNums, true);
waitALittleBit(memoriseTime);
//hide the memory tiles
setMemTiles(randomNums, false);
}
private int calculateARandomNumber(int limit) {
generator = new Random();
System.out.println("* Calculating random number which is smaller than " + memGridDimX * memGridDimY);
int randomNum = generator.nextInt() % (memGridDimX * memGridDimY);
System.out.println("- Calculated random number: " + randomNum);
if (randomNum < 0) {
System.out.println(".. it is negative, so we add: " + memGridDimX * memGridDimY);
randomNum += memGridDimX * memGridDimY;
}
System.out.println(".. and we add 1 to have a grid array between 1 and 12");
randomNum += 1;
System.out.println(".. and our new random number is: " + randomNum);
return randomNum;
}
private boolean isThisRandomNumberExistInAlreadyFoundRandomNumbersArray(int number, int[] numberArr, int numberArrSize) {
for (int j = 0 ; j < numberArrSize ; j ++) {
System.out.println("# Comparing random number: " + number + " and " + (j+1) + ". random number selected earlier: " + numberArr[j]);
if (number == numberArr[j])
return true;
}
return false;
}
private void setMemTiles(int[] randomNums, boolean showMemTiles) {
centerPanel.removeAll();
memTileCoordinates = new int[randomNums.length][2];
for (int i = 1 ; i <= memGridDimY ; i ++) {
for (int j = 1 ; j <= memGridDimX ; j ++) {
int rnX = -1;
int rnY = -1;
boolean isMemTile = false;
for (int k = 0 ; k < randomNums.length ; k ++) {
int rn = randomNums[k];
if (rn % memGridDimX == 0) {
rnY = rn / memGridDimX;
rnX = memGridDimX;
} else {
rnY = rn / memGridDimX + 1;
rnX = rn % memGridDimX;
}
if (i == 1 && j == 1 && !showMemTiles) { //do it once
System.out.println("********* ************");
System.out.println("Random label number: " + rn + " and it's position in the grid: " + rnX + "," + rnY);
memTileCoordinates[k][0] = rnX;
memTileCoordinates[k][1] = rnY;
System.out.println("> Memory Tiles coordinates: " + memTileCoordinates[k][0] + "," + memTileCoordinates[k][1]);
System.out.println("> Memory Tiles length: " + memTileCoordinates.length);
System.out.println("********* ************");
}
if (rnX == j && rnY == i)
isMemTile = true;
}
memTile = new JButton();
if (isMemTile) {
update(getGraphics());
if (showMemTiles) {
memTile.setBackground(Color.red);
System.out.println("%%%% PAINTING MEM TILES IN RED %%%%");
} else
memTile.setBackground(Color.white);
update(getGraphics());
} else
memTile.setBackground(Color.white);
if (!showMemTiles) // we listen actions after the memory tiles disappears
memTile.addActionListener(this);
centerPanel.add(memTile);
update(getGraphics());
}
}
setJPanelSettings();
}
private void setJPanelSettings() {
setSize(memGridDimX * memGridWidthX, memGridDimY * memGridWidthY);
setTitle("Memory :: " + memGridDimX + "x" + memGridDimY);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setVisible(true);
}
private void waitALittleBit(long waitingMillisSeconds) {
long t0 = System.currentTimeMillis();
long t1 ;
do {
t1 = System.currentTimeMillis();
} while (t1 - t0 < waitingMillisSeconds);
}
public static void main(String[] args) {
new Memory(minDimX,minDimY);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(">>> An action came >>>");
JButton memTile = (JButton) e.getSource();
Dimension size = memTile.getSize();
int chosenMemTileDimX = memTile.getX();
int chosenMemTileDimY = memTile.getY();
int chosenMemTilePosX = chosenMemTileDimX / size.width + 1; // we add 1 becausee we present our tile numbers as 1:1, 1:2, ... ( instead of 0:0,0:1, ... )
int chosenMemTilePosY = chosenMemTileDimY / size.height + 1;
System.out.println("Chosen Tile's x dimension: " + chosenMemTileDimX + " ans y dimension: " + chosenMemTileDimY);
System.out.println("Chosen Tile's width: " + size.width + " and height: " + size.height);
System.out.println("Chosen Tile's coordinates: " + chosenMemTilePosX + ", " + chosenMemTilePosY);
boolean tileIsMemTile = false;
System.out.println("Memory Tiles Coordinates: ");
for (int i = 0 ; i < memTileCoordinates.length ; i ++) {
int memTileDimX = memTileCoordinates[i][0];
int memTileDimY = memTileCoordinates[i][1];
System.out.println("x: " + memTileDimX + ", y: " + memTileDimY);
if (chosenMemTilePosX == memTileDimX && chosenMemTilePosY == memTileDimY)
tileIsMemTile = true;
}
if (tileIsMemTile) {
System.out.println("!!! Right Tile !!!");
memTile.setBackground(Color.red);
numberOfMemTilesToGuess -= 1;
System.out.println("It rest " + numberOfMemTilesToGuess + " tiles to guess");
} else {
System.out.println("!!! Wrong Tile !!!");
Icon falseTileIcon;
try {
falseTileIcon = new ImageIcon(getClass().getResource("wrong.png"));
if (falseTileIcon.getIconHeight() > 0)
memTile.setIcon(falseTileIcon);
} catch (Exception e1) {
memTile.setBackground(Color.black);
}
update(getGraphics()); // good trick!!
waitALittleBit(1000);
//TODO !!! FAILED IN LEVEL MESSAGE !!!
dispose();
if (memGridDimX == minDimX && ( memGridDimY == minDimY || memGridDimY == minDimY + 1))
new Memory(minDimX, minDimY);
else if (memGridDimX == memGridDimY)
new Memory(memGridDimX - 1, memGridDimY);
else
new Memory(memGridDimX, memGridDimY -1);
}
System.out.println(">>> Action processed >>>");
if (numberOfMemTilesToGuess == 0) {
System.out.println("\n END OF THE LEVEL");
System.out.println("Congratulations, you guessed all the tiles without error !! \n");
dispose();
//TODO !!!! SHOW INTERLEVEL INFORMATION !!!!
if (memGridDimX != maxDimX && memGridDimY != maxDimY) {
if (memGridDimX == memGridDimY)
new Memory(memGridDimX, memGridDimY + 1);
else
new Memory(memGridDimX + 1, memGridDimY);
} else
System.out.println("You have a really good memory my friend!");
}
}}
I used update(getGraphics()); many times, it was just for a test...
Thanks in advance.

You where told in your last posting to NOT use the update() method.
do
{
t1 = System.currentTimeMillis();
}
while (t1 - t0 < waitingMillisSeconds);
Also, never use a tight loop like that. Its just as bad as using Thread.sleep(...);
You where given suggestions in your last posting!

I think you can use LWJGL, which is a java game library.
https://www.lwjgl.org

Some of the issues may be due to the thread on which the various bit of code run. The first time through you are running on the "Main" thread, and to be completely correct calls to update the AWT/Swing GUI should be done using the "Event Dispatcher Thread".
The actionPerformed method is called from the "Event Dispatcher Thread" and so then the second time you call into the constructor for Memory you are in this thread.
Also, aside from the fact you have implemented a delay with a spin-loop, which is not efficient; you should not delay the "Event Dispatcher Thread".
See this short overview: http://www.javamex.com/tutorials/threads/swing_ui.shtml

Related

I have some problems with ArrayList (quiz of head first java)

I've just started learning java since last week. I'm using book called 'head first java' and i'm struggling with solving problems about ArrayList. Error says "The method setLocationCells(ArrayList) in the type DotCom is not applicable for the
arguments (int[])" and I haven't found the solution :( help me..!
enter image description here
This looks like a Locate & Conquer type game similar to the game named Battleship with the exception that this game is a single player game played with a single hidden ship in a single horizontal row of columnar characters. Rather simplistic but kind of fun to play I suppose. The hard part is to locate the hidden ship but once you've located it, conquering (sinking) it becomes relatively easy. I'm sure this isn't the games' intent since it is after all named "The Dot Com Game" but the analogy could be possibly helpful.
There are several issues with your code but there are two major ones that just can not be there for the game to work:
Issue #1: The call to the DotCom.setLocationCells() method:
The initial problem is located within the DotComGame class on code line 13 (as the Exception indicates) where the call is made to the DotCom.setLocationCells() method. As already mentioned in comments the wrong parameter type is passed to this method. You can not pass an int[] Array to the setLocationCell() method when this method contains a parameter signature that stipulates it requires an ArrayList object. The best solution in my opinion would be to satisfy the setLocationCells() method parameter requirement...supply an ArrayList to this method.
The reason I say this is because all methods within the DotCom class work with an established ArrayList and one of the tasks of one of these methods (the checkYourself() method) actually removes elements from the ArrayList which is easy to do from a collection but very cumbersome to do the same from an Array.
To fix this problem you will need to change the data type for the locations variable located within the DotComGame class. Instead of using:
int[] locations = {randomNum, randomNum + 1, randomNum + 2};
you should have:
ArrayList<Integer> locations = new ArrayList<>(
Arrays.asList(random, randomNum + 1, randomNum + 2));
or you could do it this way:
ArrayList<Integer> locations = new ArrayList<>();
locations.add(randomNum);
locations.add(randomNum + 1);
locations.add(randomNum + 2);
There are other ways but these will do for now. Now, when the call to the setLocationCells() method is made you ahouldn't get an exception this issue should now be resolved.
Issue #2: The call to the DotCom.checkYourself() method:
Again, this particular issue is located within the DotComGame class on code line 18 where the call is made to the DotCom.checkYourself() method. Yet another parameter data type mismatch. You are trying to pass a variable of type String (named guess) to this method whereas its signature stipulates that it requires an integer (int) value. That again is a no go.
To fix this problem you will need to convert the string numerical value held by the guess variable to an Integer (int) value. So instead of having this:
while(isAlive) {
String guess = helper.getUserInput("Enter a Number: ");
String result = theDotCom.checkYourself(guess);
// ... The rest of your while loop code ...
}
you should have something like:
while(isAlive) {
String guess = helper.getUserInput("Enter a Number: ");
/* Validate. Ensure guess holds a string representation
of a Integer numerical value. */
if (!guess.matches("\\d+")) {
System.err.println("Invalid Value (" + guess
+ ") Supplied! Try again...");
continue;
}
int guessNum = Integer.parseInt(guess);
String result = theDotCom.checkYourself(guessNum);
numOfGuesses++;
if (result.equals("kill")) {
isAlive = false;
System.out.println(numOfGuesses + " guesses!");
}
else if (result.equals("hit")) {
// Do Something If You Like
System.out.println("HIT!");
}
else {
System.out.println("Missed!");
}
}
Below is a game named Simple Battleship which I based off of your code images (please don't use images for code anymore - I hate using online OCR's ;)
BattleshipGame.java - The application start class:
import java.awt.Toolkit;
public class BattleshipGame {
public static int gameLineLength = 10;
public static void main(String[] args) {
GameHelper helper = new GameHelper();
Battleship theDotCom = new Battleship();
int score = 0; // For keeping an overall score
// Display About the game...
System.out.println("Simple Battleship Game");
System.out.println("======================");
System.out.println("In this game you will be displayed a line of dashes.");
System.out.println("Each dash has the potential to hide a section of a");
System.out.println("hidden Battleship. The size of this ship is randomly");
System.out.println("chosen by the game engine and can be from 1 to 5 sections");
System.out.println("(characters) in length. The score for each battle is based");
System.out.println("on the length of the game line that will be displayed to");
System.out.println("you (default is a minimum of 10 charaters). You now have");
System.out.println("the option to supply the game line length you want to play");
System.out.println("with. If you want to use the default then just hit ENTER:");
System.out.println();
// Get the desire game line length
String length = helper.getUserInput("Desired Game Line Length: --> ", "Integer", true, 10, 10000);
if (!length.isEmpty()) {
gameLineLength = Integer.parseInt(length);
}
System.out.println();
// Loop to allow for continuous play...
boolean alwaysReplay = true;
while (alwaysReplay) {
int numOfGuesses = 0;
/* Create a random ship size to hide within the line.
It could be a size from 1 to 5 characters in length. */
int shipSize = new java.util.Random().nextInt((5 - 1) + 1) + 1;
int randomNum = (int) (Math.random() * (gameLineLength - (shipSize - 1)));
int[] locations = new int[shipSize];
for (int i = 0; i < locations.length; i++) {
locations[i] = randomNum + i;
}
System.out.println("Destroy the " + shipSize + " character ship hidden in the");
System.out.println("displayed line below:");
System.out.println();
String gameLine = String.join("", java.util.Collections.nCopies(gameLineLength, "-"));
theDotCom.setLocationCells(locations);
// Play current round...
boolean isAlive = true;
while (isAlive == true) {
System.out.println(gameLine);
String guess = helper.getUserInput("Enter a number from 1 to " + gameLineLength
+ " (0 to quit): --> ", "Integer", 1, gameLineLength);
int idx = Integer.parseInt(guess);
if (idx == 0) {
System.out.println("Quiting with an overall score of: " + score + " ... Bye-Bye");
alwaysReplay = false;
break;
}
idx = idx - 1;
String result = theDotCom.checkYourself(idx);
numOfGuesses++;
System.out.println(result);
if (result.equalsIgnoreCase("kill")) {
Toolkit.getDefaultToolkit().beep();
isAlive = false;
/* Tally the score dependent upon the gameLineLength... */
if (gameLineLength <= 10) { score += 5; }
else if (gameLineLength > 10 && gameLineLength <= 20) { score += 10; }
else if (gameLineLength > 20 && gameLineLength <= 30) { score += 15; }
else if (gameLineLength > 30 && gameLineLength <= 40) { score += 20; }
else { score += 25; }
gameLine = gameLine.substring(0, idx) + "x" + gameLine.substring(idx + 1);
System.out.println(gameLine);
System.out.println(numOfGuesses + " guesses were made to sink the hidden ship.");
System.out.println("Your overall score is: " + (score < 0 ? 0 : score));
}
else if (result.equalsIgnoreCase("hit")) {
gameLine = gameLine.substring(0, idx) + "x" + gameLine.substring(idx + 1);
}
if (result.equalsIgnoreCase("miss")) {
score -= 1;
}
System.out.println();
}
// Play Again? [but only if 'alwaysReplay' holds true]
if (alwaysReplay) {
String res = helper.getAnything("<< Press ENTER to play again >>\n"
+ "<< or enter 'q' to quit >>");
if (res.equalsIgnoreCase("q")) {
System.out.println("Quiting with an overall score of: " + score + " ... Bye-Bye");
break;
}
System.out.println();
}
}
}
}
GameHelper.java - The GameHelper class:
import java.util.Scanner;
public class GameHelper {
private final Scanner in = new Scanner(System.in);
public String getUserInput(String prompt, String responseType, int... minMAX) {
int min = 0, max = 0;
if (minMAX.length == 2) {
min = minMAX[0];
max = minMAX[1];
}
if (minMAX.length > 0 && min < 1 || max < 1) {
throw new IllegalArgumentException("\n\ngetUserInput() Method Error! "
+ "The optional parameters 'min' and or 'max' can not be 0!\n\n");
}
String response = "";
while (response.isEmpty()) {
if (prompt.trim().endsWith("-->")) {
System.out.print(prompt);
}
else {
System.out.println(prompt);
}
response = in.nextLine().trim();
if (responseType.matches("(?i)\\b(int|integer|float|double)\\b")) {
if (!response.matches("-?\\d+(\\.\\d+)?") ||
(responseType.toLowerCase().startsWith("int") && response.contains("."))) {
System.err.println("Invalid Entry (" + response + ")! Try again...");
response = "";
continue;
}
}
// Check entry range value if the entry is to be an Integer
if (responseType.toLowerCase().startsWith("int")) {
int i = Integer.parseInt(response);
if (i != 0 && (i < min || i > max)) {
System.err.println("Invalid Entry (" + response + ")! Try again...");
response = "";
}
}
}
return response;
}
public String getUserInput(String prompt, String responseType, boolean allowNothing, int... minMAX) {
int min = 0, max = 0;
if (minMAX.length == 2) {
min = minMAX[0];
max = minMAX[1];
}
if (minMAX.length > 0 && min < 1 || max < 1) {
throw new IllegalArgumentException("\n\ngetUserInput() Method Error! "
+ "The optional parameters 'min' and or 'max' can not be 0!\n\n");
}
String response = "";
while (response.isEmpty()) {
if (prompt.trim().endsWith("-->")) {
System.out.print(prompt);
}
else {
System.out.println(prompt);
}
response = in.nextLine().trim();
if (response.isEmpty() && allowNothing) {
return "";
}
if (responseType.matches("(?i)\\b(int|integer|float|double)\\b")) {
if (!response.matches("-?\\d+(\\.\\d+)?") ||
(responseType.toLowerCase().startsWith("int") && response.contains("."))) {
System.err.println("Invalid Entry (" + response + ")! Try again...");
response = "";
continue;
}
}
// Check entry range value if the entry is to be an Integer
if (responseType.toLowerCase().startsWith("int")) {
int i = Integer.parseInt(response);
if (i != 0 && (i < min || i > max)) {
System.err.println("Invalid Entry (" + response + ")! Try again...");
response = "";
}
}
}
return response;
}
public String getAnything(String prompt) {
if (prompt.trim().endsWith("-->")) {
System.out.print(prompt);
}
else {
System.out.println(prompt);
}
return in.nextLine().trim();
}
}
Battleship.java - The Battleship class:
import java.util.ArrayList;
public class Battleship {
private ArrayList<Integer> locationCells;
public void setLocationCells(java.util.ArrayList<Integer> loc) {
locationCells = loc;
}
// Overload Method (Java8+)
public void setLocationCells(int[] loc) {
locationCells = java.util.stream.IntStream.of(loc)
.boxed()
.collect(java.util.stream.Collectors
.toCollection(java.util.ArrayList::new));
}
/*
// Overload Method (Before Java8)
public void setLocationCells(int[] loc) {
// Clear the ArrayList in case it was previously loaded.
locationCells.clear();
// Fill the ArrayList with integer elements from the loc int[] Array
for (int i = 0; i < loc.length; i++) {
locationCells.add(loc[i]);
}
}
*/
/**
* Completely removes one supplied Integer value from all elements
* within the supplied Integer Array if it exist.<br><br>
*
* <b>Example Usage:</b><pre>
*
* {#code int[] a = {103, 104, 100, 10023, 10, 140, 2065};
* a = removeFromArray(a, 104);
* System.out.println(Arrays.toString(a);
*
* // Output will be: [103, 100, 10023, 10, 140, 2065]}</pre>
*
* #param srcArray (Integer Array) The Integer Array to remove elemental
* Integers from.<br>
*
* #param intToDelete (int) The Integer to remove from elements within the
* supplied Integer Array.<br>
*
* #return A Integer Array with the desired elemental Integers removed.
*/
public static int[] removeFromArray(int[] srcArray, int intToDelete) {
int[] arr = {};
int cnt = 0;
boolean deleteIt = false;
for (int i = 0; i < srcArray.length; i++) {
if (srcArray[i] != intToDelete) {
arr[cnt] = srcArray[i];
cnt++;
}
}
return arr;
}
public String checkYourself(int userInput) {
String result = "MISS";
int index = locationCells.indexOf(userInput);
if (index >= 0) {
locationCells.remove(index);
if (locationCells.isEmpty()) {
result = "KILL";
}
else {
result = "HIT";
}
}
return result;
}
}

Extracting Polynomial Coefficients From input String in JAVA

I made this code for extracting Polynomial coefficients and also evaluating equation in a point,and it is work.
but i want to modify that so the user can enter any shape of polynomial equation.
in my code you have to enter equation like this:
2*x^2+3*x^1+4
but i want :
2*x^5+1*x+6
also if there any term with same power , their coeffs must be added together.
Here is my code in java:
package Priest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class Equation {
private String Eq;
private final String[] C;
private int Deg;
private final String EqHolder;
public Equation(String Equation) {
this.Eq = Equation;
EqHolder = Equation;
Eq = Eq.replaceAll("[^0-9\\-\\.]+", " ");
Eq = Eq.replaceAll("-", " -");
this.C = Eq.split(" ");
}
public String SourceEquation() {
return EqHolder.toUpperCase().replaceAll("\\*", "").replaceAll("[a-zA-Z]", "\\*(X)").replaceAll("\\+", "\\ + ").replaceAll("\\-", "\\ - ");
}
public List<BigDecimal> CaptureCoeff() {
getDegree();
List<BigDecimal> Temp = new ArrayList<>();
for (String S : C) {
Temp.add(new BigDecimal(S));
}
int Location = Temp.indexOf(BigDecimal.valueOf(Deg));
List<BigDecimal> Coeffs = new ArrayList<>();
for (int Counter = Location - 1; Counter < Temp.size(); Counter += 2) {
Coeffs.add(Temp.get(Counter));
}
return Coeffs;
}
public int getDegree() {
int Degree = 0;
for (int Counter = 0; Counter < C.length; Counter += 2) {
if ((new Double(C[Counter])) != 0) {
Degree = new Integer(C[Counter + 1]);
this.Deg = Degree;
break;
}
}
return Degree;
}
public BigDecimal Evaluate(List<BigDecimal> Coefficients, double EvalPoint) {
BigDecimal Output = BigDecimal.ZERO;
for (int Index = 0; Index < Coefficients.size(); Index++) {
Output = Output.add(Coefficients.get(Index).multiply(BigDecimal.valueOf(EvalPoint).pow(Deg--)));
}
return Output;
}
}
and main class:
package Priest;
import java.math.RoundingMode;
public class MainClass {
public static void main(String[] args) {
long Start = System.nanoTime();
String Str = "3.1415x^5-12.6x^4+6x^3+12*x^2-6*x^1-0";
Equation E = new Equation(Str);
System.out.println("Equation is: " + E.SourceEquation());
System.out.println("Coefficients :" + E.CaptureCoeff());
System.out.println("Polynomial Degree: " + E.getDegree());
double Target = 47.784;
System.out.println("Equation # (X:" + Target + ")= " + E.Evaluate(E.CaptureCoeff(), Target).setScale(15, RoundingMode.HALF_UP));
System.out.println("Elapsed Time: " + String.format("%.20G", (System.nanoTime() - Start) / 1.0e6) + " ms.");
}
}
the output:
run:
Equation is: 3.1415*(X)^5 - 12.6*(X)^4 + 6*(X)^3 + 12*(X)^2 - 6*(X)^1 - 0
Coefficients :[3.1415, -12.6, 6, 12, -6, 0]
Polynomial Degree: 5
Equation # (X:47.784)= 717609084.382589022327914
Elapsed Time: 32.306242000000000000 ms.
BUILD SUCCESSFUL (total time: 0 seconds)
Let's go with the following equation String Str2 = "3.1415x^5+6x^2+12*x-5";
Here is the code that I have added upon your code in order to preprocess this equation and made it compatible to your actual logic so that It will treat it without any major change to your code.
To be totally accurate I had to change the following in your equation class:
public List<BigDecimal> CaptureCoeff() {
getDegree();
List<BigDecimal> Temp = new ArrayList<BigDecimal>();
for (String S : C) {
if (! "".equals(S.trim())) {
Temp.add(new BigDecimal(S));
}
}
So I have added the control to check that none of these S strings is trim - empty.
Here is my preprocessing code.
I have added a method called powerSplitt that allows to splitt the equation on the basis of the '^' char.
Then I created another method called generateNullCoeffPolynomeWithDegree that generate a monome in the form 0*X^k. And a similar one that generate all the similar intermediate monomes between the greater power and the lesser power
Example:
String str3 = generateAllNullCoeffPolynomesWithDegreeExclusiveBetween(5, 2);
System.out.println("all poly = " + str3);
will generate: all poly = 0*x^4+0*x^3
Then I created a buildPreProcessedPolynome that takes the initial equation and pre process it to produce one with the null monomes inside of it. And then I just gave it to your equation program and it could process it fine!!!
Here is the code and a call example all done in the MainClass
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
public class MainClass {
private static List<String> workList = new ArrayList<String>();
public static void powerSplitt(String equationText) {
char[] charsList = equationText.toCharArray();
boolean foundTargetChar = false;
int index = 0;
for (int i = 0; i < charsList.length; i++) {
index = i;
if (charsList[i] == '^') {
foundTargetChar = true;
break;
}
}
if (foundTargetChar) {
workList.add(equationText.substring(0, index));
if (index +1 < equationText.length()) {
powerSplitt(equationText.substring(index+1));
} else {
workList.add(equationText);
return;
}
} else {
workList.add(equationText);
}
}
public static String generateNullCoeffPolynomeWithDegree(int degree) {
return "0*x^" + degree;
}
public static String generateAllNullCoeffPolynomesWithDegreeExclusiveBetween(int startDegree, int endDegree) {
if (startDegree-endDegree <= 1) {
return "";
}
int index = 0;
StringBuilder builder = new StringBuilder();
for (int i = startDegree -1; i > endDegree; i--) {
if (index > 0) {
builder.append("+");
}
builder.append(generateNullCoeffPolynomeWithDegree(i));
index++;
}
return builder.toString();
}
public static String buildPreProcessedPolynome(String initialEquationText) {
workList.clear();
powerSplitt(initialEquationText);
StringBuilder resultBuilder = new StringBuilder();
assert workList.size() >= 3;
resultBuilder.append(workList.get(0));
for (int i = 1; i <= workList.size()-2; i++) {
int actualPower = Integer.parseInt( workList.get(i).substring(0,1));
int nextFoundPower = Integer.parseInt( workList.get(i+1).substring(0,1));
System.out.print("actual power = " + actualPower + " and next power = " + nextFoundPower);
System.out.println();
String additionalPolyParts = generateAllNullCoeffPolynomesWithDegreeExclusiveBetween(actualPower, nextFoundPower);
resultBuilder.append("^" + actualPower);
resultBuilder.append("+");
resultBuilder.append(additionalPolyParts);
resultBuilder.append(workList.get(i).substring(1));
}
resultBuilder.append("^" + workList.get(workList.size()-1));
return resultBuilder.toString();
}
public static void main(String[] args) {
workList.clear();
String Str2 = "3.1415x^5+6x^2+12*x-5";
powerSplitt(Str2);
for (String part: workList) {
System.out.println("PART:" + part);
}
System.out.println("-----------------");
long Start = System.nanoTime();
String str3 = generateAllNullCoeffPolynomesWithDegreeExclusiveBetween(5, 2);
System.out.println("all poly = " + str3);
String preprocessed = buildPreProcessedPolynome(Str2);
System.out.println("preprocessed = " + preprocessed);
System.out.println();
Equation E = new Equation(preprocessed);
System.out.println("Equation is: " + E.SourceEquation());
System.out.println("Coefficients :" + E.CaptureCoeff());
System.out.println("Polynomial Degree: " + E.getDegree());
double Target = 47.784;
System.out.println("Equation # (X:" + Target + ")= " + E.Evaluate(E.CaptureCoeff(), Target).setScale(15, RoundingMode.HALF_UP));
System.out.println("Elapsed Time: " + String.format("%.20G", (System.nanoTime() - Start) / 1.0e6) + " ms.");
}
}
And here is the produced results (I haved added some System.out.println to check the results of my methods calls. I just noticed I have to take into account the last constant as a monome of type K*X^0, but I will leave that to you):
PART:3.1415x
PART:5+6x
PART:2+12*x-5
all poly = 0*x^4+0*x^3
actual power = 5 and next power = 2
preprocessed = 3.1415x^5+0*x^4+0*x^3+6x^2+12*x-5
Equation is: 3.1415*(X)^5 + 0*(X)^4 + 0*(X)^3 + 6*(X)^2 + 12*(X) - 5
Coefficients :[3.1415, 0, 0, 6, 12]
Polynomial Degree: 5
Equation # (X:47.784)= 782631805.485054892561514
Elapsed Time: 18,441978000000000000 ms.

Increase of 3 variables

In my program, I have three variables: when one of these variables reaches 100, it must appear the words "variable came first to the finish line."
How do I organize the arrival of the second and third variable, so they come out like this:
variable1-arrived first
variable2-finished second
variable3 finished third
Help!
public Corsa(String name)
{
this.name = name;
System.out.println("Start: " + name);
System.out.println("---------------");
}
public void run()
{
while(finita == false)
{
try
{
avanza = (int) (Math.random()*20+1);
percorso = percorso + avanza;
System.out.println(name + " has path " + percorso + " meters");
if(percorso < 100)
{
System.out.println("---------------");
sleep = (int) (Math.random()*20+1);
Thread.sleep(sleep);
}
else
{
System.out.println("---------------");
System.out.println("---------------");
System.out.println(name + " came in first");
finita = true;
}
}
catch(InterruptedException e){}
Thread.yield();
}
}
}
I haven't tested this (so it might not even compile), but something like the following should work:
public class myRace
{
private int distance = 100;
private float offset = 20;
public int runners[3];
public void run()
{
// Set all runners to 0
for ( int i = 0; i < runners.length; i++ )
runners[i] = 0;
// Run the race and stop when at least 1 runner has reached the distance...
boolean finished = false;
while ( !finished )
{
for ( int i = 0; i < runners.length; i++ )
{
runners[i] += (int)((Math.random() * offset) + 1);
if ( runners[i] >= distance ) finished = true;
}
}
// Race finished now sort the runners
TreeMap<String, int> ranking = new TreeMap<String, int>();
for ( int i = 0; i < runners.length; i++ )
{
// A TreeMap is sorted on its key, not the value!
// The runners number is tagged on, just in case two runners have finished on the same distance.
String sortedKey = Integer.toString(runners[i]) + "." + Integer.toString(i);
ranking.put(sortedKey, i);
}
// Print the results
int pos = 1;
for ( Map.Entry entry : ranking.entrySet() )
{
String key = entry.getKey();
String distance = key.subString(0, key.indexOf(".")); // chop off the "." + runners number.
System.out.println("#" + pos + // position
"." + entry.getValue() + // who
", Distance = " + distance); // distance covered
pos++; // this does take in account whether multiple runners finished on the same distance.
}
}
}

OpenGL - too many textures

I have a 90 frames animation and i want to display it on the minecraft hud.
Here is the code i use now:
String CType = "Target";
int CSpeed = 30;
int fast = 0;
public int CenterRoteryCounter = 0;
#ForgeSubscribe
public void CenterRotery(RenderGameOverlayEvent.Post event){
//========Resolution========
res = new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight);
int width = res.getScaledWidth();
int height = res.getScaledHeight();
//========Resolution========+
if(CenterRoteryCounter == 90){CenterRoteryCounter = 0;}
if(CenterRoteryCounter < 10){
this.mc.renderEngine.func_110577_a(new ResourceLocation("CenterRotery/"+CType+"000" + CenterRoteryCounter + ".png"));
}else{if(CenterRoteryCounter < 100){
this.mc.renderEngine.func_110577_a(new ResourceLocation("CenterRotery/"+CType+"00" + CenterRoteryCounter + ".png"));
}else{
this.mc.renderEngine.func_110577_a(new ResourceLocation("CenterRotery/"+CType+"0" + CenterRoteryCounter + ".png"));
}
}
drawTexturedModalRect((width/2)-44, (height/2)-37, 0, 0, 250, 250);
mc.func_110434_K().func_110577_a(Gui.field_110324_m);
if((fast % CSpeed)==0){CenterRoteryCounter++;}fast++;
}
but as you can see, this is creating ~30 new ResourceLocations every second..!!
How can i pre-load the textures and display them the same way?
You can simply use a private static final Hashmap from your class in a method getResourceLocation(String resourceLocation). Something like :
private static ResourceLocation getResourceLocation(String resourceLocation) {
ResourceLocation myRes = myHashMap.get(resourceLocation);
if (myRes == null) {
myRes = new ResourceLocation(resourceLocation);
myHashMap.put(resourceLocation, myRes);
}
return myRes;
}
It will cache your resources on demand. Just be sure of the necessary amount of memory needed !

Return the index of clicked button?

I have got an array of 30 buttons []. I have a variable buttonClicked. When I press the button how can I get the index and store the index number in the buttonClicked?
Thanks :)
JButton [] buttons = new JButton[30];
for(int i = 1; i <= 30; i++)
{
int btnNumber = (i > 10 && i <= 20) ? (31 - i) : i;
System.out.printf("i = %d, btnNumber = %d%n", i, btnNumber);
buttons[btnNumber - 1] = new JButton("label " + btnNumber);
//buttons[btnNumber - 1].setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
buttons[btnNumber - 1].setBorder(BorderFactory.createEtchedBorder());
buttons[btnNumber - 1].setOpaque(true);
buttons[btnNumber - 1].setBackground(Color.white);
//Puts the player 1 piece on button 1,3,5,7,9 and player 2 piece on button 2,4,6,8,10
if ((btnNumber - 1) < 10)
{
if (((btnNumber - 1) % 2) == 0)
{
buttons[btnNumber - 1].setIcon(piece1);
}
else
{
buttons[btnNumber - 1].setIcon(piece2);
}
}
centerPanel.add(buttons[btnNumber - 1]);
}
//Below is what I am attempting to do, I know is not correct.
public void move()
{
Move = dice.getDiceResult();
int buttonClicked = 0;
if(playerOneTurn =true)
{
buttonclicked + diceResult();
}
//revised
public class MyActionListener implements ActionListener {
Dice dice;
private boolean playerOneTurn = true;
private boolean playerTwoTurn = false;
#Override
public void actionPerformed(ActionEvent e)
{
String num = e.getActionCommand();
int index = Integer.parseInt(num);
int move = dice.getDiceResult();
int positionLanding = 0;
if(playerOneTurn = true)
{
positionLanding = index + move;
positionLanding.setIcon("piece1");//how can I set the image Icon to this position?
}
}
}
1) putClientProperty
buttons[i][j].putClientProperty("column", i);
buttons[i][j].putClientProperty("row", j);
buttons[i][j].addActionListener(new MyActionListener());
and getClientProperty
public class MyActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JButton btn = (JButton) e.getSource();
System.out.println("clicked column " + btn.getClientProperty("column")
+ ", row " + btn.getClientProperty("row"));
}
2) ActionCommand
You can find the button in ActionEvent.getSource(). To find the index it is just a matter of iterating through the array, looking for that particular button.
The prettiest way is using Component.setName. Then you don't even need to maintain variables with your components - you can go straight off of the name
I prefer the strategy suggested by aioobe, but here is another way.
buttons[btnNumber - 1] = new JButton("label " + btnNumber);
buttons[btnNumber - 1].setActionCommand("" + btnNumber);
// ...
// ...later.. in the actionPerformed() method
String num = actionEvent.getActionCommand();
int index = Integer.parseInt(num);
// ..proceed..

Categories

Resources