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 last year.
Improve this question
I'm currently taking an online course in Java using Android Studio. As part of the course we had an exercise to build Higher or Lower number guessing game. The initial code I wrote worked just fine (despite being a bit wordy, but I'm still learning), it generated a random number and everything worked right with all the correct messaging. Here is the working code.
import java.util.Random;
public class MainActivity extends AppCompatActivity {
Random ran = new Random();
int gameStart = 1 + (int) (Math.random() * (30));
public void buttonClick(View view) {
EditText number = (EditText) findViewById(R.id.number);
Button button = (Button) findViewById(R.id.button);
int num = Integer.parseInt(number.getText().toString());
if (num == gameStart) {
Toast.makeText(this, "Correct!", Toast.LENGTH_SHORT).show();
} else if (num > gameStart) {
Toast.makeText(this, "Lower", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Higher", Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
But then the instructor has introduced extra code to make game restart if the answer is correct with a new number by making Random a method and adding it in the initial if statement. In the video it worked but when I added it and compiled the only number Random generates is 0. I have tried everything but for the love of god can't get it to work correctly. Can someone please have a look at the changes below and spot what could be creating this issue? What needs to be ammended?
public class MainActivity extends AppCompatActivity {
int gameStart;
public void gameRestart() {
Random ran = new Random();
int gameStart = 1 + (int) (Math.random() * (30));
}
public void buttonClick(View view) {
EditText number = (EditText) findViewById(R.id.number);
Button button = (Button) findViewById(R.id.button);
int num = Integer.parseInt(number.getText().toString());
if (num == gameStart) {
Toast.makeText(this, "Correct!", Toast.LENGTH_SHORT).show();
gameRestart();
}
int gameStart;
public void gameRestart() {
Random ran = new Random();
int gameStart = 1 + (int) (Math.random() * (30));
}
you never alter the value of instance variable gameStart, so it keeps the default value, which is 0.
You create a local variable gameStart in your constructor, which isn't used afterwards.
Alter your code to this to set the instance variable:
int gameStart;
public void gameRestart() {
Random ran = new Random();
gameStart = 1 + (int) (Math.random() * (30));
}
EDIT: as #AndyTurner remarked: you 're also not using your ran instance of the Random class, so you can delete that variable as well.
public void gameRestart() {
Random ran = new Random();
int gameStart = 1 + (int) (Math.random() * (30));
}
Here, I suppose you want to store your random value inside the member variable called gameStart.
It is not the case because you redefine a local variable with the same number in the method. You just have to delete the int before your variable (and delete the ran line because unused)
public void gameRestart() {
gameStart = 1 + (int) (Math.random() * (30));
}
you can try this;
final int random = new Random().nextInt(50) + 30;
// it will generate random number between 30 & 80
I'm currently working on a school project (a small android game) and so far I've written a code which generates a random equation 2 seconds after the activity InGame is launched and displays it in a textview. Another 5 seconds later, the second equation is generated and displayed in a different textview. Now the user has to decide if the second equation has a bigger result than the first one by either pressing the button bigger or smaller. If it was correct, the next equation should be displayed and it would go on like this until the user decided wrong.
Here is my code so far:
(Code for the first equation):
// Generate random equation and display it in textview
String[] operationSet = new String[]{"+", "-", "/", "*"};
String equation;
static double doubleAnswer1;
public void start1() {
Random random = new Random();
int numOfOperations = random.nextInt(2) + 1;
List<String> operations = new ArrayList<>();
for (int i = 0; i < numOfOperations; i++) {
String operation = operationSet[random.nextInt(4)];
operations.add(operation);
}
int numOfNumbers = numOfOperations + 1;
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < numOfNumbers; i++) {
int number = random.nextInt(10)+1;
numbers.add(number);
}
String equation = "";
for (int i = 0; i < numOfOperations; i++) {
equation += numbers.get(i);
equation += operations.get(i);
}
equation += numbers.get(numbers.size() -1);
TextView TextEquation = (TextView)findViewById(R.id.textView_first_equation);
TextEquation.setText(equation);
// Evaluate the result of the equation
double doubleAnswer1 = eval(equation);
String stringAnswer = Double.toString(doubleAnswer1);
TextView textAnswer = (TextView)findViewById(R.id.textView4);
textAnswer.setText(stringAnswer);
}
(Code for second equation (basically same as for first equation except the name of the strings and doubles are different)):
String equation2;
static double doubleAnswer2;
public void start2() {
Random random = new Random();
int numOfOperations = random.nextInt(2) + 1;
List<String> operations = new ArrayList<>();
for (int i = 0; i < numOfOperations; i++) {
String operation = operationSet[random.nextInt(4)];
operations.add(operation);
}
int numOfNumbers = numOfOperations + 1;
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < numOfNumbers; i++) {
int number = random.nextInt(10)+1;
numbers.add(number);
}
String equation2 = "";
for (int i = 0; i < numOfOperations; i++) {
equation2 += numbers.get(i);
equation2 += operations.get(i);
}
equation2 += numbers.get(numbers.size() -1);
TextView TextEquation = (TextView)findViewById(R.id.textView3);
TextEquation.setText(equation2);
// Evaluate the result of the equation
double doubleAnswer2 = eval(equation2);
String stringAnswer = Double.toString(doubleAnswer2);
TextView textAnswer = (TextView)findViewById(R.id.textView_result2);
textAnswer.setText(stringAnswer);
}
And here is my onCreate code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ingame);
// Display first equation 2 seconds after the activity is launched
final Handler handler1 = new Handler();
handler1.postDelayed(new Runnable() {
#Override
public void run() {
start1();
}
}, 2000);
final Handler handler2 = new Handler();
handler2.postDelayed(new Runnable() {
#Override
public void run() {
start2();
}
}, 7000);
// Check if user was right or wrong
final Button buttonBigger = (Button)findViewById(R.id.button_bigger);
final Button buttonSmaller = (Button)findViewById(R.id.button_smaller);
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if(v.equals(buttonBigger) && doubleAnswer1 < doubleAnswer2) {
Log.v("TAG", "you are right");
} else if(v.equals(buttonSmaller) && doubleAnswer1 > doubleAnswer2) {
Log.v("TAG", "you are right");
} else {
Log.v("TAG", "you are wrong");
}
}
};
buttonBigger.setOnClickListener(listener);
buttonSmaller.setOnClickListener(listener);
}
The app launches correctly and it also displays the first and second equation, but when I press one of the button, it tells me in the logcat you are wrong but I decided 100% correct. However if I debug the app, it tells me that doubleAnswer1 and doubleAnswer2 are both = 0. That's why it all ways tells me 'you are wrong'. I don't know how to fix this, maybe I need to store the doubleAnswer1 and doubleAnswer2 somewhere.
I really don't know what to do, so it would really help me if someone has an idea what to do.
If anything is unclear in my question, feel free to ask and I will try to clarify the problem.
Thank you in advance for your help!
I think your problem lies here:
double doubleAnswer1 = eval(equation);
I did a quick internet search and did not find any native function called eval(). Instead you should look into Script Engine Manager for java:
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String foo = "40+2";
System.out.println(engine.eval(foo));
or exp4j which is shown here:
Executing math equation in Android
Edit:
change the following:
double doubleAnswer1 = eval(equation);
to:
doubleAnswer1 = eval(equation);
Similarly do the same for doubleAnswer2
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to connect two string that hasn't same word for matching game. I've the code that, I've create, work with same text. For example if first pick = "word1" the second pick must has same text "word1".I want first pick = "word1" and second pick = "definition1". Please help
for more details see the code below .
protected void onCreate(Bundle savedInstanceState) {
text[0] = "word1";
text[1] = ("definition1");
twotext[0] = "word2";
twotext[1] = ("definition2");
threetext[0] = "word3";
threetext[1] = ("definition3");
foretext[0] = "word4";
foretext[1] = ("definition4");
}
public void setBoard()
{
board = new String[8];
//Assigns each image to two random positions
for(int i = 0; i < 2; i++)
{
int pic1 = (int)(Math.random()*board.length);
int pic2 = (int)(Math.random()*board.length);
int pic3 = (int)(Math.random()*board.length);
int pic4 = (int)(Math.random()*board.length);
while(board[pic1]!=null)
{
pic1 = (int)(Math.random()*board.length);
}
board[pic1] = text[i];
while(board[pic2]!=null)
{
pic2 = (int)(Math.random()*board.length);
}
board[pic2] = twotext[i];
while(board[pic3]!=null)
{
pic3 = (int)(Math.random()*board.length);
}
board[pic3] = threetext[i];
while(board[pic4]!=null)
{
pic4 = (int)(Math.random()*board.length);
}
board[pic4] = foretext[i];
}
//Sets the question mark image to each ImageView and makes each clickable
for(int i = 0; i < board.length; i++)
{
pics[i].setText(board[i]);
}
for(Button i: pics)
{
i.setClickable(true);
}
}
//If an image is clicked it will "flip" to reveal the image below
//If the first and second pick match, 100 points are awarded, otherwise 200 are deducted
public void click(View v){
switch (v.getId())
{
case R.id.i0:
pics[0].setText(board[0]);
if(firstPick) pick1 = 0;
else pick2 = 0;
break;
case R.id.i1:
pics[1].setText(board[1]);
if(firstPick) pick1 = 1;
else pick2 = 1;
break;
case R.id.i2:
pics[2].setText(board[2]);
if(firstPick) pick1 = 2;
else pick2 = 2;
break;
case R.id.i3:
pics[3].setText(board[3]);
if(firstPick) pick1 = 3;
else pick2 = 3;
break;
case R.id.i4:
pics[4].setText(board[4]);
if(firstPick) pick1 = 4;
else pick2 = 4;
break;
case R.id.i5:
pics[5].setText(board[5]);
if(firstPick) pick1 = 5;
else pick2 = 5;
break;
case R.id.i6:
pics[6].setText(board[6]);
if(firstPick) pick1 = 6;
else pick2 = 6;
break;
case R.id.i7:
pics[7].setText(board[7]);
if(firstPick) pick1 = 7;
else pick2 = 7;
break;
}
if(!firstPick)
{
pics[pick2].setClickable(false);
if(board[pick1]==board[pick2]) {
matches++;
score += 100;
layout.setBackgroundColor(Color.GREEN);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
layout.setBackgroundColor(Color.WHITE);
}
}, 500);
}
............
............
for all k
case R.id.ik:
pics[k].setText(board[k]);
you set the same old text, because textof (pics[i]) = board[i]:
for(int i = 0; i < board.length; i++)
{
pics[i].setText(board[i]);
}
You said you want different match(that you predefined)
case R.id.ik:
pics[k].setText(board[matches.get(board[i])]);
where matches is your predifined matches:
HashMap<String, String> matches = new HashMap<String, String>();
and you put your matches any way you like
for(int i = 1; i <= 4; i++)
matches.put("word"+i, "definition" + i);
Note: your code for board part is excessive, You can accomplish everything in onCreate in just a couple of lines with a much better understanding.
Alright so here is my problem and my question to you.....
I have a game in which it needs to load images from the jar file (all the images are packed into the jar file like so):
I first have the unzip of the jar file:
Then it goes to:
Then inside each of those folder i have something that looks like this:
Now reminder above is the Jarfile GameClient.jar unziped and you see where the cards are in it.
So here is my code for trying to load each and every one of those images into memory
private void addCardsAndChangeSize() throws IOException
{
String tempString;
ImageIcon tempIcon;
allCards.clear();
ClassLoader cldr = this.getClass().getClassLoader();
URL imageURL;
for(int i = 0; i < all.length; i++)
{
for(int x = 0; x < clubs.length; x++)
{
tempString = all[i][x];
tempString = "/cards/"+cardFolders[i]+"/"+tempString;
imageURL = cldr.getResource(tempString);
tempIcon = resizeImage(new ImageIcon(imageURL),70,70,false);
tempString = all[i][x];
tempIcon.setDescription(tempString);
allCards.add(tempIcon);
}
}
backCard = resizeImage(new ImageIcon(cldr.getResource(back)),70,70,false);
}
So i call that in the contructor to load all the images into an ArrayList here is the whole class if you want to know what i do.
package global;
import java.awt.*;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Cards
{
private ImageIcon backCard = new ImageIcon("cards/backCard.jpg");
private String back = "/cards/backCard.jpg";
private String[] cardFolders = {
"clubs","diamonds","hearts","spades"
};
private String[] clubs = {
"aceClubs.jpg","eightClubs.jpg","fiveClubs.jpg","fourClubs.jpg","jackClubs.jpg",
"kingClubs.jpg","nineClubs.jpg","queenClubs.jpg","sevenClubs.jpg","sixClubs.jpg",
"tenClubs.jpg","threeClubs.jpg","twoClubs.jpg"
};
private String[] diamonds = {
"aceDia.jpg","eightDia.jpg","fiveDia.jpg","fourDia.jpg","jackDia.jpg","kingDia.jpg",
"nineDia.jpg","queenDia.jpg","sevenDia.jpg","sixDia.jpg","tenDia.jpg","threeDia.jpg",
"twoDia.jpg"
};
private String[] hearts = {
"aceHearts.jpg","eightHearts.jpg","fiveHearts.jpg","fourHearts.jpg","jackHearts.jpg",
"kingHearts.jpg","nineHearts.jpg","queenHearts.jpg","sevenHearts.jpg","sixHearts.jpg",
"tenHearts.jpg","threeHearts.jpg","twoHearts.jpg"
};
private String[] spades = {
"aceSpades.jpg","eightSpades.jpg","fiveSpades.jpg","fourSpades.jpg","jackSpades.jpg",
"kingSpades.jpg","nineSpades.jpg","queenSpades.jpg","sevenSpades.jpg","sixSpades.jpg",
"tenSpades.jpg","threeSpades.jpg","twoSpades.jpg"
};
private String[][] all = {
clubs,diamonds,hearts,spades
};
private ArrayList<ImageIcon> allCards = new ArrayList<ImageIcon>();
public Cards()
{
try
{
addCardsAndChangeSize();
shuffle();
}
catch(Exception e)
{e.printStackTrace();}
}
/**
* #param x Cards name with extension
* #return Face Value of Card
*/
public static int getFaceValue(String x)
{
int face = 0;
switch(x)
{
case "aceClubs.jpg":
case "aceDia.jpg":
case "aceHearts.jpg":
case "aceSpades.jpg":
face = 1;
break;
case "eightClubs.jpg":
case "eightDia.jpg":
case "eightHearts.jpg":
case "eightSpades.jpg":
face = 8;
break;
case "fiveClubs.jpg":
case "fiveDia.jpg":
case "fiveHearts.jpg":
case "fiveSpades.jpg":
face = 5;
break;
case "fourClubs.jpg":
case "fourDia.jpg":
case "fourHearts.jpg":
case "fourSpades.jpg":
face = 4;
break;
case "jackClubs.jpg":
case "jackDia.jpg":
case "jackHearts.jpg":
case "jackSpades.jpg":
case "kingClubs.jpg":
case "kingDia.jpg":
case "kingHearts.jpg":
case "kingSpades.jpg":
case "queenClubs.jpg":
case "queenDia.jpg":
case "queenHearts.jpg":
case "queenSpades.jpg":
case "tenClubs.jpg":
case "tenDia.jpg":
case "tenHearts.jpg":
case "tenSpades.jpg":
face = 10;
break;
case "twoClubs.jpg":
case "twoDia.jpg":
case "twoHearts.jpg":
case "twoSpades.jpg":
face = 2;
break;
case "threeClubs.jpg":
case "threeDia.jpg":
case "threeHearts.jpg":
case "threeSpades.jpg":
face = 3;
break;
case "sixClubs.jpg":
case "sixDia.jpg":
case "sixHearts.jpg":
case "sixSpades.jpg":
face = 6;
break;
case "sevenClubs.jpg":
case "sevenDia.jpg":
case "sevenHearts.jpg":
case "sevenSpades.jpg":
face = 7;
break;
case "nineClubs.jpg":
case "nineDia.jpg":
case "nineHearts.jpg":
case "nineSpades.jpg":
face = 9;
break;
}
return face;
}
//shuffles all the cards in the deck
private void shuffle()
{
long seed = System.nanoTime();
Collections.shuffle(allCards, new Random(seed));
}
/**
* Chooses a card at random from the deck. Also removes that card when chosen
* #return randomly chosen card
*/
public ImageIcon getRandomCard()
{
int index = ((int)Math.random() * allCards.size());
return allCards.remove(index);
}
/**
* #return Image of the back of a card
*/
public ImageIcon getBackCard()
{return backCard;}
public static ImageIcon parseImage(String x)
{
if(x.contains("Dia"))
return new ImageIcon("cards/diamonds/"+x);
else
if(x.contains("Clubs"))
return new ImageIcon("cards/clubs/"+x);
else
if(x.contains("Hearts"))
return new ImageIcon("cards/hearts/"+x);
else
if(x.contains("Spades"))
return new ImageIcon("cards/spades/"+x);
return null;
}
//adds all the cards and adds a description to them loaded into memory
private void addCardsAndChangeSize() throws IOException
{
String tempString;
ImageIcon tempIcon;
allCards.clear();
ClassLoader cldr = this.getClass().getClassLoader();
URL imageURL;
for(int i = 0; i < all.length; i++)
{
for(int x = 0; x < clubs.length; x++)
{
tempString = all[i][x];
tempString = "/cards/"+cardFolders[i]+"/"+tempString;
imageURL = cldr.getResource(tempString);
tempIcon = resizeImage(new ImageIcon(imageURL),70,70,false);
tempString = all[i][x];
tempIcon.setDescription(tempString);
allCards.add(tempIcon);
}
}
backCard = resizeImage(new ImageIcon(cldr.getResource(back)),70,70,false);
}
//resizes images
public ImageIcon resizeImage(ImageIcon imageIcon, int width, int height, boolean max)
{
Image image = imageIcon.getImage();
Image newimg = image.getScaledInstance(-1, height, java.awt.Image.SCALE_SMOOTH);
int width1 = newimg.getWidth(null);
if ((max && width1 > width) || (!max && width1 < width))
newimg = image.getScaledInstance(width, -1, java.awt.Image.SCALE_SMOOTH);
return new ImageIcon(newimg);
}
}
I keep getting null pointer exception on the tempIcon = resizeImage(new ImageIcon(imageURL),70,70,false);
Can anyone tell me why this isn't loading the images properly? Reminder i am pre-loading them into memory. My question is not how to make this better i am just simply asking what am i doing wrong with the class loader and stuff like that......
I am somewhat new at java and i know some of this code will look horrible to you but please again i am not asking how to make this code "pro" im just looking for the explanation why its giving me null.
Thanks!
P.S. If you need more pictures of info or w.e. i will try to put that up right away
Your problem is that cldr.getResource(tempString); does not return object but null. Then, something is wrong with tempString. Classloader cannot find this file, so returns null.
Change tempString = "/cards/"+cardFolders[i]+"/"+tempString;
To tempString = "cards/"+cardFolders[i]+"/"+tempString;
You should be using the getResource of Class, not ClassLoader. The getResource method in Class does useful transformations on the path before giving it to the ClassLoader version of the method, like deciding if the path is relative to the class or absolute, and so ClassLoader doesn't expect to see things like / at the start of the path. You can see this clearly in the getResource javadoc.
So i found out the solution i still don't quite understand why this is the answer but here ya go.
This is the revised code and works fine
private void addCardsAndChangeSize() throws Exception
{
String tempString;
ImageIcon tempIcon;
allCards.clear();
URL imageURL;
for(int i = 0; i < all.length; i++)
{
for(int x = 0; x < clubs.length; x++)
{
tempString = all[i][x];
tempString = "/cards/"+cardFolders[i]+"/"+tempString;
imageURL = this.getClass().getResource(tempString);
System.out.println(tempString);
System.out.println(imageURL == null);
tempIcon = resizeImage(new ImageIcon(imageURL),70,70,false);
tempString = all[i][x];
tempIcon.setDescription(tempString);
allCards.add(tempIcon);
}
}
backCard = resizeImage(new ImageIcon(this.getClass().getResource(back)),70,70,false);
}
You have to have that "/cards/" and also you this.getClass().getResource(String res);
Thanks for all your help guys!
I have Images in drawable and I shuffle these images But I want that R.drawable.a this image come 5 time and this R.drawable.b come 10 time but in my code image come again and again.
My question is that I want that image a R.drawable.a come 5 time after that image R.drawable.a remove from list and other images come on shuffling all images .
But in mean time image a R.drawable.a come n time
public void addNewImageToScreen() {
//array of all drawable id's
int pics[] = { R.drawable.a, R.drawable.b, R.drawable.c, ...etc...};
Random rand = new Random();
int pos = rand.nextInt(pics.length);
addNewImageToScreen(pics[pos]);
}
Can Anybody help me how this is possible?
You need to remove the one you have shown earlier
addNewImageToScreen(pics[pos]);
int arraySize=pics.length;
pics[pos] = pics[--arraySize];
Edit:
or use this logic
ArrayList picsarr=Arrays.asList(pics);
for(int i=0;i<picsarr.size;i++)
{
Collections.shuffle(picsarr);
addNewImageToScreen(picsarr.get[i]);
picsarr.remove(i);
}
Try this code i think it will help you but i am not sure in my case it works fine
Random random = new Random( System.currentTimeMillis() );
List<Integer> generated = new ArrayList<Integer>();
for (int i = 0; i < imageViews.length; i++) {
int v = imageViews[i];
int next = random.nextInt( 15 ) + 1;
if ( !generated.contains( next ) ) {
generated.add( next );
ImageView iv = (ImageView) findViewById( v );
iv.setImageResource( images[next] );
}
else {
i--;
}
}
After some discussion with this fella it seems that this is what he wants:
private ArrayList<Integer> mDrawableIds = new ArrayList<Integer>();
private void populateList() {
mDrawableIds.add(R.drawable.a);
mDrawableIds.add(R.drawable.b);
mDrawableIds.add(R.drawable.c);
}
private int returnImageResource(int buttonClickCount) {
int imageResource = -1;
switch (buttonClickCount) {
case 1:
imageResource = mDrawableIds.get(0);
break;
case 2:
imageResource = mDrawableIds.get((int) (Math.random() * mDrawableIds.size()));
break;
case 3:
imageResource = mDrawableIds.get(1);
break;
// more cases here
case 10:
imageResource = mDrawableIds.get((int) (Math.random() * mDrawableIds.size()));
mDrawableIds.remove(0);
break;
}
return imageResource;
}
I left out some code but this should get you started. What you lacked was an ArrayList which you can remove entries from dynamically.