不到一个月独自一人开发斗地主游戏(h5 + 安卓 + 苹果) 您所在的位置:网站首页 斗地主游戏为什么要身份信息认证呢 不到一个月独自一人开发斗地主游戏(h5 + 安卓 + 苹果)

不到一个月独自一人开发斗地主游戏(h5 + 安卓 + 苹果)

2024-06-26 13:59| 来源: 网络整理| 查看: 265

独自一人开发斗地主游戏(h5 + 安卓 + 苹果) 开篇感言背景涉及到的知识点技能架构设计及其思路详细设计1 单张卡牌设计2 打牌时,卡牌组合的牌型设计3 一种通用的牌型及其比较算法房间的设计游戏控制器与回合的设计前端0号座椅总是为自己的设计 效果图

开篇感言

不枉我深入学习基础知识,算法与数据结构,编译原理,java并发编程,这些东西都有用得到的时候。

再极端的时间内学习了cocos creator引擎,并学以致用,有极大的增加了自己的自信心。

在公司总是拧螺丝,一个人开发一个完成的作品,我又觉得自己彷佛回到了色彩斑斓的世界中。

前端代码地址:https://github.com/neroHua/neroGameClient 后端代码地址:https://github.com/neroHua/neroGameServer

背景

本人使用java工作已经7年之多了,js和ts基本懂一些。 打算开发一款逮狗腿子的棋牌游戏(合同学们玩),先仿制一款斗地主游戏,试一下。

涉及到的知识点技能

编码功底:

算法和数据结构设计模式(策略,责任链)敏捷开发。

游戏引擎: 1.Cocos creator 2.0.4

网络通信: 1. http 2. websocket

编程语言: 1.java (后端) 2.typeScript(前端)

后端: 1.spring,springMVC,spring boot, mybatis 2.flyway,jwt,h2,junit

前端: h5

架构设计及其思路 服务器整体为单机结构(以后有需要,再扩容好了),提供 h5,安卓,苹果 三种客户端接入服务器,且前端由Cocos 引擎处理,直接打包成三个端 。客户端和服务器端的通信协议选择为http,和 websocket (三端都支持的通信方式)。用户点击等等事件由客户端发送http请求。通过websocket,服务器向客户端推送消息。服务器端不接收用户通过websocket推送到服务器的消息。只用用户进入房间以后,才会开启websocket通信。游戏的主要模型/功能设计。用户,房间,游戏,游戏控制器,游戏回合。房间是核心: 用户再房间里面玩游戏。每一个房间都有一个游戏控制器用以控制游戏的进程。用户有手牌。游戏控制器,通过游戏回合控制每回合的进行。 详细设计 1 单张卡牌设计

为了便于,排序,比较,等操作,设计如下:

这里的code呢,等于卡牌前端的图片名称(不过我这里前端使用的图集)。 这里的value呢,代表了单张卡牌的权值大小,可用于比较牌面的大小。 这里的message呢,代表了卡牌的中文名称。 这里不需要花色,所以没有设计花色字段

