当前位置: 首页 > news >正文

基于ArrayList实现简单洗牌

前言

在之前的那篇文章中,我们已经认识了顺序表—>http://t.csdnimg.cn/2I3fE

基于此,便好理解ArrayList和后面的洗牌游戏了。

什么是ArrayList?

 ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表,与普通数组的区别就是它是没有固定大小的限制。

ArrayList的一些常见操作

首先我们要导入一个ArrayList包

import java.util.ArrayList;

在正式调用方法之前,别忘了创建一个ArrayList对象哦~

ArrayList<String> list = new ArrayList<>();

在这里,我就创建了一个只能存储String类型数据的ArrayList(顺序表)

下面便是ArrayList一些常见的使用方法,仔细观察就不难发现这些方法在模拟实现顺序表的时候就已经实现过了,现在直接用就行了,若有不记得了,可查看帮助手册-->Overview (Java SE 17 & JDK 17)

import java.util.ArrayList;public class commonTest {public static void main(String[] args) {// 创建一个ArrayList并添加一些元素ArrayList<String> list = new ArrayList<>();list.add("apple");list.add("banana");list.add("orange");// 使用get方法获取指定位置的元素String fruit = list.get(1);System.out.println("下标为1的水果是: " + fruit);// 使用set方法替换指定位置的元素list.set(0, "hello");System.out.println("替换之后 " + list);// 使用remove方法移除指定位置的元素list.remove(2);System.out.println("移除之后 " + list);// 使用size方法获取列表大小int size = list.size();System.out.println("列表大小: " + size);// 使用contains方法判断列表是否包含指定元素boolean containsBanana = list.contains("banana");System.out.println("是否包含banana " + containsBanana);}}

运行结果如图


运用之实现简单洗牌

纸牌相信大家都接触过,来看看如何利用ArrayList去实现洗牌?

这才是本文的重点哦~理论最终还是要服务与实践的,接下来就由我来带着各位看官来实现吧~

首先思考:

要洗牌,首先要有牌,想要表示出来,那么便要想好牌的属性--->花色和数字,好,那么就可以定义一个Card类专门存储这个,看下图:

public class Card {public int rank; // 表示牌面的数字public String suit; // 表示花色// 构造方法,用于初始化牌的数字和花色public Card(int rank, String suit) {this.rank = rank;this.suit = suit;}// 重写toString()方法,以便打印Card对象时能够直观地展示牌的信息@Overridepublic String toString() {return "Card{" + suit + "  " + rank + "}";}
}

这样一来,这个Card类很好地封装了扑克牌的属性。

一张牌肯定不够,一副牌有52张(去掉大小王)---4个花色,1到13的数字,在洗牌之前,先有一副完整的牌才行显示出来才行

于是就新定义一个Cards类,规定好牌的花色

public static final String[] suits = {"♥", "♠", "♣", "♦"};//定义四种花色

还记得final 的作用吗?这里用final 修饰就是为了不被修改

接着通过两个循环,一个遍历花色,一个遍历数字 ,这样一张新牌就创建好了,别忘了要创建存放牌的List,这里就导入了ArrayList包以便用add方法了。

import java.util.ArrayList;
import java.util.List;
// 买一副牌
public List<Card> buyCards() {List<Card> cardList = new ArrayList<>(); // 基于ArrayList创建一个用于存放牌的Listfor (int i = 0; i < 4; i++) { // 循环四种花色for (int j = 0; j < 13; j++) { // 循环13个数字(2-10,J,Q,K,A)int rank = j; // 当前数字String suit = suits[i]; // 当前花色Card card = new Card(rank, suit); // 创建一张新的牌对象cardList.add(card); // 将新牌加入到牌组中}}return cardList; // 返回完整的一副牌
}

此时运行便是这个样子

这下牌有了那就开始洗牌了,洗牌肯定讲究随机,讲到随机少不了Random方法,要调用它,也到导入对应的Random包。将生成的随机数对应的牌(看索引)在遍历的过程中与每个牌的位置进行交换,这样便完成了洗牌,配合代码食用效果更佳~

import java.util.Random;
// 洗牌
public void shuffle(List<Card> cardList) {Random random = new Random(); // 创建一个随机数生成器for (int i = cardList.size(); i > 0; i--) { // 从最后一张牌开始向前遍历int index = random.nextInt(i); // 生成一个随机的索引swap(cardList, i - 1, index); // 将当前牌与随机选出的牌进行交换}
}// 洗牌的原理-交换
public void swap(List<Card> cardList, int i, int j) {Card tmp = cardList.get(i); // 临时保存第i张牌cardList.set(i, cardList.get(j)); // 将第i张牌替换为第j张牌cardList.set(j, tmp); // 将第j张牌替换为临时保存的牌
}

还记得set方法是干嘛的吗?--->替换指定位置的元素,常见的记住可以提高效率的

此时效果是这样的 

那么到此牌洗好了,那就开始发牌,假设我们有三个人打牌,为了方便展示,就每人抽4张牌,思考一下,拿到牌后是不是也要存储才是?于是便要创建3个List去接受摸到的牌

// 发牌,三个人,每个人轮流摸4
public void drawCard(List<Card> cardList) {List<Card> hand1 = new ArrayList<>(); // 第一个人的手牌List<Card> hand2 = new ArrayList<>(); // 第二个人的手牌List<Card> hand3 = new ArrayList<>(); // 第三个人的手牌List<List<Card>> hand = new ArrayList<>(); // 存放三个人的手牌列表hand.add(hand1);hand.add(hand2);hand.add(hand3);for (int i = 0; i < 4; i++) { // 每个人轮流摸4张牌for (int j = 0; j < 3; j++) { // 三个人依次摸牌Card card = cardList.remove(0); // 从牌组中抽取一张牌,并从原来的牌组中移除hand.get(j).add(card); // 将抽取的牌加入到对应人的手牌列表中}}// 打印每个人摸到的牌System.out.println("第1个人摸到的牌:" + hand1);System.out.println("第2个人摸到的牌:" + hand2);System.out.println("第3个人摸到的牌:" + hand3);}

开始摸牌,用嵌套循环去模拟分发,这里要明白为啥每次只remove(0),这是因为存储牌的也是是基于ArrayList的List,每次移除第一个元素,后续的元素会自动补上,这样一来,每次遍历,下标为0的元素就是原来的下一张牌,就很好地模拟了实际的摸牌体验,

当然,循环停止后,也可以打印剩下的牌

        System.out.println("剩余的牌");//显示剩余的牌System.out.println(cardList);

 最后在创建一个测试类来看看效果是否符合预期

import java.util.List;public class demo {public static void main(String[] args) {Cards cards=new Cards();List<Card> cardList=cards.buyCards();System.out.println("刚开始的牌"+cardList);cards.shuffle(cardList);System.out.println("洗牌之后"+cardList);cards.drawCard(cardList);//摸牌}
}

最后的效果便是这般

说到这里,简单的洗牌游戏就被成功实现啦,如果感觉文章对你有所帮助的话,还请点点赞~

期待我们下次相会😉

相关文章:

  • 完美运营版商城源码 虚拟商品全功能商城 全能商城小程序 智慧商城系统 全品类百货商城(带安装教程)
  • cesium 加载gltf并实时改变位置 SampledProperty方式
  • 数据挖掘比赛比较基础的baseline
  • I.MX6ULL的MAC网络外设设备树实现说明一
  • VScode 集成终端设置默认打开当前文件夹 mac系统
  • vscode通过ssh连接服务器(吐血总结)
  • 【测试篇】测试用例
  • Claude-3全解析:图片问答,专业写作能力显著领先GPT-4
  • 如何正确使用reflect:Go反射规范与最佳实践
  • Linux的学习之路:4、权限
  • 某眼实时票房接口获取
  • 记忆力考验游戏-第15届蓝桥第5次STEMA测评Scratch真题精选
  • UniswapV2周边合约学习(五)-- ExampleFlashSwap.sol
  • Acwing.1388 游戏(区间DP对抗思想)
  • [环境配置]conda 64位安装32位python
  • [译] React v16.8: 含有Hooks的版本
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • create-react-app做的留言板
  • JavaScript服务器推送技术之 WebSocket
  • Java程序员幽默爆笑锦集
  • Mysql5.6主从复制
  • scrapy学习之路4(itemloder的使用)
  • Spring Cloud中负载均衡器概览
  • 阿里云Kubernetes容器服务上体验Knative
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 理清楚Vue的结构
  • 力扣(LeetCode)56
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 区块链技术特点之去中心化特性
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 鱼骨图 - 如何绘制?
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • ionic异常记录
  • linux 淘宝开源监控工具tsar
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • ​学习一下,什么是预包装食品?​
  • #{}和${}的区别?
  • #git 撤消对文件的更改
  • #Linux(make工具和makefile文件以及makefile语法)
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • $.proxy和$.extend
  • (Git) gitignore基础使用
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (四)鸿鹄云架构一服务注册中心
  • (算法)N皇后问题
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (一)Linux+Windows下安装ffmpeg
  • (一)基于IDEA的JAVA基础10
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • (转)Scala的“=”符号简介
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .gitattributes 文件
  • .java 9 找不到符号_java找不到符号