Java实现王者匹配机制(简易版)

4 篇文章 1 订阅

最近打王者被制裁的有点惨,突发奇想,用代码实现下王者的匹配机制。先声明,我不是什么算法大神,轻喷。

分析:王者匹配机制会让一个人的胜率总是保持在50%左右,即胜率高了,给你匹配坑队友降低胜率,低了给你匹配几个大神带你飞。

围绕这个点,进行设计。大概思路为:设置一个隐藏分,如果你的隐藏分高于当前段位,就给你降低胜率,反正则提升胜率,具体代码实现如下。

玩家模型类

package com.ty.atlantis.base.kingofglorymodel;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * @author :TianYuan
 * @date :Created in 2022/3/25 14:51
 * @description:高端玩家模型
 * @modified By:
 */
public class HighEndPlayer {

    /**
     * 排位段位和战力息息相关。
     * 此处采用的简易算法是:
     * 假设玩家初始段位为钻石50,战力为5000,赢一把mvp后段位为51,战力为5000+130=5130
     * 51段位对应的战力为5100。为了修正段位对应的战力,系统会匹配几个坑货降低胜率
     */

    //排位段位 假设初始为钻石5/0星。枚举值为50
    private int rankLevel = 50;

    //战力(隐藏分),默认5000,正常输一把减105,正常赢一把加110。败方MVP不减,赢方Mvp加130
    private long flightPower = 5000;

    //活跃度,默认80,上限100。玩家连续上线每天+5,一天不上线-2,当连续不上线活跃度掉到70就不再减
    private int activity = 80;

    //贵族等级
    private int vipLevel;

    //氪金总额
    private BigDecimal amount;

    public String getRankLevelMean(int rankLevel){
        Map<Integer,String> map = new HashMap<>();
        map.put(39,"铂金二零星");
        map.put(40,"铂金二一星");
        map.put(41,"铂金二二星");
        map.put(42,"铂金二三星");
        map.put(43,"铂金二四星");
        map.put(44,"铂金二五星");
        map.put(45,"铂金一一星");
        map.put(46,"铂金一二星");
        map.put(47,"铂金一三星");
        map.put(48,"铂金一四星");
        map.put(49,"铂金一五星");
        map.put(50,"钻石五零星");
        map.put(51,"钻石五一星");
        map.put(52,"钻石五二星");
        map.put(53,"钻石五三星");
        map.put(54,"钻石五四星");
        map.put(55,"钻石五五星");
        map.put(56,"钻石四零星");
        map.put(57,"钻石四一星");
        map.put(58,"钻石四二星");
        map.put(59,"钻石四三星");
        map.put(60,"钻石四四星");
        map.put(61,"钻石四五星");
        map.put(62,"钻石三零星");
        map.put(63,"钻石三一星");
        map.put(64,"钻石三二星");
        map.put(65,"钻石三三星");
        map.put(66,"钻石三四星");
        map.put(67,"钻石三五星");
        map.put(68,"钻石二零星");
        map.put(69,"钻石二一星");
        map.put(70,"钻石二二星");
        map.put(71,"钻石二三星");
        map.put(72,"钻石二四星");
        map.put(73,"钻石二五星");
        map.put(74,"钻石一零星");
        map.put(75,"钻石二一星");
        map.put(76,"钻石一二星");
        map.put(77,"钻石一三星");
        map.put(78,"钻石一四星");
        map.put(78,"钻石一五星");
        return map.get(rankLevel);
    }

    public int getRankLevel() {
        return rankLevel;
    }

    public void setRankLevel(int rankLevel) {
        this.rankLevel = rankLevel;
    }

    public long getFlightPower() {
        return flightPower;
    }

    public void setFlightPower(long flightPower) {
        this.flightPower = flightPower;
    }

    public int getActivity() {
        return activity;
    }

    public void setActivity(int activity) {
        this.activity = activity;
    }

    public int getVipLevel() {
        return vipLevel;
    }

    public void setVipLevel(int vipLevel) {
        this.vipLevel = vipLevel;
    }

    public BigDecimal getAmount() {
        return amount;
    }

    public void setAmount(BigDecimal amount) {
        this.amount = amount;
    }
}

最终游戏结果类:

package com.ty.atlantis.base.kingofglorymodel;

/**
 * @author :TianYuan
 * @date :Created in 2022/3/25 15:35
 * @description:当前这把游戏的最后结果
 * @modified By:
 */
public class CurrentGameResult {

    //当前游戏是否胜利
    private boolean victoryFlag = false;

    //当前游戏是否为mvp(不区分胜方mvp和败方mvp)
    private boolean mvpFlag = false;

    public boolean isVictoryFlag() {
        return victoryFlag;
    }

    public void setVictoryFlag(boolean victoryFlag) {
        this.victoryFlag = victoryFlag;
    }

    public boolean isMvpFlag() {
        return mvpFlag;
    }

