How to retrieve value changes made from a For Loop within it's own method in Android Studio? - java

I have a for loop within my main activity that is used to randomly shuffle/reassign the values within an array at the beginning of every time the application is opened.
I was told that for loops in Android Studio could only exist within a method (after getting errors when it was placed without one), but by doing so the random shuffling of the array is not carried over to the rest of the click events that are outside of the method and it just continues to output the same originally assigned values of in the array.
int[] money = {1,10,5,2,20,500,50,100,1000000,5000,1000,50000,100000,500000,250000,10000};
int swap1;
int swap2;
int temp;
Random random = new Random();
void what(){
for (int j=0;j<16;j+=1)
{
swap1 = random.nextInt(16);
swap2 = random.nextInt(16);
temp = money[swap1];
money[swap1] = money[swap2];
money[swap2] = temp;
}
}
The click events that are using the values from this array are like this one:
one.setOnClickListener(new View.OnClickListener() {
public void onClick(View b) {
one.setVisibility(View.INVISIBLE);
counter++;
money[0] = 0;
Context one = getApplicationContext();
CharSequence message1 = "$1";
int duration = Toast.LENGTH_LONG; //this could also be a number
final Toast one1 = Toast.makeText(one, message1, duration);
one1.show();
for (int x = 0; x < 16; x++) {
sum += money[x];
}
banker = sum / 16;
Context oney = getApplicationContext();
CharSequence message1y = "The Banker offers you $" + banker + " for your case.";
int durationy = Toast.LENGTH_LONG; //this could also be a number
final Toast one1y = Toast.makeText(oney, message1y, durationy);
one1y.show();
}
});
The aim was that if I were to click this button this time the money output was something like $500, and the next time I opened the application it would randomly shuffle and I might get a new value like $1.