package com.nero.hua.enumeration; import lombok.Getter; @Getter public enum CardEnumeration { CARD_103("card_103", 3, "方块3"), CARD_104("card_104", 4, "方块4"), CARD_105("card_105", 5, "方块5"), CARD_106("card_106", 6, "方块6"), CARD_107("card_107", 7, "方块7"), CARD_108("card_108", 8, "方块8"), CARD_109("card_109", 9, "方块9"), CARD_110("card_110", 10, "方块10"), CARD_111("card_111", 11, "方块J"), CARD_112("card_112", 12, "方块Q"), CARD_113("card_113", 13, "方块K"), CARD_114("card_114", 14, "方块1"), CARD_115("card_115", 15, "方块2"), CARD_203("card_203", 3, "梅花3"), CARD_204("card_204", 4, "梅花4"), CARD_205("card_205", 5, "梅花5"), CARD_206("card_206", 6, "梅花6"), CARD_207("card_207", 7, "梅花7"), CARD_208("card_208", 8, "梅花8"), CARD_209("card_209", 9, "梅花9"), CARD_210("card_210", 10, "梅花10"), CARD_211("card_211", 11, "梅花J"), CARD_212("card_212", 12, "梅花Q"), CARD_213("card_213", 13, "梅花K"), CARD_214("card_214", 14, "梅花1"), CARD_215("card_215", 15, "梅花2"), CARD_303("card_303", 3, "红桃3"), CARD_304("card_304", 4, "红桃4"), CARD_305("card_305", 5, "红桃5"), CARD_306("card_306", 6, "红桃6"), CARD_307("card_307", 7, "红桃7"), CARD_308("card_308", 8, "红桃8"), CARD_309("card_309", 9, "红桃9"), CARD_310("card_310", 10, "红桃10"), CARD_311("card_311", 11, "红桃J"), CARD_312("card_312", 12, "红桃Q"), CARD_313("card_313", 13, "红桃K"), CARD_314("card_314", 14, "红桃1"), CARD_315("card_315", 15, "红桃2"), CARD_403("card_403", 3, "黑桃3"), CARD_404("card_404", 4, "黑桃4"), CARD_405("card_405", 5, "黑桃5"), CARD_406("card_406", 6, "黑桃6"), CARD_407("card_407", 7, "黑桃7"), CARD_408("card_408", 8, "黑桃8"), CARD_409("card_409", 9, "黑桃9"), CARD_410("card_410", 10, "黑桃10"), CARD_411("card_411", 11, "黑桃J"), CARD_412("card_412", 12, "黑桃Q"), CARD_413("card_413", 13, "黑桃K"), CARD_414("card_414", 14, "黑桃1"), CARD_415("card_415", 15, "黑桃2"), CARD_500("card_500", 0, "背面"), CARD_508("card_508", 8, "狗子"), CARD_516("card_516", 16, "小王"), CARD_517("card_517", 17, "大王"); private String code; private int value; private String message; CardEnumeration(String code, int value, String message) { this.code = code; this.value = value; this.message = message; } } 2 打牌时,卡牌组合的牌型设计

为了便于,排序,比较,等操作,设计如下: 权值大的牌型,比权值小的牌型大。 权值相同的牌型,需要牌型一样(牌型为同一个枚举)方可比较

这里的code呢,一种编码。 这里的value呢,代表的组合的权值。 这里的message呢,代表了卡牌的中文名称。 逮狗腿子,有些牌型不支持,还需要更多的牌型,后面再弄了,不过思路是已经想好了。

package com.nero.hua.enumeration; import lombok.Getter; @Getter public enum PlayCardTypeEnumeration { SINGLE("single", 0, "单牌"), STRAIGHT("straight", 0, "顺子"), PAIR("pair", 0, "对子"), PAIR_STRAIGHT("pairStraight", 0, "连对"), TRIPLE("triple", 0, "三不带"), TRIPLE_SINGLE("tripleSingle", 0, "三带一"), TRIPLE_PAIR("triplePAIR", 0, "三带一对"), AIRPLANE("airplane", 0, "飞机不带"), AIRPLANE_SINGLE("airplaneSingle", 0, "飞机带单"), AIRPLANE_PAIR("airplanePair", 0, "飞机带对"), FOUR_SINGLE("fourSingle", 0, "4带2"), FOUR_PAIR("fourPair", 0, "4带2对"), BOMB("bomb", 1, "炸弹"), BOMB_KING("bombKing", 2, "王炸"); private String code; private int value; private String message; PlayCardTypeEnumeration(String code, int value, String message) { this.code = code; this.value = value; this.message = message; } } 3 一种通用的牌型及其比较算法

1.为了便于比较牌型,先把牌按照一定格式格式化, 比如下面的。(对于有变种的牌型可以让客户端选择)

/** * 客户端需要根据牌型把本字段格式化并排序降低服务器计算压力 * * 比如 * 顺子:7, 6, 5, 4, 3 * 对子:5,5, 4, 4, 3, 3 * 三带一: 3, 3, 3, 2 * 三带对: 3, 3, 3, 2, 2 * 飞机带单: 4, 4, 4, 3, 3, 3, 2, 1 * 飞机带对: 4, 4, 4, 3, 3, 3, 2, 2, 1, 1 * 王炸:大王, 小王 * */

2.对于格式化后的牌型,比较的办法如下:

