Java零基础入门-如何代码模拟斗地主洗牌发牌动作?【完整版】
【摘要】 一、本期教学目标掌握map集合常用方法。掌握map集合使用场景。通过map集合实现斗地主洗牌发牌动作。二、前言 对于双列集合之map集合,它的相关知识点及拓展咱们都已经差不多学完了。接下来,就是带着大家如何灵活运用map进行一个实战教学,概念加实践相结合,才能让你更好的掌握与理解每一个知识点,废话不多说,我这就开始。 今天就给大家玩个有意思的,日常我们对于斗地...
一、本期教学目标
- 掌握map集合常用方法。
- 掌握map集合使用场景。
- 通过map集合实现斗地主洗牌发牌动作。
二、前言
对于双列集合之map集合,它的相关知识点及拓展咱们都已经差不多学完了。接下来,就是带着大家如何灵活运用map进行一个实战教学,概念加实践相结合,才能让你更好的掌握与理解每一个知识点,废话不多说,我这就开始。
今天就给大家玩个有意思的,日常我们对于斗地主都司空见惯了,随时随地都可以玩儿,今天我要讲的案例就与它有关,不是实现三人斗地主输赢机制哈,这点有兴趣的小伙伴可以私下研究研究,我今天要演示的就是如何通过代码实现斗地主的洗牌发牌动作,而且就用map集合来实现,这个对于你们而言,难么?难度肯定有。
但是没关系,我会一步一步帮助大家分析,分析完再动手。
三、案例介绍
首先我们都知道,一副牌有54张,我们就严格按照斗地主的规则,通过代码来完成洗牌发牌动作。
如下是随机模拟了斗地主中三位小伙伴的手牌展示,并按从"大"到"小"的顺序进行排列。
如下是案例的具体规则:
- 准备一副正规的54张扑克牌。
- 将54张扑克牌随机打乱。
- 参照斗地主模式,三人参与游戏,交替摸牌。
- 每人交替摸牌17张,最后三张留做底牌。
- 每人查看各自手牌,并按牌的顺序"大小"有序排列展示。
注意:扑克牌从大到小的摆放顺序应为:大王,小王,2,A,K,Q,J,10,9,8,7,6,5,4,3。
四、需求分析
接下来,就是对该场景进行分析模拟了,具体如下:
1️⃣准备牌
自定义好数字与扑克牌数字的对应映射关系,比如:0=大王,1=小王,2=♥2,3=♠2,4=♦2,5=♣2 ... ...依次类推。具体指定该映射关系,我们可以用到双列集合map,完成数字与扑克牌的对应关系(map字典)。
具体映射关系可参考如下:
2️⃣洗牌
洗牌的话就可以通过数字完成洗牌动作。代码层面可通过Collections.shuffle()方法来打乱元素顺序。
3️⃣发牌
将每个人以及底牌设计为一个ArrayList<String>集合,将最后3张除开作为底牌,其他牌按取模的方式依次轮发牌,每次一张。其中发牌,发的是牌所对应的编号;并且在发牌时,要求数字排列顺序要按斗地主规则的大小顺序排列,所以这里我们在确定数字与扑克牌之间的映射关系时就是从大到小进行确定的,从左往右,从大王到2到A到K...最后到3,而它们对应的key则数字是从小到大依次递增,这也就是为了方便后续直接看牌步骤只需要将对应数字从map字段中找到对应字符展示即可,这也就是按斗地主排序的规则的排列的。不知道你们有没有理解。
4️⃣排序
这一步就是要按照斗地主的排序规则,对各位玩家的手牌进行一个排序处理。
5️⃣看牌
将各自手牌中的数字从map字典中取出对应的字符展示即可。代码实现:通过编号也就是map 的key,直接map.get(key)即可。
五、代码实现
1️⃣创建数字与扑克字符的映射
组装一副由54张扑克组成的扑克牌,由编号按斗地主牌面值顺序进行排序,说明一下,这样有序排列,目的是最后好按斗地主牌排序输出,如果乱序,怎么知道斗地主的牌面排序是如何呢?完全没有规则,所以从这里就得确定排序规则。
接下来就是对该小点实现步骤分析:
- 创建一个map字典,目的是用于存放编码与扑克牌面值。
- 分别创建扑克中的 花色集合 与 数字集合,目的是为了排列组合所有的扑克牌值。
- 列举扑克中所包含的所有花色与数字。
- 大小王先写入map字典中,编号从0开始。
- 接着再分别将所有的花色与数字组合按集合顺序有序写进。
具体该创建map字典完整代码实现如下:
由于扑克牌中大小王是最大,且不跟花色数字一样,所以就单独进行map写入,大王为0,小王为1,其次就是根据扑克数字集合进行双遍历排列组合,编号就每次加1,这样就保证了同牌面值越大编号则越小,牌面值越小的值越大。
扑克字典顺序(pokerMap)展示如下:
具体完整pokerMap打印如下:
pokerMap:{0=大王, 1=小王, 2=♦2, 3=♣2, 4=♥2, 5=♠2, 6=♦A, 7=♣A, 8=♥A, 9=♠A, 10=♦K, 11=♣K, 12=♥K, 13=♠K, 14=♦Q, 15=♣Q, 16=♥Q, 17=♠Q, 18=♦J, 19=♣J, 20=♥J, 21=♠J, 22=♦10, 23=♣10, 24=♥10, 25=♠10, 26=♦9, 27=♣9, 28=♥9, 29=♠9, 30=♦8, 31=♣8, 32=♥8, 33=♠8, 34=♦7, 35=♣7, 36=♥7, 37=♠7, 38=♦6, 39=♣6, 40=♥6, 41=♠6, 42=♦5, 43=♣5, 44=♥5, 45=♠5, 46=♦4, 47=♣4, 48=♥4, 49=♠4, 50=♦3, 51=♣3, 52=♥3, 53=♠3}
这样你们直观的看, 是不是就一目了然,花色因为不需要考虑顺序,所以对于花色集合防御内循环,外循环有牌面值来固定,对于每一个牌面值它都有4种花色,这是扑克的特点,这大家别忽略掉了。
2️⃣洗牌
接下来就是洗牌动作了,所谓的洗牌就是把一副牌打乱,那我们按什么来固定一副牌呢,很简单,你只需要确定一个list集合,而其中的元素就是一副牌中的所有编号,然后将装有编号的list进行元素位置打乱调整即可。
接下来就是对该小点实现步骤分析:大家请看
- 先从map字典中取出所有的扑克编号porkSet。
- 定义一个存放扑克编号的list集合。
- 将porkSet全部添加到list集合中。
- 对list集合进行打乱操作。
具体实现洗牌动作完整代码实现如下:
顺序打乱前我们可以明显看到获取到的正是map字典的所有字典编号。
而我们执行Collections.shuffle()方法,目的就是将上述所获取到的map字典编号进行顺序打乱,我们可以从下方截图得知:是否被全部打乱?具体请看如下截图,咱们一见分晓。
很明显,将所获取到的map字典所有的编号已打乱,目的不就是洗牌么。
打印洗牌后的打印结果:很明显是无序的把。
porkList:[2, 11, 20, 51, 24, 5, 33, 27, 21, 45, 22, 17, 50, 44, 15, 10, 1, 19, 6, 39, 49, 12, 37, 35, 23, 7, 47, 41, 25, 38, 31, 46, 8, 32, 28, 9, 48, 34, 16, 52, 43, 18, 4, 30, 0, 53, 14, 36, 29, 26, 40, 3, 13, 42]
3️⃣发牌
洗完牌,接着就是给三名玩家进行发牌了。发牌规则就是每名玩家轮流摸牌,每名玩家各17张牌,且摸到第17轮时停手,剩余3张作为底牌。
至于如何代码实现发牌动作,接下来就是对该小点实现步骤分析:大家请看
- 定义4个list集合,分别存放玩家123及底牌。
- 对上述进行洗牌后的porkList进行遍历。完成三个玩家交替摸牌。
- 遍历porkList,遍历步长为1。
- 如何控制3人轮流摸牌?这好办呀,这我们可以这么做,取遍历下标index,对3进行取模依次判断模值是否为0、1、2,不就实现了一人一模。
- 注意,如何确定三张底牌?最简单的做法就是判断当index >=51时,则表示循环已经是第18轮循环,对最后获取到的三张牌写入底牌list集合中即可。
具体实现发牌动作完整代码实现如下:
我们可以来看下,我们三名玩家且底牌的获取是否满足一副完整牌。
数量总数相加是54,这是毫无疑问的。至于里头的编号是否有重复的,我们可以来检验一下,哪怕是通过肉眼也行啊。
大家请看下边的排序展示,这对于肉眼排查也是最直接的啊。
4️⃣玩家各手牌牌按编号排序
由于map字典是按斗地主大小排序的,所以对于这几名玩家及底牌,我们可以直接用Collections集合工具类提供的sort()方法一键排序。就非常的方便快捷。
发牌后手动按斗地主牌规则排完序的打印结果:
playerNo1:[2, 4, 6, 10, 12, 23, 29, 31, 32, 33, 41, 45, 48, 50, 51, 52, 53]
playerNo2:[1, 7, 11, 14, 22, 24, 25, 26, 27, 28, 30, 34, 37, 39, 43, 44, 46]
playerNo3:[0, 5, 8, 9, 15, 16, 17, 18, 19, 20, 21, 35, 36, 38, 40, 47, 49]dipaiNo:[3, 13, 42]
5️⃣牌由编号转牌面值
由于我们这里对玩家的手牌只是存储的map字典表中的编号,如果需要真实展示,那肯定是需要对编号进行转扑克牌面值吧,这对于大家来说,这一步非常的简单,具体如何做呢?
- 定义一个方法,入参为list手牌。
- 遍历list手牌,根据遍历所取到的编号从map字典中获取porkMap所对应的牌面值。
具体代码实现如下:
而对于该方法,我们就要手动调用4次,依次传入玩家123及底牌集合。
然后打印结果如下:
玩家1手牌:[♦2, ♥2, ♦A, ♦K, ♥K, ♣10, ♠9, ♣8, ♥8, ♠8, ♠6, ♠5, ♥4, ♦3, ♣3, ♥3, ♠3]
玩家2手牌:[小王, ♣A, ♣K, ♦Q, ♦10, ♥10, ♠10, ♦9, ♣9, ♥9, ♦8, ♦7, ♠7, ♣6, ♣5, ♥5, ♦4]
玩家3手牌:[大王, ♠2, ♥A, ♠A, ♣Q, ♥Q, ♠Q, ♦J, ♣J, ♥J, ♠J, ♣7, ♥7, ♦6, ♥6, ♣4, ♠4]
底牌:[♣2, ♠K, ♦5]
6️⃣展示所有玩家及底牌
由于步骤5已经对底牌进行了转换,我们便可以直接对该转后的集合分别进行打印输出:
具体代码实现如下:
转成扑克牌字符结果如下:
玩家1手牌:[♦2, ♥2, ♦A, ♦K, ♥K, ♣10, ♠9, ♣8, ♥8, ♠8, ♠6, ♠5, ♥4, ♦3, ♣3, ♥3, ♠3]
玩家2手牌:[小王, ♣A, ♣K, ♦Q, ♦10, ♥10, ♠10, ♦9, ♣9, ♥9, ♦8, ♦7, ♠7, ♣6, ♣5, ♥5, ♦4]
玩家3手牌:[大王, ♠2, ♥A, ♠A, ♣Q, ♥Q, ♠Q, ♦J, ♣J, ♥J, ♠J, ♣7, ♥7, ♦6, ♥6, ♣4, ♠4]
底牌:[♣2, ♠K, ♦5]
如下是完整控制台打印内容:
7️⃣总结
如上就是完整的通过代码模拟斗地主的洗牌发牌到展示牌的这一系列动作,不知道你对于该模拟场景有何思考?对于里头的那一阶段遇到了问题或者有难度的,都可以评论区进行交流呀,不懂咱就问。
要我来说就是要分析理清楚每一个环节分别做什么事,比如从刚开始的map字典,这一步,如果你能想到,并且还通过编号来确定斗地主牌面值排序,就已经完成了百分之五十,其次就是能运用到Collections所提供的shuffle()、sort().其实也不枉费我这段期间给大家的免费教学map集合相关知识点啦,其实这一期也是对map双列集合的一个实地联系加具体业务联合使用,对于你在日后的业务开发中,也能有一定的业务锻炼及方法选型起到一定的启蒙锻炼。
不要说写的这些练习,压根实际业务开发中就遇不到,这并不是说业务写到的东西就才是用用的,大错特错,千万别这样想啊,兄弟们,现在教学的都是身为一名java开发必须要掌握的,这并不是跟大家开玩笑,毕竟我就是这么过来的。
8️⃣附完整代码
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)