You might want to check out Collections.shuffle() instead of implementing it (don't reinvent the wheel etc).
Sounds like what you want to do is call the shuffle method from inside onCreate() and onResume()

You should do the shuffle inside of the "onCreate" method.
public void onCreate(Bundle savedInstanceState){
...
int[] money = {1,10,5,2,20,500,50,100,1000000,5000,1000,50000,100000,500000,250000,10000};
int swap1;
int swap2;
int temp;
Random random = new Random();
void what(){
for (int j=0;j<16;j+=1)
{
swap1 = random.nextInt(16);
swap2 = random.nextInt(16);
temp = money[swap1];
money[swap1] = money[swap2];
money[swap2] = temp;
}
}
}

Related

changing the color of an ellipse using hashtag data using Twitter4j 3.0.3

Okay, so i dont really know much about writing code, yet. I am working on a project that uses twitter API data. My goal for the project is to use hash tags to represent both good and bad things (for sake of simplicity, lets use #good and #bad).
I want that hashtag data to modify the color of a simple ellipse to a shade of color in between red and green, depending on the number of #good and #bad tweets.
I like to think of it as a +100/-100 spectrum. each #good tweet is +1, each #bad is -1. If it is at -100 tweets, then the ellipse is full red. If it is at +100 tweets, then the ellipse is full green.
I know this is a little complicated, but its for an art project im doing. I followed a tutorial and currently have the twitter data responding on a simple array list of tweets (tutorial # https://www.youtube.com/watch?v=gwS6irtGK-c)
I am using processing, java, twitter4j 3.0.3, and a macbook pro with OSX el capitan 10.11.3
Any help would be greatly appreciated. Even pointing me in the direction on how to code it myself. If you need more information from me, ill respond as quickly as I see it!
ConfigurationBuilder cb = new ConfigurationBuilder();
Twitter twitterInstance;
Query queryForTwitter;
ArrayList tweets;
void setup() {
cb.setOAuthConsumerKey("****");
cb.setOAuthConsumerSecret("****");
cb.setOAuthAccessToken("****");
cb.setOAuthAccessTokenSecret("****");
cb.setUseSSL(true);
twitterInstance = new TwitterFactory( cb.build()
).getInstance();
queryForTwitter = new Query("#good");
size(640,440);
FetchTweets();
} //setup
void draw() {
background(0);
DrawTweets();
} //draw
void DrawTweets() {
for(int i=0; i<tweets.size(); i++) {
Status t = (Status) tweets.get(i);
String user = t.getUser().getName();
String msg = t.getText();
text(user + ": " + msg,
20,15+i*30-mouseY, width-20, 40);
} //for
} //drawTweets
void FetchTweets(){
try {
QueryResult result = twitterInstance.search(
queryForTwitter );
tweets = (ArrayList) result.getTweets();
} catch(TwitterException te) {
println("Couldn't connect: " +te);
} // end of catch TwitterException
}// end of FetchAndDrawTweets()
SECOND VERSION:
ConfigurationBuilder cb = new ConfigurationBuilder();
Twitter twitterInstance;
Query queryForTwitter;
//ArrayList tweets;
void setup() {
cb.setOAuthConsumerKey("****");
cb.setOAuthConsumerSecret("****");
cb.setOAuthAccessToken("****");
cb.setOAuthAccessTokenSecret("****");
cb.setUseSSL(true);
//twitterInstance = new TwitterFactory( cb.build()
// ).getInstance();
//queryForTwitter = new Query("#feelthebern");
size(640,440);
int numGood = 50;
int numBad = 50;
for (int i = 0; i < numGood; i++) {
tweets.add("#good");
}
for (int i = 0; i < numBad; i++) {
tweets.add("#bad");
}
} //setup
ArrayList<String> tweets = new ArrayList<String>();
//create a function that counts the tweets
//that contain a certain hashtag
int countTweets(String hashtag){
int total = 0;
for(String tweet : tweets){
if(tweet.contains(hashtag)){
total++;
}
}
return total;
}
void draw(){
//count the good and bad tweets
int goodTweets = countTweets("#good");
int badTweets = countTweets("#bad");
//calculate color based on tweet counts
float r = badTweets/100.0 * 255;
float g = goodTweets/100.0 * 255;
float b = 0;
background(r, g, b);
}
You have to break your problem down into smaller steps.
Step 1: Create a function that simply returns an ArrayList of tweets.
Step 2: Create a function that takes that ArrayList and a String value, and returns the number of times that String occurs in the tweets in the ArrayList.
This code assumes you have a ArrayList<String> tweets:
int countTweets(String hashtag){
int total = 0;
for(String tweet : tweets){
if(tweet.contains(hashtag)){
total++;
}
}
return total;
}
Step 3: Calculate the color based on the number of tweets containing each word. You said you'll always have 100 tweets, so you can just divide the tweet count by 100, then multiply by 255 to get the color value.
Putting it all together, it looks like this:
ArrayList<String> tweets = new ArrayList<String>();
void setup() {
//you would actually get these from twitter,
//but for testing let's just fill them ourselves
int numGood = 50;
int numBad = 50;
for (int i = 0; i < numGood; i++) {
tweets.add("#good");
}
for (int i = 0; i < numBad; i++) {
tweets.add("#bad");
}
}
//create a function that counts the tweets
//that contain a certain hashtag
int countTweets(String hashtag){
int total = 0;
for(String tweet : tweets){
if(tweet.contains(hashtag)){
total++;
}
}
return total;
}
void draw(){
//count the good and bad tweets
int goodTweets = countTweets("#good");
int badTweets = countTweets("#bad");
//calculate color based on tweet counts
float r = badTweets/100.0 * 255;
float g = goodTweets/100.0 * 255;
float b = 0;
background(r, g, b);
}

Randomize String Array and display all of the values

I'm making a card game, and I've arrived at the shufflin' time.
I've to shuffle a few cards (that are chosen before from the user, so they're not always the same amount) and then display them to the user one by one.
As I'm still developing the game's logic I'm displaying cards' name by changing a button text.
But I get stuck when I try to get the cards' name and set them as the button's text.
What happens is me gettin' a blank button or just with "Masons" or "Villager" String. Infact if I check the log I see that all the others cards(characters) get displayed as "null".
This is how I tried to achieve the goal (Yes I'm a newbie):
This is the head:
int demoniac;
int guard;
int masons;
int medium;
int mythomaniac;
int owl;
int villager;
int werehamster;
int all;
int i;
int t;
String[] characters = new String[24];
Button randomButton;
My method to addAll the cards(characters):
public void addAll(){
for(i = 0; i < all; i++){
add(demoniac, "Demoniac");
add(guard, "Guard");
add(medium, "Medium");
add(mythomaniac, "Mythomaniac");
add(owl, "Owl");
add(werehamster, "Werehamster");
add(villager, "Villager");
add(masons, "Masons");
}
}
My method to add and manage the various types of cards(characters):
public int add(int character, String name){
if(character != 0 && name == "Villager"){
for(t = 0; t < character; t++){
i+=t;
characters[i] = name;}
}
else if(character == 2 && name == "Masons"){
characters[i] = name;
i++;
characters[i] = name;
Toast.makeText(randomSelection.this, "works", Toast.LENGTH_SHORT).show();
}else if(character != 0){
characters[i] = name;
}
return i;
}
To randomize:
public void randomize(){
Collections.shuffle(Arrays.asList(characters));
for (int s = 1; s < characters.length; s++)
{
System.out.println(characters[s]);
}
}
The method to display a different card(character) each time the user clicks the button:
public void show(View view){
for (int s = 1; s < characters.length; s++)
{
randomButton.setText(characters[s]);
}
}
EDIT:
I've noticed the no sense for loop I've done, by the way you should know although most of the characters are only 1 of their kind (demoniac, guard, etc..) there are 2 Masons and from 5 to 12 Villagers, so We need to retrieve these ints and add as much Strings to the Array as much we're told from those ints.
Example: If I get 6 Villagers, I've to add the String "Villager" 6 times into the String Array.
Then I've set that s value to 1 'cause I've to display the first
String ([0]) as soon as the Activity gets started, so on the OnCreate() method.
Maybe I'm wrong, if so I please you to correct me!
Getting a blank button or just with "Masons" or "Villager" String
That is because you only set the Button's text with the last element of the list. Which is either null or "Masons" (not seeing how it could be "Villager").
for (int s = 1; s < characters.length; s++)
{
randomButton.setText(characters[s]);
}
If I check the log I see that all the others cards(characters) get displayed as "null"
You only set position 0 of your array. For example, you don't initialize the positions, so these int values default to 0.
int demoniac;
int guard;
int all;
Then
for(i = 0; i < all; i++){
add(demoniac, "Demoniac");
add(guard, "Guard");
Really, that loop shouldn't be entered because all equals 0.
Additionally
Collections are zero-indexed, so this doesn't print element 0. You need to set int s = 0;.
for (int s = 1; s < characters.length; s++)
It isn't clear to me what the add(int character, String name) method is returning, but if you explain it, I will update this answer.
I believe this code fulfills most of what you are trying to achieve
// Where the characters are stored
private ArrayList<String> characters;
public void initDeck() {
if (characters == null)
characters = new ArrayList<String>();
// Extract the numbers if you actually need them, otherwise, they just are constants
addCharacter("Demoniac", 1, characters);
addCharacter("Guard", 1, characters);
addCharacter("Medium", 1, characters);
addCharacter("Mythomaniac", 1, characters);
addCharacter("Owl", 1, characters);
addCharacter("Werehamster", 1, characters);
addCharacter("Villager", 5, characters);
addCharacter("Masons", 1, characters);
}
public void addCharacter(String name, int amount, ArrayList<String> cards) {
if (amount < 0) {
throw new IllegalArgumentException("Must add a non-negative number of characters for " + name);
}
// Don't use '==' for Strings
if (name.equals("Villager")) {
if (amount != 5 || amount != 12) {
throw new IllegalArgumentException("There can only be 5 or 12 " + name);
}
}
for (int i = 0; i < amount; i++) {
cards.add(name);
}
}
public int searchCharacters(String character, ArrayList<String> cards) {
return cards.indexOf(character);
}
public Map<String, Integer> getAllCharacterPositions() {
Map<String, Integer> allPositions = new LinkedHashMap<String, Integer>();
for (int i = 0; i < characters.size(); i++) {
allPositions.put(characters.get(i), i);
}
return allPositions;
}
void run() {
// initialize the characters
initDeck();
// shuffle them
Collections.shuffle(characters);
// print them all out
for (int i = 0; i < characters.size(); i++) {
System.out.printf("%d: %s\n", i, characters.get(i));
}
// Find the position of a character
System.out.println();
String findCharacter = "Owl";
// Option 1 -- always linear search lookup
System.out.printf("%d: %s\n", searchCharacters(findCharacter, characters), findCharacter);
// Option 2 -- one-time linear scan, constant lookup
Map<String, Integer> positions = getAllCharacterPositions();
System.out.printf("%d: %s\n", positions.get(findCharacter), findCharacter);
// Get a random character
System.out.println();
Random rand = new Random(System.currentTimeMillis());
int randPos = rand.nextInt(characters.size());
System.out.printf("%d: %s\n", randPos, characters.get(randPos));
// randomButton.setText(characters.get(randPos));
}
Given the array is already shuffled, just look at the first card:
public void show(View view){
randomButton.setText(characters[0]);
}
If you want to navigate that deck I suggest you put the shuffled list in to a Queue, where you can look at the next card (peek) or take the next card (poll):
private static Queue<string> buildNewShuffledDeck(String[] characters){
List<String> shuffledCharacterList = new ArrayList<String>(characters);
Collections.shuffle(shuffledCharacterList);
Queue<string> deck = new ArrayDeque(shuffledCharacterList);
return deck;
}
public void show(View view){
String nextCard = deck.peek();
if (nextCard != null)
randomButton.setText(nextCard);
else
//deck is empty...
}
Then to take from the deck, say on the random button click:
String nextCard = deck.poll();
General advice on arrays: Stop using them in favor of other data types that are far more useful and interchangeable.
Then next step advice, make a class that represents a Card and stop using Strings, the string you currently have is just one property of a card.
You are just displaying the last character name that you add
Replace with this
public void show(View view){
Random r = new Random(System.currentTimeMillis());
randomButton.setText(characters[r.nexInt(characters.length)])
}

Android How to assign a variable to a button?

public void allButtonChoice(){
Button[] multiChoice = new Button[3];
multiChoice = new Button[]{choiceButton1,choiceButton2,choiceButton3,choiceButton4};
//to output shuffled array in an randomized order.
//Random number generator.
Random generateMultiChoice = new Random();
for(int i = 0; i < multiChoice.length; i++){
int randomPosition = generateMultiChoice.nextInt(multiChoice.length);
Button temp = multiChoice[i];
multiChoice[i] = multiChoice[randomPosition];
multiChoice[randomPosition] = temp;
}
//set the positions to the buttons in order
choiceButton1.setX(10f);
choiceButton1.setY(10f);
choiceButton2.setX(10f);
choiceButton2.setY(10f);
choiceButton3.setX(10f);
choiceButton3.setY(12f);
choiceButton4.setX(10f);
choiceButton4.setY(12f);
}
How can I assign a variable to choiceButton1, choiceButton2, choiceButton3, and choiceButton4? Is it possible to have one variable that holds the four buttons with setX and setY data?
choiceButton1.setTag(value);
will be useful for you
you can retrieve data by calling getTag

2 randoms seem to give near identical result

thanks in advance for taking time to look at my Q. and anyone with the same problem i hope we get a solution...
so basicly i have an app that spins 2 coins at the same time and displays what the result is.
This method generates the first coin...
public void coinResult1(){
ImageView coin1View = (ImageView) findViewById(R.id.coin1);
Random r = new Random();
int coin1result = r.nextInt(2);
if (coin1result == 0){
coin1View.setBackgroundResource(R.drawable.coinheads);
coinresult1 = 0;
}
else if (coin1result == 1) {
coin1View.setBackgroundResource(R.drawable.cointails);
coinresult1 = 1;
}
}
and this is for the second coin
public void coinResult2(){
ImageView coin2View = (ImageView) findViewById(R.id.coin2);
Random r = new Random();
int coin2result = r.nextInt(2);
if (coin2result == 0){
coin2View.setBackgroundResource(R.drawable.coinheads);
coinresult2 = 0;
}
else if (coin2result == 1) {
coin2View.setBackgroundResource(R.drawable.cointails);
coinresult2 = 1;
}
}
this is linked to onclick() of button which check the results to a player selection
public void checkResult(){
coinResult1();
coinResult2();
coinResult = coinresult1 + coinresult2;
if (coinResult == playerSelection){
playerWins();
buttonsReset();
}
else {
playerLost();
buttonsReset();
}
}
Now the only problem i have is...
the results of both coins of 1000 presses are this...
HeadsHeads 54%
HeadsTails 2%
TailsTails 44%
of 1000000 spins was roughly the same percentages
when each coin result was counted seprately
COIN1 heads 53% tails 47%
COIN2 heads 48% tails 52%
Now my friend says their is something wrong with those odds....beacause HeadsTails wasnt a high enough percent, hes expecting it to be close to 33% each combination at random
the code seems to favour HeadsHeads and TailsTails or HeadsTails.....ive tried several times and keep getting a low % of HeadsTails
can anyone shead some light on whats going on....and what is causing HeadsTails to rarely come out?
hope to hear back soon
Your repeated instantiation of Random is ruining the statistical properties of the generator.
You need to create one instance and pass that into your functions. Better still, use a field in your class.
Please refer to this question for concerns over thread safety of the Random class:Is Random class thread safe?. It seems to suggest that you should synchronize the nextInt calls.
You should never re-create random number generator over and over again:
public void coinResult1(){
ImageView coin1View = (ImageView) findViewById(R.id.coin1);
Random r = new Random(); // <- That's the source of errors!
int coin1result = r.nextInt(2);
...
Instead, create random generator instance once and for all:
// Simplest, not thread-safe amendment
private static Random s_Gen = new Random();
...
public void coinResult1(){
ImageView coin1View = (ImageView) findViewById(R.id.coin1);
int coin1result = s_Gen.nextInt(2);
...
The cause of the misbehaviour is that when you re-create Random it often re-initializes from the same seed (which is usually current time) and so generates the same values.
You must create only one instance of Random.
private Random r;
// initialize r in onCreate or somehere else only once
protected void onCreate(Bundle savedInstanceState){
// ...
r = new Random();
}
public void coinResult1(){
ImageView coin1View = (ImageView) findViewById(R.id.coin1);
int coin1result = r.nextInt(2);
if (coin1result == 0){
coin1View.setBackgroundResource(R.drawable.coinheads);
coinresult1 = 0;
}
else if (coin1result == 1) {
coin1View.setBackgroundResource(R.drawable.cointails);
coinresult1 = 1;
}
}
public void coinResult2(){
ImageView coin2View = (ImageView) findViewById(R.id.coin2);
int coin2result = r.nextInt(2);
if (coin2result == 0){
coin2View.setBackgroundResource(R.drawable.coinheads);
coinresult2 = 0;
}
else if (coin2result == 1) {
coin2View.setBackgroundResource(R.drawable.cointails);
coinresult2 = 1;
}
}

Trouble with asList().contains() comparing variables

I'm making an app where the user has to choose a 4 digit number, and this will be compared to a randomly chosen hidden 4 digit number, but when ever I run the code which should check my array for a comparison between the chosen numbers and the random numbers the 'Arrays.asList().contains())' doesn't seem to pickup on the fact that the array it is checking does have the value it is checking for, any advice?
The code that compares the two variables:-
guess.v1 = code.int1;
guess.v2 = code.int2;
guess.v3 = code.int3;
guess.v4 = code.int4;
int[] guess_list = { guess.v1, guess.v2, guess.v3, guess.v4 };
if (Arrays.asList(guess_list).contains(home.value1)) {
if (code.int1 == home.value1) {
X1.setText("V");
guess.c1 = GuessStatus.V;
} else {
X1.setText("S");
guess.c1 = GuessStatus.S;
}
} else {
X1.setText("X");
guess.c1 = GuessStatus.X;
}
The code that generates the random numbers:-
Code.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent openCode = new Intent(b, code.class);
// adventure_time checks whether there is a saved game already,
// if 1, saved game,
adventure_time = 0;
// random number generation LET THE NUMBER GAMES BEGIN///
Random a1 = new Random();
random1 = new ArrayList<Integer>();
check.fudge = 0;
for (int index = 0; index < 4; index++) {
random1.add(a1.nextInt(5) + 1);
Log.v("MM", "" + random1.get(index));
}
value1 = random1.get(0);
value2 = random1.get(1);
value3 = random1.get(2);
value4 = random1.get(3);
startActivity(openCode);
}
});
You're not calling the Arrays.asList call you think you are. You're actually creating a List<int[]>, not a List<Integer> are you're probably expecting. (There's no such type as List<int> in Java, as it doesn't support generics over primitive types.)
The simplest fix would be to change this:
int[] guess_list = { guess.v1, guess.v2, guess.v3, guess.v4 };
to this:
Integer[] guess_list = { guess.v1, guess.v2, guess.v3, guess.v4 };
You'll then end up creating a List<Integer> which will work appropriately.

Categories

Resources