public static boolean currentPlayCardListBetterThanLastPlayCardList(UserPlayCardTurnMO lastUserPlayCardTurnMO, List playCardList, PlayCardTypeEnumeration playCardTypeEnumeration) { if (null == lastUserPlayCardTurnMO) { return Boolean.TRUE; } PlayCardTypeEnumeration lastPlayCardTypeEnumeration = lastUserPlayCardTurnMO.getPlayCardTypeEnumeration(); if (playCardTypeEnumeration.getValue() return Boolean.TRUE; } if (lastPlayCardTypeEnumeration != playCardTypeEnumeration) { return Boolean.FALSE; } List lastPlayCardList = lastUserPlayCardTurnMO.getCardList(); return lastPlayCardList.size() == playCardList.size() && lastPlayCardList.get(0).getValue() List cardEnumerationList = playCardCountListMap.get(countList.get(i)); for (int j = 0; j Map playCardValueCountMap = new HashMap(); for (int i = 0; i playCardValueCountMap.put(playCardList.get(i).getValue(), 1); } else { playCardValueCountMap.put(playCardList.get(i).getValue(), count + 1); } } return playCardValueCountMap; }

对牌按照单牌权值递减的顺序进行排序(这里使用快排)

public static void quickSortOneCardList(int start, int end, List cardList) { if (start >= end) { return; } CardEnumeration keyCard = cardList.get(start); int i = start; int j = end; while (i != j) { if (cardList.get(i).getValue() i++; } } int middle = cardList.get(i).getValue() >= keyCard.getValue() ? i : i - 1; if (middle >= start && middle Map playCardCountListMap = new HashMap(); for (Integer i : playCardValueCountMap.keySet()) { playCardCountListMap.put(playCardValueCountMap.get(i), new LinkedList()); } for (int i = 0; i List countList = new ArrayList(); for (Integer i : playCardCountListMap.keySet()) { countList.add(i); } selectionSort(countList); return countList; } public static void selectionSort(List countList) { if (1 == countList.size()) { return; } for (int i = 0; i Integer tobeCompared = countList.get(j); if (tobeCompared > current) { countList.set(i, tobeCompared); countList.set(j, current); current = tobeCompared; } } } }

把按照相同单牌权值数量分割的碎片,根据数量的大小拼接起来

for (int i = 0, k = 0; i playCardList.set(k, cardEnumerationList.get(j)); k++; } } 对格式化的牌进行牌型的识别 可以使用责任链模式,对于变种的可以可以处理。(playCardTypeValidateList 可以通过spring或者静态代码初始化进去),这种方式比较面向对象,看着更加优雅。不过考虑牌型的概率分布我使用了另外一种方式。 for (PlayCardTypeValidate playCardTypeValidate : playCardTypeValidateList) { if (playCardTypeValidate.match(formattedPlayCardList)) { playCardTypeMap.put(playCardTypeValidate.getPlayCardTypeEnumeration(), formattedPlayCardList); break; } }

对于格式化好的三带二可以使用下面的代码识别。

package com.nero.hua.validate.impl; import com.nero.hua.enumeration.CardEnumeration; import com.nero.hua.enumeration.PlayCardTypeEnumeration; import com.nero.hua.validate.PlayCardTypeValidate; import java.util.List; public class AirplanePairValidate implements PlayCardTypeValidate { private static final int MIN_COUNT = 10; private static final int GROUP_COUNT = 5; private static final int TRIPLE_COUNT = 3; @Override public PlayCardTypeEnumeration getPlayCardTypeEnumeration() { return PlayCardTypeEnumeration.AIRPLANE_PAIR; } @Override public boolean match(List cardEnumerationList) { if (cardEnumerationList.size() return Boolean.FALSE; } for (int i = 0; i return Boolean.FALSE; } } for (int i = 0; i return Boolean.FALSE; } } if (cardEnumerationList.get(0).getValue() >= CardEnumeration.CARD_415.getValue()) { return Boolean.FALSE; } int lastTripleStartIndex = this.calculateLastTripleStartIndex(cardEnumerationList.size()); for (int i = lastTripleStartIndex + 3; i return Boolean.FALSE; } } return Boolean.TRUE; } private int calculateLastTripleStartIndex(int size) { return (size / GROUP_COUNT - 1) * TRIPLE_COUNT; } } 房间的设计

房间中由用户,游戏控制器。