    public void setMvpFlag(boolean mvpFlag) {
        this.mvpFlag = mvpFlag;
    }
}

对局模型类:(并没有什么用,在设计的时候考虑的太复杂了,没有对这个类进行实现)

package com.ty.atlantis.base.kingofglorymodel;

/**
 * @author :TianYuan
 * @date :Created in 2022/3/25 15:17
 * @description:对局模型
 * @modified By:
 */
public class GameModel {

    //蓝色方对局总战力
    private long blueFlightPowerCount;

    //红色发对局总战力
    private long redFlightPowerCount;

    //蓝色方胜率
    private long blueWinRate;

    //蓝色方胜率
    private long redWinRate;

    public long getBlueFlightPowerCount() {
        return blueFlightPowerCount;
    }

    public void setBlueFlightPowerCount(long blueFlightPowerCount) {
        this.blueFlightPowerCount = blueFlightPowerCount;
    }

    public long getRedFlightPowerCount() {
        return redFlightPowerCount;
    }

    public void setRedFlightPowerCount(long redFlightPowerCount) {
        this.redFlightPowerCount = redFlightPowerCount;
    }

    public long getBlueWinRate() {
        return blueWinRate;
    }

    public void setBlueWinRate(long blueWinRate) {
        this.blueWinRate = blueWinRate;
    }

    public long getRedWinRate() {
        return redWinRate;
    }

    public void setRedWinRate(long redWinRate) {
        this.redWinRate = redWinRate;
    }
}

启动类:

package com.ty.atlantis.base;

import com.ty.atlantis.base.kingofglorymodel.CurrentGameResult;
import com.ty.atlantis.base.kingofglorymodel.GameModel;
import com.ty.atlantis.base.kingofglorymodel.HighEndPlayer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import java.util.Random;

/**
 * @author :TianYuan
 * @date :Created in 2022/1/25 16:27
 * @description:测试类基类
 * @modified By:
 */
@SpringBootTest
@RunWith(SpringRunner.class)
@WebAppConfiguration
public class BaseTest {

    @Before
    public void init() {
        System.out.println("开始测试-----------------");
    }

    @After
    public void after() {
        System.out.println("测试结束-----------------");
    }

    @Test
    public void kingOfGlory(){
        //模拟一个高端玩家连续五天,每天十把排位,最后的排位分数
        HighEndPlayer highEndPlayer = new HighEndPlayer();
        for (int i = 0;i<5;i++){
            for (int j = 0;j<10;j++){
//                if (i == 0 && j == 0){
//                    //第一天第一把,让他拿个赢方Mvp,谁叫他是大神呢
//                    highEndPlayer.setRankLevel(highEndPlayer.getRankLevel()+1);//加一星
//                    highEndPlayer.setFlightPower(highEndPlayer.getFlightPower() + 150L);//赢方mvp战力+150
//                    continue;
//                }
                //判断此时战力和当前段位战力差多少
                long diff = highEndPlayer.getFlightPower() - highEndPlayer.getRankLevel() * 100L;
                //当前游戏结果
                CurrentGameResult currentGameResult = null;
                //建立游戏模型
                GameModel gameModel = new GameModel();
                if (diff > 0){
                    //当前战力超过当前段位战力,需要给你匹配几个坑货降降温
                    //这里为了简单,当前战力超过当前段位战力就让他胜率低于50%
                    if (diff <= 150){
                        //超过0~150,下把胜率40%;
                        currentGameResult  = genGameResult(40);
                    }else if (diff > 150 && diff <= 200){
                        //超过150~200,下把胜率30%;
                        currentGameResult  = genGameResult(30);
                    }else if (diff > 200 && diff <= 250){
                        //超过200~250,下把胜率20%;
                        currentGameResult  = genGameResult(20);
                    }else if (diff > 250 && diff <= 300){
                        //超过250~300,下把胜率10%;
                        currentGameResult  = genGameResult(10);
                    }else {
                        //超过300以上,下把胜率0%;
                        currentGameResult  = genGameResult(0);
                    }
                }else if (diff < 0){
                    //当前战力低于当前段位战力,需要给你匹配几个大神带飞
                    if (diff < 0 && diff >=-40){
                        //低于0~40,下把胜率60%;
                        currentGameResult  = genGameResult(60);
                    }else if (diff < -40 && diff >= -90){
                        //低于40~90,下把胜率70%;
                        currentGameResult  = genGameResult(70);
                    }else if (diff < -90 && diff >= -100){
                        //低于90~100,下把胜率80%;
                        currentGameResult  = genGameResult(80);
                    }else if (diff < -100 && diff >= -150){
                        //低于100~150,下把胜率90%;
                        currentGameResult  = genGameResult(90);
                    }else {
                        //低于150以上,下把胜率100%;
                        currentGameResult  = genGameResult(100);
                    }
                }else if (diff == 0){
                    currentGameResult  = genGameResult(50);
                }
                StringBuilder sb = new StringBuilder();
                if (currentGameResult.isVictoryFlag()){
                    //这把赢了
                    sb.append("这把赢了");
                    if (currentGameResult.isMvpFlag()){
                        //并且是mvp
                        highEndPlayer.setFlightPower(highEndPlayer.getFlightPower() + 130);
                        sb.append(",并且Carry了,");
                    }else {
                        highEndPlayer.setFlightPower(highEndPlayer.getFlightPower() + 110);
                    }
                    highEndPlayer.setRankLevel(highEndPlayer.getRankLevel()+1);//加星
                }else {
                    //这把输了
                    sb.append("这把跪了");
                    if (currentGameResult.isMvpFlag()){
                        //败方mvp
                        highEndPlayer.setFlightPower(highEndPlayer.getFlightPower() - 105);
                        sb.append(",他们太坑了带不动,");
                    }else {
                        highEndPlayer.setFlightPower(highEndPlayer.getFlightPower() - 105);
                    }
                    highEndPlayer.setRankLevel(highEndPlayer.getRankLevel()-1);//减星
                }
                sb.append("当前段位为:"+highEndPlayer.getRankLevelMean(highEndPlayer.getRankLevel()));
                System.out.println(sb.toString());
            }
        }
        System.out.println("最后的段位为:"+highEndPlayer.getRankLevelMean(highEndPlayer.getRankLevel()));
    }

