So I have been creating this simple poker game in java. I have Created a deck of cards (The cards are objects that consist of a string and integer) and array lists to represent your hand and the dealers hand. Once I have cards in the yourHand array, how can I create a way to check for different suits? I want to keep it simple like having it only check for pairs and 3 of a kind. How can I approach this? The way I think it may be done, is to create a loop that will check each element in the array, and see if any of those elements are equal to another. But that seems easier said then done as I really don't understand how I would do that. And then the idea comes up, would it be an issue to do it that way since the card objects are of type String AND integer? I'm new to programming and will appreciate any help. Thanks! (also, let me know if you guys would like to see my code that sets up the card objects, which I have in a different class)
public class pokerMain implements StackInterFace {
public static void main (String [] args){
ArrayList<String> suits = new ArrayList<String>();//array list for the card suits
ArrayList<Integer> val = new ArrayList<Integer>();//array list for card values
ArrayList<CARDS> newCards = new ArrayList<CARDS>();//array list for cards with assigned val/suits
ArrayList<CARDS> yourHand = new ArrayList<CARDS>();//array list for your hand
ArrayList<CARDS> dealerHand = new ArrayList<CARDS>();//array list for the dealer's hand
Stack<CARDS> deck = new Stack();//Stack to represent deck
suits.add("Clubs");//These are the suits, added to the suits ArrayList
suits.add("Hearts");
suits.add("Diamonds");
suits.add("Spades");
System.out.println("suits contains: " + suits );//Testing for suit
for(int i = 1; i <= 13; i ++){//loop that adds all 13 values to to the val ArrayList
val.add(i);
}
System.out.println("val contains " + val);//Testing for val
for(Integer i : val) {//second attempt of adding objects to newCards
for(String s : suits) {
newCards.add(new CARDS(s, i));
}
}
System.out.println("the full deck contains: ");
System.out.println(newCards.toString());//prints newCards arrayList
Collections.shuffle(newCards);//shuffles array newCards
System.out.println("When shuffled this is what is in the deck");
System.out.println(newCards.toString());//prints shuffled array
deck.addAll(newCards);//adds newCards into the decks stack
System.out.println("Test print stack");
System.out.println(deck.toString());//prints stack as test
System.out.println("You pulled a " + deck.pop());//test pulling card from deck
for(int i = 0; i < 5; i ++){//loop to draw cards and put into hand
yourHand.add(deck.pop());
}
for(int i = 0; i < 5; i ++){//loop to draw cards and put into hand
dealerHand.add(deck.pop());
}
System.out.println("Please draw your cards");
System.out.println("Your hand contains:");
System.out.println(yourHand.toString());
for(int i = 0; i < yourHand.size(); i ++){//loop to check for pairs
}
}
#Override
public Object pop() {
// TODO Auto-generated method stub
return null;
}
#Override
public Object peek() {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return false;
}
#Override
public void clear() {
// TODO Auto-generated method stub
}
#Override
public void push(ArrayList newCards) {
// TODO Auto-generated method stub
}
#Override
public void addAll(ArrayList newCards) {
// TODO Auto-generated method stub
}
}
One simple way is to sort the cards by face value. That makes it easy to find N of the same values in a row.
I don't write java, so this is probably full of syntax errorrs, but do something like:
class CardFaceComparartor implements Comparator<CARD>
public int compare(CARD a, CARD b) {
return a.getFaceval() - b.getFaceaval;
}
}
...
Collections.sort(yourHand, CardFaceComparator);
int numSame=1;
int sets[4] = {0,0,0,0} //counts singles, pairs, ...
bool maybeFlush=True;
for (i=0; i<yourHand.size()-; i++) {
if (yourHand[i].getFaceval()== yourHand[i-1].getFaceval())
numSame+=1;
else {
sets[numSame]+=1;
numSame = 1;
}
maybeFlush = maybeFlush & (yourHand[i].getSuit() == yourHand[i-1.getSuit());
}
// now you have all the info to find best hand.
Consider this example of using a Comparator and the Collections utils:
public static final Comparator comparator = new Comparator<Card>() {
#Override
public int compare(Card cardOne, Card cardTwo) {
return cardOne.getFaceVal().compareTo(cardTwo.getFaceVal());
}
};
/* Later on we can then use the comparator object to sort! */
Collections.sort(cards, comparator);
Make the fields of your Card object have type String for Suit, and of type Integer for value. Then the above code can be applied to sort a particular ArrayList that contains Card objects such as your hand, or the dealers hand, etc.. What you gain from this is checking for straights, pairs, etc can be optimized and easier since everything is in ascending order.
Here is an example of a hand before sort:
5, 4, Q, 5, 2
Without the sort, you can see checking for a straight is very hard to while then also needing to find pairs... The algorithm would be to see you have a 5, and check for a straight like [5,6,7,8,9] by looking through the rest of the cards, and that is difficult to also keep track of pairs. The logic would get very messy in code, and hard to test or have someone else read. By sorting it we would get
2, 3, 4, 5, 5
We can, in one scan, see there is no straight as well as finding pairs. We know to expect the subsequent card to be just one value greater than the last card, and if it's not no straight can exist. If it's the same value it's a pair! More logic is involved at well for finding a three of a kind, 4 of a kind, etc.. but I'll leave that exercise up to you!
There will be edge cases for an Ace though, as it in some games can be used in sequence with 2, 3, 4, 5 to be a straight.. You didn't say what poke game you were making. Also ensure to consider J-A to be 11-14 respectively.
Related
I have an assignment in which I need to write an implementation class for a Bag (or Multiset) ADT. Problem is, the assignment is worded in a way that's hard to follow and I'm not sure what exactly I need to do.
Here is the assignment description and here is the interface I was provided. This is my implementation class so far. I haven't written any of my methods yet because I'm not sure where to go from here, especially in regards to the 3 different constructors.
package Bags;
import java.io.*;
public class ConBag implements Bag, Serializable {
private String[] items; // The items in the bag
private int itemCount; // The number of items
private int size; // The size of the bag
// This constructor creates a new empty bag able to hold 100 items.
public ConBag ( ) {
this(100);
}; // Constructor
// This constructor creates a new bag with a specified capacity.
public ConBag ( int size ) {
items = new String[size];
}; // Constructor
// This constructor takes an array of Strings and copies them into a bag of 100 or fewer items.
public ConBag ( String[] items ) {
}; // Constructor
public void add ( String item ) {
try{
if(!contains(item) && (!(size == items.length))){
items[itemCount] = item;
itemCount++;
}
}catch (NoSpaceException exception) {
System.out.println("Bag is full.");
}
}; // Add
public void remove ( String item ) {
for (int i=0; i<size; i++) {
if (contains(item)) {
items[i] = items[itemCount-1];
}else {
NoItemException exception;
System.out.println("Item not in bag.");
}
}
};
public int cardinality ( ) {
return itemCount;
};
public boolean contains ( String item ) {
for (int i=0; i<itemCount; i++) {
if(items[i].equals(item))
return true;
}
return false;
};
public int count ( String item ) {
int count;
return count;
};
public String draw ( ) {
};
}
I feel like I'm missing something important, but I don't know what. I already have NoItemException and NoSpaceException, but I don't think I need to include them in this post as they're pretty basic. Any help or a nudge in the right direction would be great. Thanks!
You need to allow duplication, therefore using String array as a data structure makes things difficult. It's better to use a map where the key is a String and the value is an Integer.
It's unclear what is the limit of the room, so, for now you can define a private member called room, which will be int and whenever you intend to add a String, check cardinality against room. If it's smaller, then increment the value of the map entry if exists. If it did not, then just create it with a value of 1.
remove should check for contains. If the Map you have does not contain the item, throw an exception. Otherwise decrement the value of the map entry if it's higher than 1. If it is 1, then just remove it from the map.
To calculate cardinality traverse the map and calculate the sum of the values.
contains should be simple, you will just have to call a method of your map. count should be simple as well.
draw is interesting. First, calculate cardinality, use it as the unreachable upper bound of your randomization and initialize a sum and start traversing the map. On each iteration increase sum (which is 0 before the loop) with the value of the map entry. If the randomized number is smaller than sum, then call remove passing the key of the item and exit the loop.
EDIT
If you need to do this with an array of String items, then you can do so, but you will also need to store an integer for each String, that would be another array and the easiest representation would be to ensure that every item in the String array would be associated to the int value in the int array at the same index. Not too elegant, but can be used. Now, in this case you could not use Map methods, but will need to implement stuff yourself.
I know everyone gets skeptical whenever people put homework on here but I've run out of options and could really use some direction. I have a project where I have to create a deck of cards and allow the user to pick the size of the hand and then fill that hand with random cards and display that to the user. I've found plenty of answers using ArrayLists but mine requires an array and I've tried everything I know and my code is either completely wrong or throws a bunch of errors.
So here are the problems I have:
1) The addCard method in the Hand class can be used to add one Card object at a time to the hand array until it is full. It should increment the cardsInHand counter each time a Card object is added to the Hand as long as there is room for the Card to fit into the Hand.
Here is the code for the Hand class:
public class Hand
{
private int handSize; //Holds the size of the hand
private int cardsInHand; //Holds the number of cards allowed in the hand
private Card[] hand; //Array of card objects
public Hand()
{
this.handSize = 5;
this.cardsInHand = 0;
this.hand = new Card[52];
}//end Default Constructor
public Hand(int handSize)
{
this.handSize = handSize;
}//end Parameterized Constructor
public Hand(Hand handIn)
{
this.handSize = handIn.handSize;
this.cardsInHand = handIn.cardsInHand;
this.hand = handIn.hand;
}//end Copy Constructor
public void addCard(Card card)
{
hand[card]; //--> throws a type mismatch exception (change card param to an int)
}//end addCard()
public int getHandSize()
{
return handSize;
}
public void setHandSize(int handSize)
{
this.handSize = handSize;
}
public int getCardsInHand()
{
return cardsInHand;
}
public void setCardsInHand(int cardsInHand)
{
this.cardsInHand = cardsInHand;
}
public Card[] getHand()
{
return hand;
}
public void setHand(Card[] hand)
{
this.hand = hand;
}
public String toString()
{
String msg = "";
return msg;
}//end toString()
}//end class
My addCard method is just all janky and I could really use some help trying to fill it so my program works. Any help or even a pointing in the right direction would be appreciated!
My addCard method is just all janky and I could really use some help trying to fill it so my program works. Any help or even a pointing in the right direction would be appreciated
Sometimes the best thing to do is stop, turn the screen off, get a pen and piece of paper and just nut it out without any code. Try to understand the problem and get the logic straight in your head.
Basically, you have a series of buckets into which you can put a Card. Before you can put a Card in a bucket, you need to know if you have any free buckets available.
If there are, you need to add the Card to the next available bucket (which should be pointed to by cardsInHand) and increment cardsInHand
Your error is because you're trying reference a "bucket" using a Card, but you can only reference a "bucket" by an index (number) so...
hand[card];
should be more like...
hand[cardsInHand] = card;
but only after you've determined if there is a free "bucket" available, and you should increment cardsInHand AFTER this statement
I'd also be worried about your constructors
public Hand(int handSize)
{
this.handSize = handSize;
}//end Parameterized Constructor
isn't initialising hand, so that's going to be null. A better solution might be to use existing constructors where possible to build a common "initialisation" path
public Hand() {
this(5);
}//end Default Constructor
public Hand(int handSize) {
this.handSize = handSize;
this.cardsInHand = cardsInHand;
this.hand = new Card[handSize];
}//end Parameterized Constructor
Also
public Hand(Hand handIn)
{
this.handSize = handIn.handSize;
this.cardsInHand = handIn.cardsInHand;
this.hand = handIn.hand;
}//end Copy Constructor
is worrying, as it's possible for some external class to make a change to handIn's hand and that change will be reflected by this instance as well (as they are pointing to the same array).
A "copy" constructor should be making a "copy" of the data. Realistically, this should probably be a "deep" copy, so any changes to Card don't mess with the Hand as well, but I'll start with a simple "shallow" copy to get you started
public Hand(Hand handIn) {
this.handSize = handIn.handSize;
this.cardsInHand = 0;
this.hand = new Card[this.handSize];
// Yes, I know there is a better way to do this, but
// I want the OP to learn something
for (int index = 0; index < handIn.hand.length; index++) {
Card card = handIn.hand[index];
if (card != null) {
hand[cardsInHand] = card;
cardsInHand++;
}
}
}//end Copy Constructor
#MadProgrammer already give better answer, I only want to chime a little. Knowing the OP project assignment using Java I want to comment a little about the Hand class design.
The task clearly said that user can pick hand with custom size, then the user will add card into the hand until the hand is full. Thus, I would propose the Hand class design like below.
public class Hand {
private int size; // Hold the amount of card can be hold by hand.
private int counter; // Count how many card added.
private Card[] cards; // The card on hand.
public Hand(int size) {
this.counter = 0;
this.size = size;
this.cards = new Card[size];
}
public void addCard(Card card) {
if (this.counter > this.size) {
throw new IllegalStateArgument("The hand is full of card!");
}
this.cards[this.counter] = card;
this.counter++;
}
public String show() {
StringBuilder result = new StringBuilder("The card on hand is: \n");
for (int i=0; i<this.size; i++) {
result.append(this.cards[i].toString()).append("\n");
}
return result.toString();
}
}
In my opinion the Hand class more easy to understand and achieve the goals of the Hand purpose from the task. However, just use this as reference and write code that you understand well.
My problem lies with the 5th function. I'm not getting how to solve it. Could someone help me?
populate from the database and store in the list.
List<Player>populate() throws ClassNotFoundException, SQLException;
sort the list according to runs (highest first).
void sortRuns(List<Player> list);
sort the list according to debut date.
void sortByDebut(List<Player> list);
calculate the average of each player and return a list which has field average. The return list should be sorted according to average (highest first).
List<Player>sortByAverage(List<Player>list);
return the set of players who have runs less than 10000. For example if you pass 3 to the function, it should return only 3 players randomly and each time a different set
should be generated.
Set<Player> randomSet(List<Player> list,int n);
Beans Classes are:
public class Player{
int capid;
String playerName;
Country country;
int matches;
int runs;
Date Debut;
int notOut;
float average;
}
Country As enum:
public enum Country {
India,Australia,SouthAfrica,NewZeland,England,SriLanka,WestIndies
}
Above Solved 4 functions are:
public class DataManagerImpl implements DataManager
{
DBConnectionImpl dm=new DBConnectionImpl();
Connection conn;
#Override
public List<Player> populate() throws ClassNotFoundException, SQLException {
List<Player> list=new ArrayList<Player>();
conn=dm.getConnection();
Statement st=conn.createStatement();
ResultSet rs=st.executeQuery("Select * from stats");
while(rs.next())
{
Player p=new Player(rs.getInt(1),rs.getString(2),Country.valueOf(rs.getString(3)),rs.getInt(4),rs.getInt (5),rs.getDate(6),rs.getInt(7));
list.add(p);
}
return list;
}
#Override
public void sortRuns(List<Player> list) {
// TODO Auto-generated method stub
Collections.sort(list,new Comparator<Player>(){
#Override
public int compare(Player o1, Player o2) {
// TODO Auto-generated method stub
return Integer.compare(o2.getRuns(),o1.getRuns());
}
});
}
#Override
public void sortByDebut(List<Player> list) {
// TODO Auto-generated method stub
Collections.sort(list,new Comparator<Player>(){
#Override
public int compare(Player o1, Player o2) {
// TODO Auto-generated method stub
return o1.getDebut().compareTo(o2.getDebut());
}
});
}
#Override
public List<Player> sortByAverage(List<Player> list) {
List<Player> plist=new ArrayList<Player>();
float average;
for(Player p:list)
{
int runs=p.getRuns();
int matchs=p.getMatches();
average=(runs/matchs);
p.setAverage(average);
plist.add(p);
}
Collections.sort(plist,new Comparator<Player>(){
#Override
public int compare(Player o1, Player o2) {
// TODO Auto-generated method stub
return Double.compare(o2.getAverage(),o1.getAverage());
}
});
// TODO Auto-generated method stub
return plist;
}
So here is how I understand the problem. This will probably not run, but should give you an idea how to do it.
Set<Player> randomSet(List<Player> list,int n){
ArrayList<Player> possiblePlayers = new ArrayList<>(); // fist we create a list where we can put all players that have 10000 runs
for(Player player: list){ // we loop through the list
if(player.getRuns()> 10000){ // check each player if he had more than 10000 runs
possiblePlayers.add(player); // and if so, we add him to our list of possible results
}
}
// at this point we have a list of players that have more than 10000 runs and we need to randomly select a player and put him into the new Set
// so first we create a Set that we can return
Set<Player> resultSet = new HashSet<>(); // Set is abstract and needs an implemented class like HashSet. This may not be the most appropriate implementation for your case, but it will do for now.
// now we need to pick n random players from our list. So we actually generate n numbers that we use as indexes
Random random = new Random(); // first we instantiate our random generator
ArrayList<Integer> indexes = new ArrayList<>(); // we will use this list to store the generated indexes, so we can check that we don't pick the same index twice
while (n > 0) {
Integer randomIndex = random.nextInt(possiblePlayers.size()); // first we pick a number between 0 and the size of our possiblePlayers list
if (!indexes.contains(randomIndex)) { // then we check if that number is already in the indexes list
indexes.add(randomIndex); // if not, we add it
n--; // and decrement n;
}
// if the random number where already in the indexes list, the loop would simply continue and try again
}
// here we have now a lost of randomly generated (and unique) indexes
// now we get the players at that indexes and put them in the result set
for(Integer index: indexes){
resultSet.add(possiblePlayers.get(index));
}
// and finally return the set
return resultSet;
}
As I said before, I am not sure if this method runs without errors. (I did not test it). It does however give you a solution. No guarantee that it is a good solution, though :) As you can see there are quite a lot of lists and Objects that are created, for such a small task. And I see a lot of potential to make it more efficient.
I'm writing a program which adds telephone entries into a staff phone directory, I want to add the elements to the array in alphabetical order (using surnames) rather than adding the elements then calling Arrays.sort every time a new entry is added, as that would be less efficient. Here is some code I have so far, I'm not sure how to compare each element in the array with the following one and so forth.
public class ArrayDirectory implements Directory {
Entry [] directory = new Entry [50];
#Override
public void addEntry(String initials, String surname, int extension) {
//Entries are added here in alphabetical order
}
Here is my Entry class -
public class Entry {
private String initals,surname;
private int extention;
public Entry(String initals, String surname, int extention){
this.initals = initals;
this.surname = surname;
this.extention = extention;
}
public String getInitals(){
return initals;
}
public String getSurname(){
return surname;
}
public int getExtention(){
return extention;
}
}
Any suggestions, do I override compareTo? Thanks
edit - should have noted I have been asked to use an array. Sorry for the confusion.
Edit 2: updated my addEntry method and overriden compareTo in Entry -
public void addEntry(String initials, String surname, int extension) {
for (int i = 0; i < directory.length; i++) {
if (directory[i] != null) {
int y = directory[i].getSurname().compareTo(surname);
if (y == 1) {
int position = i;
break;
}
} else if (directory[i] == null) {
int position = i;
break;
}
}
}
And my compareTo method -
public int compareTo(Entry other) {
return this.surname.compareTo(other.getSurname());
}
I'm not sure how to shift the elements in the array to the right after I have found the correct position? Thank you for all of you help.
If you dont have to use an array then your using the wrong data structure.
No matter what path you need to implement Comparable:
public class Entry implements Comparable<Entry>{
..
#Override
public int compareTo(Entry other) {
// TODO Auto-generated method stub
return this.surname.compareTo(other.getSurname());
}
..
Consider using a SortedSet:
Set<Entry> map = new TreeSet<Entry>();
map.add(new Entry("JEH", "Hamlet", 123));
map.add(new Entry("AAC", "Adams", 123));
map.add(new Entry("FAM", "Monti", 321));
That will print in the desired order. If you must use an Array then you need to sort it upon insert.
You could make Entry comparable and implement the compareTo in it. But you don't really have to in this case because String is already comparable.
Since this is a homework, I think it will be best to just give you some suggestions on how to proceed, instead of handing you the code -
In your method you do not need to sort the array, you just need to insert it at the correct location in the array.
loop through the array starting at the first index
as you pass through each element in the array, you will have to check following two conditions
is the element null
is the surname of current element greater than surname-argument to the method
as soon as you find the element that satisfies any of the above conditions, record the index and break the loop
then, starting at that index shift the rest of elements to the right
and finally create a new instance of Entry for the provided arguments and set it at that index
Note: This doesn't take care of the situation where you are out of the space in the array.
Update:
I think you mixed up my answer and #David Wallace's answer. It wasn't my suggestion to implement compareTo. Also, it's great that you at least gave it a try and came back.
int position = -1; //declare the position outside (if declared inside, it's not visible outside the loop)
for (int i = 0; i < directory.length; i++) {
// position = i; just assign value of i inside the loop
}
//use the position after the loop
int j = position; // start at position
Entry temp = null; // temp will temporarily hold the entry at the next index
while(true) {
temp = directory[j + 1]; // since we need move entry at j to j+1, first we need save the entry at j+1
directory[j + 1] = directory[j]; // entry at j to j+1
if(temp == null) { // if the next entry is null, don't really need to move no more, so break
break;
}
}
// finally place new entry at index position
directory[position] = //the new Entry
Make Entry implement Comparable<Entry> and write the appropriate compareTo method in your Entry class. Then, in your insert method, you want to
Use Arrays.binarySearch to find the right place in the array to insert your the entry.
Use System.arraycopy to shift everything in the array that's after the appropriate location one place to the right.
Set the appropriate entry.
You'll want to check out the Javadoc for Arrays.binarySearch and System.arraycopy.
Firstly, never use arrays unless you absolutely have to. Use Collecctions instead - they are far easier to deal with and have support for lots of operations you commonly want to perform on groups of things.
In your case, a TreeSet would be a good choice. If you want to sort the entries by surname only in this usage (and not generally), you can pass a customer Comparator to the constructor:
Set<Entry> directory = new TreeSet<>(new Comparator<Entry>() {
#Override
public int compare(Entry o1, Entry o2) {
return o1.getSurname().compareTo(o2.getSurname());
}
});
If your always want to sort Entry objects using surname, have your Entry class implement Comparable<Entry> and move the code into the compareTo() method of the Entry class.
Ok, here is the code and then the discussion follows:
public class FlatArrayList {
private static ArrayList<TestWrapperObject> probModel = new ArrayList<TestWrapperObject>();
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int [] currentRow = new int[10];
int counter = 0;
while (true) {
for (int i = 0; i < 10; i++) {
currentRow[i] = probModel.size();
}
TestWrapperObject currentWO = new TestWrapperObject(currentRow);
probModel.add(counter, currentWO);
TestWrapperObject testWO = probModel.get(counter);
// System.out.println(testWO);
counter++;
if (probModel.size() == 10) break;
}
// Output the whole ArrayList
for (TestWrapperObject wo:probModel) {
int [] currentTestRow = wo.getCurrentRow();
}
}
}
public class TestWrapperObject {
private int [] currentRow;
public void setCurrentRow(int [] currentRow) {
this.currentRow = currentRow;
}
public int [] getCurrentRow() {
return this.currentRow;
}
public TestWrapperObject(int [] currentRow) {
this.currentRow = currentRow;
}
}
What is the above code supposed to do? What I am trying to do is load an array as a member of some wrapper object (TestWrapperObject in our case). When I get out of the loop,
the probModel ArrayList has the number of elements it is supposed to have but all have the same value of the last element (an array of size 10 with each item equal to 9). This is not the case inside the loop. If you perform the same "experiment" with a primitive int value everything works fine. Am I missing something myself regarding arrays as object members? Or did I just encounter a Java bug? I am using Java 6.
You are only creating one instance of the currentRow array. Move that inside the row loop and it should behave more like you expect.
Specifically, the assignment in setCurrentRow does not create a copy of the object, but only assigns the reference. So each copy of your wrapper object will hold a reference to the same int[] array. Changing the values in that array will make the values appear to change for all other wrapper objects that hold a reference to the same instance of the array.
i don' t want to sound condescending, but always try to remember tip #26 from the excellent pragmatic programmer book
select isn't broken
it is very rare to find a java bug. keeping this in mind often helps me to look over my code again, turn it around, and shake out the loose bits until i finally discover where i was wrong. of course asking for help early enough is very encouraged, too :)