Say I want to pick 5 random colors from an array list like this one:
static final List<Color> colors = new ArrayList<Color>();
static {
colors.add(Color.RED);
colors.add(Color.BLUE);
colors.add(Color.GREEN);
}
It's pretty easy I can just do this...
static Random random = new Random();
public static Color getRandomColor() {
return colors.get(random.nextInt(colors.size());
}
But what if I want to pick unique colors which aren't the same? So say I pick RED, how can I make sure to not pick RED again; preferably without removing it from the list, too.
EDIT:
I've found something that works:
Color generatedColor = Theme.randomColor();
for (int i = 0; i < pie.segments.size(); i++) {
if (generatedColor == pie.segments.get(i).getColor()) {
generatedColor = Theme.randomColor();
return;
}
}
this.color = generatedColor;
However someone suggested I just remove them all and re-add once I've finished generating them all, which method should I go for?
EDIT 2:
After shuffling, I get this:
http://i.imgur.com/HPKQNFH.png
Thanks! :)
Use remove method, which return the object at the position and then remove it.
list.remove(int i)
Then your method becomes:
public static Color getRandomColor() {
return colors.remove(random.nextInt(colors.size());
}
and when the list size is 0, reinsert all the colors.
Related
I am building simple java game which the user has to find gold. There are some obstacles like Orc, Goblin, and Poop.
What I am trying to do is that I am creating Cell and Board class.
Inside of my Cell class,
public Cell{
public enum TheCell { Orc, Goblin, Poop, Gold, Empty};
TheCell type;
public Cell(TheCell type){
this.type = type;
}
}
and I make two dimensions in Board class,
public Board{
Cell[][] grid = new Cell[7][7];
Random r = new Random();
for(int i = 0; i<3; i++){
int randNum1 = r.nextInt(7);
int randNum2 = r.nextInt(7);
grid[randNum1][randNum2] = new Cell(Cell.TheCell.Orc);
}
for(int i = 0; i<3; i++){
int randNum1 = r.nextInt(7);
int randNum2 = r.nextInt(7);
grid[randNum1][randNum2] = new Cell(Cell.TheCell.Goblin);
}
}
My question is that, in case of Orc and Goblin are same cell, I wanna keep them both monster in same cell. Is there some how I can keep both or multiple obstacles in same cell? Thank you!
One way to achieve this is to have the Cell class hold a list of all monsters/things that are currently on the cell (using the enum, that is already available)
A more "low level" approach is to use an Integer for the cell and then use bitflags to model multiple obstacles on the same cell.
Update:
I agree with #ajb, in this case an Enum Set should be used
As pointed out by #JimGarrison, the EnumSet approach only works until you need to have more than one instance of an enum value for one cell.
public Cell{
public enum TheCell { Orc, Goblin, Poop, Gold, Empty};
List<TheCell> type = new ArrayList<TheCell>();
public Cell(TheCell type){
addType(type);
}
public addType(TheCell type) {
this.type.add(type);
}
}
I'm building a Java based game in Swing, which is essentially a grid of Jbuttons
I have an Object called Cell, which is a custom JButton with additional parameters for storing objects. The game grid is represented by Cell[][]
I have an arraylist of type Cell[][] to allow me to store the state of the gamegrid after each move. If I want to undo the move, I need to copy the last element of the ArrayList to the game grid to allow it to be displayed on the UI.
My gamegrid is panelHolder and my arraylist is moveHolder.
So far I've tried Collections.copy(panelHolder, moveHolder.get(moveHolder.size())); which will not compile due to the "arguments not being applicable for the type Cell[][]"
I've also tried System.arraycopy(moveHolder.get(moveHolder.size()-1), 0, panelHolder, 0, panelHolder.length);, which throws and out of bounds exception. Initially I thought this was due to the moveHolder.size()-1, but even just as moveHolder.size() it has the same problem.
I've found numerous questions on StackOverflow and others that both show these two ways of doing it, but I can't seem to get it to work. Is there something more obvious I'm missing? Full class method below:
public class UndoClass implements MoveCommand{
public ArrayList<Cell[][]> moveHolder = new ArrayList<Cell[][]>();
public Cell[][] execute(Cell[][] panelHolder) {
if (moveHolder.size() > 0){
Collections.copy(panelHolder, moveHolder.get(moveHolder.size()));
if (moveHolder.size() > 0){
moveHolder.remove(moveHolder.size());
}
}
System.out.println("Move Undone. Undos available:" + moveHolder.size());
return panelHolder;
}
public void addMove(Cell[][] panelHolder){
moveHolder.add(panelHolder);
}
public ArrayList<Cell[][]> getMoves(){
return moveHolder;
}
}
Cell Class
public class Cell extends JButton {
int co_x = 0;
int co_y = 0;
ArrayList<Players> current = new ArrayList <Players>();
}
Just wanted to point our your execute(...) method accepts the Cell[][] both as a parameter and the return argument. That approach is going to force all of your commands to keep copying your input param arrays to the return statement array. Notice if you don't need to keep the two in sync and you just use the return arg, you don't have to worry about copying at all:
Cell[][] lastState = moveHolder.get(moveHolder.size()-1);
moveHolder.remove(moveHolder.size()-1);
return lastState; // Not updating the panelHolder array, just returning
But of course now the input parm and return are out of sync. Instead you might want to encapsulate that state into a single object to make your life easier. Something like this (note that the execute now returns a void):
public ArrayList<GameState> previousStates = new ArrayList<GameState>();
public void execute(GameState currentState) {
if (previousStates .size() > 0) {
GameState lastState = previousStates.get(previousStates.size()-1);
currentState.restoreFrom(lastState);
previousStates .remove(moveHolder.size()-1);
}
}
Good luck on the game!
if (moveHolder.size() > 0) {
for (int i = 0; i < panelHolder.length; i++) {
panelHolder[i] = moveHolder.get(moveHolder.size()-1)[i].clone();
}
moveHolder.remove(moveHolder.size()-1);
}
Try this. You need to make copies of each internal array when copying 2D arrays.
Try a Linked List
LinkedList<Cell[][]> ll = new LinkedList();
ll.removeLast();
panelHolder = ll.clone();
I'm trying to make a small game like thing for school. It's designed to help you learn your times tables. What I want is for the multiplier of the table to be random each time (5x8 then 5x3 then 5x9 etc).
I've got the generating of the numbers in control with an array as can be seen below
public static Integer[] generateNumbers()
{
Integer[] arr = new Integer[12];
for(int j = 0; j < arr.length; j++)
{
arr[j] = j+1;
}
Collections.shuffle(Arrays.asList(arr));
System.out.println(Arrays.asList(arr));
return arr;
}
How can I make it so that every time the user clicks a button, the next number in the array is selected, baring in mind that the button is declared in another class, and the ActionListener is also declared elsewhere?
Oh and the array is available class-wide as the function is declared like this:
public static Integer[] arr = generateNumbers();
Thematic answer
public class UnicornFrame extends JFrame {
private Integer[] poneyArr = MyClassThatGeneratesNumbers.generateNumbers();
private int poneyCounter = 0;
private JButton poneyButton;
public void poneyInit() {
System.out.println("Unicorns are poney magical friends!");
poneyButton = new JButton("OMG! Ponies!");
// Java 8 Lambdas! Yey!
poneyButton.addActionListener(e -> {
if (poneyCounter >= poneyArr.length) {
poneyArray = MyClassThatGeneratesNumbers.generateNumbers();
poneyCounter = 0;
}
Integer selected = poneyArr[poneyCounter++];
System.out.println("OMG! I have selected " + selected);
});
// other stuff
add(poneyButton, BorderLayout.CENTER);
}
}
The button int he separate class is not needed, the action listener will communicate with your array whenever its clicked, the easiest way I see is to put a public method int the array's class, that takes an index, which then increments the index, and returns the element stored at it.
Have fun coding, but these assignments are meant for you to scratch your head, try writing some code, and let us know if it breaks, rather than asking for general answers.
I have an ArrayList of object in my Fragment.
ArrayList<MenuListItem> menuItems = new ArrayList<MenuListItem>();
menuItems.add(new MenuListItem("Newsfeed", 20));
menuItems.add(new MenuListItem("FriendsRequest", 1));
menuItems.add(new MenuListItem("Messages", 2));
private class MenuListItem {
public String label;
public int count;
public MenuListItem(String label, int count) {
this.label = label;
this.count = count;
}
}
How can I find the index of object that has the label value "Messages" in my ArrayList from my Activity.
have you try to iterate through elements of menuItems?
something of this sort:
for(MenuListItem menuListItem : menuItems){
if (menuListItem.label.equals(<what you are looking for>){
<do something>
break; // in case when 1st occurence is sufficient
}
}
side note (not related make your members private and add accessors for them)
Edit: just noticed that you are looking for an index, what i have included is to get an MenuListItem what you can do is iterate and return index if you want.
try
String search="Messages";
for(int i=0;i<menuItems.size();i++){
if(menuItems.get(i).label.equalsIgnoreCase(search)){
System.out.println("Index " + i);
break;
}
}
public static int indexOf(final List<MenuListItem> menuItems, final String what) {
final int size = menuItems.size();
for (int i = 0; i < size; i++) {
final String label = menuItems.get(i).label;
if (label != null && label.equals(what)) {
return i;
}
}
return -1;
}
There's a easier and standard way to do this.
Eclipse
Right-click inside MenuListItem class and select Source -> Generate hashCode() and equals() once you are done generating the implementations of these methods. You can use ArrayList.indexOf(Object) to get the index of the item you are looking for.
IntelliJ or Android Studio
Right-click inside your editor and click on Generate and from the dialog that pops up, select hashCode() and equals().
The Collections framework has made things easier for you already. Why not leverage it instead of writing loops to find objects? :)
PS: This can be hand written, but this is something best left to the IDE. Because having too many attributes makes it tricky to get it right the first time.
I'm new to using OOP, I typically just put all my code in a single class and use methods. But I want to maintain state information and think classes are the best fit but I'm having trouble wrapping my head around it.
Say I have a list of items and I want to stop when the total sum of all previous items in the list equals X(in this case 10 so it takes item 1 + 2, then 2+3.etc..until it hits the threshold 10), I can use a method to calculate it but it involves me doing the entire process all over again when all I really need to do is increment by the last item and then see if my data exceeds the threshold. Here's my code so far but I know its not good because although it works its really just using the class as an independent method and recalculating on every loop. My goal is to,using this structure, reduce loops if not necessary to check thresholds.
Any suggestions?
Code:
public class LearningClassesCounter {
public static void main(String[] args) {
int[] list = new int[]{1,2,3,4,5,6,7,8,9,10};
int[] data_list = new int[list.length];
for (int current_location = 0; current_location<list.length;current_location++) {
//can only put commands in here. Nothing above.
Counter checker = new Counter(data_list);
System.out.println(checker.check_data(current_location));
for (int i =0; i<100; i++){
if (checker.check_data(current_location) == false) {
break;
}
data_list[current_location] = (list[current_location]+1); //this is just a random function, it could be any math function I just put it in here to show that some work is being done.
}
}
//its done now lets print the results
for (Integer item : data_list) {
System.out.println(item);
}
}
}
class Counter {
private int[] data_list;
private int total_so_far;
// create a new counter with the given parameters
public Counter(int[] data_list) {
this.data_list = data_list;
this.total_so_far = 0;
}
public boolean check_data(int current_location) {
// TODO Auto-generated method stub
int total_so_far = 0;
//System.out.println(total_so_far);
for (int item : data_list) {
total_so_far = item + total_so_far;
if (total_so_far >= 10) {
break;
}
}
if (total_so_far>=10) {
return false;
} else {
return true;
}
}
}
I don't need anyone to fix my code or anything(I want to do it myself, the code is just to give an idea of what I'm doing). I'm more interested in the flaw in my logic and maybe a way for me to better think about designing classes so I can apply them to my own situations better.
So the solution is that you do not update the data_list directly. Instead have a setter method in the Counter class that takes the index and value to update. It updates the value in the array and also updates a count value.
Something like this:
class Counter{
private final int[] list;
private count = 0;
private final maxCount = 10;
public Counter(int[] list){
this.list = list;
}
public boolean updateValueAndCheckPastMax(int index, int value){
list[index] = value;
count += value;
return count >= maxCount;
}
}
You are way over thinking this, and a counter class is not really necessary in this case.
I'm also interested as to why you'd be doing this line:
data_list[current_location] = (list[current_location]+1);
Do you want your data_list to be the same as list, but each value is incremented by 1?
If you are merely trying to return a sub-array of the values that are < 10, i would suggest just doing this in a for loop, and using an int as a counter.