From 376b05a297022ea8bbd04def11ab27fcde54915c Mon Sep 17 00:00:00 2001 From: Hide_D Date: Sat, 23 Apr 2022 03:05:40 +0900 Subject: [PATCH] =?UTF-8?q?feat,wip:=20=EB=B2=A0=ED=8C=85=EC=9D=84=20ng=5F?= =?UTF-8?q?betting=20=EA=B8=B0=EB=B0=98=EC=9C=BC=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hwe/b_betting.php | 118 ++++++++++++++++++------------ hwe/func_tournament.php | 155 ++++++++++++++++++++++++---------------- hwe/j_betting.php | 55 +++++--------- hwe/sammo/Betting.php | 5 +- 4 files changed, 185 insertions(+), 148 deletions(-) diff --git a/hwe/b_betting.php b/hwe/b_betting.php index dae28212..478dbdea 100644 --- a/hwe/b_betting.php +++ b/hwe/b_betting.php @@ -16,11 +16,35 @@ TurnExecutionHelper::executeAllCommand(); $generalID = $session->generalID; -//NOTE: general_id만 빼기 귀찮음. -$myBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = %i', $generalID); -$myBet = array_splice($myBet, -16); -$globalBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = 0'); -$globalBet = array_splice($globalBet, -16); + +$bettingID = $gameStor->lastTournamentBettingID ?? 0; +if ($bettingID == 0) { + //TODO: 좋은 방법 없나? + die('아직 베팅이 열리지 않았습니다.'); +} +$betting = new Betting($bettingID); + + +$info = $betting->getInfo(); + +$myBet = []; +$globalBet = []; + +foreach ($db->queryAllLists( + 'SELECT general_id, user_id, amount, betting_type FROM ng_betting WHERE betting_id = %i', + $this->bettingID +) as [$betGeneralID, $userID, $amount, $bettingTypeKey]) { + $bettingKey = Json::decode($bettingTypeKey)[0]; + if ($betGeneralID == $generalID) { + $myBet[$bettingKey] = $amount; + } + + if (key_exists($bettingKey, $globalBet)) { + $globalBet[$bettingKey] += $amount; + } else { + $globalBet[$bettingKey] = $amount; + } +} $me = $db->queryFirstRow('SELECT no,tournament,con,turntime from general where owner=%i', $userID); @@ -293,9 +317,9 @@ if ($str3) { } $gen[$i] = $general['name']; if (array_key_exists($tp, $general)) { - $stat[$i] = $general[$tp]; + $stat[$i] = $general[$tp]; } else { - $stat[$i] = "-"; + $stat[$i] = "-"; } } for ($i = 0; $i < 8; $i++) { @@ -305,17 +329,17 @@ if ($str3) { echo "{$line[$i * 2]}{$cent[$i]}{$line[$i * 2 + 1]}"; } ?> - - - - - - - - - - - + + + + + + + + + + + @@ -323,29 +347,29 @@ if ($str3) { candidates as $key => $candidate) { + $keyMap[$candidate->aux['idx']] = $key; + } - for ($i = 0; $i < 16; $i++) { - if ($globalBet[$i] == 0) { - $bet[$i] = "∞"; - } else { - $bet[$i] = round($globalBetTotal / $globalBet[$i], 2); - } - } - - for ($i = 0; $i < 16; $i++) { - if (!is_numeric($bet[$i])) { - $gold[$i] = 0; - } else { - $gold[$i] = Util::round($myBet[$i] * $bet[$i]); - } - } + foreach ($globalBet as $key => $amount) { + if ($amount == 0) { + $bet[$key] = "∞"; + $gold[$key] = 0; + } else { + $rewardRatio = round($globalBetTotal / $amount, 2); + $bet[$key] = $rewardRatio; + $gold[$key] = $rewardRatio * ($myBet[$key] ?? 0); + } + } echo " "; - for ($i = 0; $i < 16; $i++) { - echo ""; + foreach (range(0, 15) as $i) { + $amount = $bet[$keyMap[$i]] ?? 0; + echo ""; } ?> @@ -369,8 +393,9 @@ if ($str3) { {$myBet[$i]}"; + foreach (range(0, 15) as $i) { + $amount = $myBet[$keyMap[$i]] ?? 0; + echo ""; } ?> @@ -394,8 +419,9 @@ if ($str3) { {$gold[$i]}"; + foreach (range(0, 15) as $i) { + $amount = $gold[$keyMap[$i]] ?? 0; + echo ""; } echo " @@ -406,10 +432,11 @@ if ($str3) { echo " "; - for ($i = 0; $i < 16; $i++) { + foreach (range(0, 15) as $i) { + $key = $keyMap[$i]; echo " "; - for ($i = 0; $i < 16; $i++) { + foreach (range(0, 15) as $i) { + $key = $keyMap[$i]; echo " - "; + "; } echo ""; diff --git a/hwe/func_tournament.php b/hwe/func_tournament.php index c67754c6..6b24a426 100644 --- a/hwe/func_tournament.php +++ b/hwe/func_tournament.php @@ -2,13 +2,14 @@ namespace sammo; +use sammo\DTO\BettingInfo; function processTournament() { $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); - $admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'tnmt_auto', 'tnmt_time']); + $admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'tnmt_auto', 'tnmt_time', 'lastTournamentBettingID']); $now = new \DateTime(); $offset = $now->getTimestamp() - (new \DateTime($admin['tnmt_time']))->getTimestamp(); @@ -90,9 +91,12 @@ function processTournament() final16set(); $tnmt = 6; $phase = 0; - startBetting(); + startBetting($type, $unit); break; case 6: //베팅중 + $bettingID = $admin['lastTournamentBettingID']; + $betting = new Betting($bettingID); + $betting->closeBetting(); $tnmt = 7; $phase = 0; break; @@ -164,23 +168,32 @@ function processTournament() $gameStor->tnmt_time = (new \DateTimeImmutable($admin['tnmt_time']))->add(new \DateInterval("PT{$second}S"))->format('Y-m-d H:i:s'); } -function getTournamentTerm(): ?int{ +function getTournamentTerm(): ?int +{ $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); $tnmt_auto = $gameStor->tnmt_auto; - if($tnmt_auto === null){ + if ($tnmt_auto === null) { $tnmt_auto = $gameStor->tnmt_trig; } - switch($tnmt_auto){ - case 0: return null; - case 1: return 12 * 60; - case 2: return 7 * 60; - case 3: return 3 * 60; - case 4: return 1 * 60; - case 5: return 30; - case 6: return 15; - case 7: return 5; + switch ($tnmt_auto) { + case 0: + return null; + case 1: + return 12 * 60; + case 2: + return 7 * 60; + case 3: + return 3 * 60; + case 4: + return 1 * 60; + case 5: + return 30; + case 6: + return 15; + case 7: + return 5; } return null; } @@ -189,16 +202,16 @@ function getTournamentTermText() { $term = getTournamentTerm(); - if($term === null){ + if ($term === null) { return '수동'; } - if($term % 60 === 0){ + if ($term % 60 === 0) { $termMin = intdiv($term, 60); return "경기당 {$termMin}분"; } - if($term > 60){ + if ($term > 60) { $termSec = $term % 60; $termMin = intdiv($term, 60); return "경기당 {$termMin}분 {$termSec}초"; @@ -268,7 +281,7 @@ function printRow($k, $npc, $name, $abil, $tgame, $win, $draw, $lose, $gd, $gl, $k += 1; if ($prmt > 0) { $name = "" . $name . ""; - } else if($npc > 0){ + } else if ($npc > 0) { $name = formatName($name, $npc); } echo ""; @@ -416,15 +429,64 @@ function startTournament($auto, $type) pushGlobalHistoryLog($history, $admin['year'], $admin['month']); } -function startBetting() +function startBetting($type, $unit) { $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); - [$year, $month, $startyear] = $gameStor->getValuesAsArray(['year', 'month', 'startyear']); + [$year, $month, $startyear, $turnterm] = $gameStor->getValuesAsArray(['year', 'month', 'startyear', 'turnterm']); pushGlobalHistoryLog([ "◆{$year}년 {$month}월:【대회】우승자를 예상하는 내기가 진행중입니다! 호사가의 참여를 기다립니다!" ], $year, $month); + [$typeText, $statName, $statKey] = [ + ['전력전', '종능', 'total'], + ['통솔전', '통솔', 'leadership'], + ['일기토', '무력', 'strength'], + ['설전', '지력', 'intel'], + ][$type]; + + $bettingID = Betting::genNextBettingID(); + + + //어차피 강제로 닫을 것이므로 크게 신경쓰지 않는다. + $monthGap = floor(Util::valueFit($unit * 60, 3600) / ($turnterm * 60)) + 1; + + $openYearMonth = Util::joinYearMonth($year, $month); + $closeYearMonth = $openYearMonth + $monthGap; + + /** @var \sammo\DTO\SelectItem[] */ + $candidates = []; + + $generalList = $db->query('SELECT no,npc,name,win,leadership,strength,intel,leadership+strength+intel as total from tournament where grp>=20 order by grp, grp_no LIMIT 16'); + foreach($generalList as $idx=>$general) { + if($general['no'] <= 0){ + continue; + } + $general['idx'] = $idx; + $candidates[$general['no']] = new \sammo\DTO\SelectItem( + $general['name'], + "{$statName}: {$general[$statKey]}", + $general + ); + } + $candidateCnt = count($candidates); + + Betting::openBetting(new BettingInfo( + id: $bettingID, + type: 'tournament', + name: $typeText, + finished: false, + selectCnt: 1, + reqInheritancePoint: false, + openYearMonth: $openYearMonth, + closeYearMonth: $closeYearMonth, + candidates: $candidates, + )); + + $betting = new Betting($bettingID); + + $gameStor->lastTournamentBettingID = $bettingID; + $betGold = Util::valueFit(floor((3 + $year - $startyear) * 0.334) * 10, 10); $npcList = $db->queryFirstColumn('SELECT no FROM general WHERE npc >= 2 AND gold >= (500 + %i)', $betGold); @@ -435,25 +497,13 @@ function startBetting() ]; foreach ($npcList as $npcID) { - $target = Util::randRangeInt(0, 15); + $target = Util::randRangeInt(0, $candidateCnt - 1); $betSum[$target] += $betGold; $npcBet[] = [$npcID, $target]; } - $db->update('general', [ - 'gold' => $db->sqleval('gold - %i', $betGold), - ], 'no IN %li', $npcList); foreach ($npcBet as [$npcID, $betTarget]) { - $targetKey = "bet{$betTarget}"; - $db->update('betting', [ - "bet{$betTarget}" => $db->sqleval('%b + %i', $targetKey, $betGold), - ], 'general_id = %i', $npcID); - } - foreach ($betSum as $betTarget => $betSumGold) { - $targetKey = "bet{$betTarget}"; - $db->update('betting', [ - "bet{$betTarget}" => $db->sqleval('%b + %i', $targetKey, $betSumGold), - ], 'general_id = 0'); + $betting->bet($npcID, null, [$betTarget], $betGold); } } @@ -514,19 +564,19 @@ function fillLowGenAll($tnmt_type) //자동신청하고, 돈 있고, 아직 참가 안한 장수 $freeJoinerCandidate = []; - foreach($db->query( + foreach ($db->query( 'SELECT no,npc,name,leadership,strength,intel,explevel,horse,weapon,book from general where tnmt=1 and tournament=0', - ) as $gen){ + ) as $gen) { $score = $scoringCandFunction($gen); - $freeJoinerCandidate[$gen['no']] = [$gen, $score**1.5]; + $freeJoinerCandidate[$gen['no']] = [$gen, $score ** 1.5]; } $joinersValues = []; $joinersIdx = []; - foreach(Util::range($toBeFilledCnt) as $_){ - if(!$freeJoinerCandidate){ + foreach (Util::range($toBeFilledCnt) as $_) { + if (!$freeJoinerCandidate) { break; } $general = Util::choiceRandomUsingWeightPair($freeJoinerCandidate); @@ -987,7 +1037,7 @@ function setGift($tnmt_type, $tnmt, $phase) $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); - $admin = $gameStor->getValues(['year', 'month', 'develcost']); + $admin = $gameStor->getValues(['year', 'month', 'develcost', 'lastTournamentBettingID']); $resultHelper = []; @@ -1143,31 +1193,10 @@ function setGift($tnmt_type, $tnmt, $phase) $generalObjList[$generalID]->increaseInheritancePoint('tournament', $general['inheritance_point']); } - //우승자 번호 - $winnerGrp = $resultHelper[$winner['no']]['grp']; - $winnerGrpNo = $resultHelper[$winner['no']]['grp_no']; - $winnerSlot = ($winnerGrp - 20) * 2 + $winnerGrpNo; - //당첨칸에 베팅한 사람들만 - $globalBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = 0'); - $globalBet = array_splice($globalBet, -16); - $globalBetTotal = array_sum($globalBet); - $rewardRate = round($globalBetTotal / max($globalBet[$winnerSlot], 1), 2); - - $betKey = "bet{$winnerSlot}"; - $gambleResult = Util::convertArrayToDict($db->query('SELECT general_id, %b as bet FROM betting WHERE %b > 0 AND general_id > 0', $betKey, $betKey), 'general_id'); - - foreach (General::createGeneralObjListFromDB(Util::squeezeFromArray($gambleResult, 'general_id'), ['gold', 'npc'], 1) as $gambler) { - $reward = Util::round($gambleResult[$gambler->getID()]['bet'] * $rewardRate); - $gambler->increaseVar('gold', $reward); - if (($gambler->getNPCType() == 0) || ($gambler->getNPCType() == 1 && $gambler->getRankVar('betgold', 0) > 0)) { - $gambler->increaseRankVar('betwingold', $reward); - $gambler->increaseRankVar('betwin', 1); - } - $rewardText = number_format($reward); - $gambler->getLogger()->pushGeneralActionLog("{$tp} 대회의 베팅 당첨으로 {$rewardText}의 금 획득!", ActionLogger::EVENT_PLAIN); - $gambler->applyDB($db); - } + $bettingID = $gameStor->lastTournamentBettingID; + $betting = new Betting($bettingID); + $betting->giveReward([$winner['no']]); } function setRefund() diff --git a/hwe/j_betting.php b/hwe/j_betting.php index af4d0d52..01268109 100644 --- a/hwe/j_betting.php +++ b/hwe/j_betting.php @@ -1,4 +1,5 @@ = 16 || $betGold < 10 || $betGold > 1000){ +if ($betGold < 10 || $betGold > 1000) { Json::die([ - 'result'=>false, - 'reason'=>'올바르지 않은 입력입니다' + 'result' => false, + 'reason' => '올바르지 않은 입력입니다' ]); } @@ -28,49 +29,27 @@ $gameStor = KVStorage::getStorage($db, 'game_env'); increaseRefresh("베팅", 1); $tournament = $gameStor->tournament; -if($tournament != 6) { +if ($tournament != 6) { Json::die([ - 'result'=>false, - 'reason'=>'베팅 기간이 아닙니다.' + 'result' => false, + 'reason' => '베팅 기간이 아닙니다.' ]); } -$myGold = $db->queryFirstField('SELECT gold FROM general WHERE no = %i', $generalID); -$bets = $db->queryFirstList('SELECT * FROM betting WHERE general_id = %i', $generalID); -$bets = array_splice($bets, -16); -$totalBet = array_sum($bets); -$oldBet = $bets[$betTarget]; -$targetKey = "bet{$betTarget}"; +$bettingID = $gameStor->lastTournamentBettingID; +$betting = new Betting($bettingID); -if($myGold - $betGold < 500){ +try { + $betting->bet($generalID, $userID, [$betTarget], $betGold); +} catch (\Exception $e) { Json::die([ - 'result'=>false, - 'reason'=>'여유 자금이 부족합니다.' + 'result' => false, + 'reason' => $e->getMessage() ]); } -if($betGold + $totalBet > 1000){ - Json::die([ - 'result'=>false, - 'reason'=>'베팅 허용 금액을 초과했습니다.' - ]); -} - -$db->update('betting', [ - $targetKey=>$db->sqleval('%b + %i', $targetKey, $betGold), -], 'general_id = %i', $generalID); -$db->update('general', [ - 'gold'=>$db->sqleval('gold - %i', $betGold), -], 'no = %i', $generalID); -$db->update('rank_data', [ - 'value'=>$db->sqleval('value + %i', $betGold) -], 'general_id = %i AND type = "betgold"', $generalID); -$db->update('betting', [ - $targetKey=>$db->sqleval('%b + %i', $targetKey, $betGold) -], 'general_id = 0'); - Json::die([ - 'result'=>true, - 'reason'=>'SUCCESS' -]); \ No newline at end of file + 'result' => true, + 'reason' => 'SUCCESS' +]); diff --git a/hwe/sammo/Betting.php b/hwe/sammo/Betting.php index 680f3365..def3584e 100644 --- a/hwe/sammo/Betting.php +++ b/hwe/sammo/Betting.php @@ -61,7 +61,7 @@ class Betting if (!$noValidate) { foreach($bettingType as $bettingKey){ if(!key_exists($bettingKey, $this->info->candidates)){ - throw new \InvalidArgumentException('올바르지 않은 값이 있습니다.(후보에 없음)' . print_r($bettingType, true)); + throw new \InvalidArgumentException('올바른 후보가 아닙니다.' . print_r($bettingType, true)); } } } @@ -123,6 +123,7 @@ class Betting throw new \RuntimeException('필요한 선택 수를 채우지 못했습니다.'); } + $resKey = $this->info->reqInheritancePoint?'유산포인트':'금'; $bettingTypeKey = $this->convertBettingKey($bettingType); $inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}"); @@ -130,7 +131,7 @@ class Betting $prevBetAmount = $db->queryFirstField('SELECT sum(amount) FROM ng_betting WHERE betting_id = %i AND user_id = %i', $this->bettingID, $userID) ?? 0; if ($prevBetAmount + $amount > 1000) { - throw new \RuntimeException((1000 - $prevBetAmount) . ' 포인트까지만 베팅 가능합니다.'); + throw new \RuntimeException((1000 - $prevBetAmount) . $resKey.'까지만 베팅 가능합니다.'); } if ($bettingInfo->reqInheritancePoint) {
{$bet[$i]}{$amount}
{$amount}
{$amount}
- @@ -425,9 +452,10 @@ if ($str3) {
$k$name$abil$tgame$win$draw$lose$gd$gl