package com.nero.hua.model.room; import com.nero.hua.enumeration.CardEnumeration; import com.nero.hua.enumeration.PlayCardTypeEnumeration; import com.nero.hua.enumeration.RoomEnumeration; import com.nero.hua.exception.RoomException; import com.nero.hua.game.manager.GameManager; import com.nero.hua.model.user.GameUserMO; import lombok.Getter; import lombok.Setter; import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @Setter @Getter public class RoomMO { private Long roomId; private GameManager gameManager; private List gameUserMOList = new ArrayList(); public void joinUser(String userId) { if (gameUserMOList.size() > this.gameManager.getMaxUserCount()) { throw new RoomException(RoomEnumeration.ROOM_NOT_FOUND); } GameUserMO gameUserMO = new GameUserMO(); gameUserMO.setUserId(userId); gameUserMO.setPrepared(Boolean.TRUE); gameUserMOList.add(gameUserMO); } public void leaveUser(String userId) { Iterator iterator = gameUserMOList.iterator(); while (iterator.hasNext()) { GameUserMO next = iterator.next(); if (userId.equals(next.getUserId())) { iterator.remove(); break; } } } public List getAllUserList() { List userIdList = new LinkedList(); for (GameUserMO gameUserMO : this.getGameUserMOList()) { userIdList.add(gameUserMO.getUserId()); } return userIdList; } public List getAllOtherUserList(String userId) { List userIdList = new LinkedList(); for (GameUserMO gameUserMO : this.getGameUserMOList()) { if (!userId.equals(gameUserMO.getUserId())) { userIdList.add(gameUserMO.getUserId()); } } return userIdList; } public void changeUserPrepareStatus(String userId, boolean prepared) { Iterator iterator = gameUserMOList.iterator(); while (iterator.hasNext()) { GameUserMO next = iterator.next(); if (userId.equals(next.getUserId())) { next.setPrepared(prepared); break; } } } public boolean empty() { return null == gameUserMOList ? Boolean.TRUE : CollectionUtils.isEmpty(gameUserMOList); } public boolean shouldNotStartGame() { return gameManager.shouldNotStartGame(this.gameUserMOList); } public void startGame() { this.gameManager.startGame(this.gameUserMOList); } public String chooseOneUserToRobLandlord() { return this.gameManager.chooseOneUserToRobLandlord(this.gameUserMOList); } public void doRob(String userId) { this.gameManager.doRob(userId); } public void doNotRob(String userId) { this.gameManager.doNotRob(userId); } public List getLandlordCardList() { return this.gameManager.getLandlordCardList(); } public void giveLandlordCardToThisGuy(String userId) { this.gameManager.giveLandlordCardToThisGuy(userId, this.gameUserMOList); } public boolean hasNextOneToStartRob() { return this.gameManager.hasNextOneToStartRob(); } public String makeNextUserToStartRob() { return this.gameManager.makeNextUserToStartRob(this.gameUserMOList); } public String makeLastUserRobLandlordCard() { return this.gameManager.makeLastUserRobLandlordCard(this.gameUserMOList); } public void doPlayCard(String userId, List cardEnumerationList, PlayCardTypeEnumeration playCardTypeEnumeration) { this.gameManager.doPlayCard(userId, cardEnumerationList, playCardTypeEnumeration, this.gameUserMOList); } public boolean thisGuyWin(String userId) { return this.gameManager.thisGuyWin(userId, this.gameUserMOList); } public String makeNextUserToStartPlayCard() { return this.gameManager.makeNextUserToStartPlayCard(this.gameUserMOList); } public void doNotPlayCard(String userId) { this.gameManager.doNotPlayCard(userId); } public boolean hasNextOneToStartPlayCard() { return this.gameManager.hasNextOneToStartPlayCard(); } public String makeLastPlayCardUserToStartPlayCard() { return this.gameManager.makeLastPlayCardUserToStartPlayCard(); } } 游戏控制器与回合的设计

回合实体类和gameManager配合完成,回合开始,回合结束,下一个该谁打牌

