哈哈 今天再补充一个之前撒懒的笔记java
游戏中的擂台赛,游戏玩家开始报名,进行海选赛,再进行32强赛、16强,8强,4强,半决赛,决赛算法
海选赛中失败一次既被淘汰,最终决出32强(海选赛报名人数不足32人则直接晋级32强)spring
海选赛中报名的人数:n,分红32组,apache
每组人数:m = n/32;dom
未分配组的人数:x = n%32;ide
1组,2组,3组,。。。。。32组的人员分配以下fetch
for(int i=0; i<32; i++){ group[i] = m + ((x-->0)? 1 : 0); }
如:总报名人数 n=134; 每组人数:m=n/32=4; 未分配人数:x=n%32=6ui
group[0]第1组 | group[1]第2组 | group[2]第3组 | group[3]第4组 | group[4]第5组 | group[5]第6组 | group[6]第7组 | group[7]第8组 | group[.....]第i组 | group[31]第32组 |
4+1=5 | 4+1=5 | 4+1=5 | 4+1=5 | 4+1=5 | 4+1=5 | 4 | 4 | 4 | 4 |
呵呵 也就是把剩下没分完组的人加入到每组中,从第一组开始this
海选赛以两两随机配对战斗,败者淘汰, 海选赛中每组决出一名,海选赛结束后就决出了32强(固然能够保留种子选手直接进入32强,相应的规则本身制定 哈哈)google
淘汰赛既32强开始机制简单设为PK失败被淘汰,PK胜利就晋级(其实能够采用世界杯的那种形式 哈哈)
贴上代码
package models.competition; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import models.i18n.I18N; import models.i18n.I18NUtils; import models.user.GameUser; import play.i18n.Lang; import play.modules.morphia.Model; import play.modules.morphia.Model.AutoTimestamp; import com.google.code.morphia.annotations.Entity; import com.google.code.morphia.annotations.Transient; import exception.Constants; @Entity @AutoTimestamp @I18N(fields={"urankDesc","pkRankDesc"}) public class PkInfo extends Model{ public static final int PK_TYPE_SELECT = 1; public static final int PK_TYPE_PKOUT = 2; public static final int SELECT_PK_STATUS_CONTINUE = 0;//海选晋级下一轮 public static final int SELECT_PK_STATUS_OUT = 1;//海选被淘汰 public static final int SELECT_PK_STATUS_GOUP = 2;//成功闯入32强 /** * 第几届擂台赛 */ public long code; /** * 级别类型 */ public int levelType; /** * 第几轮 */ public int round; /** * 擂台赛阶段【1;海选赛,2:淘汰赛】 */ public int pkType; public int groupIndex; public String uid; public String pkUid; @Transient public String uname; @Transient public String pkName; /** * 进入几强 */ public int urank; public String urankDesc; public int pkRank; public String pkRankDesc; /** * 海选用户晋级状态【0:晋级下一轮,1:被淘汰;2:出入32强】 */ @Transient public int uselectPkStatus; /** * 海选对手的晋级状态【0:晋级下一轮,1:被淘汰;2:出入32强】 */ @Transient public int pkSelectPkStatus; /** * 战斗结果【true:user胜利,false:pkuser胜利】 */ public boolean result; public PkInfo(long code, int levelType, int groupIndex, int round, int pkType, String uid, String pkUid) { super(); this.code = code; this.levelType = levelType; this.groupIndex = groupIndex; this.round = round; this.pkType = pkType; this.uid = uid; this.pkUid = pkUid; } public static final int[] ranks={32,16,8,3,2,1}; public static final String rankContinueDesc=Constants.COMPETITION_RANK_CONTINUE_DESC_1; public static final String[] rankSuccDescs={ Constants.COMPETITION_RANK_SUCC_DESC_1, Constants.COMPETITION_RANK_SUCC_DESC_2, Constants.COMPETITION_RANK_SUCC_DESC_3, Constants.COMPETITION_RANK_SUCC_DESC_4, Constants.COMPETITION_RANK_SUCC_DESC_5, Constants.COMPETITION_RANK_SUCC_DESC_6, }; public static final String[] rankFailDescs={ Constants.COMPETITION_RANK_FAIL_DESC_1, Constants.COMPETITION_RANK_FAIL_DESC_2, Constants.COMPETITION_RANK_FAIL_DESC_3, Constants.COMPETITION_RANK_FAIL_DESC_4, Constants.COMPETITION_RANK_FAIL_DESC_5, Constants.COMPETITION_RANK_FAIL_DESC_6, }; public void loadUserInfo(){ GameUser gu = null; GameUser pkgu = null; if(this.uid != null){ gu = GameUser.getSimpleInfo(this.uid, new String[]{"name"}); } if(this.pkUid != null){ pkgu = GameUser.getSimpleInfo(this.pkUid, new String[]{"name"}); } if(gu != null){ this.uname = gu.name; } if( pkgu != null){ this.pkName = pkgu.name; }else{ this.pkName = "-"; } } /** * 海选 * user VS pker * @param result */ public void setSelectPkResult(boolean result, int uselectPkStatus,int pkSelectPkStatus){ this.result = result; //海选阶段 if(this.pkType == PK_TYPE_SELECT){ //晋级32强 if(uselectPkStatus == SELECT_PK_STATUS_GOUP){ this.urank = ranks[0]; this.urankDesc = rankSuccDescs[0]; //海选被淘汰 }else if( uselectPkStatus == SELECT_PK_STATUS_OUT){ this.urankDesc = rankFailDescs[0]; //海选晋级下一轮 }else if( uselectPkStatus == SELECT_PK_STATUS_CONTINUE){ this.urankDesc = rankContinueDesc; } //晋级32强 if(pkSelectPkStatus == SELECT_PK_STATUS_GOUP){ this.pkRank = ranks[0]; this.pkRankDesc = rankSuccDescs[0]; //海选被淘汰 }else if( pkSelectPkStatus == SELECT_PK_STATUS_OUT){ this.pkRankDesc = rankFailDescs[0]; //海选晋级下一轮 }else if( pkSelectPkStatus == SELECT_PK_STATUS_CONTINUE){ this.pkRankDesc = rankContinueDesc; } } } /** * user VS pker * @param result */ public void setPkOutResult(boolean result){ this.result = result; //淘汰赛第一轮,晋级16强 if(this.round == 1){ if(result){ //user胜利 成功晋级16强 this.urank = ranks[1]; this.urankDesc = rankSuccDescs[1]; //pker失败 晋级16强被淘汰 this.pkRank = ranks[0]; this.pkRankDesc = rankFailDescs[1]; }else{ //user胜利 成功晋级16强 this.urank = ranks[0]; this.urankDesc = rankFailDescs[1]; //pker失败 晋级16强被淘汰 this.pkRank = ranks[1]; this.pkRankDesc = rankSuccDescs[1]; } //淘汰赛第二轮 晋级8强 }else if(this.round == 2){ if(result){ //user胜利 成功晋级8强 this.urank = ranks[2]; this.urankDesc = rankSuccDescs[2]; //pker失败 晋级8强被淘汰 this.pkRank = ranks[1]; this.pkRankDesc = rankFailDescs[2]; }else{ //user胜利 成功晋级8强 this.urank = ranks[1]; this.urankDesc = rankFailDescs[2]; //pker失败 晋级8强被淘汰 this.pkRank = ranks[2]; this.pkRankDesc = rankSuccDescs[2]; } //淘汰赛第三轮 晋级半决赛 }else if(this.round == 3){ if(result){ //user胜利 成功晋级半决赛 this.urank = ranks[3]; this.urankDesc = rankSuccDescs[3]; //pker失败 晋级半决赛被淘汰 this.pkRank = ranks[2]; this.pkRankDesc = rankFailDescs[3]; }else{ //user胜利 成功晋级半决赛 this.urank = ranks[2]; this.urankDesc = rankFailDescs[3]; //pker失败 晋级半决赛被淘汰 this.pkRank = ranks[3]; this.pkRankDesc = rankSuccDescs[3]; } //淘汰赛第四轮 半决赛 }else if(this.round == 4){ if(result){ //user胜利 成功晋级决赛 this.urank = ranks[4]; this.urankDesc = rankSuccDescs[4]; //pker失败 半决赛被淘汰,得到擂台赛季军 this.pkRank = ranks[3]; this.pkRankDesc = rankFailDescs[4]; }else{ //user胜利 成功晋级半决赛 this.urank = ranks[3]; this.urankDesc = rankFailDescs[4]; //pker失败 晋级半决赛被淘汰 this.pkRank = ranks[4]; this.pkRankDesc = rankSuccDescs[4]; } //淘汰赛第五轮 决赛 }else if(this.round == 5){ if(result){ //user胜利 成功晋级决赛 this.urank = ranks[5]; this.urankDesc = rankSuccDescs[5]; //pker失败 半决赛被淘汰,得到擂台赛季军 this.pkRank = ranks[4]; this.pkRankDesc = rankFailDescs[5]; }else{ //user胜利 成功晋级半决赛 this.urank = ranks[4]; this.urankDesc = rankFailDescs[5]; //pker失败 晋级半决赛被淘汰 this.pkRank = ranks[5]; this.pkRankDesc = rankSuccDescs[5]; } } } public static List<PkInfo> getTempList(String uid,List<PkInfo> list){ Comparator<PkInfo> sort = new Comparator<PkInfo>() { @Override public int compare(PkInfo o1, PkInfo o2) { long t1 = o1._getCreated(); long t2 = o2._getCreated(); return (int)(t2-t1); } }; Collections.sort(list,sort); List<PkInfo> templist = new ArrayList<PkInfo>(); PkInfo temp = null; for(PkInfo pkinfo : list){ pkinfo.loadUserInfo(); //若是本身在Pk阵列中则须要转换 if(uid.equals(pkinfo.pkUid)){ temp = new PkInfo(pkinfo.code, pkinfo.levelType, pkinfo.groupIndex, pkinfo.round, pkinfo.pkType, uid, pkinfo.uid); temp.loadUserInfo(); temp.groupIndex = pkinfo.groupIndex; temp.urank = pkinfo.pkRank; temp.urankDesc = pkinfo.pkRankDesc; temp.pkName = pkinfo.uname; temp.pkRankDesc = pkinfo.urankDesc; temp.result = !pkinfo.result; templist.add(temp); }else{ templist.add(pkinfo); } } I18NUtils.setI18NFields(templist, Lang.get()); return templist; } }
package models.competition; import java.util.ArrayList; import java.util.List; import models.user.FightAttribute; import models.user.GameUser; import models.wow.UserWarcraft; import play.modules.morphia.Model; import service.util.RandomUtil; import com.google.code.morphia.annotations.Entity; import com.google.code.morphia.annotations.Transient; import exception.MonsterException; @Entity public class UserCompetition extends Model{ public static final int SIGN_STATUS_N = 0; public static final int SIGN_STATUS_Y = 1; public static final int RECEIVE_REWARD_STATUS_N = 0; public static final int RECEIVE_REWARD_STATUS_Y = 1; public static final int LEVEL_TYPE_NOMAL = 1; public static final int LEVEL_TYPE_HIGH = 2; public static final int LEVEL_SPLITER = 60; public static final int MAX_FAIL_TIMES = 3; /** * 第几届擂台赛 */ public long code; /** * GameUser Id */ public String uid; @Transient public String name; @Transient public int level; /** * 报名状态 */ public int signStatus; /** * 海选时的攻击力 */ public long attackPower; /** * 级别类型 */ public int levelType; /** * 海选失败的次数 */ public int failTimes; /** * 海选是否被淘汰 */ public boolean isSelectPkOut; /** * 淘汰赛是否被淘汰 */ public boolean isPkoutOut; /** * 淘汰赛排名【1,2,3(2个),8(4个),16(8个),32(16个)】(未进入淘汰赛的为0) */ public int rank; /** * 领取奖励状态【0:未领取;1:已领取】 */ public int receiveRewardStatus; /** * 战斗记录 */ @Transient public List<PkInfo> pkLogs; public UserCompetition(long code, String uid) { super(); this.code = code; this.uid = uid; this.signStatus = SIGN_STATUS_N; this.receiveRewardStatus = RECEIVE_REWARD_STATUS_N; } /** * 报名 */ public void sign(int levelType){ this.signStatus = SIGN_STATUS_Y; this.rank = 0; this.failTimes = MAX_FAIL_TIMES; this.levelType = levelType; } /** * 晋级 * @param pkInfo */ public void goUp(boolean isWin,int rank){ //海选失败 if(!isWin && rank == 0){ this.failTimes--; //更新排名(淘汰赛失败则记录上一局的排名) }else if(rank > 0){ this.rank = rank; } } /** * 计算攻击力 */ public void loadAttackPower(){ GameUser gu = GameUser.getSimpleInfo(this.uid, new String[]{"level", "camp", "dynamicProp"}); UserWarcraft userWarcraft = UserWarcraft.find("uid", this.uid).first(); long power = 0; if(gu != null){ //计算攻击力 power = getFightValue(gu); //添加魔兽攻击力 if(userWarcraft != null){ power += userWarcraft.getUserWeapon(); } } this.attackPower = power; } /** * 获取用户综合战斗能力值 * @param gameUser Game User * @return int */ private int getFightValue(GameUser gameUser) { FightAttribute fightAttribute = gameUser.dynamicProp; return fightAttribute.maxHp + 10 * ((fightAttribute.mainWeaponMax + fightAttribute.mainWeaponMin)/2); } /** * 海选赛的选拔过程 * @param pker * @return */ public boolean getSelectPkResult(UserCompetition pker){ boolean isWin = false; long selfFightValue = this.attackPower; long upDownFightValue = selfFightValue * 10 / 100; long otherFightValue = pker.attackPower; if (otherFightValue - selfFightValue > upDownFightValue){ //困难级别 isWin = false; }else if (selfFightValue - otherFightValue > upDownFightValue){ //简单级别 isWin = true; }else{ //普通级别取随机 int winValue = 50; int resRandom = RandomUtil.getRandomValue(1, 100); if(winValue>resRandom){ isWin = true; }else{ isWin = false; } } if(isWin){ pker.isSelectPkOut = true; }else{ this.isSelectPkOut = true; } return isWin; } public static int getLevelType(int level){ if(level<LEVEL_SPLITER){ return LEVEL_TYPE_NOMAL; }else{ return LEVEL_TYPE_HIGH; } } public void loadUserInfo(){ GameUser gu = GameUser.getSimpleInfo(this.uid, new String[]{"name","level"}); if(gu != null){ this.name = gu.name; this.level = gu.level; } } }
package service.impl; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; import exception.Constants; import exception.MonsterException; import models.AchievementResult; import models.competition.Competition; import models.competition.CompetitionReturn; import models.competition.CompetitionReward; import models.competition.PkInfo; import models.competition.UserCompetition; import models.fight.Battle; import models.fight.FightResult; import models.tdo.PageTDO; import models.user.FightableObj; import models.user.GameUser; import play.modules.morphia.Model.MorphiaQuery; import play.modules.spring.Spring; import service.CompetitionService; import service.GameUserService; import service.util.AchievementUtils; import service.util.RandomUtil; /** * @author ZhangYude * @date 2012-11-21 * @version 1.4 * @since 2012 * @desc: * 擂台赛接口实现 */ public class CompetitionServiceImpl implements CompetitionService{ /** * 获取用户擂台赛信息 * @param uid * @return */ @Override public CompetitionReturn getUserCompetitionInfo(String uid, int levelType) { GameUser gu = GameUser.getSimpleInfo(uid, new String[]{"level"}); CompetitionReturn cr = new CompetitionReturn(); Competition competition = Competition.find().order("-code").first(); if(competition == null){ // competition = createNextCompetitionInfo(); cr.statusStep = Competition.STATUS_IN_INIT; return cr; } int myLevelType = UserCompetition.getLevelType(gu.level); //传入参数的状况 if(levelType>0){ myLevelType = levelType; } // competition.updateStatus(); cr.code = competition.code; cr.statusStep = competition.status; cr.curLevel = gu.level; cr.curRankList = getUserCompetitionByLevelType(competition.code, myLevelType); cr.myPkInfoList = getPkInfoByLevelType(uid, competition.code, myLevelType,0); cr.signBeginTime = competition.signBeginTime; cr.signEndTime = competition.signEndTime; cr.selectBeginTime = competition.selectBeginTime; cr.pkoutBeginTime = competition.pkoutBeginTime; UserCompetition userCompetition = UserCompetition.find("uid,code,signStatus", uid,competition.code,UserCompetition.SIGN_STATUS_Y).first(); if(userCompetition == null){ cr.mySignStatus = UserCompetition.SIGN_STATUS_N; }else{ cr.mySignStatus = UserCompetition.SIGN_STATUS_Y; if(userCompetition.levelType == levelType || levelType == 0){ cr.curRank = userCompetition.rank; } } UserCompetition ucPerInfo = getUserCompetitionInfo(uid, competition.code-1); if(ucPerInfo != null && (ucPerInfo.levelType == levelType || levelType == 0)){ cr.perRank = ucPerInfo.rank; } return cr; } /** * 获取上届擂台赛战况结果信息 * @param levelType * @return */ @Override public CompetitionReturn getPerCompetitionInfo(int levelType) { CompetitionReturn cr = new CompetitionReturn(); Competition competition = Competition.find().order("-code").first(); if(competition != null && competition.code > 1){ cr.perRankList = getUserCompetitionByLevelType(competition.code-1,levelType); } return cr; } /** * 根据等级类型获取擂台赛战况结果 * @param code * @param levelType * @param isCurrent * @return */ private UserCompetition getUserCompetitionInfo(String uid, long code){ UserCompetition uc = null; MorphiaQuery q = UserCompetition.find("code", code); q.filter("uid", uid); q.and(q.criteria("rank").greaterThan(0)); uc = q.first(); // uc.loadUserInfo(); return uc; } /** * 根据等级类型获取擂台赛战况结果 * @param levelType * @return */ private List<UserCompetition> getUserCompetitionByLevelType(long code, int levelType){ Competition competition = Competition.find("code",code).first(); if(competition != null && competition.status != competition.STATUS_IN_CLOSED){ return null; } List<UserCompetition> list = new ArrayList<UserCompetition>(); MorphiaQuery q = UserCompetition.find("code", code); q.filter("levelType", levelType); q.and(q.criteria("rank").greaterThan(0)); list = q.asList(); for(UserCompetition uc : list){ uc.loadUserInfo(); } return list; } /** * 获取战况信息 * @param uid * @param code * @param levelType * @return */ private List<PkInfo> getPkInfoByLevelType(String uid, long code, int levelType, int pkType){ List<PkInfo> list = new ArrayList<PkInfo>(); MorphiaQuery q1 = PkInfo.find("code", code); MorphiaQuery q2 = PkInfo.find("code", code); if(uid != null){ q1.filter("uid", uid); q2.filter("pkUid", uid); } if(levelType>0){ q1.filter("levelType", levelType); q2.filter("levelType", levelType); } if(pkType>0){ q1.filter("pkType", pkType); q2.filter("pkType", pkType); } List<PkInfo> l1 = q1.asList(); List<PkInfo> l2 = q2.asList(); list.addAll(l1); list.addAll(l2); return PkInfo.getTempList(uid, list); // return list; } @Override public void beginSign() { Competition competition = Competition.find().order("-code").first(); if(competition != null){ competition.signBegin(); competition.save(); } } /** * 擂台赛报名 * @param uid * @param levelType * @return */ @Override public CompetitionReturn sign(String uid, int levelType) { GameUser gu = GameUser.getSimpleInfo(uid, new String[]{"level"}); CompetitionReturn cr = new CompetitionReturn(); if(gu != null){ Competition competition = Competition.find().order("-code").first(); UserCompetition userCompetition = UserCompetition.find("code,uid", competition.code,uid).first(); long now = new Date().getTime(); // if(UserCompetition.getLevelType(gu.level) != levelType){ // throw new MonsterException(Constants.COMPETITION_SIGN_ERROR_LEVELTYPE_NOT_FIT); // }else if(now < competition.signBeginTime || now > competition.signEndTime){ // throw new MonsterException(Constants.COMPETITION_SIGN_ERROR_SIGNTIME_NOT_FIT); // } if(userCompetition == null){ userCompetition = new UserCompetition(competition.code, uid); } userCompetition.sign(levelType); userCompetition.save(); cr.mySignStatus = userCompetition.signStatus; } return cr; } /** * 获取擂台赛奖励信息 * @return */ @Override public CompetitionReturn getCompetitionRewardInfo() { CompetitionReturn cr = new CompetitionReturn(); cr.nomalRewardList = CompetitionReward.getPrizePackageList(UserCompetition.LEVEL_TYPE_NOMAL); cr.highRewardList = CompetitionReward.getPrizePackageList(UserCompetition.LEVEL_TYPE_HIGH); return cr; } /** * 初始化下届擂台赛信息 */ @Override public Competition createNextCompetitionInfo() { Competition competition = new Competition(); competition.init(); competition.createNextCompetition(); competition.save(); return competition; } /** * 结束报名(计算参与者个战斗力) */ @Override public void endSign() { // TODO Auto-generated method stub Competition competition = Competition.find().order("-code").first(); if(competition != null){ competition.signEnd(); competition.save(); MorphiaQuery q = UserCompetition.createQuery(); q.filter("code", competition.code); q.filter("signStatus",UserCompetition.SIGN_STATUS_Y); long count = q.count(); int pageSize = 100; int pageCount=(int) (count%pageSize==0?(count/pageSize):(count/pageSize+1)); List<UserCompetition> list = null; for(int i=1;i<=pageCount;i++){ list=q.fetch(i, pageSize); for(UserCompetition uc:list){ uc.loadAttackPower(); uc.save(); } } } } /** * 开始海选 * a) 设定32个小组。 * b) 全部人随机分配到32个小组(总人数/32,余数平均分配)。 * c) 小组赛以淘汰赛制两两随机配对战斗,败者淘汰。 * d) 小组赛第一名出线参加淘汰赛。 */ @Override public boolean beginSelecting(int levelType) { Competition competition = Competition.find().order("-code").first(); if(competition != null){ competition.selectBegin(); competition.save(); MorphiaQuery q = UserCompetition.createQuery(); q.filter("code", competition.code); q.filter("levelType", levelType); q.and(q.criteria("failTimes").greaterThan(0)); q.filter("signStatus",UserCompetition.SIGN_STATUS_Y); long count = q.count(); //设置总共32页 int pageCount = 32; if(count<=pageCount){ return true; } //每页条数 int pageSize = (int) (count/pageCount); //32页以后的条数 int pageSubSize = (int) (count%pageCount); List<UserCompetition> list = null; List<UserCompetition> templist = null; List<UserCompetition> winlist = null; List<UserCompetition> sublist = null; int groupIndex = 0 ; //取出33页的数据 if(pageSubSize>0){ int start = (int) (count-pageSubSize); q.from(start); sublist = q.fetch(pageCount); } q.from(0); for(int i=1;i<=pageCount;i++){ groupIndex = i; list = new ArrayList<UserCompetition>(); //取一条加入当前组 if(i<=pageSubSize){ list.add(sublist.get(i-1)); } //若是每页条数小于100条 if(pageSize<=100){ templist = q.fetch(i, pageSize); list.addAll(templist); //当前组开始一轮战斗 doSelectPking2(list,groupIndex); //若是每页条数大于100条,则再分页每页100条进行处理 }else{ winlist = new ArrayList<UserCompetition>(); //分页条数 int pageSize1 = 100; //偏移量(用于计算32组,每组分页的起始位置) int offset = (i-1)*pageSize; //计算不满100条的偏移量 int offsetSub = 0; //本组的总页数 int pageCount1 = pageSize/pageSize1; //不满100条的页 int pageSubCount1 = pageSize%pageSize1>0?1:0; //不满100条的页的条数 int pageSubSize1 = pageSize%pageSize1; List<UserCompetition> sublist1 = null; //若是有不满100条的页单独处理 if(pageSubCount1>0){ //计算余数 offsetSub = pageSize - pageSubSize1; //只取剩余条数 sublist1 = q.from(offsetSub).fetch(pageSubSize1); winlist.add(doSelectPking2(sublist1,groupIndex)); } //设置该组的起始偏移量 q.from(offset); for(int j=1;j<=pageCount1;j++){ //分页取出 templist = q.fetch(j, pageSize1); list.addAll(templist); winlist.add(doSelectPking2(list,groupIndex)); } doSelectPking2(winlist,groupIndex); } } //处理竞技32强的信息 // endSelectingPk(levelType); }else{ return true; } return false; } @Override public void endSelectingPk() { Competition competition = Competition.find().order("-code").first(); if(competition != null){ competition.selectEnd(); competition.save(); } } /** * 进行海选战斗算法1 * @param list */ public void doSelectPking(List<UserCompetition> list,int groupIndex){ List<UserCompetition> templist = new ArrayList<UserCompetition>(); List<UserCompetition> tlist = new ArrayList<UserCompetition>(); templist.addAll(list); tlist.addAll(list); UserCompetition pkerA = null; UserCompetition pkerB = null; int pkerAindex = 0; int pkerBindex = 0; boolean isWin = false; while(tlist.size()>1){ tlist.clear(); //从队列中随机选一个做为第一个选手 pkerAindex = new Random().nextInt(templist.size()); pkerA = templist.remove(pkerAindex); //从剩余的队列中随机选一个做为第二个选手 pkerBindex = new Random().nextInt(templist.size()); pkerB = templist.remove(pkerBindex); //进行pk isWin = pkerA.getSelectPkResult(pkerB); PkInfo pkInfo = new PkInfo(pkerA.code, pkerA.levelType, groupIndex, 0, PkInfo.PK_TYPE_SELECT, pkerA.uid, pkerB.uid); if(isWin){ //若是A胜利了则从新回到队列中,不然被淘汰 templist.add(pkerA); //竞技32强 if(templist.size()==1){ pkInfo.setSelectPkResult(isWin, PkInfo.SELECT_PK_STATUS_GOUP, PkInfo.SELECT_PK_STATUS_OUT); //更新排名 pkerA.rank = PkInfo.ranks[0]; //晋级下一轮 }else{ pkInfo.setSelectPkResult(isWin, PkInfo.SELECT_PK_STATUS_CONTINUE, PkInfo.SELECT_PK_STATUS_OUT); } }else{ //若是B胜利了则从新回到队列中,不然被淘汰 templist.add(pkerB); //竞技32强 if(templist.size()==1){ pkInfo.setSelectPkResult(isWin, PkInfo.SELECT_PK_STATUS_OUT, PkInfo.SELECT_PK_STATUS_GOUP); //更新排名 pkerB.rank = PkInfo.ranks[0]; //晋级下一轮 }else{ pkInfo.setSelectPkResult(isWin, PkInfo.SELECT_PK_STATUS_OUT, PkInfo.SELECT_PK_STATUS_CONTINUE); } } pkInfo.save(); pkerA.save(); pkerB.save(); tlist.addAll(templist); } } /** * 进行海选战斗算法2 * @param list */ public UserCompetition doSelectPking2(List<UserCompetition> list, int groupIndex){ List<UserCompetition> templist = new ArrayList<UserCompetition>(); List<UserCompetition> winlist = new ArrayList<UserCompetition>(); List<UserCompetition> tlist = new ArrayList<UserCompetition>(); templist.addAll(list); winlist.addAll(list); tlist.addAll(list); UserCompetition pkerA = null; UserCompetition pkerB = null; int pkerAindex = 0; int pkerBindex = 0; boolean isWin = false; boolean isLastRound = list.size()<=2?true:false; int round = 0; UserCompetition winner = null; //当胜利者个数为1的时候为胜利 while(winlist.size()>1){ //轮次自增 round++; winlist.clear(); //进行第round轮死斗赛 while(tlist.size()>1){ tlist.clear(); //从胜利的队列中随机选一个做为第一个选手 pkerAindex = new Random().nextInt(templist.size()); pkerA = templist.remove(pkerAindex); //从胜利的队列中随机选一个做为第二个选手 pkerBindex = new Random().nextInt(templist.size()); pkerB = templist.remove(pkerBindex); //进行pk isWin = pkerA.getSelectPkResult(pkerB); PkInfo pkInfo = new PkInfo(pkerA.code, pkerA.levelType,groupIndex, round, PkInfo.PK_TYPE_SELECT, pkerA.uid, pkerB.uid); if(isWin){ //若是A胜利了则放入到胜利队列中,不然被淘汰 winlist.add(pkerA); //竞技32强 if(isLastRound){ pkInfo.setSelectPkResult(isWin, PkInfo.SELECT_PK_STATUS_GOUP, PkInfo.SELECT_PK_STATUS_OUT); //更新排名 pkerA.rank = PkInfo.ranks[0]; //晋级下一轮 }else{ pkInfo.setSelectPkResult(isWin, PkInfo.SELECT_PK_STATUS_CONTINUE, PkInfo.SELECT_PK_STATUS_OUT); } }else{ //若是B胜利了则从新回到队列中,不然被淘汰 winlist.add(pkerB); //竞技32强 if(isLastRound){ pkInfo.setSelectPkResult(isWin, PkInfo.SELECT_PK_STATUS_OUT, PkInfo.SELECT_PK_STATUS_GOUP); //更新排名 pkerB.rank = PkInfo.ranks[0]; //晋级下一轮 }else{ pkInfo.setSelectPkResult(isWin, PkInfo.SELECT_PK_STATUS_OUT, PkInfo.SELECT_PK_STATUS_CONTINUE); } } pkInfo.save(); pkerA.save(); pkerB.save(); tlist.addAll(templist); } tlist.clear(); templist.addAll(winlist); tlist.addAll(templist); winlist.clear(); winlist.addAll(templist); if(templist.size()<=2){ isLastRound = true; } } return winner; } /** * 开始淘汰赛 */ @Override public boolean beginPkouting(int levelType) { Competition competition = Competition.find().order("-code").first(); if(competition != null){ competition.pkoutBegin(); competition.save(); MorphiaQuery q = UserCompetition.createQuery(); q.filter("code", competition.code); q.filter("levelType", levelType); q.filter("signStatus",UserCompetition.SIGN_STATUS_Y); q.filter("isSelectPkOut", false); q.order("-attackPower"); List<UserCompetition> list = q.fetch(32); int round = getRoundByRank(list.size()); //根据进入32强的人数判断淘汰赛从第几轮开始 for(int i=round;i<=5;i++){ doPkouting(list, i); } } return false; } /** * 淘汰赛PK * @param list * @param round */ public void doPkouting(List<UserCompetition> list, int round){ List<UserCompetition> templist = new ArrayList<UserCompetition>(); List<UserCompetition> rmvlist = new ArrayList<UserCompetition>(); templist.addAll(list); for(UserCompetition uc:list){ //过滤被淘汰掉的选手 if(uc.isPkoutOut){ templist.remove(uc); rmvlist.add(uc); } } list.removeAll(rmvlist); int size = templist.size(); int spliter = 0; if(size>1){ spliter = size%2==0?size/2:(size/2+1); } //分组 //A组 List<UserCompetition> listA = templist.subList(0, spliter); //B组 List<UserCompetition> listB = templist.subList(spliter,size); UserCompetition ucA = null; UserCompetition ucB = null; boolean isWin = false; for(int i=0;i<listA.size();i++){ ucA = listA.get(i); if(i<listB.size()){ ucB = listB.get(i); }else{ ucB = null; } //战斗 if(ucA !=null && ucB !=null){ PkInfo pkInfo = new PkInfo(ucA.code, ucA.levelType, 0, 0, PkInfo.PK_TYPE_PKOUT, ucA.uid, ucB.uid); pkInfo.round = round; isWin = battle(ucA.uid, ucB.uid).result; pkInfo.setPkOutResult(isWin); //A胜利晋级,则B被淘汰 if(isWin){ ucA.rank = getRankByRound(round); ucB.isPkoutOut = true; //B胜利晋级,则A被淘汰 }else{ ucB.rank = getRankByRound(round); ucA.isPkoutOut = true; } pkInfo.save(); ucA.save(); ucB.save(); } } } @Override public boolean endPkoutingPk(int levelType) { // TODO Auto-generated method stub return false; } public Battle battle(String uid, String targetId) { BattleServiceImpl battleService = new BattleServiceImpl(); //1. Construct data for fight GameUserService service = Spring.getBeanOfType(GameUserService.class); GameUser user = service.getSimpleInfoForFight(uid); //Refresh target user energy/physical/fight attributes. GameUser targetUser = service.getGameUser(targetId); targetUser.autoIncreaseLiveAttribute(); targetUser.save(); GameUser target = service.getSimpleInfoForFight(targetId); List<FightableObj> attacker = new ArrayList<FightableObj>(); attacker.add(user); List<FightableObj> anAttacker = new ArrayList<FightableObj>(); anAttacker.add(target); //2. Fight Battle battle = battleService.battleMultipleMembers(attacker, anAttacker); //3. Fight result process String winnerId = uid; String loserId = targetId; boolean isTargetWin = false; if(!battle.result){ winnerId = targetId; loserId = uid; isTargetWin = true; } Map<String,FightResult> map = doFightResult(winnerId, loserId, null,user.getId().toString()); FightResult result = map.get(uid); battle.fightNeeds = result; return battle; } public Map<String, FightResult> doFightResult(String winnerId, String loserId, String objId,String uid) { int loserConsumedFight = RandomUtil.getRandomValue(10, 20); int loserExp = 0; int loserFightPoint = 1; long loserHonor = 0; long winHonor = 0; int winExp = RandomUtil.getRandomValue(1, 4); int winFightPoint = RandomUtil.getRandomValue(1, 3); int winConsumedFight = RandomUtil.getRandomValue(1, 10); int finalWinExp = AchievementUtils.getExpForPK(winExp); int physicalPower = 1; FightResult loserResult = new FightResult(loserId, false, 0,loserHonor, loserExp, loserFightPoint, loserConsumedFight, physicalPower, objId); FightResult winnerResult = new FightResult(winnerId, true, 0,winHonor, finalWinExp, winFightPoint, winConsumedFight, physicalPower, objId); winnerResult.additionalExp = AchievementUtils.getAdditionalValue(AchievementResult.TYPE_EXP_PK); winnerResult.additionalMoney = AchievementUtils.getAdditionalValue(AchievementResult.TYPE_MONEY_PK); Map<String, FightResult> result = new HashMap<String, FightResult>(2); result.put(winnerId, winnerResult); result.put(loserId, loserResult); return result; } public int getRankByRound(int round){ int rank = 0; if(round == 1){ rank = 16; }else if(round == 2){ rank = 8; }else if(round == 3){ rank = 3; }else if(round == 4){ rank = 2; }else if(round == 5){ rank = 1; } return rank; } public int getRoundByRank(int rank){ int round = 0; if(rank>16){ round = 1; }else if(rank > 8 && rank <= 16){ round = 2; }else if(rank > 4 && rank <= 8){ round = 3; }else if(rank > 2 && rank <= 4){ round = 4; }else if(rank > 1 && rank <= 2){ round = 5; } return round; } /** * 自动发放奖励 */ @Override public void autoRewarding() { Competition competition = Competition.find().order("-code").first(); if(competition != null){ competition.toReward(); competition.save(); MorphiaQuery q = UserCompetition.createQuery(); q.filter("code", competition.code); q.filter("signStatus",UserCompetition.SIGN_STATUS_Y); // q.filter("receiveRewardStatus", UserCompetition.RECEIVE_REWARD_STATUS_N); long count = q.count(); int pageSize = 100; int pageCount=(int) (count%pageSize==0?(count/pageSize):(count/pageSize+1)); List<UserCompetition> list = null; GameUser gu = null; for(int i=1;i<=pageCount;i++){ list=q.fetch(i, pageSize); for(UserCompetition uc:list){ gu = GameUser.findById(uc.uid); //发送礼包 CompetitionReward.rewardToUser(gu, uc.rank, uc.levelType); uc.receiveRewardStatus = UserCompetition.RECEIVE_REWARD_STATUS_Y; uc.save(); } } } } /** * 获取本届战况信息 * @param pageNum * @return */ @Override public PageTDO getCompetitionPkInfo(int pageNum, int levelType) { Competition competition = Competition.find().order("-code").first(); if(competition == null){ return null; } List<PkInfo> list = null; long now = new Date().getTime(); MorphiaQuery q = PkInfo.find("code", competition.code); q.filter("levelType", levelType); q.order("-pkType,-groupIndex,-round"); long count = q.countAll(); int pageCount=(int) (count%PageTDO.pageSize==0?(count/PageTDO.pageSize):(count/PageTDO.pageSize+1)); list = q.fetch(pageNum, PageTDO.pageSize); for(PkInfo info: list){ info.loadUserInfo(); } if(competition.status == Competition.STATUS_IN_INIT || competition.status == Competition.STATUS_IN_SIGN || competition.status == Competition.STATUS_IN_SIGN_END){ list = null; } PageTDO page = new PageTDO(count,pageNum,pageCount,list); return page; } @Override public void clearData() { // TODO Auto-generated method stub Competition competition = Competition.find().order("-code").first(); if(competition == null){ return; } long code = competition.code-1; //清除上一届PKinfo MorphiaQuery clearPkinfo = PkInfo.filter("code", code); PkInfo.delete(clearPkinfo); //清除上一届报名表数据只保留三十二强数据 MorphiaQuery clearUserinfo = UserCompetition.filter("code", code); clearUserinfo.filter("isSelectPkOut", true); UserCompetition.delete(clearUserinfo); } }
package models.competition; import java.util.Date; import java.util.List; import org.apache.ivy.core.event.download.EndArtifactDownloadEvent; import play.modules.morphia.Model; import service.AppConfigKeyConstants; import service.util.AppConfigUtils; import service.util.DateUtils; import com.google.code.morphia.annotations.Entity; import com.google.code.morphia.annotations.Transient; @Entity public class Competition extends Model{ public static final int STATUS_IN_INIT = 0; public static final int STATUS_IN_SIGN = 1; public static final int STATUS_IN_SIGN_END = 11; public static final int STATUS_IN_SELECT = 2; public static final int STATUS_IN_SELECT_END = 22; public static final int STATUS_IN_PKOUT = 3; public static final int STATUS_IN_CLOSED = 4; public static final int COMPETITION_ENABLE_N = 0; public static final int COMPETITION_ENABLE_Y = 1; /** * 第几届擂台赛 */ public long code; /** * 报名开始时间 */ public long signBeginTime; /** * 报名结束时间 */ public long signEndTime; /** * 海选开始时间 */ public long selectBeginTime; /** * 淘汰赛开始时间 */ public long pkoutBeginTime; /** * 初级淘汰赛对阵名单及结果 */ @Transient public List<PkInfo> nomalLevelPkList; /** * 高级淘汰赛对阵名单及结果 */ @Transient public List<PkInfo> highLevelPkList; /** * 所在状态【1:报名中;2:海选中;3:淘汰赛;】 */ public int status; /** * 上一个擂台赛结束的时候 新建一个擂台赛 */ public void init(){ Competition competition = Competition.find().order("-code").first(); if(competition == null){ this.code = 1; }else{ this.code = competition.code+1; } //第一届擂台赛刚开始 //若是当前时间尚未到报名截止时间 if(competition == null){ this.signBeginTime = DateUtils.getTimeOfWeekByTime(1, 9, 0, 0).getTime(); this.signEndTime = DateUtils.getTimeOfWeekByTime(5, 9, 0, 0).getTime(); this.selectBeginTime = DateUtils.getTimeOfWeekByTime(5, 20, 0, 0).getTime(); this.pkoutBeginTime = DateUtils.getTimeOfWeekByTime(6, 20, 0, 0).getTime(); //下一届 }else{ this.signBeginTime = DateUtils.getTimeOfNextWeekByTime(1, 9, 0, 0).getTime(); this.signEndTime = DateUtils.getTimeOfNextWeekByTime(5, 9, 0, 0).getTime(); this.selectBeginTime = DateUtils.getTimeOfNextWeekByTime(5, 20, 0, 0).getTime(); this.pkoutBeginTime = DateUtils.getTimeOfNextWeekByTime(6, 20, 0, 0).getTime(); } } /** * 检查擂台赛是否可用发布使用 */ public static boolean checkEnable(){ int status = AppConfigUtils.getIntValue(AppConfigKeyConstants.COMPETITION_ENABLE_STATUS, COMPETITION_ENABLE_N); if(status == COMPETITION_ENABLE_N){ return false; }else if (status == COMPETITION_ENABLE_Y){ return true; } return false; } /** * 产生下一届 */ public void createNextCompetition(){ this.status = STATUS_IN_INIT; } /** * 报名开始 */ public void signBegin(){ this.status = STATUS_IN_SIGN; } /** * 报名结束 */ public void signEnd(){ this.status = STATUS_IN_SIGN_END; } /** * 海选赛开始 */ public void selectBegin(){ this.status = STATUS_IN_SELECT; } /** * 海选赛结束 */ public void selectEnd(){ this.status = STATUS_IN_SELECT_END; } /** * 淘汰赛开始 */ public void pkoutBegin(){ this.status = STATUS_IN_PKOUT; } /** * 淘汰赛结束 */ public void toReward(){ this.status = STATUS_IN_CLOSED; } }