Skip to content

Instantly share code, notes, and snippets.

@motsu0
Created February 23, 2023 02:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save motsu0/c42069f627a2c44f2c60416a6d4cb8de to your computer and use it in GitHub Desktop.
Save motsu0/c42069f627a2c44f2c60416a6d4cb8de to your computer and use it in GitHub Desktop.
.block{
margin-bottom: 40px;
}
.bt-common{
padding: 4px 8px;
cursor: pointer;
}
/* */
.area-table{
overflow-x: auto;
}
.table{
width: 100%;
border-collapse: collapse;
}
.cell{
padding: 4px;
border: 1px solid #777;
word-break: keep-all;
}
th.cell{
font-weight: normal;
background-color: #C5CAE9;
}
/* */
.settings__row{
padding: 12px;
border: 1px dashed #777;
}
.settings__row:nth-of-type(n+2){
border-top: none;
}
#input-rate{
width: 60px;
height: 2em;
padding-left: 8px;
text-align: center;
}
#sel-odds-round{
height: 2em;
cursor: pointer;
}
/* */
.area-sum{
text-align: right;
}
.result-unit{
background-color: #E8EAF6;
cursor: pointer;
}
.result__amount,.result__odds{
text-align: right;
}
/* */
.register-unit{
background-color: #E8EAF6;
}
.register__input{
display: block;
box-sizing: border-box;
width: 100%;
height: 2em;
padding-left: 8px;
border: none;
}
#bt-register{
display: block;
margin: 12px auto;
}
/* */
.bet-unit{
background-color: #E8EAF6;
}
.bet__amount,.bet__refund{
text-align: right;
}
.bt-bet-delete{
display: block;
margin: 0 auto;
}
/* */
.s-win{
background-color: #FFECB3;
}
.t-bold{
font-weight: bold;
}
<h3>設定</h3>
<div class="block">
<div class="settings">
<div class="settings__row">
払戻率:<input type="number" id="input-rate" value="80" min="0">%
</div>
<div class="settings__row">
払戻金計算方法:<select id="sel-odds-round">
<option value="normal">オッズ(丸め後)で計算</option>
<option value="strict">オッズ(丸め前)で計算</option>
</select>
</div>
</div>
</div>
<h3>オッズ表</h3>
<div class="block">
<div class="area-table">
<table class="table table--result">
<thead>
<tr>
<th class="cell">賭け対象</th>
<th class="cell">賭金総額</th>
<th class="cell">オッズ</th>
</tr>
</thead>
<tbody id="result__tbody"></tbody>
</table>
</div>
<div class="area-sum">
全賭金総額:<span id="sum-amount">0</span>
</div>
</div>
<h3>ベット登録</h3>
<div class="block">
<div class="area-table">
<table class="table table--register">
<thead>
<tr>
<th class="cell">参加者名</th>
<th class="cell">賭け対象</th>
<th class="cell">賭金</th>
</tr>
</thead>
<tbody id="register__tbody">
<tr class="register-unit">
<td class="cell">
<input type="text" id="input-name" class="register__input" placeholder="参加者名" autocomplete="on" list="datalist-name">
<datalist id="datalist-name"></datalist>
</td>
<td class="cell">
<input type="text" id="input-player" class="register__input" placeholder="賭け対象" autocomplete="on" list="datalist-player">
<datalist id="datalist-player"></datalist>
</td>
<td class="cell">
<input type="number" id="input-amount" class="register__input" placeholder="123456" min="1">
</td>
</tr>
</tbody>
</table>
</div>
<button id="bt-register" class="bt-common">ベット</button>
</div>
<h3>ベット一覧</h3>
<div class="block">
<div class="area-table">
<table class="table table--bet">
<thead>
<th class="cell">参加者名</th>
<th class="cell">賭け対象</th>
<th class="cell">賭金</th>
<th class="cell">払戻金</th>
<th class="cell">操作</th>
</thead>
<tbody id="bet__tbody"></tbody>
</table>
</div>
</div>
const dialog = new simpleDialog();
const el_input_rate = document.getElementById('input-rate');
const el_sel_odds_round = document.getElementById('sel-odds-round');
const el_result__tbody = document.getElementById('result__tbody');
const els_result_unit = document.getElementsByClassName('result-unit');
const els_result__player = document.getElementsByClassName('result__player');
const els_result__amount = document.getElementsByClassName('result__amount');
const els_result__odds = document.getElementsByClassName('result__odds');
const el_sum_amount = document.getElementById('sum-amount');
const el_input_name = document.getElementById('input-name');
const el_input_player = document.getElementById('input-player');
const el_datalist_name = document.getElementById('datalist-name');
const el_datalist_player = document.getElementById('datalist-player');
const el_input_amount = document.getElementById('input-amount');
const bt_register = document.getElementById('bt-register');
const el_bet__tbody = document.getElementById('bet__tbody');
const els_bet_unit= document.getElementsByClassName('bet-unit');
const els_bet_unit_win= document.getElementsByClassName('bet-unit--win');
const els_bet__player = document.getElementsByClassName('bet__player');
const els_bet__amount = document.getElementsByClassName('bet__amount');
const els_bet__refund = document.getElementsByClassName('bet__refund');
const els_s_win = document.getElementsByClassName('s-win');
let list_name = [];
let list_player = [];
let obj_option_name = {};
let obj_option_player = {};
init();
function init(){
bt_register.addEventListener('click',betRegister);
el_input_rate.addEventListener('input',calcOdds);
el_sel_odds_round.addEventListener('change',calcOdds);
}
function betRegister(){
//例外処理
const array_error = [];
if(el_input_name.value===''){
array_error.push('「参加者名」');
}
if(el_input_player.value===''){
array_error.push('「賭け対象」');
}
if(el_input_amount.value===''){
array_error.push('「賭金」');
}
if(array_error.length>0){
dialog.setStrHead('入力値エラー');
dialog.setStrBody(array_error.join('')+'を入力して下さい。');
dialog.display();
return;
}
const amount = Number(el_input_amount.value);
if(!Number.isInteger(amount)){
dialog.setStrHead('入力値エラー');
dialog.setStrBody('賭金は整数値を入力して下さい。');
dialog.display();
return;
}
if(amount<1){
dialog.setStrHead('入力値エラー');
dialog.setStrBody('賭金は1以上の整数を入力して下さい。');
dialog.display();
return;
}
//登録処理
const name = el_input_name.value;
const player = el_input_player.value;
//初めてのname
if(!list_name.includes(name)){
list_name.push(name);
const el_option = document.createElement('option');
el_option.value = name;
el_option.textContent = name;
el_datalist_name.appendChild(el_option);
obj_option_name[name] = el_option;
}
//初めてのplayer
if(!list_player.includes(player)){
list_player.push(player);
const el_option = document.createElement('option');
el_option.value = player;
el_option.textContent = player;
el_datalist_player.appendChild(el_option);
obj_option_player[player] = el_option;
//
const el_tr_result = document.createElement('tr');
el_tr_result.classList.add('result-unit');
el_tr_result.addEventListener('click',()=>{
selectWin(el_tr_result, player);
});
el_tr_result.dataset.player = player;
const el_td_result_player = document.createElement('td');
el_td_result_player.classList.add('cell');
el_td_result_player.classList.add('result__player');
el_td_result_player.textContent = player;
el_tr_result.appendChild(el_td_result_player);
const el_td_result_amount = document.createElement('td');
el_td_result_amount.classList.add('cell');
el_td_result_amount.classList.add('result__amount');
el_tr_result.appendChild(el_td_result_amount);
const el_td_result_odds = document.createElement('td');
el_td_result_odds.classList.add('cell');
el_td_result_odds.classList.add('result__odds');
el_tr_result.appendChild(el_td_result_odds);
el_result__tbody.appendChild(el_tr_result);
}
//DOM処理
const el_tr_bet = document.createElement('tr');
el_tr_bet.classList.add('bet-unit');
//
const el_td_bet_name = document.createElement('td');
el_td_bet_name.classList.add('cell');
el_td_bet_name.classList.add('bet__name');
el_td_bet_name.textContent = name;
el_tr_bet.appendChild(el_td_bet_name);
const el_td_bet_player = document.createElement('td');
el_td_bet_player.classList.add('cell');
el_td_bet_player.classList.add('bet__player');
el_td_bet_player.textContent = player;
el_tr_bet.appendChild(el_td_bet_player);
const el_td_bet_amount = document.createElement('td');
el_td_bet_amount.classList.add('cell');
el_td_bet_amount.classList.add('bet__amount');
el_td_bet_amount.textContent = amount;
el_tr_bet.appendChild(el_td_bet_amount);
const el_td_bet_refund = document.createElement('td');
el_td_bet_refund.classList.add('cell');
el_td_bet_refund.classList.add('bet__refund');
el_tr_bet.appendChild(el_td_bet_refund);
const el_td_bet_delete = document.createElement('td');
el_td_bet_delete.classList.add('cell');
const bt_bet_delete = document.createElement('button');
bt_bet_delete.classList.add('bt-bet-delete');
bt_bet_delete.classList.add('bt-common');
bt_bet_delete.addEventListener('click',()=>{betDelete(el_tr_bet)});
bt_bet_delete.textContent = '取消';
el_td_bet_delete.appendChild(bt_bet_delete);
el_tr_bet.appendChild(el_td_bet_delete);
//
el_tr_bet.dataset.name = name;
el_tr_bet.dataset.player = player;
el_tr_bet.dataset.amount = amount;
el_bet__tbody.appendChild(el_tr_bet);
//登録フォーム初期化
el_input_name.value = '';
el_input_player.value = '';
el_input_amount.value = '';
//ハイライト初期化
[...els_s_win].forEach(el=>{
el.classList.remove('s-win');
});
//
betSort();
calcOdds();
}
function betSort(){
const list_element = [...els_bet_unit].sort((a,b)=>{
if(a.dataset.name !== b.dataset.name){
return (a.dataset.name > b.dataset.name) ? 1 : -1;
}
if(a.dataset.player !== b.dataset.player){
return (a.dataset.player > b.dataset.player) ? 1 : -1;
}
if(a.dataset.amount !== b.dataset.amount){
return (a.dataset.amount > b.dataset.amount) ? 1 : -1;
}
return 1;
});
list_element.forEach(el=>{
el_bet__tbody.appendChild(el);
});
}
function betDelete(el_bet_unit){
const name = el_bet_unit.dataset.name;
const player = el_bet_unit.dataset.player;
let is_exist_name = false;
let is_exist_player = false;
el_bet_unit.remove();
for(let i=0;i<els_bet_unit.length;i++){
if(els_bet_unit[i].dataset.name===name){
is_exist_name = true;
break;
}
}
for(let i=0;i<els_bet_unit.length;i++){
if(els_bet_unit[i].dataset.player===player){
is_exist_player = true;
break;
}
}
if(!is_exist_name){
list_name = list_name.filter(v=>v!==name);
obj_option_name[name].remove();
}
if(!is_exist_player){
list_player = list_player.filter(v=>v!==player);
obj_option_player[player].remove();
}
calcOdds();
}
function calcOdds(){
const rate = Number(el_input_rate.value);
//例外処理
if(!Number.isInteger(rate)||rate<0){
[...els_result__odds].forEach(el=>{
el.textContent = '-';
});
[...els_bet__refund].forEach(el=>{
el.textContent = '-';
});
return;
}
//賭金取得 オッズ計算
const obj_player = {};
let sum_amount = 0;
for(let i=0;i<els_bet_unit.length;i++){
const player = els_bet_unit[i].dataset.player;
const amount = Number(els_bet_unit[i].dataset.amount);
if(obj_player[player]===undefined){
obj_player[player] = {
amount: amount
};
}else{
obj_player[player].amount += amount;
}
sum_amount += amount;
}
const sum_refund = Math.floor(sum_amount * rate / 100);
for(let key in obj_player){
obj_player[key].odds = Math.max(Math.floor((sum_refund / obj_player[key].amount)*10)/10,1).toFixed(1);
obj_player[key].odds_raw = Math.max(sum_refund / obj_player[key].amount,1);
}
//DOM sum
el_sum_amount.textContent = sum_amount;
//DOM result
const list_delete = [];
for(let i=0;i<els_result_unit.length;i++){
const player = els_result_unit[i].dataset.player;
if(obj_player[player]===undefined){
//賭け対象から削除
list_delete.push(els_result_unit[i]);
}else{
els_result__amount[i].textContent = obj_player[player].amount;
els_result__odds[i].textContent = obj_player[player].odds;
}
}
list_delete.forEach(el=>{el.remove()});
//DOM bet
for(let i=0;i<els_bet_unit.length;i++){
const amount = Number(els_bet_unit[i].dataset.amount);
const odds = obj_player[els_bet_unit[i].dataset.player].odds;
const odds_raw = obj_player[els_bet_unit[i].dataset.player].odds_raw;
const refund = (el_sel_odds_round.value==='normal') ? Math.floor(amount*odds) : Math.floor(amount*odds_raw);
els_bet__refund[i].textContent = refund;
}
}
function selectWin(el_result_unit, player){
if(el_result_unit.classList.contains('s-win')){
[...els_s_win].forEach(el=>{
el.classList.remove('s-win');
});
}else{
[...els_s_win].forEach(el=>{
el.classList.remove('s-win');
});
el_result_unit.classList.add('s-win');
for(let i=0;i<els_bet_unit.length;i++){
if(els_bet_unit[i].dataset.player===player) els_bet_unit[i].classList.add('s-win');
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment