洗牌
此操作包含的基本功能有:
- 组牌:组建 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;
}