IndependentProbabilityRandomCountTest.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. <?php
  2. namespace Tests\Unit\Game;
  3. use Tests\TestCase;
  4. use App\Module\Game\Dtos\RewardGroupDto;
  5. use App\Module\Game\Dtos\RewardItemDto;
  6. use App\Module\Game\Logics\IndependentProbabilityReward;
  7. /**
  8. * 独立概率模式随机数量限制测试
  9. */
  10. class IndependentProbabilityRandomCountTest extends TestCase
  11. {
  12. /**
  13. * 测试非随机模式:应该返回所有命中的奖励项
  14. */
  15. public function testNonRandomModeReturnsAllHitItems()
  16. {
  17. // 创建奖励组DTO(非随机模式)
  18. $groupDto = new RewardGroupDto();
  19. $groupDto->id = 1;
  20. $groupDto->name = '测试奖励组';
  21. $groupDto->code = 'test_group';
  22. $groupDto->isRandom = false; // 非随机模式
  23. $groupDto->randomCount = 2; // 这个值在非随机模式下应该被忽略
  24. $groupDto->rewardMode = 2; // 独立概率模式
  25. // 创建奖励项(设置高概率确保命中)
  26. $item1 = new RewardItemDto();
  27. $item1->id = 1;
  28. $item1->groupId = 1;
  29. $item1->rewardType = 1;
  30. $item1->targetId = 1001;
  31. $item1->param1 = 0;
  32. $item1->param2 = 0;
  33. $item1->quantity = 1;
  34. $item1->weight = 1.0;
  35. $item1->probability = 100.0; // 100%概率
  36. $item1->minQuantity = null;
  37. $item1->maxQuantity = null;
  38. $item1->isGuaranteed = false;
  39. $item1->extraData = null;
  40. $item2 = new RewardItemDto();
  41. $item2->id = 2;
  42. $item2->groupId = 1;
  43. $item2->rewardType = 1;
  44. $item2->targetId = 1002;
  45. $item2->param1 = 0;
  46. $item2->param2 = 0;
  47. $item2->quantity = 1;
  48. $item2->weight = 1.0;
  49. $item2->probability = 100.0; // 100%概率
  50. $item2->minQuantity = null;
  51. $item2->maxQuantity = null;
  52. $item2->isGuaranteed = false;
  53. $item2->extraData = null;
  54. $item3 = new RewardItemDto();
  55. $item3->id = 3;
  56. $item3->groupId = 1;
  57. $item3->rewardType = 1;
  58. $item3->targetId = 1003;
  59. $item3->param1 = 0;
  60. $item3->param2 = 0;
  61. $item3->quantity = 1;
  62. $item3->weight = 1.0;
  63. $item3->probability = 100.0; // 100%概率
  64. $item3->minQuantity = null;
  65. $item3->maxQuantity = null;
  66. $item3->isGuaranteed = false;
  67. $item3->extraData = null;
  68. $groupDto->items = [$item1, $item2, $item3];
  69. // 执行处理
  70. $result = IndependentProbabilityReward::process($groupDto);
  71. // 验证结果:非随机模式应该返回所有3个命中的奖励项
  72. $this->assertCount(3, $result, '非随机模式应该返回所有命中的奖励项');
  73. }
  74. /**
  75. * 测试随机模式:应该限制返回的奖励项数量
  76. */
  77. public function testRandomModeLimitsReturnedItems()
  78. {
  79. // 创建奖励组DTO(随机模式)
  80. $groupDto = new RewardGroupDto();
  81. $groupDto->id = 1;
  82. $groupDto->name = '测试奖励组';
  83. $groupDto->code = 'test_group';
  84. $groupDto->isRandom = true; // 随机模式
  85. $groupDto->randomCount = 2; // 限制返回2个奖励项
  86. $groupDto->rewardMode = 2; // 独立概率模式
  87. // 创建奖励项(设置高概率确保命中)
  88. $item1 = new RewardItemDto();
  89. $item1->id = 1;
  90. $item1->groupId = 1;
  91. $item1->rewardType = 1;
  92. $item1->targetId = 1001;
  93. $item1->param1 = 0;
  94. $item1->param2 = 0;
  95. $item1->quantity = 1;
  96. $item1->weight = 1.0;
  97. $item1->probability = 100.0; // 100%概率
  98. $item1->minQuantity = null;
  99. $item1->maxQuantity = null;
  100. $item1->isGuaranteed = false;
  101. $item1->extraData = null;
  102. $item2 = new RewardItemDto();
  103. $item2->id = 2;
  104. $item2->groupId = 1;
  105. $item2->rewardType = 1;
  106. $item2->targetId = 1002;
  107. $item2->param1 = 0;
  108. $item2->param2 = 0;
  109. $item2->quantity = 1;
  110. $item2->weight = 1.0;
  111. $item2->probability = 100.0; // 100%概率
  112. $item2->minQuantity = null;
  113. $item2->maxQuantity = null;
  114. $item2->isGuaranteed = false;
  115. $item2->extraData = null;
  116. $item3 = new RewardItemDto();
  117. $item3->id = 3;
  118. $item3->groupId = 1;
  119. $item3->rewardType = 1;
  120. $item3->targetId = 1003;
  121. $item3->param1 = 0;
  122. $item3->param2 = 0;
  123. $item3->quantity = 1;
  124. $item3->weight = 1.0;
  125. $item3->probability = 100.0; // 100%概率
  126. $item3->minQuantity = null;
  127. $item3->maxQuantity = null;
  128. $item3->isGuaranteed = false;
  129. $item3->extraData = null;
  130. $groupDto->items = [$item1, $item2, $item3];
  131. // 执行处理
  132. $result = IndependentProbabilityReward::process($groupDto);
  133. // 验证结果:随机模式应该限制返回的奖励项数量为2个
  134. $this->assertCount(2, $result, '随机模式应该限制返回的奖励项数量');
  135. }
  136. /**
  137. * 测试必中项优先级:必中项应该优先选择
  138. */
  139. public function testGuaranteedItemsPriority()
  140. {
  141. // 创建奖励组DTO(随机模式)
  142. $groupDto = new RewardGroupDto();
  143. $groupDto->id = 1;
  144. $groupDto->name = '测试奖励组';
  145. $groupDto->code = 'test_group';
  146. $groupDto->isRandom = true; // 随机模式
  147. $groupDto->randomCount = 2; // 限制返回2个奖励项
  148. $groupDto->rewardMode = 2; // 独立概率模式
  149. // 创建必中项
  150. $guaranteedItem = new RewardItemDto();
  151. $guaranteedItem->id = 1;
  152. $guaranteedItem->groupId = 1;
  153. $guaranteedItem->rewardType = 1;
  154. $guaranteedItem->targetId = 1001;
  155. $guaranteedItem->param1 = 0;
  156. $guaranteedItem->param2 = 0;
  157. $guaranteedItem->quantity = 1;
  158. $guaranteedItem->weight = 1.0;
  159. $guaranteedItem->probability = 0; // 概率无关紧要
  160. $guaranteedItem->minQuantity = null;
  161. $guaranteedItem->maxQuantity = null;
  162. $guaranteedItem->isGuaranteed = true; // 必中
  163. $guaranteedItem->extraData = null;
  164. // 创建普通项(高概率)
  165. $normalItem1 = new RewardItemDto();
  166. $normalItem1->id = 2;
  167. $normalItem1->groupId = 1;
  168. $normalItem1->rewardType = 1;
  169. $normalItem1->targetId = 1002;
  170. $normalItem1->param1 = 0;
  171. $normalItem1->param2 = 0;
  172. $normalItem1->quantity = 1;
  173. $normalItem1->weight = 1.0;
  174. $normalItem1->probability = 100.0; // 100%概率
  175. $normalItem1->minQuantity = null;
  176. $normalItem1->maxQuantity = null;
  177. $normalItem1->isGuaranteed = false;
  178. $normalItem1->extraData = null;
  179. $normalItem2 = new RewardItemDto();
  180. $normalItem2->id = 3;
  181. $normalItem2->groupId = 1;
  182. $normalItem2->rewardType = 1;
  183. $normalItem2->targetId = 1003;
  184. $normalItem2->param1 = 0;
  185. $normalItem2->param2 = 0;
  186. $normalItem2->quantity = 1;
  187. $normalItem2->weight = 1.0;
  188. $normalItem2->probability = 100.0; // 100%概率
  189. $normalItem2->minQuantity = null;
  190. $normalItem2->maxQuantity = null;
  191. $normalItem2->isGuaranteed = false;
  192. $normalItem2->extraData = null;
  193. $groupDto->items = [$guaranteedItem, $normalItem1, $normalItem2];
  194. // 执行处理
  195. $result = IndependentProbabilityReward::process($groupDto);
  196. // 验证结果
  197. $this->assertCount(2, $result, '应该返回2个奖励项');
  198. // 验证必中项在结果中
  199. $targetIds = array_map(function($item) {
  200. return $item->targetId;
  201. }, $result);
  202. $this->assertContains(1001, $targetIds, '必中项应该在结果中');
  203. }
  204. /**
  205. * 测试必中项数量超过限制:应该只返回限制数量的必中项
  206. */
  207. public function testTooManyGuaranteedItems()
  208. {
  209. // 创建奖励组DTO(随机模式)
  210. $groupDto = new RewardGroupDto();
  211. $groupDto->id = 1;
  212. $groupDto->name = '测试奖励组';
  213. $groupDto->code = 'test_group';
  214. $groupDto->isRandom = true; // 随机模式
  215. $groupDto->randomCount = 2; // 限制返回2个奖励项
  216. $groupDto->rewardMode = 2; // 独立概率模式
  217. // 创建3个必中项(超过限制数量)
  218. $guaranteedItem1 = new RewardItemDto();
  219. $guaranteedItem1->id = 1;
  220. $guaranteedItem1->groupId = 1;
  221. $guaranteedItem1->rewardType = 1;
  222. $guaranteedItem1->targetId = 1001;
  223. $guaranteedItem1->param1 = 0;
  224. $guaranteedItem1->param2 = 0;
  225. $guaranteedItem1->quantity = 1;
  226. $guaranteedItem1->weight = 1.0;
  227. $guaranteedItem1->probability = null;
  228. $guaranteedItem1->minQuantity = null;
  229. $guaranteedItem1->maxQuantity = null;
  230. $guaranteedItem1->isGuaranteed = true;
  231. $guaranteedItem1->extraData = null;
  232. $guaranteedItem2 = new RewardItemDto();
  233. $guaranteedItem2->id = 2;
  234. $guaranteedItem2->groupId = 1;
  235. $guaranteedItem2->rewardType = 1;
  236. $guaranteedItem2->targetId = 1002;
  237. $guaranteedItem2->param1 = 0;
  238. $guaranteedItem2->param2 = 0;
  239. $guaranteedItem2->quantity = 1;
  240. $guaranteedItem2->weight = 1.0;
  241. $guaranteedItem2->probability = null;
  242. $guaranteedItem2->minQuantity = null;
  243. $guaranteedItem2->maxQuantity = null;
  244. $guaranteedItem2->isGuaranteed = true;
  245. $guaranteedItem2->extraData = null;
  246. $guaranteedItem3 = new RewardItemDto();
  247. $guaranteedItem3->id = 3;
  248. $guaranteedItem3->groupId = 1;
  249. $guaranteedItem3->rewardType = 1;
  250. $guaranteedItem3->targetId = 1003;
  251. $guaranteedItem3->param1 = 0;
  252. $guaranteedItem3->param2 = 0;
  253. $guaranteedItem3->quantity = 1;
  254. $guaranteedItem3->weight = 1.0;
  255. $guaranteedItem3->probability = null;
  256. $guaranteedItem3->minQuantity = null;
  257. $guaranteedItem3->maxQuantity = null;
  258. $guaranteedItem3->isGuaranteed = true;
  259. $guaranteedItem3->extraData = null;
  260. $groupDto->items = [$guaranteedItem1, $guaranteedItem2, $guaranteedItem3];
  261. // 执行处理
  262. $result = IndependentProbabilityReward::process($groupDto);
  263. // 验证结果:应该只返回2个必中项(按限制数量)
  264. $this->assertCount(2, $result, '必中项数量超过限制时,应该只返回限制数量的必中项');
  265. }
  266. }