package com.nero.hua.game.manager; import com.nero.hua.enumeration.CardEnumeration; import com.nero.hua.enumeration.PlayCardEnumeration; import com.nero.hua.enumeration.PlayCardTypeEnumeration; import com.nero.hua.enumeration.RobLandlordEnumeration; import com.nero.hua.exception.PlayCardException; import com.nero.hua.exception.RobLandlordException; import com.nero.hua.model.user.*; import com.nero.hua.util.CardUtil; import lombok.Getter; import lombok.Setter; import org.springframework.util.CollectionUtils; import java.util.LinkedList; import java.util.List; import java.util.Map; @Getter @Setter public class GameManager { private static final int COLOR_CARD_COUNT = 52; private static final int NORMAL_USER_CARD_COUNT = 17; private static final int LANDLORD_CARD_COUNT = 3; private static final int MAX_USER_COUNT = 3; private List landlordCardList; private RobLandlordRoundMO robLandlordRoundMO; private PlayCardRoundMO playCardRoundMO; public int getMaxUserCount() { return MAX_USER_COUNT; } public int getNormalUserCardCount() { return NORMAL_USER_CARD_COUNT; } public int getLandlordCardCount() { return LANDLORD_CARD_COUNT; } public boolean shouldStartGame(List gameUserMOList) { if (gameUserMOList.size() if (!gameUserMO.isPrepared()) { return Boolean.FALSE; } } return Boolean.TRUE; } public boolean shouldNotStartGame(List gameUserMOList) { return !this.shouldStartGame(gameUserMOList); } public void startGame(List gameUserMOList) { List shuffledCardList = this.shuffleCard(); List dealCardList = this.dealCard(shuffledCardList); for (int i = 0; i List aDeckCardList = getADeckCardList(); List aShuffledCardList = new LinkedList(); while (!aDeckCardList.isEmpty()) { int random = (int) (Math.random() * aDeckCardList.size()); CardEnumeration randomCard = aDeckCardList.remove(random); aShuffledCardList.add(randomCard); } return aShuffledCardList; } private List getADeckCardList() { List cardEnumerationList = new LinkedList(); CardEnumeration[] cardEnumerationArray = CardEnumeration.values(); for (int i = 0; i List dealCardList = new LinkedList(); for (int i = 0; i userCardList.add(shuffledCardList.remove(0)); } dealCardList.add(userCardList); } dealCardList.add(shuffledCardList); return dealCardList; } public String chooseOneUserToRobLandlord(List gameUserMOList) { int random = (int) (Math.random() * MAX_USER_COUNT); String userId = gameUserMOList.get(random).getUserId(); this.robLandlordRoundMO = new RobLandlordRoundMO(random, userId); return userId; } public void doRob(String userId) { UserRobLandlordTurnMO userRobLandlordTurnMO = this.thisGuyTurnForRobRound(userId); userRobLandlordTurnMO.setDoRob(Boolean.TRUE); } public void doNotRob(String userId) { UserRobLandlordTurnMO userRobLandlordTurnMO = this.thisGuyTurnForRobRound(userId); userRobLandlordTurnMO.setDoRob(Boolean.FALSE); } private UserRobLandlordTurnMO thisGuyTurnForRobRound(String userId) { if (null == this.robLandlordRoundMO) { throw new RobLandlordException(RobLandlordEnumeration.NOT_TIME_TO_ROB); } List userRobLandlordTurnMOList = this.robLandlordRoundMO.getUserRobLandlordTurnMOList(); UserRobLandlordTurnMO userRobLandlordTurnMO = userRobLandlordTurnMOList.get(userRobLandlordTurnMOList.size() - 1); if (!userId.equals(userRobLandlordTurnMO.getUserId())) { throw new RobLandlordException(RobLandlordEnumeration.NOT_YOUR_TURN); } return userRobLandlordTurnMO; } private int getUserIndexInUserListByUserId(String userId, List gameUserMOList) { for (int i = 0; i return i; } } return 0; } private GameUserMO getUserInUserListByUserId(String userId, List gameUserMOList) { for (int i = 0; i return gameUserMOList.get(i); } } return null; } public void giveLandlordCardToThisGuy(String userId, List gameUserMOList) { int userIndex = this.getUserIndexInUserListByUserId(userId, gameUserMOList); GameUserMO gameUserMO = gameUserMOList.get(userIndex); Map cardMap = gameUserMO.getCardMap(); for (CardEnumeration cardEnumeration : this.landlordCardList) { if (cardMap.containsKey(cardEnumeration)) { Integer count = cardMap.get(cardEnumeration); cardMap.put(cardEnumeration, count + 1); } else { cardMap.put(cardEnumeration, 1); } } this.playCardRoundMO = new PlayCardRoundMO(); this.playCardRoundMO.addNewUserToStartPlayCard(userIndex, userId); } public boolean hasNextOneToStartRob() { if (null == this.robLandlordRoundMO) { throw new RobLandlordException(RobLandlordEnumeration.NOT_TIME_TO_ROB); } return this.robLandlordRoundMO.getUserRobLandlordTurnMOList().size() int index = robLandlordRoundMO.getCurrentTurnUserIndex(); int nextIndex = (index + 1) % this.getMaxUserCount(); String nextUserId = gameUserMOList.get(nextIndex).getUserId(); this.robLandlordRoundMO.addNewUserToDoRob(nextIndex, nextUserId); return nextUserId; } public void doPlayCard(String userId, List cardEnumerationList, PlayCardTypeEnumeration playCardTypeEnumeration, List gameUserMOList) { if (CardUtil.playCardNotMatchPlayCardType(cardEnumerationList, playCardTypeEnumeration)) { throw new PlayCardException(PlayCardEnumeration.PLAY_CARD_DO_NOT_MATCH_ITS_TYPE); } UserPlayCardTurnMO userPlayCardTurnMO = this.thisGuyTurnForPlayCardRound(userId); GameUserMO gameUserMO = gameUserMOList.get(userPlayCardTurnMO.getUserIndex()); Map cardEnumerationMap = CardUtil.convertCardListToCardMap(cardEnumerationList); if (CardUtil.handCardMapNotContainsPlayCardMap(gameUserMO.getCardMap(), cardEnumerationMap)) { throw new PlayCardException(PlayCardEnumeration.HAND_CARD_DO_NOT_CONTAINS_PLAY_CARD); } UserPlayCardTurnMO lastUserPlayCardTurnMO = this.playCardRoundMO.getLastUserPlayCardTurnMO(); if (CardUtil.currentPlayCardListNotBetterThanLastPlayCardList(lastUserPlayCardTurnMO, cardEnumerationList, playCardTypeEnumeration)) { throw new PlayCardException(PlayCardEnumeration.PLAY_CARD_DO_NOT_BETTER_THAN_LAST_PLAY_CARD); } this.removeUserCardList(gameUserMO, cardEnumerationList); userPlayCardTurnMO.setCardList(cardEnumerationList); userPlayCardTurnMO.setPlayCardTypeEnumeration(playCardTypeEnumeration); } private UserPlayCardTurnMO thisGuyTurnForPlayCardRound(String userId) { if (null == this.playCardRoundMO) { throw new PlayCardException(PlayCardEnumeration.NOT_TIME_TO_PLAY_CARD); } List userPlayCardTurnMOList = this.playCardRoundMO.getUserPlayCardTurnMOList(); UserPlayCardTurnMO userPlayCardTurnMO = userPlayCardTurnMOList.get(userPlayCardTurnMOList.size() - 1); if (!userId.equals(userPlayCardTurnMO.getUserId())) { throw new PlayCardException(PlayCardEnumeration.NOT_YOUR_TURN); } return userPlayCardTurnMO; } private void removeUserCardList(GameUserMO gameUserMO, List cardEnumerationList) { Map cardMap = gameUserMO.getCardMap(); for (CardEnumeration cardEnumeration : cardEnumerationList) { Integer cardCount = cardMap.get(cardEnumeration); if (1 == cardCount) { cardMap.remove(cardEnumeration); } else { cardMap.put(cardEnumeration, cardCount - 1); } } } public boolean thisGuyWin(String userId, List gameUserMOList) { GameUserMO gameUserMO = this.getUserInUserListByUserId(userId, gameUserMOList); return CollectionUtils.isEmpty(gameUserMO.getCardMap()); } public String makeNextUserToStartPlayCard(List gameUserMOList) { int index = playCardRoundMO.getCurrentTurnUserIndex(); int nextIndex = (index + 1) % this.getMaxUserCount(); String nextUserId = gameUserMOList.get(nextIndex).getUserId(); this.playCardRoundMO.addNewUserToStartPlayCard(nextIndex, nextUserId); return nextUserId; } public void doNotPlayCard(String userId) { this.thisGuyTurnForPlayCardRound(userId); UserPlayCardTurnMO lastUserPlayCardTurnMO = this.playCardRoundMO.getLastUserPlayCardTurnMO(); if (null == lastUserPlayCardTurnMO) { throw new PlayCardException(PlayCardEnumeration.MUST_PLAY_CARD_WHEN_ROUND_START); } } public boolean hasNextOneToStartPlayCard() { return !this.playCardRoundMO.thisRoundFinish(this.getMaxUserCount()); } public String makeLastPlayCardUserToStartPlayCard() { List userPlayCardTurnMOList = playCardRoundMO.getUserPlayCardTurnMOList(); UserPlayCardTurnMO lastUserPlayCardTurnMO = userPlayCardTurnMOList.get(userPlayCardTurnMOList.size() - 1 - (MAX_USER_COUNT - 1)); this.playCardRoundMO = new PlayCardRoundMO(); this.playCardRoundMO.addNewUserToStartPlayCard(lastUserPlayCardTurnMO.getUserIndex(), lastUserPlayCardTurnMO.getUserId()); return lastUserPlayCardTurnMO.getUserId(); } } package com.nero.hua.model.user; import lombok.Getter; import lombok.Setter; import org.springframework.util.CollectionUtils; import java.util.LinkedList; import java.util.List; @Getter @Setter public class PlayCardRoundMO { private int currentTurnUserIndex; List userPlayCardTurnMOList = new LinkedList(); public void addNewUserToStartPlayCard(int userIndex, String userId) { this.currentTurnUserIndex = userIndex; userPlayCardTurnMOList.add(new UserPlayCardTurnMO(userIndex, userId)); } public boolean thisRoundFinish(int maxUserCount) { if (this.userPlayCardTurnMOList.size() if (this.userPlayCardTurnMOList.get(this.userPlayCardTurnMOList.size() - 1 - i).userDoPlayCard()) { return Boolean.FALSE; } } return Boolean.TRUE; } public UserPlayCardTurnMO getLastUserPlayCardTurnMO() { if (CollectionUtils.isEmpty(userPlayCardTurnMOList)) { return null; } for (int i = this.userPlayCardTurnMOList.size() - 1; i >= 0; i--) { if (!CollectionUtils.isEmpty(this.userPlayCardTurnMOList.get(i).getCardList())) { return this.userPlayCardTurnMOList.get(i); } } return null; } } 前端0号座椅总是为自己的设计

