0

Ok, so, I have the method straight(ArrayList<Card> l) defined below. It works but I really want to improve it because my algorithm is running quite slow.

The idea here is: get all value of the Cards and add them to an arraylist, then check whether the arraylist contain the list of straights or not. If yes, add it to a hashmap, the last array added will be the best straight (in case there are 3 straight: 1 2 3 4 5 6 7)

The Card is define by 2 arrays: value and suit which are:

private String[] name = {"Joker", "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
private String[] suit = {"Club", "Diamond", "Spade", "Heart"};

So I have 2 questions:

1, Is there anyway to improve the code below?

2, I do this project for fun, I want this to be multiple player. So should the server detect the best hand of each player or players do that and then send the result back to server by a pair in form of (String, ArrayList bestHand)?

public ArrayList<Card> straight(ArrayList<Card> l){
        ArrayList<Card> straight = new ArrayList<>();
        ArrayList<Card> card_value = this.removeDuplicate(l);
        ArrayList<Integer> temp_value = this.getCardValue(card_value);

        ArrayList<Integer[]> possible_straight = new ArrayList<>();
        possible_straight.add(new Integer[]{1, 2, 3, 4, 5});
        possible_straight.add(new Integer[]{2, 3, 4, 5, 6}); 
        possible_straight.add(new Integer[]{3, 4, 5, 6, 7});
        possible_straight.add(new Integer[]{4, 5, 6, 7, 8});
        possible_straight.add(new Integer[]{5, 6, 7, 8, 9});
        possible_straight.add(new Integer[]{6, 7, 8, 9, 10});
        possible_straight.add(new Integer[]{7, 8, 9, 10, 11});
        possible_straight.add(new Integer[]{8, 9, 10, 11, 12});
        possible_straight.add(new Integer[]{9, 10, 11, 12, 13});
        possible_straight.add(new Integer[]{10, 11, 12, 13, 1});

        HashMap<Integer, Integer[]> check_list = new HashMap<>();
        int controller = 0;

        for (int i = 0; i < possible_straight.size(); i++){
            Integer[] dummy = possible_straight.get(i);
            if (temp_value.containsAll(Arrays.asList(dummy))){
                check_list.put(controller++, dummy);
            }
        }

        if (!check_list.isEmpty()){
            for (int k = 0; k < check_list.get((controller - 1)).length; k++){
                for (int m = 0; m < card_value.size(); m++){
                    Card temp_card = card_value.get(m);
                    if (temp_card.getValue() == check_list.get(controller - 1)[k]){
                      straight.add(temp_card);
                    }
                }
            }
        }

        return straight;
    }
TacticalCoder
  • 6,275
  • 3
  • 31
  • 39
Trung Nguyen
  • 459
  • 1
  • 5
  • 6

2 Answers2

0

An answer to your first question: Except for the special case 10, 11, 12, 13, 1, you could do this by simply sorting the array and then checking each element to see if it is exactly one more than the element before it. The following code is all you should need, except for handling that special case: (Note that this solution returns a list of ints, not a list of cards. You may wish to modify it to return cards instead.)

ArrayList<int[]> straights = new ArrayList();
sort(l)//Implement some sort of sorting algorithm here.
int consecutive=0;
for(int i=1;i<l.size();i++){
    if(l.get(i).getValue()-l.get(i-1).getValue()<=1)){
        consecutive++;
        if(consecutive>=5){
            int[] values=new int[5];
            values[0]=l.get(i).getValue()-4;
            for(int j=1;j<5;j++)values[j]=values[0]+j;
            straights.add(values);
        }
    }
}

After sorting the list, this looks to see if there are any cards in the list that are not exactly one more than the one before them; if there are, it returns an empty list, and if there are not it returns the original list.

Epiglottal Axolotl
  • 1,048
  • 8
  • 17
0

You can retrieve all of the possible straights like so:

Output

[0, 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 12, 13, 14]
Straight?: [[0, 1, 2, 3, 4], [4, 5, 6, 7, 8], [8, 9, 10, 11, 12]]

StrightDetector.java

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class StraightDetector {
    public static void main(String[] args) {
        List<Card> cards = new ArrayList<Card>();
        int lengthOfStrait = 5, numberOfStrights = 3;
        for (int i = 0; i < lengthOfStrait * numberOfStrights; i++) {
            cards.add(new Card(i));
            // Insert a duplicate after every straight. 
            if (i % (lengthOfStrait - 1) == 0) cards.add(new Card(i));
        }
        System.out.println(cards);
        List<List<Card>> strights = findStrights(cards, lengthOfStrait);
        System.out.println("Straight?: " + (!strights.isEmpty() ? strights : "Nope..."));
    }

    public static List<List<Card>> findStrights(List<Card> cards, int length) {
        List<List<Card>> straights = new ArrayList<List<Card>>();
        Collections.sort(cards);
        int consecutive = 1;
        for (int i = 1; i < cards.size(); i++) {
            if (Math.abs(cards.get(i).getRank() - cards.get(i - 1).getRank()) >= 1) {
                consecutive++;
                if (consecutive >= length) {
                    List<Card> values = new ArrayList<Card>();
                    for (int j = length - 1; j >= 0; j--) values.add(cards.get(i - j));
                    straights.add(values);
                }
            } else
                consecutive = 1;
        }
        return straights;
    }
}

Card.java

public class Card implements Comparable<Card>, Comparator<Card> {
    private int rank;
    public int getRank() { return rank; }
    public void setRank(int rank) { this.rank = rank; }

    public Card(int rank) {
        this.rank = rank;
    }

    @Override
    public int compare(Card card1, Card card2) {
        return card1.compareTo(card2);
    }
    @Override
    public int compareTo(Card other) {
        return Integer.compare(getRank(), other.getRank());
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        return prime * result + rank;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        Card other = (Card) obj;
        if (rank != other.rank) return false;
        return true;
    }
    @Override
    public String toString() {
        return String.format("%d", rank);
    }
}
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132