123, * "avatar" => "http://2.png", * "nickname" => "xxx", * "level" => 1, * "value" => 23.3, * "border" => 1, * "vip" => 2, */ static public $robots = []; // N x 3 機器人 /** * 构建机器人信息。 * * 可重现:多次构建结果应一致 * * TODO:结果存入 redis * * @return boolean */ public static function build(): bool { self::_build_headers(); if ( count(self::$nicknames) != count(self::$headers) || count(self::$nicknames) != 64 ) { Log::error('nickname or headers has wrong numbers'); return false; } // clear self::$robots = []; for ($i = 0; $i < 64; $i++) { $uid = self::$ROBOT_BASE_ID + $i; self::$robots[$uid] = [ 'uid' => $uid, 'avatar' => self::$headers[$i], 'nickname' => self::$nicknames[$i], 'level' => tw_rand(1, 4), 'value' => 0, 'border' => 0, 'vip' => 0, ]; } // for return true; } /** * 如果没有操作七牛中文件,不要修改本函数。 * * 本函数不是用于生成,而是对已有资源的描述/信息提取。 */ protected static function _build_headers() { // clear self::$headers = []; for ($i = 1; $i <= 64; $i++) { self::$headers[] = self::$HEADER_BASE_URL . $i . '.png'; } } /** * 把成員 robots 寫入 redis */ public static function to_redis() { if (count(self::$robots) <= 0) { self::build(); } if (count(self::$robots) <= 0) { errlog('build robots failed?'); return; } foreach (self::$robots as $robot) { (new RobotsInfoRds)->hset(false, $robot['uid'], $robot); } } /** * 加载 redis 数据到 self::$robots */ public static function from_redis() { $robots = (new RobotsInfoRds)->hget_all(false); foreach ($robots as $k => $v) { $robots[$k] = json_decode($v, true); } self::$robots = $robots; } /** * 下單,隨機選擇若幹機器人,模擬下單(增加 value 值) * * 排行時,簡單取出所有機器人數據,內存排序即可 */ public static function order() { if (count(self::$robots) <= 0) { self::from_redis(); } if (count(self::$robots) <= 0) { errlog("load robots from redis failed."); return; } // 下单人数 $robot_num = tw_rand(0, count(self::$robots) / 2); $min = sys_config_int('leader_robot_earn_min'); $max = sys_config_int('leader_robot_earn_max'); if ($min > $max) { // swap $t = $min; $min = $max; $max = $t; } debuglog("there will be $robot_num robot making order. will earn: min=$min,max=$max"); for ($i = 0; $i < $robot_num; $i++) { // 下单人UID $index = tw_rand(0, count(self::$robots)); $uid = self::$ROBOT_BASE_ID + $index; // 获利金额 $value = tw_divf(tw_rand($min * 100, $max * 100), 100.0, 2); // get - update - set $srobot = (new RobotsInfoRds)->hget(false, $uid); if (!$srobot) { console::log('not found: uid=' . $uid); } $robot = json_decode($srobot, true); $robot['value'] = tw_addf($robot['value'], $value, 2); (new RobotsInfoRds)->hset(false, $uid, $robot); debuglog("robot $uid order win $value"); } } /** * 重置所有機器人 value 字段 */ public static function reset() { return self::build(); } /** * 根據 value 字段的前 n 個 */ public static function first_n_by_value(int $n): array { $robots = (new RobotsInfoRds)->hget_all(false); foreach ($robots as $uid => $robot) { $robots[$uid] = json_decode($robot, true); } usort($robots, function ($l, $r) { return $r['value'] <=> $l['value']; }); return array_slice($robots, 0, $n); } }