跟后端的回合流转类似,只不过多了位置。 前端房间的userList跟后端的userList保持一直,通过一个计算座椅位置来达到目的

import Card from "../../../enumeration/CardEnumeration"; import PlayCardType from "../../../enumeration/PlayCardTypeEnumeration"; export default class RoundMO { private currentTurnUserId : string ; private palyCardList : Array = new Array(); private palyCardTypeList : Array = new Array(); constructor(currentTurnUserId : string) { this.currentTurnUserId = currentTurnUserId; } public getCurrentTurnUserId() : string { return this.currentTurnUserId; } public setCurrentTurnUserId(currentTurnUserId : string) : void { this.currentTurnUserId = currentTurnUserId; } public doPlayCard(cardList : Array, playCardType : PlayCardType) : void { this.palyCardList.push(cardList); this.palyCardTypeList.push(playCardType); } public doNotPlayCard() : void { this.palyCardList.push(null); this.palyCardTypeList.push(null); } public thisRoundFinish(maxUserCount : number) : boolean { if (this.palyCardList.length if (null !== this.palyCardList[j]) { return false; } } return true; } public getLastPlayCard() : Array { if (null == this.palyCardList) { return null; } for (let i = this.palyCardList.length; i >= 0; i--) { if (null != this.palyCardList[i]) { return this.palyCardList[i]; } } return null; } public getLastPlayCardType() : PlayCardType { if (null == this.palyCardTypeList) { return null; } for (let i = this.palyCardTypeList.length; i >= 0; i--) { if (null != this.palyCardTypeList[i]) { return this.palyCardTypeList[i]; } } return null; } } private calculateSeatIndexByMeIndex(userIndex : number, meIndex : number) : number { return (userIndex - meIndex + 3) % 3; } 效果图

在这里插入图片描述 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有