I'm doing a small project where I have two different types of ball objects inside a bag array and I want to take two random objects from that bag. The problem that I am having is removing the objects from that bag array. I am succeeding to take two random objects but it takes in their position in the bag array and I don't really know how to remove objects from that bag array.
public class Bag {
public static void main(String[] args) {
Balls whiteBalls = new Balls("White");
Balls blackBalls = new Balls("Black");
Balls[] objArray;
whiteBalls.setAmount(16);
blackBalls.setAmount(20);
int totalBalls = whiteBalls.getAmount() + blackBalls.getAmount();
// Create two arrays that hold white and black balls together.
Balls[] white = new Balls[whiteBalls.getAmount()];
Balls[] black = new Balls[blackBalls.getAmount()];
// Adding white balls into array "white".
for (int i = 0; i < whiteBalls.getAmount(); i++) {
white[i] = new Balls("White");
} // Adding black balls into array "black"
for (int i = 0; i < blackBalls.getAmount(); i++) {
black[i] = new Balls("Black");
}
Balls[] bag = new Balls[totalBalls]; // Making a bag which holds all the balls.
// Copy's both arrays and fills up array "bag".
System.arraycopy(white, 0, bag, 0, whiteBalls.getAmount());
System.arraycopy(black, 0, bag, 16, blackBalls.getAmount());
//System.out.println(Arrays.toString(bag));
int count = 0;
Random rnd = new Random();
String[] colours = new String[]{"White", "Black"};
while(bag.length != 1){ // Depending on what colour the balls are either black ball or white ball is placed back into the bag.
count++;
int select1 = rnd.nextInt(colours.length);
int select2 = rnd.nextInt(colours.length);
while(white.length != 0 || black.length != 0){
if(select1 == 0 && select2 == 0){
System.out.println("Both are the same colour. " + select1 + " " + select2);
}
}
}
}
}
The other problem that I am running into is in my other class which balls one method 'getColour()' doesn't want to work for some reason.
public class Balls {
private String colour;
private int amount;
public Balls(String type) {
colour = type;
}
public String getColour() {
return colour;
}
public void changeAmount(int num){
this.setAmount(num);
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public String toString() {
return colour;
}
}
Any feedback is appreciated. Thank you for reading and thanks in advance.
I'd recommend you using an ArrayList, as it provides methods to remove elements from within the list (be aware, as this can be quite costly in a large array). The remove() method can take an index of the object to remove or the object to remove itself, as the method is overloaded. Be aware, as storing to int's that hold the index of the element in the bag that should be removed, can result in unexpected results, as it can be, that this index points to the wrong object after you removed an object after you stored the indices.So, I hope this answer helps you.
Related
I have an arraylist that looks like this:
public static ArrayList<ArrayList<String[]>> x = new ArrayList<>();
I store groups of 2 persons in a pair. For example:
[Person1, Person2]
[Person3, Person4]
The algorithm I use right now still makes duplicates, I've tried out hashmaps and iterating through them with for loop but they just give me back the original list.
This is the code:
package com.company;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
public class createGroups
{
public static ArrayList<ArrayList<String[]>> x = new ArrayList<>();
public static void main(String[] args){
//Define names
String[] names = {"Person1", "Person2", "Person3", "Person4"};
try
{
//Create combinations. In a try catch because of the saveFile method.
combination(names, 0, 2);
//Print all the pairs in the Arraylist x
printPairs();
} catch (IOException e)
{
e.printStackTrace();
}
}
static void combination(String[] data, int offset, int group_size) throws IOException
{
if(offset >= data.length)
{
//Create new Arraylist called foo
ArrayList<String[]> foo = new ArrayList<>();
//Create a pair of 2 (data.length = 4 / group_size = 2)
for(int i = 0; i < data.length / group_size; i++)
{
//Add the pair to foo.
foo.add(Arrays.copyOfRange(data, 2 * i, 2 * (i + 1)));
}
//Add foo to x
x.add(foo);
//saveFile(foo);
}
for(int i = offset; i < data.length; i++){
for(int j = i + 1; j < data.length; j++){
swap(data, offset, i);
swap(data, offset + 1, j);
combination(data, offset + group_size, group_size);
swap(data, offset + 1, j);
swap(data, offset, i);
}
}
}
public static void printPairs(){
//Print all pairs
for(ArrayList<String[]> q : x){
for(String[] s : q){
System.out.println(Arrays.toString(s));
}
System.out.println("\n");
}
}
private static void swap(String[] data, int a, int b){
//swap the data around.
String t = data[a];
data[a] = data[b];
data[b] = t;
}
}
The output right now is this:
Output
Every group of 4 names is a 'list' of pairs (Not really a list but that's what I call it)
And this is the desired output:
Desired output
But then you can see that the first and the last list of pairs are basically the same how do I change that in my combination method
The question:
How can I change my combination method so that it doesn't create duplicate groups.
And how can I make the list smaller (The desired output) when printing the created lists.
If I wasn't clear enough or if I didn't explain what I want very well, let me know. I'll try to make it clearer.
Create an object similar to this. It takes 4 strings (2 pairs). Puts the strings into array and sorts this array. That means any combination of strings you put in will be converted into one sorted combination, but the object internaly remembers which person is person1, person2, ...
private class TwoPairs {
private final String person1;
private final String person2;
private final String person3;
private final String person4;
private final String[] persons;
TwoPairs(String person1, String person2, String person3, String person4) {
this.person1 = person1;
this.person2 = person2;
this.person3 = person3;
this.person4 = person4;
persons = new String[4];
persons[0] = person1;
persons[1] = person2;
persons[2] = person3;
persons[3] = person4;
// if we sort array of persons it will convert
// any input combination into single (sorted) combination
Arrays.sort(persons); // sort on 4 objects should be fast
// hashCode and equals will be comparing this sorted array
// and ignore the actual order of inputs
}
// compute hashcode from sorted array
#Override
public int hashCode() {
return Arrays.hashCode(persons);
}
// objects with equal persons arrays are considered equal
#Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
TwoPairs other = (TwoPairs) obj;
if (!Arrays.equals(persons, other.persons)) return false;
return true;
}
// add methods which you might need
// getters for individual persons
// String getPerson1() { return person1; }
// or perhaps pairs of persons
// String[] getPair1() { return new String[] {person1, person2}; }
// add sensible toString method if you need it
}
Your ArrayList x will change like this
ArrayList<TwoPairs> x = new ArrayList<TwoPairs>();
before adding new TwoPairs object into x check if this list already contains this object.
if (!x.contains(twoPairsObject)) {
x.add(twoPairsObject);
}
I have created two classes, one called "Bucket", and the other called "Player".
In "Bucket", I have a constructor method that creates a virtual bucket (i.e. small array) that contains three values - 1, 1, and 1. As well, I created a method to get the bucket array.
In the "Player" class, I have created a method that uses a larger array (I have called this larger array "ArrayOfBuckets"), which uses a loop to store a new bucket at each index value, up until a certain point (when i>NumberSticks). However, when I try to set
ArrayofBuckets[i] = bucketInstance.getBucket();
I get an error from Eclipse, saying that "Type mismatch: cannot convert from Bucket to int". I have spent an hour trying to solve this, to no avail. Any help would be really nice. Thanks a lot, and here is all the code that is used:
The Player Class:
import java.util.Scanner;
public class Player {
Scanner scan = new Scanner(System.in);
public String name;
private int pType;
private int[] ArrayOfBuckets;
public Player(String tempName)
{
this.name = tempName; //this. is unneccessary
}
public void ArrayOfBuckets(int NumberSticks) //this is a constructor method and creates the arrays that contains a
{
ArrayOfBuckets = new int[NumberSticks];
int i = 0;
while(i<NumberSticks)
{
Bucket bucketInstance = new Bucket();
ArrayOfBuckets[i] = bucketInstance.getBucket();//new Bucket(); //ADD THIS
i++;
}
}
and the Bucket Class:
import java.util.Random;
public class Bucket {
// private int[][] largeArray = null; //WTF DO I DO HERE
private int AIChoiceStick;
private int[] bucket;
private Random random = new Random();
private int CurrentScore[] = new int[51]; //at max, if 100 sticks are initially chosen, then each player takes at max 50 sticks,
private int h = 0; //^so why not have one more in case
public Bucket()
{
bucket = new int[3];
bucket[0] = 1;
bucket[1] = 1;
bucket[2] = 1;
public int[] getBucket()
{
return bucket;
}
You're speaking about a two-dimensional array.
private int[][] ArrayOfBuckets;
Your ArrayOfBuckets (should be just buckets according to naming conventions) is an array of arrays, so it gets two sets of square brackets.
Then the initialization:
ArrayOfBuckets = new int[NumberSticks][3];
By the way, if you want to have room for 50 elements in an array, then initialize it new int[50] so it will have indexes 0 through 49.
I'm trying to learn about how constructors and methods work. I pretty much have the concepts down, it's just that I don't know how to set them up. I especially don't know how to use them with ArrayLists.
I'm trying to calculate and print the area of a rectangle, the commented parts are what I don't know how to set up.
import java.util.ArrayList;
class RectangleStats
{
// Private instance variables
// length is an ArrayList which will contain integer values, width is an array which will contain integer
// values, and area is an array which will contain decimal values.
//code goes here for instance variables goes here
// The constructor for the RectangleStats class takes an ArrayList and an array as parameters for
// length and width, respectively.
// code for constructor goes here
// The calcRectangleArea() method calculates the area of rectangles using the length and
// the width assigned to the private instance variables and assigns the results to the area array of type
// double. This method does not return anything.
// code for the calcRectangleArea() method goes here
// The printArea() method prints the values assigned to the area array using the most appropriate
// type of loop. This method does not return anything.
// code for the printArea() method goes here
}
// The RectangleStatsTesterClass assigns the length of two rectangles to an ArrayList and assigns the
// width of two rectangles to an array. The calcRectangleArea() and printArea() methods are invoked to
// calculate and print the area of the two rectangles.
public class RectangleStatsTesterClass2
{
public static void main(String[] args)
{
ArrayList intLength = new ArrayList();
intLength.add(7);
intLength.add(5);
int [ ] intWidth = {3, 4};
RectangleStats rectStats = new RectangleStats(intLength, intWidth);
rectStats.calcRectanglePerimeter();
rectStats.printArea();
}
}
Try like this:
import java.util.ArrayList;
import java.util.List;
class RectangleStats
{
private List<Integer> length;
private int[ ] width;
double areas[];
RectangleStats(List<Integer> length, int[] width){
this.length = length;
this.width = width;
this.areas = new double[this.width.length];
}
private void calcRectangleArea(){
for(int i=0; i<width.length; i++){
areas[i] = length.get(i) * width[i];
}
}
public void printArea(){
calcRectangleArea();
for(int i=0; i<areas.length; i++){
System.out.println("Area " + i + " : " + areas[i]);
}
}
public void calcRectanglePerimeter(){
for(int i=0; i<width.length; i++){
System.out.println("Parameter for "+ i +"th Rectangle : " + (2 * (length.get(i) + width[i])));
}
}
}
public class RectangleStatsTesterClass2
{
public static void main(String[] args)
{
ArrayList<Integer> intLength = new ArrayList<Integer>();
intLength.add(7);
intLength.add(5);
int [ ] intWidth = {3, 4};
RectangleStats rectStats = new RectangleStats(intLength, intWidth);
rectStats.calcRectanglePerimeter();
rectStats.printArea();
}
}
I'm making a program to get the midpoint of a line. However i'm running into a problem.
What i need to be able to do is have as many points as i want, and dimensions. However i have no idea how to do this
So let me give you an idea of what i want to do.
points[point][x]=1; points[point][y]=2; points[point][z]=3;
See what i'm getting at? This is what i currently have
public float[][] points={{}};
And when i want to write to it
for(int i=0; i<parts.length;i++){
points[currentPoint][i]=Float.valueOf(parts[i]);
}
java.lang.ArrayIndexOutOfBoundsException: 0
So how can i do this?
public float[][] points={{}};
This creates an empty two dimensional array. Hence, the ArrayIndexOutOfBoundsException.
If you want to create an array to hold 6 points and 3 dimensions then you have to allocate it:
public float[][] points = new float[6][3];
However, I would reconsider your design. If you would like to go more object oriented way than you would probably like to have a class for line as well as for point. For example:
class Line {
private final Point startPoint;
private final Point endPoint;
Line(Point startPoint, Point endPoint) {
this.startPoint = startPoint;
this.endPoint = endPoint;
final int startPointDimensions = startPoint.getDimensions().size();
final int endPointDimensions = endPoint.getDimensions().size();
if (startPointDimensions != endPointDimensions) {
throw new RuntimeException("Points that form a line must have the same dimension! " +
"Start point dimension: " + startPointDimensions +
"End point dimension: " + endPointDimensions);
}
}
public Point midpoint() {
// your code goes here
}
}
class Point {
private final List<Float> dimensions;
Point(List<Float> dimension) {
dimensions = dimension;
}
public List<Float> getDimensions() {
return dimensions;
}
}
You can read more about lists in the oracle's documentation. I would prefer lists to arrays if you do not know up front how many dimensions you want to support or if you want to support different number of dimensions.
Use this to create a 3x3 2-D array and initialize all values to 0:
public float points[][] = new float[3][3];
And this to iterate through the array and set values:
for (int j=0; j<3; j++) {
for (int i=0; i<3; i++) {
points[j][i] = 42; //Or whatever
}
}
I am trying to make a poker game through java.
The first thing I wanted to do is distribute 5 cards using arrays. I have done the distribution part, but how can I prevent the same cards being distributed twice. In other words, how can I check if an array already contains an element. I want it to be able to detect if the element already exists in an array, and if it does, I want to be able to change just that card that has been given out twice, help would be much appreciated.
My codes down below,
import java.util.Random;
import java.util.Scanner;
import java.util.Arrays;
public class Poker
{
public final static String[] numbers = {"❤","♠","♦","♣"};
public final static String[] sign = {"1","2","3","4","5","6","7","8","10","J","Q","K","A"};
private String[] hand = {"","","","",""};
private boolean found;
private Random random;
public Poker()
{
found = false;
String hand[] = {"","","","",""};
int tokens = 10;
Scanner in = new Scanner(System.in);
random = new Random();
}
public void handOut()
{
for (int i = 0; i < 5; i++)
{
int numberRandom = random.nextInt(numbers.length);
int signRandom = random.nextInt(sign.length);
String pickedNumber = numbers[numberRandom];
String pickedSign = sign[signRandom];
String combinedSigns = pickedSign + pickedNumber;
hand[i] = combinedSigns;
System.out.print(hand[i] + " ");
}
System.out.println("\n");
}
}
Your choice of terminology is ... err ... interesting :-)
The card value is a "face value", not a sign. And whether it's hearts or diamonds or so on, that's its "suit" rather than its number.
But, on to the question. I believe the best way to do this is to construct an entire 52-card deck out of your facevalue and suit arrays and then use a Fisher Yates shuffle to distribute cards.
This is a nifty way to randomly choose elements from an array without duplicates. The beauty is that the items in the array don't actually need to be shuffled up front. Details on how it works can be found here.
If you can use the collections framework as opposed to an array, create a Stack and populate it with all the 52 cards. then call Collections.shuffle() on it.
finally set hand[i]=(deck name).pop()
Once a card is popped from the stack it will be removed from the deck so it can't be dealt again.
What you want to do is break your code into different methods. You should have a method for generating one card, a method for checking whether or not a card is in the hand, and a method to distribute cards to the hand.
public String generateCard() {
int numberRandom = random.nextInt(numbers.length);
int signRandom = random.nextInt(sign.length);
String pickedNumber = numbers[numberRandom];
String pickedSign = sign[signRandom];
return pickedSign + pickedNumber;
}
public static boolean cardIsInHand(String card) {
for(int i = 0; i < 5; i++) {
if(hand[i] != null && hand[i].contains(card)) {
return true;
}
}
return false;
}
public static void handout() {
for (int i = 0; i < 5; i++) {
String card = generateCard();
while(cardIsInHand(card)) {
card = generateCard();
}
hand[i] = card;
}
}