赞
踩
不枉我深入学习基础知识,算法与数据结构,编译原理,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
为了便于,排序,比较,等操作,设计如下:
这里的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; } }
为了便于,排序,比较,等操作,设计如下:
权值大的牌型,比权值小的牌型大。
权值相同的牌型,需要牌型一样(牌型为同一个枚举)方可比较
这里的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; } }
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<CardEnumeration> playCardList, PlayCardTypeEnumeration playCardTypeEnumeration) { if (null == lastUserPlayCardTurnMO) { return Boolean.TRUE; } PlayCardTypeEnumeration lastPlayCardTypeEnumeration = lastUserPlayCardTurnMO.getPlayCardTypeEnumeration(); if (playCardTypeEnumeration.getValue() < lastPlayCardTypeEnumeration.getValue()) { return Boolean.FALSE; } else if (playCardTypeEnumeration.getValue() > lastPlayCardTypeEnumeration.getValue()) { return Boolean.TRUE; } if (lastPlayCardTypeEnumeration != playCardTypeEnumeration) { return Boolean.FALSE; } List<CardEnumeration> lastPlayCardList = lastUserPlayCardTurnMO.getCardList(); return lastPlayCardList.size() == playCardList.size() && lastPlayCardList.get(0).getValue() < playCardList.get(0).getValue(); }
public static int formatCardList(List<CardEnumeration> playCardList) { Map<Integer, Integer> playCardValueCountMap = getPlayCardValueCountMap(playCardList); quickSortOneCardList(0, playCardList.size() - 1, playCardList); Map<Integer, List<CardEnumeration>> playCardCountListMap = getPlayCardCountListMap(playCardList, playCardValueCountMap); List<Integer> countList = getSortedPlayCardCountList(playCardCountListMap); for (int i = 0, k = 0; i < countList.size(); i++) { List<CardEnumeration> cardEnumerationList = playCardCountListMap.get(countList.get(i)); for (int j = 0; j < cardEnumerationList.size(); j++) { playCardList.set(k, cardEnumerationList.get(j)); k++; } } return countList.get(0); }
计算单牌权值及其数量Map
private static Map<Integer, Integer> getPlayCardValueCountMap(List<CardEnumeration> playCardList) {
Map<Integer, Integer> playCardValueCountMap = new HashMap<>();
for (int i = 0; i < playCardList.size(); i++) {
Integer count = playCardValueCountMap.get(playCardList.get(i).getValue());
if (null == count) {
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<CardEnumeration> cardList) { if (start >= end) { return; } CardEnumeration keyCard = cardList.get(start); int i = start; int j = end; while (i != j) { if (cardList.get(i).getValue() < keyCard.getValue()) { CardEnumeration temp = cardList.get(j); cardList.set(j, cardList.get(i)); cardList.set(i, temp); j--; } else { i++; } } int middle = cardList.get(i).getValue() >= keyCard.getValue() ? i : i - 1; if (middle >= start && middle <= end) { CardEnumeration temp = cardList.get(middle); cardList.set(middle, cardList.get(start)); cardList.set(start, temp); } quickSortOneCardList(start, middle - 1, cardList); quickSortOneCardList(middle + 1, end, cardList); }
把已经排序好的牌,按照相同单牌权值的数量,平滑分割成多个小数组
private static Map<Integer, List<CardEnumeration>> getPlayCardCountListMap(List<CardEnumeration> sortedPlayCardList, Map<Integer, Integer> playCardValueCountMap) {
Map<Integer, List<CardEnumeration>> playCardCountListMap = new HashMap<>();
for (Integer i : playCardValueCountMap.keySet()) {
playCardCountListMap.put(playCardValueCountMap.get(i), new LinkedList<>());
}
for (int i = 0; i < sortedPlayCardList.size(); i++) {
CardEnumeration cardEnumeration = sortedPlayCardList.get(i);
Integer count = playCardValueCountMap.get(cardEnumeration.getValue());
List<CardEnumeration> cardEnumerationList = playCardCountListMap.get(count);
cardEnumerationList.add(cardEnumeration);
}
return playCardCountListMap;
}
把相同单牌权值的数量进行排序(由大到小)
private static List<Integer> getSortedPlayCardCountList(Map<Integer, List<CardEnumeration>> playCardCountListMap) {
List<Integer> countList = new ArrayList<>();
for (Integer i : playCardCountListMap.keySet()) {
countList.add(i);
}
selectionSort(countList);
return countList;
}
public static void selectionSort(List<Integer> countList) { if (1 == countList.size()) { return; } for (int i = 0; i < countList.size() - 1; i++) { Integer current = countList.get(i); for (int j = i + 1; j < countList.size(); j++) { 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 < countList.size(); i++) {
List<CardEnumeration> cardEnumerationList = playCardCountListMap.get(countList.get(i));
for (int j = 0; j < cardEnumerationList.size(); j++) {
playCardList.set(k, cardEnumerationList.get(j));
k++;
}
}
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<CardEnumeration> cardEnumerationList) { if (cardEnumerationList.size() < MIN_COUNT) { return Boolean.FALSE; } if (0 != cardEnumerationList.size() % GROUP_COUNT) { return Boolean.FALSE; } for (int i = 0; i < cardEnumerationList.size() / GROUP_COUNT; i += 3) { if (cardEnumerationList.get(i).getValue() != cardEnumerationList.get(i + 1).getValue() || cardEnumerationList.get(i + 1).getValue() != cardEnumerationList.get(i + 2).getValue()) { return Boolean.FALSE; } } for (int i = 0; i < cardEnumerationList.size() / GROUP_COUNT; i += 3) { if (cardEnumerationList.get(i).getValue() - 1 != cardEnumerationList.get(i + 3).getValue()) { 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 < cardEnumerationList.size(); i += 2) { if (cardEnumerationList.get(i).getValue() != cardEnumerationList.get(i + 1).getValue()) { 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<GameUserMO> 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<GameUserMO> iterator = gameUserMOList.iterator(); while (iterator.hasNext()) { GameUserMO next = iterator.next(); if (userId.equals(next.getUserId())) { iterator.remove(); break; } } } public List<String> getAllUserList() { List<String> userIdList = new LinkedList<>(); for (GameUserMO gameUserMO : this.getGameUserMOList()) { userIdList.add(gameUserMO.getUserId()); } return userIdList; } public List<String> getAllOtherUserList(String userId) { List<String> 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<GameUserMO> 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<CardEnumeration> 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<CardEnumeration> 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<CardEnumeration> 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<GameUserMO> gameUserMOList) { if (gameUserMOList.size() < MAX_USER_COUNT) { return Boolean.FALSE; } for (GameUserMO gameUserMO : gameUserMOList) { if (!gameUserMO.isPrepared()) { return Boolean.FALSE; } } return Boolean.TRUE; } public boolean shouldNotStartGame(List<GameUserMO> gameUserMOList) { return !this.shouldStartGame(gameUserMOList); } public void startGame(List<GameUserMO> gameUserMOList) { List<CardEnumeration> shuffledCardList = this.shuffleCard(); List<List<CardEnumeration>> dealCardList = this.dealCard(shuffledCardList); for (int i = 0; i < gameUserMOList.size(); i++) { Map<CardEnumeration, Integer> cardMap = CardUtil.convertCardListToCardMap(dealCardList.remove(0)); gameUserMOList.get(i).setCardMap(cardMap); } this.landlordCardList = dealCardList.get(dealCardList.size() - 1); } private List<CardEnumeration> shuffleCard() { List<CardEnumeration> aDeckCardList = getADeckCardList(); List<CardEnumeration> 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<CardEnumeration> getADeckCardList() { List<CardEnumeration> cardEnumerationList = new LinkedList<>(); CardEnumeration[] cardEnumerationArray = CardEnumeration.values(); for (int i = 0; i < COLOR_CARD_COUNT; i++) { cardEnumerationList.add(cardEnumerationArray[i]); } cardEnumerationList.add(CardEnumeration.CARD_516); cardEnumerationList.add(CardEnumeration.CARD_517); return cardEnumerationList; } private List<List<CardEnumeration>> dealCard(List<CardEnumeration> shuffledCardList) { List<List<CardEnumeration>> dealCardList = new LinkedList<>(); for (int i = 0; i < MAX_USER_COUNT; i++) { List<CardEnumeration> userCardList = new LinkedList<>(); for (int j = 0; j < NORMAL_USER_CARD_COUNT; j++) { userCardList.add(shuffledCardList.remove(0)); } dealCardList.add(userCardList); } dealCardList.add(shuffledCardList); return dealCardList; } public String chooseOneUserToRobLandlord(List<GameUserMO> 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<UserRobLandlordTurnMO> 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<GameUserMO> gameUserMOList) { for (int i = 0; i < gameUserMOList.size(); i++) { if (userId.equals(gameUserMOList.get(i).getUserId())) { return i; } } return 0; } private GameUserMO getUserInUserListByUserId(String userId, List<GameUserMO> gameUserMOList) { for (int i = 0; i < gameUserMOList.size(); i++) { if (userId.equals(gameUserMOList.get(i).getUserId())) { return gameUserMOList.get(i); } } return null; } public void giveLandlordCardToThisGuy(String userId, List<GameUserMO> gameUserMOList) { int userIndex = this.getUserIndexInUserListByUserId(userId, gameUserMOList); GameUserMO gameUserMO = gameUserMOList.get(userIndex); Map<CardEnumeration, Integer> 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() < MAX_USER_COUNT - 1; } public String makeNextUserToStartRob(List<GameUserMO> gameUserMOList) { int index = robLandlordRoundMO.getCurrentTurnUserIndex(); int nextIndex = (index + 1) % this.getMaxUserCount(); String nextUserId = gameUserMOList.get(nextIndex).getUserId(); this.robLandlordRoundMO.addNewUserToStartRob(nextIndex, nextUserId); return nextUserId; } public String makeLastUserRobLandlordCard(List<GameUserMO> gameUserMOList) { 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<CardEnumeration> cardEnumerationList, PlayCardTypeEnumeration playCardTypeEnumeration, List<GameUserMO> 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<CardEnumeration, Integer> 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<UserPlayCardTurnMO> 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<CardEnumeration> cardEnumerationList) { Map<CardEnumeration, Integer> 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<GameUserMO> gameUserMOList) { GameUserMO gameUserMO = this.getUserInUserListByUserId(userId, gameUserMOList); return CollectionUtils.isEmpty(gameUserMO.getCardMap()); } public String makeNextUserToStartPlayCard(List<GameUserMO> 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<UserPlayCardTurnMO> 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<UserPlayCardTurnMO> 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() < maxUserCount) { return Boolean.FALSE; } for (int i = 0; i < maxUserCount - 1; i++) { 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; } }
跟后端的回合流转类似,只不过多了位置。
前端房间的userList跟后端的userList保持一直,通过一个计算座椅位置来达到目的
import Card from "../../../enumeration/CardEnumeration"; import PlayCardType from "../../../enumeration/PlayCardTypeEnumeration"; export default class RoundMO { private currentTurnUserId : string ; private palyCardList : Array<Array<Card>> = new Array(); private palyCardTypeList : Array<PlayCardType> = 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<Card>, 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 < maxUserCount) { return false; } for (let i : number = 0, j : number = this.palyCardList.length - 1; i < maxUserCount - 1; i++, j--) { if (null !== this.palyCardList[j]) { return false; } } return true; } public getLastPlayCard() : Array<Card> { 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 © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。