ExaminationService.java 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. package com.qxgmat.service.extend;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.github.pagehelper.Page;
  4. import com.nuliji.tools.AbstractService;
  5. import com.nuliji.tools.PageResult;
  6. import com.nuliji.tools.Tools;
  7. import com.nuliji.tools.Transform;
  8. import com.nuliji.tools.exception.ParameterException;
  9. import com.nuliji.tools.exception.SystemException;
  10. import com.qxgmat.data.constants.enums.QuestionSubject;
  11. import com.qxgmat.data.constants.enums.QuestionType;
  12. import com.qxgmat.data.constants.enums.ServiceKey;
  13. import com.qxgmat.data.constants.enums.module.PaperOrigin;
  14. import com.qxgmat.data.constants.enums.status.DirectionStatus;
  15. import com.qxgmat.data.dao.entity.*;
  16. import com.qxgmat.data.relation.ExaminationPaperRelationMapper;
  17. import com.qxgmat.data.relation.QuestionNoRelationMapper;
  18. import com.qxgmat.data.relation.UserPaperRelationMapper;
  19. import com.qxgmat.data.relation.UserReportRelationMapper;
  20. import com.qxgmat.data.relation.entity.QuestionDifficultRelation;
  21. import com.qxgmat.data.relation.entity.QuestionNoRelation;
  22. import com.qxgmat.service.UserPaperService;
  23. import com.qxgmat.service.UsersService;
  24. import com.qxgmat.service.inline.*;
  25. import org.springframework.stereotype.Service;
  26. import org.springframework.transaction.annotation.Transactional;
  27. import javax.annotation.Resource;
  28. import java.util.*;
  29. @Service
  30. public class ExaminationService extends AbstractService {
  31. private static Random rand = new Random();
  32. @Resource
  33. private QuestionService questionService;
  34. @Resource
  35. private QuestionNoService questionNoService;
  36. @Resource
  37. private QuestionNoRelationMapper questionNoRelationMapper;
  38. @Resource
  39. private ExaminationStructService examinationStructService;
  40. @Resource
  41. private ExaminationPaperService examinationPaperService;
  42. @Resource
  43. private UserPaperRelationMapper userPaperRelationMapper;
  44. @Resource
  45. private UserPaperService userPaperService;
  46. @Resource
  47. private UserReportRelationMapper userReportRelationMapper;
  48. @Resource
  49. private UserReportService userReportService;
  50. @Resource
  51. private UsersService usersService;
  52. @Resource
  53. private ExaminationPaperRelationMapper examinationPaperRelationMapper;
  54. /**
  55. * verbal考试相关设置
  56. */
  57. final public Integer verbalMaxLevel = 27;
  58. final public Integer verbalMinLevel = 9;
  59. final public Integer verbalInitLevel = 13;
  60. final public Integer verbalPre = 9;
  61. final public Integer verbalSC = 14;
  62. final public Integer verbalCR = 9;
  63. final public Integer verbalRC = 13;
  64. // 出RC阅读题的题号
  65. final public Integer[] verbalRCPosition = new Integer[]{5, 15, 24, 33};
  66. /**
  67. * quant考试相关设置
  68. */
  69. final public Integer[] quantBaseLevel = new Integer[]{8, 8, 8, 7};
  70. // 阶段的最大题目数
  71. final public Integer[] quantNumber = new Integer[]{0, 8, 16, 24, 31};
  72. final public Integer quantMinRatio = 1;
  73. final public Integer quantMaxRatio = 3;
  74. final public Integer quantInitLevel = 11;
  75. final public Integer quantPS = 17;
  76. final public Integer quantDS = 14;
  77. /**
  78. * 根据第三层结构建立paper
  79. * @param entity
  80. * @return
  81. */
  82. @Transactional
  83. public ExaminationStruct addPaper(ExaminationStruct entity){
  84. entity = examinationStructService.add(entity);
  85. if (entity.getLevel() == 3){
  86. // 添加2份paper
  87. ExaminationPaper paper = examinationPaperService.add(ExaminationPaper.builder()
  88. .isAdapt(entity.getIsAdapt())
  89. .structTwo(entity.getParentId())
  90. .structThree(entity.getId())
  91. .title(entity.getTitleZh())
  92. .status(1)
  93. .build()
  94. );
  95. }
  96. return entity;
  97. }
  98. @Transactional
  99. public ExaminationStruct editPaper(ExaminationStruct entity){
  100. entity = examinationStructService.edit(entity);
  101. if (entity.getLevel() == 3){
  102. ExaminationPaper paper = examinationPaperService.getByThree(entity.getId());
  103. if(paper == null){
  104. paper = examinationPaperService.add(ExaminationPaper.builder()
  105. .isAdapt(entity.getIsAdapt())
  106. .structTwo(entity.getParentId())
  107. .structThree(entity.getId())
  108. .title(entity.getTitleZh())
  109. .status(1)
  110. .build()
  111. );
  112. }else{
  113. examinationPaperService.edit(ExaminationPaper.builder()
  114. .id(paper.getId())
  115. .isAdapt(entity.getIsAdapt())
  116. .structTwo(entity.getParentId())
  117. .structThree(entity.getId())
  118. .title(entity.getTitleZh())
  119. .status(1)
  120. .build()
  121. );
  122. }
  123. }
  124. return entity;
  125. }
  126. @Transactional
  127. public Boolean deletePaper(Integer id){
  128. Boolean result = examinationStructService.delete(id);
  129. ExaminationPaper paper = examinationPaperService.getByThree(id);
  130. if(paper != null){
  131. examinationPaperService.delete(paper.getId());
  132. }
  133. return result;
  134. }
  135. private Map<String, String> adminMap = new HashMap<String, String>(){{
  136. put("updateTime", "q");
  137. put("", "qn");
  138. }};
  139. /**
  140. *
  141. * @param page
  142. * @param pageSize
  143. * @param questionType
  144. * @param structId
  145. * @param questionNo
  146. * @param paperId
  147. * @param place
  148. * @param difficult
  149. * @param order
  150. * @param direction
  151. * @return
  152. */
  153. public Page<QuestionNoRelation> listAdmin(int page, int pageSize, String questionType, Number structId, Number questionNo, Number paperId, String place, String difficult, String order, DirectionStatus direction){
  154. if(order == null || order.isEmpty()){
  155. order = "id";
  156. }
  157. if(adminMap.containsKey(order)){
  158. order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
  159. }else{
  160. order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
  161. }
  162. if (direction == null){
  163. direction = DirectionStatus.DESC;
  164. }
  165. String finalOrder = order;
  166. DirectionStatus finalDirection = direction;
  167. Page<QuestionNoRelation> p = page(() -> {
  168. questionNoRelationMapper.listExaminationAdmin(questionType, structId, questionNo, paperId, place, difficult, finalOrder, finalDirection.key);
  169. }, page, pageSize);
  170. Collection ids = Transform.getIds(p, QuestionNoRelation.class, "id");
  171. // 获取详细数据
  172. List<QuestionNoRelation> list = questionNoService.relation(questionNoService.select(ids));
  173. Transform.replace(p, list, QuestionNoRelation.class, "id");
  174. return p;
  175. }
  176. /**
  177. * 查找模考组卷
  178. * @param page
  179. * @param size
  180. * @param structId
  181. * @param userId
  182. * @param times
  183. * @return
  184. */
  185. public PageResult<ExaminationPaper> list(int page, int size, Number structId, Number userId, Integer qxCatNo, Integer times){
  186. Page<ExaminationPaper> p = page(()->{
  187. examinationPaperRelationMapper.listWithUser(structId, userId, qxCatNo, times);
  188. },page, size);
  189. Collection ids = Transform.getIds(p, ExaminationPaper.class, "id");
  190. // 获取详细数据
  191. List<ExaminationPaper> list = examinationPaperService.select(ids);
  192. return new PageResult<>(list, p.getTotal());
  193. }
  194. /**
  195. * cat模考是否已经完成
  196. * @param userId
  197. * @return
  198. */
  199. public boolean isFinishCat(Integer userId){
  200. User user = usersService.get(userId);
  201. ExaminationStruct struct = getCat();
  202. List<ExaminationPaper> paperList = examinationPaperService.listByTwo(struct.getId());
  203. Collection ids = Transform.getIds(paperList, ExaminationPaper.class, "id");
  204. List<UserPaper> userPaperList = userPaperService.listWithCat(userId, ids, user.getQxCat());
  205. if (paperList.size() != userPaperList.size()){
  206. return false;
  207. }
  208. Collection paperIds = Transform.getIds(userPaperList, UserPaper.class, "id");
  209. List<UserReport> reportList = userReportService.listWithLast(paperIds);
  210. for(UserReport report: reportList){
  211. if(report.getIsFinish() == 0){
  212. return false;
  213. }
  214. }
  215. return true;
  216. }
  217. /**
  218. * 重置Cat模考系列
  219. * @param userId
  220. * @return
  221. */
  222. @Transactional
  223. public Boolean resetCat(Integer userId, boolean force){
  224. User user = usersService.get(userId);
  225. ExaminationStruct struct = getCat();
  226. List<ExaminationPaper> paperList = examinationPaperService.listByTwo(struct.getId());
  227. Collection ids = Transform.getIds(paperList, ExaminationPaper.class, "id");
  228. List<UserPaper> userPaperList = userPaperService.listWithCat(userId, ids, user.getQxCat());
  229. if (!force && paperList.size() != userPaperList.size()){
  230. throw new ParameterException("未完成所有");
  231. }
  232. Collection paperIds = Transform.getIds(userPaperList, UserPaper.class, "id");
  233. if(!force){
  234. List<UserReport> reportList = userReportService.listWithLast(paperIds);
  235. for(UserReport report: reportList){
  236. if(report.getIsFinish() == 0){
  237. throw new ParameterException("未完成所有");
  238. }
  239. }
  240. }
  241. // 增加用户cat计数
  242. usersService.edit(User.builder().id(userId).qxCat(user.getQxCat() + 1).build());
  243. // 在获取start paper时,创建新的paper
  244. return userPaperService.reset(paperIds, userId);
  245. }
  246. public ExaminationStruct getCat(){
  247. List<ExaminationStruct> list = examinationStructService.main();
  248. for (ExaminationStruct struct : list){
  249. if (struct.getLevel() == 1) continue;
  250. if (struct.getExtend().equals(ServiceKey.QX_CAT.key)) return struct;
  251. }
  252. throw new SystemException("没有找到cat模考节点");
  253. }
  254. public boolean isCat(ExaminationPaper paper){
  255. ExaminationStruct struct = examinationStructService.get(paper.getStructTwo());
  256. return struct.getExtend().equals(ServiceKey.QX_CAT.key);
  257. }
  258. /**
  259. * 获取下一阶段难度分
  260. * @param currentLevel
  261. * @param number
  262. * @param correct
  263. * @return
  264. */
  265. public Integer verbalNextLevel(Integer currentLevel, Integer number, long correct){
  266. long correctRate = correct * 100 / number;
  267. if (correctRate < 60){
  268. currentLevel -= 5;
  269. if (currentLevel < verbalMinLevel) return verbalMinLevel;
  270. }else if(correctRate > 80){
  271. currentLevel += 5;
  272. if (currentLevel > verbalMaxLevel) return verbalMaxLevel;
  273. }
  274. return currentLevel;
  275. }
  276. /**
  277. * 获取下一阶段难度分
  278. * @param currentLevel
  279. * @param number
  280. * @param correct
  281. * @param step
  282. * @return
  283. */
  284. public Integer quantNextLevel(Integer currentLevel, Integer number, long correct, Integer step){
  285. long correctRate = correct * 100 / number;
  286. Integer max = quantMaxRatio * quantBaseLevel[step];
  287. Integer min = quantMinRatio * quantBaseLevel[step];
  288. if (correctRate < 60){
  289. currentLevel -= 4;
  290. if (currentLevel < min) return min;
  291. }else if(correctRate > 80){
  292. currentLevel += 4;
  293. if (currentLevel > max) return max;
  294. }
  295. return currentLevel;
  296. }
  297. /**
  298. * 分组统计不同题型的数量
  299. * @param userQuestionList
  300. * @return
  301. */
  302. public Map<String, Integer> statTypeNumber(List<UserQuestion> userQuestionList){
  303. Map<String, Integer> result = new HashMap<>();
  304. for(UserQuestion question : userQuestionList){
  305. String type = question.getQuestionType();
  306. if (!result.containsKey(type)){
  307. result.put(type, 0);
  308. }
  309. result.put(type, result.get(type) + 1);
  310. }
  311. return result;
  312. }
  313. /**
  314. * 返回还需的题目类型
  315. * @param typeNumber
  316. * @param questionTypes
  317. * @return
  318. */
  319. public List<String> needQuestionTypes(Map<String, Integer> typeNumber, List<String> questionTypes){
  320. List<String> targetTypes = new ArrayList<>();
  321. for(String type : questionTypes){
  322. int target = 0;
  323. switch(type){
  324. case "sc":
  325. target = verbalSC;
  326. break;
  327. case "cr":
  328. target = verbalCR;
  329. break;
  330. case "rc":
  331. target = verbalRC;
  332. break;
  333. case "ps":
  334. target = quantPS;
  335. break;
  336. case "ds":
  337. target = quantDS;
  338. break;
  339. }
  340. if (target == 0 || target > typeNumber.get(type)){
  341. targetTypes.add(type);
  342. }
  343. }
  344. return targetTypes;
  345. }
  346. /**
  347. * 通过当前完成的题目数,判断是否该抽取阅读题
  348. * @param number
  349. * @return
  350. */
  351. public boolean verbalRC(Integer number){
  352. for(Integer n : verbalRCPosition){
  353. if (n == number) return true;
  354. }
  355. return false;
  356. }
  357. /**
  358. * 通过当前完成的题目数,判断当前阶段
  359. * @param number
  360. * @return
  361. */
  362. public Integer quantStep(Integer number) {
  363. Integer step = 0;
  364. Integer all = 0;
  365. for(Integer n : quantBaseLevel){
  366. all += n;
  367. if (all >= number) return step;
  368. step += 1;
  369. }
  370. return step;
  371. }
  372. /**
  373. * 初始化第一阶段题目
  374. * 一篇4题的阅读压轴
  375. * { "ids": [], "level": 0 }
  376. * @param structId
  377. * @return
  378. */
  379. public JSONObject initVerbal(Integer structId){
  380. JSONObject info = new JSONObject();
  381. Integer[] rcQ = questionNoService.randomExaminationRc(structId, 4, null);
  382. List<QuestionNoRelation> rcRelationList = questionNoService.listWithRelationByIds(rcQ);
  383. Integer rcLevel = computeNoLevel(rcRelationList);
  384. Integer targetLevel = 0;
  385. Collection types = QuestionType.SpecialFromSubject(QuestionSubject.VERBAL);
  386. List<QuestionDifficultRelation> difficultList = questionNoService.allExaminationByType(structId, types);
  387. List<QuestionDifficultRelation> selectedList = null;
  388. do{
  389. selectedList = randomList(difficultList, verbalPre - 4);
  390. targetLevel = rcLevel + computeDifficultLevel(selectedList);
  391. }while(targetLevel >= verbalInitLevel);
  392. List<Integer> targetIds = new ArrayList<>(verbalPre);
  393. for(QuestionDifficultRelation relation : selectedList){
  394. targetIds.add(relation.getId());
  395. }
  396. targetIds.addAll(Arrays.asList(rcQ));
  397. info.put("level", targetLevel);
  398. info.put("ids", targetIds);
  399. return info;
  400. }
  401. /**
  402. * 生成下一阶段题目
  403. * 一篇3题的阅读压轴
  404. * { "ids": [], "level": 0 }
  405. * @param structId
  406. * @param level
  407. * @param typeNumbers
  408. * @param ids
  409. * @return
  410. */
  411. public JSONObject generateVerbal(Integer structId, Integer level, Map<String, Integer> typeNumbers, Collection ids){
  412. JSONObject info = new JSONObject();
  413. Integer[] rcQ = questionNoService.randomExaminationRc(structId, 3, ids);
  414. List<QuestionNoRelation> rcRelationList = questionNoService.listWithRelationByIds(rcQ);
  415. Integer rcLevel = computeNoLevel(rcRelationList);
  416. Collection types = QuestionType.SpecialFromSubject(QuestionSubject.VERBAL);
  417. List<QuestionDifficultRelation> difficultList = questionNoService.allExaminationByType(structId, types);
  418. List<QuestionDifficultRelation> selectedList = new ArrayList<>(verbalPre - 3);
  419. Integer[] levels = generateLevel(level - rcLevel,verbalPre - 3);
  420. do{
  421. QuestionDifficultRelation r = random(difficultList, ids, levels[selectedList.size()]);
  422. int typeNumber = typeNumbers.get(r.getQuestionType()) + 1;
  423. switch(r.getQuestionType()){
  424. case "sc":
  425. if (typeNumber > verbalSC) {
  426. continue;
  427. }
  428. break;
  429. case "cr":
  430. if (typeNumber > verbalCR) {
  431. continue;
  432. }
  433. break;
  434. }
  435. typeNumbers.put(r.getQuestionType(), typeNumber);
  436. selectedList.add(r);
  437. ids.add(r.getId());
  438. }while(selectedList.size() == verbalPre -3);
  439. List<Integer> targetIds = new ArrayList<>(verbalPre);
  440. for(QuestionDifficultRelation relation : selectedList){
  441. targetIds.add(relation.getId());
  442. }
  443. targetIds.addAll(Arrays.asList(rcQ));
  444. info.put("ids", targetIds);
  445. info.put("level", level);
  446. return info;
  447. }
  448. /**
  449. * 初始化第一阶段题目
  450. * { "ids": [], "level": 0 }
  451. * @param structId
  452. * @return
  453. */
  454. public JSONObject initQuant(Integer structId){
  455. JSONObject info = new JSONObject();
  456. Integer targetLevel = 0;
  457. Collection types = QuestionType.SpecialFromSubject(QuestionSubject.QUANT);
  458. Integer number = quantBaseLevel[0];
  459. List<QuestionDifficultRelation> difficultList = questionNoService.allExaminationByType(structId, types);
  460. List<QuestionDifficultRelation> selectedList = null;
  461. do{
  462. selectedList = randomList(difficultList, number);
  463. targetLevel = computeDifficultLevel(selectedList);
  464. }while(targetLevel >= quantInitLevel);
  465. List<Integer> targetIds = new ArrayList<>(number);
  466. for(QuestionDifficultRelation relation : selectedList){
  467. targetIds.add(relation.getId());
  468. }
  469. info.put("level", targetLevel);
  470. info.put("ids", targetIds);
  471. return info;
  472. }
  473. /**
  474. * 生成下一阶段题目
  475. * 一篇3题的阅读压轴
  476. * { "ids": [], "level": 0 }
  477. * @param structId
  478. * @param level
  479. * @param typeNumbers
  480. * @param ids
  481. * @return
  482. */
  483. public JSONObject generateQuant(Integer structId, Integer level, Map<String, Integer> typeNumbers, Collection ids, Integer step){
  484. JSONObject info = new JSONObject();
  485. Collection types = QuestionType.SpecialFromSubject(QuestionSubject.QUANT);
  486. Integer number = quantBaseLevel[step];
  487. List<QuestionDifficultRelation> difficultList = questionNoService.allExaminationByType(structId, types);
  488. List<QuestionDifficultRelation> selectedList = null;
  489. Integer[] levels = generateLevel(level,number);
  490. do{
  491. QuestionDifficultRelation r = random(difficultList, ids, levels[selectedList.size()]);
  492. int typeNumber = typeNumbers.get(r.getQuestionType()) + 1;
  493. switch(r.getQuestionType()){
  494. case "ps":
  495. if (typeNumber > quantPS) {
  496. continue;
  497. }
  498. break;
  499. case "ds":
  500. if (typeNumber > quantDS) {
  501. continue;
  502. }
  503. break;
  504. }
  505. typeNumbers.put(r.getQuestionType(), typeNumber);
  506. selectedList.add(r);
  507. ids.add(r.getId());
  508. }while(selectedList.size() == number);
  509. List<Integer> targetIds = new ArrayList<>(number);
  510. for(QuestionDifficultRelation relation : selectedList){
  511. targetIds.add(relation.getId());
  512. }
  513. info.put("ids", targetIds);
  514. info.put("level", level);
  515. return info;
  516. }
  517. /**
  518. * 随机生成对应的题目列表
  519. * @param all
  520. * @param size
  521. * @return
  522. */
  523. public List<QuestionDifficultRelation> randomList(List<QuestionDifficultRelation> all, Integer size){
  524. List<QuestionDifficultRelation> list = new ArrayList<>(size);
  525. Set<Integer> indexSet = new HashSet<>();
  526. do{
  527. int index = rand.nextInt(all.size());
  528. if (!indexSet.contains(index)){
  529. QuestionDifficultRelation target = all.get(index);
  530. list.add(target);
  531. indexSet.add(index);
  532. }
  533. }while(list.size() == size);
  534. return list;
  535. }
  536. /**
  537. * 随机生成对应的题目
  538. * @param all
  539. * @param ids
  540. * @param level
  541. * @return
  542. */
  543. public QuestionDifficultRelation random(List<QuestionDifficultRelation> all, Collection ids, Integer level){
  544. String difficult = levelToDifficult(level);
  545. do{
  546. int index = rand.nextInt(all.size());
  547. QuestionDifficultRelation target = all.get(index);
  548. if (ids == null || !ids.contains(target.getId())){
  549. if (difficult == null || target.getDifficult().equals(difficult)) return target;
  550. }
  551. }while(true);
  552. }
  553. /**
  554. * 计算考题对应的难度分
  555. * @param relationList
  556. * @return
  557. */
  558. public Integer computeNoLevel(List<QuestionNoRelation> relationList){
  559. int level = 0;
  560. for(QuestionNoRelation relation : relationList){
  561. level += difficultToLevel(relation.getQuestion().getDifficult());
  562. }
  563. return level;
  564. }
  565. public Integer computeDifficultLevel(List<QuestionDifficultRelation> relationList){
  566. int level = 0;
  567. for(QuestionDifficultRelation relation : relationList){
  568. level += difficultToLevel(relation.getDifficult());
  569. }
  570. return level;
  571. }
  572. public Integer difficultToLevel(String difficult){
  573. switch(difficult){
  574. case "easy":
  575. return 1;
  576. case "medium":
  577. return 2;
  578. case "hard":
  579. return 3;
  580. }
  581. return 0;
  582. }
  583. public String levelToDifficult(Integer level){
  584. switch(level){
  585. case 1:
  586. return "easy";
  587. case 2:
  588. return "medium";
  589. case 3:
  590. return "hard";
  591. }
  592. return null;
  593. }
  594. public Integer[] generateLevel(Integer level, Integer number){
  595. Integer[] levels = new Integer[number];
  596. int no = 0;
  597. // 至少有一个可以3分
  598. if (level > number + 1){
  599. for(int i = 0; i < number; i++){
  600. int n = rand.nextInt(2) + 2; // 随机2-3
  601. levels[i] = n;
  602. level -= n;
  603. no += 1;
  604. // 只能还有一个2分
  605. if (level == number - no + 1){
  606. break;
  607. }
  608. }
  609. number -= no;
  610. }
  611. if(level == number + 1){
  612. // 只有一个2分
  613. levels[no] = 2;
  614. no += 1;
  615. }
  616. // 剩余都是1分
  617. for (int i = 0; i < number; i++) {
  618. levels[i+no] = 1;
  619. }
  620. shuffle(levels);
  621. return levels;
  622. }
  623. public static <T> void swap(T[] a, int i, int j){
  624. T temp = a[i];
  625. a[i] = a[j];
  626. a[j] = temp;
  627. }
  628. public static <T> void shuffle(T[] arr) {
  629. int length = arr.length;
  630. for ( int i = length; i > 0; i-- ){
  631. int randInd = rand.nextInt(i);
  632. swap(arr, randInd, i - 1);
  633. }
  634. }
  635. }