Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Julian Barthel
707 PointsFunFact app Not random fact.
Hey!
I'm doing some trial and error on the FunFact app and i ws wondering if it is possible to get the Random function to not show the same fact twice?
I have been trying to read on other places like Stockowerflow and other places but since this is my first coding in java and android i don't understand what they mean.
one of the tips was: " 1.create array of size n. 2.loop through and initialize each value at index i to the value i (or i+1 if you wish to have the numbers 1 to n rather than 0 to n-1).
- finally, loop through the array again swapping each value for a value at a random index." "
im not saying this is the best way, but maybe some of you could help me whit this?
3 Answers
Dan Johnson
40,533 PointsIf you're looking to sort the array in place, you can do something like this:
import java.util.Random;
public class Shuffle {
private String[] facts = {
"#1", "#2", "#3", "#4", "#5", "#6", "#7"
};
public void shuffleFacts() {
Random random = new Random();
for (int i = facts.length - 1; i > 0; i--) {
int swapIndex = random.nextInt(i + 1);
swapFacts(i, swapIndex);
}
}
private void swapFacts(int from, int to) {
String temp = facts[to];
facts[to] = facts[from];
facts[from] = temp;
}
// Display results
// If you want to mess around with it in Workspaces
public void print() {
for(String fact : facts)
System.out.print(fact + " ");
System.out.println();
}
public static void main(String... args) {
Shuffle app = new Shuffle();
System.out.println("Sorted: ");
app.print();
System.out.println("Shuffled: ");
app.shuffleFacts();
app.print();
}
}
You could iterate through the array until you hit the end then reshuffle, mention there's no more facts, or whatever you want.
If you happen to be using a List you can use the standard library:
import java.util.Collections;
//...
Collections.shuffle(facts);
//...
Using a List would give you the advantage of removing facts until it was empty if you wanted the program to end after the last fact.
Stephen Little
8,312 PointsCould you just make a variable called mLastFactPicked and then set it when you show a fact(to the index) . Then just add in a if/else statement checking to make sure it's not the same when you go to display the fact. Then set it to the index of the fact it displays
Just a thought I had, hope it helps..
Stephen.
Dan Johnson
40,533 PointsYou can, though when dealing with random numbers you could end up repeatedly failing the check without accomplishing much. It wouldn't matter much for the FunFacts app but it's not ideal.
You'd also have to keep track of all indexes if you didn't want to repeat anything until the end.
Dan Johnson
40,533 PointsHere's the modified FunFacts:
FactBook
public class FactBook {
public String[] mFacts = {
"Ants stretch when they wake up in the morning.",
"Ostriches can run faster than horses.",
"Olympic gold medals are actually made mostly of silver.",
"You are born with 300 bones; by the time you are an adult you will have 206.",
"It takes about 8 minutes for light from the Sun to reach Earth.",
"Some bamboo plants can grow almost a meter in just one day.",
"The state of Florida is bigger than England.",
"Some penguins can leap 2-3 meters out of the water.",
"On average, it takes 66 days to form a new habit.",
"Mammoths still walked the earth when the Great Pyramid was being built." };
private int currentFact = 0;
private Context context;
public FactBook(Context context) {
this.context = context;
}
// Just to illustrate when the facts have been exhausted.
private void notifyNoFactsLeft() {
Toast.makeText(context, "No more facts! Starting again...", Toast.LENGTH_LONG).show();
}
private void shuffleFacts() {
Random random = new Random();
for(int i = mFacts.length - 1; i > 0; i--) {
int swapIndex = random.nextInt(i + 1);
swapFacts(i, swapIndex);
}
}
private void swapFacts(int from, int to) {
String temp = mFacts[to];
mFacts[to] = mFacts[from];
mFacts[from] = temp;
}
public String getFact() {
if(currentFact == mFacts.length) {
currentFact = 0;
shuffleFacts();
notifyNoFactsLeft();
}
return mFacts[currentFact++];
}
}
FunFactsActivity
public class FunFactsActivity extends Activity {
private FactBook mFactBook;
private ColorWheel mColorWheel = new ColorWheel();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fun_facts);
// Send this activty in as the context for FactBook
mFactBook = new FactBook(this);
final TextView factLabel = (TextView) findViewById(R.id.factTextView);
final Button showFactButton = (Button) findViewById(R.id.showFactButton);
final RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.relativeLayout);
// Avoid initial repeat
factLabel.setText(mFactBook.getFact());
View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View view) {
String fact = mFactBook.getFact();
factLabel.setText(fact);
int color = mColorWheel.getColor();
relativeLayout.setBackgroundColor(color);
showFactButton.setTextColor(color);
}
};
showFactButton.setOnClickListener(listener);
}
}
Normally I wouldn't pass in the Context to something like FactBook but I just wanted a quick way to show when the array was being reshuffled.
Dan Johnson
40,533 PointsForgot to mention this will run through once without sorting. If you want to have it sorted right away, just call shuffleFacts from the constructor.
Julian Barthel
707 PointsJulian Barthel
707 PointsThank you Dan Johnson !
Where you write "If you want to mess around with it in Workspaces"
Do you then mean that that goes in to the original .java file (FunFactsActivity.java) ?
and does this "#1","#2" refer to the facts? if so, do i need to input somewhere the amount of facts? or does this work like code under so it understands that there is as many facts as lines?
And the last question ( i think )
Is the "" stated here where the last message would show?
Dan Johnson
40,533 PointsDan Johnson
40,533 PointsThat example won't run directly on an Android device. It's a console app that you can just copy and paste into a new Workspace. Here's how you can set it up:
On the left you'll see an icon that's a window with angle brackets in it, click that and you can create a new project. Select "Java" for the environment type and name it whatever you want. Make a new file called "Shuffle.java" and paste in the code. Finally run these two commands in the console:
Run those again after you make changes if you want to experiment.
The Strings I had ("#1", "#2", etc.) are just placeholders. You could change the contents of the Strings or even change the types completely and it'll still shuffle (though the printing might get messed up).
The space in the print method is just to separate out the facts when they're being printed.
I'll download the FunFacts app later and try to wire everything up for an Android example.