    public static void main(String[] args) {
        BaseTest test = new BaseTest();
        for (int i = 0;i<100;i++){
            CurrentGameResult result  = test.genGameResult(10);
            System.out.println(result.isVictoryFlag()+":"+result.isMvpFlag());
        }
    }

    /**
     * 此处采用java的Random来实现胜率结果算法实现
     * 因为Random生成每个数的概率是相等的(虽然是伪随机数,但是这里不考虑那么复杂)
     * 例:想获得50%概率的结果,random.nextInt(2);则生成0和1的概率都是50%。取任意0或者1就可以得到概率结果
     * @param probability 可输入的值 0,10,20,30,40,50,60,70,80,90,100
     * @return
     */
    private CurrentGameResult genGameResult(int probability){
        CurrentGameResult currentGameResult = new CurrentGameResult();
        Random random = new Random();
        int randomInt = random.nextInt(11);
        if (probability == 0){//0%概率,这把必输
            currentGameResult.setVictoryFlag(false);
        }else if (probability == 10){//10%概率
            if (randomInt == 0){
                currentGameResult.setVictoryFlag(true);
            }
        }else if (probability == 20){//20%概率
            if (randomInt == 0 || randomInt == 1){
                currentGameResult.setVictoryFlag(true);
            }
        }else if (probability == 30){//30%概率
            if (randomInt == 0 || randomInt == 1 || randomInt == 2){
                currentGameResult.setVictoryFlag(true);
            }
        }else if (probability == 40){//40%概率
            if (randomInt == 0 || randomInt == 1 || randomInt == 2 || randomInt == 3){
                currentGameResult.setVictoryFlag(true);
            }
        }else if (probability == 50){//50%概率
            if (randomInt == 0 || randomInt == 1 || randomInt == 2 || randomInt == 3 || randomInt == 4){
                currentGameResult.setVictoryFlag(true);
            }
        }else if (probability == 60){//60%概率
            if (randomInt == 0 || randomInt == 1 || randomInt == 2 || randomInt == 3 || randomInt == 4 || randomInt == 5){
                currentGameResult.setVictoryFlag(true);
            }
        }else if (probability == 70){//70%概率
            if (randomInt == 0 || randomInt == 1 || randomInt == 2 || randomInt == 3 || randomInt == 4 || randomInt == 5 || randomInt == 6){
                currentGameResult.setVictoryFlag(true);
            }
        }else if (probability == 80){//80%概率
            if (randomInt == 0 || randomInt == 1 || randomInt == 2 || randomInt == 3 || randomInt == 4 || randomInt == 5 || randomInt == 6 || randomInt == 7){
                currentGameResult.setVictoryFlag(true);
            }
        }else if (probability == 90){//90%概率
            if (randomInt == 0 || randomInt == 1 || randomInt == 2 || randomInt == 3 || randomInt == 4 || randomInt == 5 || randomInt == 6 || randomInt == 7 || randomInt == 8){
                currentGameResult.setVictoryFlag(true);
            }
        }else if (probability == 100){//100%概率
            currentGameResult.setVictoryFlag(true);
        }
       //mvp概率假设为70%,因为他是大神
        int otherRandomInt = random.nextInt(10);
        if (otherRandomInt == 0 || otherRandomInt == 1 || otherRandomInt == 2 || otherRandomInt == 3 || otherRandomInt == 4 || otherRandomInt == 5 || otherRandomInt == 6){
            currentGameResult.setMvpFlag(true);
        }
        return currentGameResult;
    }
}

运行结果:

 仅供娱乐。

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值