I am making a guessing game for as my School project, but I am quite new to Android Studio and Java.
At the moment my code looks like this:
public class MainActivity extends AppCompatActivity {
public int score = 0;
int random = random();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button correct = (Button) findViewById(R.id.correct);
Button other = (Button) findViewById(R.id.other);
Button newGame = (Button) findViewById(R.id.newGame);
TextView words = (TextView) findViewById(R.id.words);
}
public Integer random (){
int random = (int )(Math.random() * 5);
return random;
}
private String list[] =
{"Dog", "Cat", "Mouse", "Elephant", "Rat", "Parrot"};
public void clickedButton(View view) {
TextView words = (TextView) findViewById(R.id.words);
if (view.getId()== R.id.newGame)
{
words.setText(list[random]);
score = 0;
Log.i("score", "score = " + score);
}
if (view.getId() == R.id.correct)
{
// set maybe new array so new textview does not give the same value
words.setText(list[random]);
score = score +1;
Log.i("score", "score = " + score);
}
if (view.getId() == R.id.other)
{
// set maybe new array so new textview does not give the same value
words.setText(list[random]);
Log.i("score", "score = " + score);
}
}
}
Idea is simple. I have my array with (at the moment) 6 words in it. So as I launch the game it gives me a random word on screen which I have to describe to others. If they guess it right I press correct, I get another word, if not I can pass and get another word... Well the problem I see is that there is chance that I get the same word over again. So I thought there should be a way how to fix this problem.
I thought about adding like if statements like if index 1 or 2 or 3 then give another word but if I had 100 words it would be monkey work to do it.
So I think there should be a chance how I can delete words from like temp. array, but there is no in-built method to do it.
I was reading that there are those arrayLists and lists but would not it be easier to use Array? and maybe some tips how to?
You can first Create an ArrayList (because it is more flexible):
List<String> list;
Then initialize the object in the constructor and shuffle the ArrayList like below:
list = new ArrayList<String>();
list.add("Dog");
list.add("Cat");
...
//or alternatively list.addAll(Arrays.asList(normalArray)); if you have your data in array
Collections.shuffle(list,new Random(System.nanoTime()); //randomly shuffles your list
Then you can keep track of the index of the last item you read:
int index = 0;
And every time you read an item just increase the index:
words.setText(list.get(index++));
This will do the trick
While there are a variety of ways solve your issue, personally I like mixing the array up (swapping places using random), then just keep an index on what word you are on in the array, so you don't have to keep track of the words in it.
I wrote a code for a similar program for doing a random shuffle on a deck of cards below, it goes through the int times amount, but you can remove it altogether and have a static loop value if you'd like:
// ...
// Random Shuffle
// Tip: Use this method to shuffle, may not be the fastest (not noticeable however), but it makes your array totally randomized.
public static void totalRandom(String[] array, int times)
{
// Random Initialize
Random randomGenerator = new Random();
// Variables
int first = 0;
int second = 0;
// Swap
for (int i = 0; i < times; i++)
{
// Generates number from 0 to array length
first = randomGenerator.nextInt(array.length);
second = randomGenerator.nextInt(array.length);
String word = array[second];
array[second] = array[first];
array[first] = word;
}
}
// ...
then after in your class you would want to write something along the lines of...
//...
int index = 0;
// ...
// Code for user input
// ...
if (userInput.equals(array[index]))
{
// do stuff
index++;
}
// ...
You can cache your last word. Add a String member variable.
...
public int score = 0;
public String cache; // new
Instead of using
words.setText(list[random]);
you can call a method to request a new word. You also save this word to the cache:
...
cache = getRandomWord();
words.setText(cache);
...
Your new method looks like this:
private String getRandomWord(){
int random = random();
String temp = list[random];
if(temp.equals(cache)){
temp = getRandomWord();
}
return temp;
}
Just put this method under your clickButton method. It takes a random word. Is the word equal to the previous word, the method will call itself again to pick another word. If not, it will return the new word.
There is no need to shuffle ArrayLists.
I think a more simple way is pop every shown text out from a copied list.
//when start a new game.
ArrayList<String> currentGameList = YourList.clone();
//when need next word.
String displayText = currentGameList.remove(randomIntInRestSize); //after called remove, you will get the object at list(index), and the object will be removed from the list.
Every game started, you just need to clone a new list from the original word list and play with the list.
Related
so this is the main code for my text-based game.
import java.util.Scanner;
public class D_M_RPG {
public static void main(String[] args) {
//Creating the class to call on my toolbox
D_M_RPGtoolbox toolbox = new D_M_RPGtoolbox();
//Creating the scanner class for user input
Scanner input = new Scanner(System.in);
//Initiating variables and final variables aswell as arrays
//token variable to validate open spots in an array
int slotCounter = 0;
int inventoryExpander = 11;
//First initiated will be the character creation variables
String hairColor = "";
String eyeColor = "";
String skinColor = "";
String gender = "";
//Initiating the arrays for character inventory slots
String[] weaponSlots = new String[10];
//initiating the arrays for the character creation
String[] hairColorARR = {"black","Green","Yellow","Brown","Blue","Blonde","Grey","White"};
String[] eyeColorARR = {"Green","Brown","Blue","Grey",};
String[] skinColorARR = {"White","brown","Black",};
String[] genderARR = {"Male","Female"};
//Creating the introduction title and introduction
System.out.println("Welcome to, COLD OMEN.");
System.out.println("\nNOVEMBER 12th, 2150: ONTARIO, CANADA");
System.out.println("\nYou hear loud shouts and gun fire all around you but can't pinpoint the location of anything, you feel a bit dazed until someone grabs you and you open your eyes and snap out of it.");
System.out.println("\nUnknown: 'Get up, its time to move out. Take this.'");
System.out.println("\nUnknown hands you a 'M4-A4 RIFLE'");
System.out.println("\nyou manage to catch a small glimpse of him before you get up.");
//Character creation screen
System.out.println();
//ONLY WORKS ONCE WONT INCREMEMENT THE SLOTCOUNTER
toolbox.insert(weaponSlots, slotCounter, inventoryExpander, "M4-A4 RIFLE");
System.out.println("\n" + weaponSlots[0]);
toolbox.insert(weaponSlots, slotCounter, inventoryExpander, "ak47");
System.out.println(weaponSlots[0]);
}
}
so I have this method I made to basically add an "item" to the weaponSlots array (the inventory) but whenever I run it it will add to the first element in the array [0] but it wont incremement the slotcounter which should go up by one every time the method is used so that I dont replace any items in the array It should just add items until its full which is checked using the inventoryExpander variable. at the moment I have it printing the element at 0 and 0 for the array but i have checked 1 aswell and 1 is just null no item added it only just replaces the element at 0. heres the code for the method to increment etc:
public class D_M_RPGtoolbox {
//method for random number generating to be used for crit hits, turns, loot generation etc
public int randomGen(){
int x = (int) (Math.random()*((20-0)+1)+0);
return x;
}
//method for inserting into an array ONLY WORKS ONCE WONT INCREMEMENT THE SLOTCOUNTER FIX
public void insert(String[] a, int b, int d , String c) {
if(b < d) {
a[b] = c;
b++;
}//end of if statement
}//end of method
}
What you are actually performing the ++ operation on in b is a copy of the value in slotCounter.
The variable slotCounter is passed into insert "by-value".
This unlike what you probably imagine, that it is passed "by-reference".
One solution would be to do the slotCounter++ from the call row instead; and another would be to let the toolbox own the slotCounter variable completely.
This question uses the image of passing a copy of document content (by value) where changes to the document would not be seen by the sender; or as a link to a shared document (by reference), where changes could be made to the same page that the sender sees.
Its always going to be zero since you are passing zero and incrementing the local variable b.
Try calling the method as below with post increment ++ to slotCounter and see if it works for you,
toolbox.insert(weaponSlots, slotCounter++, inventoryExpander, "M4-A4 RIFLE");
Before I start I want to state that I am learning, I am completely new. Here i have added as much detail as possible.
So, I have an array of textures of different colors, and set a Random to randomize the textures, Like this:
Texture[] bubbles;
Random random = new Random();
int lowRange = 0;
int highRange = 3;
int result = random.nextInt(highRange -lowRange) + 1; //my random
ArrayList<Integer> BubbleXs = new ArrayList<>();
ArrayList<Integer> BubbleYs = new ArrayList<>();
#Override
public void create () {
bubbles = new Texture[4];
bubbles[0] = new Texture("blue.png");
bubbles[1] = new Texture("red.png");
bubbles[2] = new Texture("green.png");
bubbles[3] = new Texture("yellow.png");
}
Then I proceed to draw the texture at a random color falling from the top of the screen using a for loop, like this:
#Override
public void render () {
if (BubbleCount < 120) {
BubbleCount++;
} else {
BubbleCount = 0;
makeBubble();
}
public void makeBubble () {
float width = random.nextFloat() * Gdx.graphics.getWidth();
BubbleXs.add((int)width);
BubbleYs.add(Gdx.graphics.getHeight());
}
for (int i=0; i < BubbleYs.size(); i++) {
batch.draw(bubbles[result], BubbleXs.get(i), BubbleYs.get(i));
BubbleYs.set(i, BubbleYs.get(i) -4);
}
and it draws the textures at a a random perfectly, but only once, when its created, I want them to be a new random each time its looped, so its a different one every time one falls. why is it not doing that? what am I missing?
Thanks in advance!
Edit: I checked out this post: Change texture with random
but its not really helping any.
The reason they're all the same is that you assign a value to result only once, when it is initialized, and you never change it. If you want it to change, you need to use your Random to assign another value.
Your formula random.nextInt(highRange -lowRange) + 1 isn't right if you're wanting a random number between lowRange and highRange inclusive. That's giving you a number between lowRange + 1 and highRange + 1. The correct formula would be random.nextInt(highRange - lowRange) + lowRange.
The way to solve this would be create an additional variable for each bubble that stores the random int. You are already keeping a list for each of the two variables you're already storing (x and y). You could theoretically add a third, but it's to the point where you really just need to create a class for each bubble, so you can expand it easily if you add more features.
class Bubble {
int x;
int y;
int textureIndex;
}
Then replace your two array lists with:
ArrayList<Bubble> bubbles = new ArrayList<>();
And your makeBubble method should look like this:
void makeBubble(){
Bubble bubble = new Bubble();
bubble.x = (int)(random.nextFloat() * Gdx.graphics.getWidth());
bubble.y = Gdx.graphics.getHeight();
bubble.textureIndex = random.nextInt(3);
}
And your for loop for drawing them would look like this. I changed your textures array name here to bubbleTextures so bubbles can be used for the list of Bubble objects.
for (Bubble bubble : bubbles) {
batch.draw(bubbleTextures[bubble.textureIndex], bubble.x, bubble.y);
bubble.y -= 4;
}
There are numerous other issues I'm seeing with your code, but I think it would be overwhelming to explain them all. This at least gets you going in the right direction.
I have created a list of 2D arrays containing randomly generated number values for different locations.
public static int Prices[][] = new int[Cities.length][ItemNames.length];
public static List<int[][]> CityPrices = new ArrayList<int[][]>();
public static void NewDay()
{
for(int i = 0; i<Cities.length; ++i)
{
Prices[i] = PriceGenerator.ReturnPricesForCity(i);
//This method returns an array of random integers
}
CityPrices.add(Prices);
}
But then later when I want to retrieve the price history for a specific item for the amount of days passed, it returns the same value for each day
int Prices[] = new int[GlobalVariables.CityPrices.size()];
String sTest = "";
for(int i = 0; i < Prices.length; ++i)
{
Prices[i] = GlobalVariables.CityPrices.get(i)[spinCity.getSelectedItemPosition()][spinItem.getSelectedItemPosition()];
sTest = sTest + Prices[i] + ",";
}
In this case, the values returned by sTest was : 6055,6055,6055,6055,6055, for five consecutive days.
If I would for instance add a day, the values would change to a range of a new number, which in this case was : 7294,7294,7294,7294,7294,7294,
Please show me what I am doing wrong, as I have been trying to figure this one out the past 4 days with no luck.
Every element in your CityPrices list is the same: in each case, you are adding the Prices two-dimensional array. Your loop modifies Prices[i], but it doesn't change Prices, which is still a reference to the same two-dimensional array right the way through.
I think you're imagining it will pass the contents of the array in its current state, but it doesn't: it passes a reference to the array to the .add() method, so any subsequent changes to the array will be reflected in the contents of CityPrices.
If at the end of your loop you try
CityPrices.get(0) == CityPrices.get(1)
you'll see it returns true.
In the assignment: Prices[i] = GlobalVariables.CityPrices.get(i)[spinCity.getSelectedItemPosition()][spinItem.getSelectedItemPosition()]; you are basically referencing an int[][] at the same index for both dimensions.
On top of that, the spinCity.getSelectedItemPosition() invocation might be returning the same index at every iteration of your loop, hence your identical values.
It's hard to assume anything further as you haven't posted the code for spinCity.
I want to add an image to an ImageButton depending on a number between 0 and 10. My getNumber method is:
public int getNumber(){
// get a random number between 0 and 10
Random randomNumber = new Random();
num = randomNumber.nextInt(10);
return num;
}
I want every image to be unique but the problem I was having was that if numList did contain num it just would leave the button blank. I've tried to call permuteButton again recursively until num is not contained within my list but this does not seem to work.
public void permuteButton(ImageButton btn){
getNumber();
for(int i=0; i<=numList.size(); i++){
//check if the number is already being used
if( numList.contains(num) ){
permuteButton(btn);
}
// else the list doesnt have the number so assign the picture and add number to list
else{
numList.add(num);
assignPictures(btn);
}
}
}
Any help would be appreciated. I'm sorry if this is a simple question.
There are various things wrong with this code:
It would be better to have a single instance of Random instead of creating a new instance on each call to getNumber()
Rather than changing an instance variable within getNumber(), it would be sensible to just return the value and assign that to a local variable in permuteButton
Instead of recursion, you could use a while loop in permuteButton:
int num = getNumber();
while (numList.contains(num)) {
num = getNumber();
}
numList.add(num);
assignPictures(btn); // Presumably you'd now want to pass in num too
It would probably be a better idea to just shuffle the list to start with, create a Queue from it, then you can just take an item from the queue each time you need one. (This would also make it very easy to spot when you've used them all)
My answer is similar to the last suggestion from Jon Skeet.
// might be more than 10 ImageButtons, with only 10 images
for (ImageButton imageButton : imageButtons)
imageButton.putImage(randomImage.next());
...
public class RandomImage {
private final List<Image> shuffledImages;
private int currentIndex;
public RandomImage(List<Image> images) {
shuffledImages = new ArrayList<>(images.size());
shuffledImages.addAll(images);
currentIndex = -1;
}
public Image next() {
currentIndex++;
if (currentIndex % shuffledImages.size() == 0) {
currentIndex = 0;
Collections.shuffle(shuffledImages);
}
return shuffledImages[currentIndex];
}
}
I am writing an app for fellow students, and I am parsing information from a website. I paid a guy to write the parser but did a poor job and he wants more money to help anymore. So im trying to fix it myself.
There is the extractor that grabs the xml info, how the gentlemen had it, was he called it in the main.java like this.
Content1 = extractor.BusRoutes.get(1);
Content2 = extractor.BusRoutes.get(2);
Content3 = extractor.BusRoutes.get(3);
But there is 30+ buses, and to me, that is not a solid idea. So I tried to do a while loop and an array in order to build the list and make it a list in android.
public class BusRoutes extends ListActivity {
TransitXMLExtractor extractor;
public String[] busroutearray()
{
extractor = new TransitXMLExtractor();
String[] busroutearray = new String[40];
int n = 0;
while(n != (busroutearray.length - 1)){
busroutearray[n] = extractor.BusRoutes.get(n);
n++;
}
return busroutearray;
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, busroutearray()));
getListView().setTextFilterEnabled(true);
}
bus when i launch it, i always get a forced quit.
edit, the n++ was there before, but got deleted while changing up the code, but with the n++ it still has same effect.
You need to increment your counter (n). So the code for the loop would be:
while (n != (busroutearray.length - 1)) {
busroutearray[n] = extractor.BusRoutes.get(n);
n++;
}
Better in this case would be a for loop (a bit easier to read and ideal when you just want to iterate through :
for (int i = 0; n < busroutearray.length; i++) {
busroutearray[i] = extractor.BusRoutes.get(i);
}
You might also want to explore using different data structures that are a bit more flexible than arrays (example).
Problem is in your while loop. It is running an infinite while loop because you doesn't change "n" value.
public String[] busroutearray()
{
extractor = new TransitXMLExtractor();
String[] busroutearray = new String[40];
int n = 0;
for (int n = 0; n < busroutearray.length; n++){
busroutearray[n] = extractor.BusRoutes.get(n);
}
}
You are not incrementing n, it's an infinite loop. And Android prolly threw a ANR (Application not Responding).
int n = 0;
while(n < busroutearray.length){
busroutearray[n] = extractor.BusRoutes.get(n);
n++;
}
Though i'm not sure, I think BusRoutes is Some kind of List of String
Why don't you use,
String[] busroutearray = extractor.BusRoutes.toArray(new String[extractor.BusRoutes.size()]);