feat,wip: 베팅을 ng_betting 기반으로 변경

This commit is contained in:
2022-04-23 03:05:40 +09:00
parent 830e1efefe
commit 376b05a297
4 changed files with 185 additions and 148 deletions
+73 -45
View File
@@ -16,11 +16,35 @@ TurnExecutionHelper::executeAllCommand();
$generalID = $session->generalID; $generalID = $session->generalID;
//NOTE: general_id만 빼기 귀찮음.
$myBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = %i', $generalID); $bettingID = $gameStor->lastTournamentBettingID ?? 0;
$myBet = array_splice($myBet, -16); if ($bettingID == 0) {
$globalBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = 0'); //TODO: 좋은 방법 없나?
$globalBet = array_splice($globalBet, -16); 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); $me = $db->queryFirstRow('SELECT no,tournament,con,turntime from general where owner=%i', $userID);
@@ -293,9 +317,9 @@ if ($str3) {
} }
$gen[$i] = $general['name']; $gen[$i] = $general['name'];
if (array_key_exists($tp, $general)) { if (array_key_exists($tp, $general)) {
$stat[$i] = $general[$tp]; $stat[$i] = $general[$tp];
} else { } else {
$stat[$i] = "-"; $stat[$i] = "-";
} }
} }
for ($i = 0; $i < 8; $i++) { for ($i = 0; $i < 8; $i++) {
@@ -305,17 +329,17 @@ if ($str3) {
echo "<td colspan=2>{$line[$i * 2]}{$cent[$i]}{$line[$i * 2 + 1]}</td>"; echo "<td colspan=2>{$line[$i * 2]}{$cent[$i]}{$line[$i * 2 + 1]}</td>";
} }
?> ?>
</tr> </tr>
<tr align=center> <tr align=center>
<?php for ($i = 0; $i < 16; $i++) { ?> <?php for ($i = 0; $i < 16; $i++) { ?>
<td width=70><?=$gen[$i]?></td> <td width=70><?= $gen[$i] ?></td>
<?php } ?> <?php } ?>
</tr> </tr>
<tr align=center> <tr align=center>
<?php for ($i = 0; $i < 16; $i++) { ?> <?php for ($i = 0; $i < 16; $i++) { ?>
<td width=70 style="font-size: 14px"><?=$stat[$i]?></td> <td width=70 style="font-size: 14px"><?= $stat[$i] ?></td>
<?php } ?> <?php } ?>
</tr> </tr>
</table> </table>
<table align=center width=1120 style="table-layout: fixed" class='tb_layout bg0'> <table align=center width=1120 style="table-layout: fixed" class='tb_layout bg0'>
<tr align=center> <tr align=center>
@@ -323,29 +347,29 @@ if ($str3) {
</tr> </tr>
<?php <?php
$bet = []; $bet = [];
$gold = []; $gold = [];
$keyMap = [];
foreach ($info->candidates as $key => $candidate) {
$keyMap[$candidate->aux['idx']] = $key;
}
for ($i = 0; $i < 16; $i++) { foreach ($globalBet as $key => $amount) {
if ($globalBet[$i] == 0) { if ($amount == 0) {
$bet[$i] = "∞"; $bet[$key] = "∞";
} else { $gold[$key] = 0;
$bet[$i] = round($globalBetTotal / $globalBet[$i], 2); } else {
} $rewardRatio = round($globalBetTotal / $amount, 2);
} $bet[$key] = $rewardRatio;
$gold[$key] = $rewardRatio * ($myBet[$key] ?? 0);
for ($i = 0; $i < 16; $i++) { }
if (!is_numeric($bet[$i])) { }
$gold[$i] = 0;
} else {
$gold[$i] = Util::round($myBet[$i] * $bet[$i]);
}
}
echo " echo "
<tr align=center>"; <tr align=center>";
for ($i = 0; $i < 16; $i++) { foreach (range(0, 15) as $i) {
echo "<td width=70><font color=skyblue>{$bet[$i]}</font></td>"; $amount = $bet[$keyMap[$i]] ?? 0;
echo "<td width=70><font color=skyblue>{$amount}</font></td>";
} }
?> ?>
</tr> </tr>
@@ -369,8 +393,9 @@ if ($str3) {
</tr> </tr>
<tr align=center> <tr align=center>
<?php <?php
for ($i = 0; $i < 16; $i++) { foreach (range(0, 15) as $i) {
echo "<td><font color=orange>{$myBet[$i]}</font></td>"; $amount = $myBet[$keyMap[$i]] ?? 0;
echo "<td><font color=orange>{$amount}</font></td>";
} }
?> ?>
</tr> </tr>
@@ -394,8 +419,9 @@ if ($str3) {
</tr> </tr>
<tr align=center> <tr align=center>
<?php <?php
for ($i = 0; $i < 16; $i++) { foreach (range(0, 15) as $i) {
echo "<td><font color=cyan>{$gold[$i]}</font></td>"; $amount = $gold[$keyMap[$i]] ?? 0;
echo "<td><font color=cyan>{$amount}</font></td>";
} }
echo " echo "
@@ -406,10 +432,11 @@ if ($str3) {
echo " echo "
<tr align=center>"; <tr align=center>";
for ($i = 0; $i < 16; $i++) { foreach (range(0, 15) as $i) {
$key = $keyMap[$i];
echo " echo "
<td> <td>
<select size=1 id='target_{$i}' style=color:white;background-color:black;> <select size=1 id='target_{$key}' style=color:white;background-color:black;>
<option style=color:white; value=10>금10</option> <option style=color:white; value=10>금10</option>
<option style=color:white; value=20>금20</option> <option style=color:white; value=20>금20</option>
<option style=color:white; value=50>금50</option> <option style=color:white; value=50>금50</option>
@@ -425,9 +452,10 @@ if ($str3) {
</tr> </tr>
<tr align=center>"; <tr align=center>";
for ($i = 0; $i < 16; $i++) { foreach (range(0, 15) as $i) {
$key = $keyMap[$i];
echo " echo "
<td><input type=button class='submitBtn' data-target='{$i}' value=베팅! style=width:100%;color:white;background-color:black;></td>"; <td><input type=button class='submitBtn' data-target='{$key}' value=베팅! style=width:100%;color:white;background-color:black;></td>";
} }
echo "</tr>"; echo "</tr>";
+92 -63
View File
@@ -2,13 +2,14 @@
namespace sammo; namespace sammo;
use sammo\DTO\BettingInfo;
function processTournament() function processTournament()
{ {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $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(); $now = new \DateTime();
$offset = $now->getTimestamp() - (new \DateTime($admin['tnmt_time']))->getTimestamp(); $offset = $now->getTimestamp() - (new \DateTime($admin['tnmt_time']))->getTimestamp();
@@ -90,9 +91,12 @@ function processTournament()
final16set(); final16set();
$tnmt = 6; $tnmt = 6;
$phase = 0; $phase = 0;
startBetting(); startBetting($type, $unit);
break; break;
case 6: //베팅중 case 6: //베팅중
$bettingID = $admin['lastTournamentBettingID'];
$betting = new Betting($bettingID);
$betting->closeBetting();
$tnmt = 7; $tnmt = 7;
$phase = 0; $phase = 0;
break; 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'); $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(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$tnmt_auto = $gameStor->tnmt_auto; $tnmt_auto = $gameStor->tnmt_auto;
if($tnmt_auto === null){ if ($tnmt_auto === null) {
$tnmt_auto = $gameStor->tnmt_trig; $tnmt_auto = $gameStor->tnmt_trig;
} }
switch($tnmt_auto){ switch ($tnmt_auto) {
case 0: return null; case 0:
case 1: return 12 * 60; return null;
case 2: return 7 * 60; case 1:
case 3: return 3 * 60; return 12 * 60;
case 4: return 1 * 60; case 2:
case 5: return 30; return 7 * 60;
case 6: return 15; case 3:
case 7: return 5; return 3 * 60;
case 4:
return 1 * 60;
case 5:
return 30;
case 6:
return 15;
case 7:
return 5;
} }
return null; return null;
} }
@@ -189,16 +202,16 @@ function getTournamentTermText()
{ {
$term = getTournamentTerm(); $term = getTournamentTerm();
if($term === null){ if ($term === null) {
return '수동'; return '수동';
} }
if($term % 60 === 0){ if ($term % 60 === 0) {
$termMin = intdiv($term, 60); $termMin = intdiv($term, 60);
return "경기당 {$termMin}"; return "경기당 {$termMin}";
} }
if($term > 60){ if ($term > 60) {
$termSec = $term % 60; $termSec = $term % 60;
$termMin = intdiv($term, 60); $termMin = intdiv($term, 60);
return "경기당 {$termMin}{$termSec}"; return "경기당 {$termMin}{$termSec}";
@@ -268,7 +281,7 @@ function printRow($k, $npc, $name, $abil, $tgame, $win, $draw, $lose, $gd, $gl,
$k += 1; $k += 1;
if ($prmt > 0) { if ($prmt > 0) {
$name = "<font color=orange>" . $name . "</font>"; $name = "<font color=orange>" . $name . "</font>";
} else if($npc > 0){ } else if ($npc > 0) {
$name = formatName($name, $npc); $name = formatName($name, $npc);
} }
echo "<tr align=center><td class='bg2'>$k</td><td style='font-size:80%;'>$name</td><td>$abil</td><td>$tgame</td><td>$win</td><td>$draw</td><td>$lose</td><td>$gd</td><td>$gl</td></tr>"; echo "<tr align=center><td class='bg2'>$k</td><td style='font-size:80%;'>$name</td><td>$abil</td><td>$tgame</td><td>$win</td><td>$draw</td><td>$lose</td><td>$gd</td><td>$gl</td></tr>";
@@ -416,15 +429,64 @@ function startTournament($auto, $type)
pushGlobalHistoryLog($history, $admin['year'], $admin['month']); pushGlobalHistoryLog($history, $admin['year'], $admin['month']);
} }
function startBetting() function startBetting($type, $unit)
{ {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $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([ pushGlobalHistoryLog([
"<S>◆</>{$year}{$month}월:<B><b>【대회】</b></>우승자를 예상하는 <C>내기</>가 진행중입니다! 호사가의 참여를 기다립니다!" "<S>◆</>{$year}{$month}월:<B><b>【대회】</b></>우승자를 예상하는 <C>내기</>가 진행중입니다! 호사가의 참여를 기다립니다!"
], $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); $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); $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) { foreach ($npcList as $npcID) {
$target = Util::randRangeInt(0, 15); $target = Util::randRangeInt(0, $candidateCnt - 1);
$betSum[$target] += $betGold; $betSum[$target] += $betGold;
$npcBet[] = [$npcID, $target]; $npcBet[] = [$npcID, $target];
} }
$db->update('general', [
'gold' => $db->sqleval('gold - %i', $betGold),
], 'no IN %li', $npcList);
foreach ($npcBet as [$npcID, $betTarget]) { foreach ($npcBet as [$npcID, $betTarget]) {
$targetKey = "bet{$betTarget}"; $betting->bet($npcID, null, [$betTarget], $betGold);
$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');
} }
} }
@@ -514,19 +564,19 @@ function fillLowGenAll($tnmt_type)
//자동신청하고, 돈 있고, 아직 참가 안한 장수 //자동신청하고, 돈 있고, 아직 참가 안한 장수
$freeJoinerCandidate = []; $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', '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); $score = $scoringCandFunction($gen);
$freeJoinerCandidate[$gen['no']] = [$gen, $score**1.5]; $freeJoinerCandidate[$gen['no']] = [$gen, $score ** 1.5];
} }
$joinersValues = []; $joinersValues = [];
$joinersIdx = []; $joinersIdx = [];
foreach(Util::range($toBeFilledCnt) as $_){ foreach (Util::range($toBeFilledCnt) as $_) {
if(!$freeJoinerCandidate){ if (!$freeJoinerCandidate) {
break; break;
} }
$general = Util::choiceRandomUsingWeightPair($freeJoinerCandidate); $general = Util::choiceRandomUsingWeightPair($freeJoinerCandidate);
@@ -987,7 +1037,7 @@ function setGift($tnmt_type, $tnmt, $phase)
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['year', 'month', 'develcost']); $admin = $gameStor->getValues(['year', 'month', 'develcost', 'lastTournamentBettingID']);
$resultHelper = []; $resultHelper = [];
@@ -1143,31 +1193,10 @@ function setGift($tnmt_type, $tnmt, $phase)
$generalObjList[$generalID]->increaseInheritancePoint('tournament', $general['inheritance_point']); $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'); $bettingID = $gameStor->lastTournamentBettingID;
$globalBet = array_splice($globalBet, -16); $betting = new Betting($bettingID);
$globalBetTotal = array_sum($globalBet); $betting->giveReward([$winner['no']]);
$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("<C>{$tp}</> 대회의 베팅 당첨으로 <C>{$rewardText}</>의 <S>금</> 획득!", ActionLogger::EVENT_PLAIN);
$gambler->applyDB($db);
}
} }
function setRefund() function setRefund()
+17 -38
View File
@@ -1,4 +1,5 @@
<?php <?php
namespace sammo; namespace sammo;
include "lib.php"; include "lib.php";
@@ -10,10 +11,10 @@ $betTarget = Util::getPost('target', 'int', -1);
$betGold = Util::getPost('amount', 'int', 0); $betGold = Util::getPost('amount', 'int', 0);
if($betTarget < 0 || $betTarget >= 16 || $betGold < 10 || $betGold > 1000){ if ($betGold < 10 || $betGold > 1000) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'올바르지 않은 입력입니다' 'reason' => '올바르지 않은 입력입니다'
]); ]);
} }
@@ -28,49 +29,27 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("베팅", 1); increaseRefresh("베팅", 1);
$tournament = $gameStor->tournament; $tournament = $gameStor->tournament;
if($tournament != 6) { if ($tournament != 6) {
Json::die([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'베팅 기간이 아닙니다.' '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([ Json::die([
'result'=>false, 'result' => false,
'reason'=>'여유 자금이 부족합니다.' '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([ Json::die([
'result'=>true, 'result' => true,
'reason'=>'SUCCESS' 'reason' => 'SUCCESS'
]); ]);
+3 -2
View File
@@ -61,7 +61,7 @@ class Betting
if (!$noValidate) { if (!$noValidate) {
foreach($bettingType as $bettingKey){ foreach($bettingType as $bettingKey){
if(!key_exists($bettingKey, $this->info->candidates)){ 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('필요한 선택 수를 채우지 못했습니다.'); throw new \RuntimeException('필요한 선택 수를 채우지 못했습니다.');
} }
$resKey = $this->info->reqInheritancePoint?'유산포인트':'금';
$bettingTypeKey = $this->convertBettingKey($bettingType); $bettingTypeKey = $this->convertBettingKey($bettingType);
$inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}"); $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; $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) { if ($prevBetAmount + $amount > 1000) {
throw new \RuntimeException((1000 - $prevBetAmount) . ' 포인트까지만 베팅 가능합니다.'); throw new \RuntimeException((1000 - $prevBetAmount) . $resKey.'까지만 베팅 가능합니다.');
} }
if ($bettingInfo->reqInheritancePoint) { if ($bettingInfo->reqInheritancePoint) {