ExaminationService.java 23 KB

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