# Project scene

Realize the function of a big turntable lottery, and can customize the awards in the background, the probability of winning each award, the number of awards, the maximum number of lottery draws on the day, etc.

# 1. Design ideas

Here is a simple sharing of ideas:

## 1. Probability of winning prizes

The sum of the odds of winning all prizes participating in the lottery is 1

## 2. Rules of the lottery

First of all, it is necessary to clarify how to win the lottery?

[Generally speaking, a random number] is generated , and then the random number is compared with the winning probability of the prize, and if it is less than the winning probability, the prize is won.

However, if the probability of each prize or several prizes is the same, the above method will result in a situation where the same prize is won every time the prize is drawn.

Therefore, we adopt the method of accumulating the probability of winning, as shown in the figure:

lottery rules:

- Get the list of prizes for the game, in ascending order according to the probability of winning (no sorting required)
- The probabilities in the prize list are cumulative probabilities, which need to be accumulated in the order in which they were added to the list
- Generate a 0-1 random number and compare it with the set prize probability cyclically
- If the random number is less than the probability value, the prize will be drawn

## 3. Prize distribution

Each type of prize distribution rules are different. Here, you can use the characteristics of Java polymorphism to create a factory class, and use different implementation classes to implement the winning processing logic of different types of prizes.

Here, because of the microservices to be used, the corresponding service methods are called directly through feign

# Second, the database design

## 1. Turntable game table

Store carousel lottery information

field | describe |
---|---|

id(varchar) | primary key id |

name(varchar) | Event name |

start_time(datetime) | Starting time |

end_time(datetime) | End Time |

description(varchar) | describe |

day_limit(int) | Limit number of times for a single person on the day 0: means no limit |

single_limit(int) | The total number of times for a single person is limited to 0: means no limit |

state(int) | Active state, 1 on 2 off |

## 2. Prize Table

Store raffle prize information

field | describe |
---|---|

id(varchar) | primary key id |

game_id(varchar) | game id |

prize_type(int) | Prize Type (1 Coupon, 2 Items, 3 Points, 4 Thank You for Participating) |

prize_name(varchar) | Prize name |

prize_id(varchar) | prize id |

prize_value(int) | Prize value (quantity) |

ratio(double) | odds of winning |

current_num(int) | current hit |

max_num(int) | The maximum number of winnings is 0: means no limit |

## 3. Lottery record sheet

Store lottery record information

field | describe |
---|---|

id(varchar) | primary key id |

game_id(varchar) | game id |

user_id(datetime) | userid |

user_name(datetime) | username |

draw_time(varchar) | Draw time |

is_hit(int) | Whether winning the lottery 0: not winning the lottery 1: winning the lottery |

hit_prize(varchar) | winning prize |

is_send(int) | Whether to issue 1 not issued, 2 issued 3 issued failed |

send_msg(text) | release result |

# 3. Business logic

## 1. Provide an interface

(1) Obtain the turntable game

(2) Obtain the remaining times of the user’s lottery record

(3) Participate in the turntable lottery

(4) The lottery record

## 2. Core code

lottery logic code

// Get the list of prize information List<Entity> prizeList = service.list(); // The probability in the prize list is the cumulative probability // It needs to be accumulated in the order of adding to the list, for the convenience of data processing, the winning probability*100 double sum = 0 ; List<Entity> newList = new ArrayList<>(); for (int i = 0; i < prizeList.size(); i++) { Entity entity = prizeList.get(i); Entity newEntity = new Entity(); BeanUtils.copyProperties(entity, newEntity); sum = sum + (entity.getRatio() * 100 ); newEntity.setRatio(sum); newList.add(newEntity); } // Generate a random number Random random = new Random(); Double userSelect = random.nextDouble() * 10000 ; for (Entity prize : prizeList) { // If the random number is less than the odds of winning, the prize will be won if (userSelect < prize.getRatio()) { // The maximum number of winnings (0: means no Limit the number of times) int maxNum = prize.getMaxNum(); // Determine the current and maximum winning number of game prizes if (maxNum != 0 && maxNum <= prize.getCurrentNum()) { // If it exceeds the maximum winning number, it will not win break ; } else { return prize; } } } List<Entity> prize = prizeList.stream().filter(item -> item.getPrizeType() == 4).collect(Collectors.toList()); if (prize.size() > 0) { return prize.get(0); } return null;

Lottery distribution: Call the corresponding service to distribute the prizes according to the type of prizes drawn; (for example, if the coupons are drawn, the service that invokes the coupons will be issued)

int type = prize.getPrizeType(); try { switch (type) { // issue coupon case 1 : ApiResult res = couponFeign.sendCouponToUser(userId, prize.getPrizeId(), prize.getPrizeValue()); // Other business processing break ; // Distributing goods case 2 : break ; // Distributing points case 3 : ApiResult res2 = pointFeign.addPointToUser(gameId, userId, prize.getPrizeValue()); // Other business processing break ; // Thank you for participating in case 4 : break ; default : break ; } } catch (Exception e) { e.printStackTrace(); }

RLock lock = redisson.getLock( "turntable:" + gameId); try { // specify the timeout time if ( lock .tryLock( 10 , TimeUnit.SECONDS)) { // lottery business processing } } finally { lock.unlock(); }

It is not easy to create, attention and likes are the greatest encouragement to the author. Please leave a comment below.

Welcome to the WeChat public account: the key refers to JAVA, regularly share Java knowledge, learn together, and grow together.