【Java】:洗牌功能和杨辉三角的实现

洗牌
此操作包含的基本功能有:
- 组牌:组建 52 张扑克牌
 
- 四种花色:“♥️”,“♠️”,“⬛️”,“♣️”
 - 每种花色 13 张牌:1~13
 
- 洗牌:将 52 张扑克牌打乱顺序
 - 发牌:给三个人每人发 5 张牌
 
扩展功能:
- 清牌:将每人手中牌按照面值进行从大到小排序
 
Card 类
在此类中,我们将完成对每一张牌的构造
-  
类中含有成员变量
- 花色:
suit - 面值:
rank 
 - 花色:
 -  
带有一个含参的构造方法,用来之后传入对应参数进行新牌的构造
 -  
重写
toString()方法,让输出的结果更美观 
public class Card {
    public int rank;
    public String suit;
    public Card(int rank, String suit) {
        this.rank = rank;
        this.suit = suit;
    }
    @Override
    public String toString() {
        return "{" +
                 + rank +
                " " + suit +
                "}";
    }
}
 
CardBox 类
所有的功能都将在这个类中进行具体地实现
组牌
组建 52 张牌:
List<Card> buildCard()
思路
- 创建一个容量为 
52,接收对象为Card的链表cardList - 两个 for 循环,为 
Card类里面的两个成员变量造值 - 随后依次为 
Card类实例化对象,将两个成员变量传入 Card 的构造方法中,创造出一张牌 - 最后依次将实例化出来的对象加入链表
 
代码
public class CardBox {
    public static final String[] suits = {"♥️", "♠️", "⬛️", "♣️"};
    public static List<Card> makeCard() {
        List<Card> cardList = new ArrayList<>(52);
        for (int i = 0; i < 4; i++) {
            for (int j = 1; j <= 13; j++) {
                int rank = j;
                String suit = suits[i];
                Card card = new Card(rank, suit);
                cardList.add(card);
            }
        }
        return cardList;
    }
}
 
洗牌
运用下标交换进行牌的打乱:
void shuffle(List<Card> cardList)
思路
- 使用随机数函数 
Random进行下标交换匹配,用随机数函数创造一个范围内的下标randomIndex - 再让随机数 
randomIndex下标在顺序表中对应的牌与目标牌进行交换 - 交换需要用到一个自定义函数:
void swap(List<Card> cardList, int i, int j)- 此函数对 
cardList链表进行操作,将其中i位置的数据与j位置的数据进行交换 
 - 此函数对 
 
代码
 public static void shuffle(List<Card> cardList) {
    for (int i = cardList.size() - 1; i > 0; i--) {
        int randomIndex = new Random().nextInt(i);
        swap(cardList,randomIndex,i);
    }
}
private static void swap(List<Card> cardList, int i, int j){
    Card tmp = cardList.get(i);
    cardList.set(i,cardList.get(j));
    cardList.set(j,tmp);
}
 
发牌
将牌分发给三个人:
void drawCard (List<Card> cardList)
思路
- 为四个人创建三个 
Card类型的链表,就相当于是“他们的手”,用来拿他们发到的牌 - 再创建一个以“
他们的手”为类型的链表,就相当于是“发牌人的手”,用来将发好的牌堆发给他们 - 发牌的原理是依次移走下标为 
0的那张牌 
代码
public void drawCard (List<Card> cardList) {
    List<Card> hand1 = new ArrayList<>();
    List<Card> hand2 = new ArrayList<>();
    List<Card> hand3 = new ArrayList<>();
    List<List<Card>> hands = new ArrayList<>();
    hands.add(hand1);
    hands.add(hand2);
    hands.add(hand3);
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 3; j++) {
            hands.get(j).add(cardList.remove(0));
        }
    }
}
 
扩展:清牌
在发牌之后,将每人手中牌按照面值进行从大到小排序:
思路
- 重写 Collection 接口中的 
sort()方法 - 在参数中直接传入一个用来排序链表的比较器
 
代码
public void drawCard (List<Card> cardList){
    List<Card> hand1 = new ArrayList<>();
    List<Card> hand2 = new ArrayList<>();
    List<Card> hand3 = new ArrayList<>();
    List<List<Card>> hands = new ArrayList<>();
    hands.add(hand1);
    hands.add(hand2);
    hands.add(hand3);
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 3; j++) {
            hands.get(j).add(cardList.remove(0));
        }
    }
    for (int i = 0; i < 3; i++) {
        Collections.sort(hands.get(i), new Comparator<Card>() {
            @Override
            public int compare(Card o1, Card o2) {
                return o1.rank - o2.rank;
            }
        });
    }
    System.out.println("第一个人的牌"+hand1);
    System.out.println("第二个人的牌"+hand2);
    System.out.println("第三个人的牌"+hand3);
}
 
运行结果

杨辉三角
思路

- 首位:每行的第一个都是 
1,直接add(1)进入当前行curRow - 中间的值: 
  
- 第 
i行的第j下标元素是第i - 1行的第j下标元素和j - 1下标元素相加之和 
 - 第 
 - 末位:为 
1,直接add(1)进入当前行curRow 
代码
public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> ret = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        //第一行第一列
        list.add(1);
        ret.add(list);
        for (int i = 1; i < numRows; i++) {
            //当前行
            List<Integer> curRow = new ArrayList<>();
            //首位均为 1
            curRow.add(1);
            //中间的
            for (int j = 1; j < i; j++) {
                //i = 1是当前行,那 i - 1就是上一行
                List<Integer> preRow = ret.get(i - 1);
                int x1 = preRow.get(j);
                int x2 = preRow.get(j - 1);
                curRow.add(x1 + x2);
            }
            //当前行,最后一个 1
            curRow.add(1);
            ret.add(curRow);
        }
        return ret;
    }
                