김동근

거의 끝

......@@ -10,7 +10,13 @@ let globalDecks
//result.ejs 렌더링 전 수행됨. 현재 덱 ID와 상대 직업을 가지고 상대의 점유율 상위 3개 덱과, 내 덱의 추천 멀리건 출력
//return : 렌더링 된 result.ejs
exports.GetResults=(req,res)=>{
//const opponentClass=req.session.opponentClass
const mineClass = req.body.MineClass
const name1 = req.body.value1
const name2 = req.body.value2
const name3 = req.body.value3
const names = [name1, name2, name3]
req.session.names = names
const opponentClass=req.session.opponentClass
//덱 ID와 상대 직업 정보 체크
const DataCheck=()=>{
return new Promise((resolve,reject)=>{
......@@ -28,42 +34,7 @@ exports.GetResults=(req,res)=>{
return getCardId.GetCardId(deckId)
}
//가져온 카드 정보를 바탕으로, hsreplay.net에서, 덱 검색하기, 검색한 결과의 html을 반환
const GetMulContent=()=>{
//cardIds=JSON.stringify(cardIds)
//cardIds=JSON.parse(cardIds)
return new Promise((resolve,reject)=>{
const asyncFunc=async ()=>{
const browser=await puppeteer.launch()
try{
const page=await browser.newPage()
await page.setViewport({width:1366,height:768})
await page.goto(`https://www.heartharena.com/ko/tierlist`,{waitUntil: 'networkidle2'})
let index = 0
if(opponentClass == "DRUID"){ index = 1 }
else if(opponentClass == "HUNTER"){ index = 2 }
else if(opponentClass == "MAGE"){ index = 3 }
else if(opponentClass == "PALADIN"){ index = 4 }
else if(opponentClass == "PRIEST"){ index = 5 }
else if(opponentClass == "ROGUE"){ index = 6 }
else if(opponentClass == "SHAMAN"){ index = 7 }
else if(opponentClass == "WARLOCK"){ index = 8 }
else if(opponentClass == "WARRIOR"){ index = 9 }
if(index != 1)
await page.click('#tier-list > div > section.navs > section.tierlist-selection > nav > ul > li:nth-child(' + index)
const content=await page.content()
browser.close()
return content
}
catch(err)
{
console.log(err)
browser.close()
}
}
resolve(asyncFunc())
})
}
//검색한 html을 가지고, 검색결과로 부터 덱의 url 파싱
const GetDeckHref=(content)=>{
return new Promise((resolve,reject)=>{
......@@ -128,18 +99,6 @@ exports.GetResults=(req,res)=>{
const page=await browser.newPage()
await page.setViewport({width:1366,height:768})
await page.goto(`https://www.heartharena.com/ko/tierlist`,{waitUntil: 'networkidle2'})
let index = 0
if(opponentClass == "DRUID"){ index = 1 }
else if(opponentClass == "HUNTER"){ index = 2 }
else if(opponentClass == "MAGE"){ index = 3 }
else if(opponentClass == "PALADIN"){ index = 4 }
else if(opponentClass == "PRIEST"){ index = 5 }
else if(opponentClass == "ROGUE"){ index = 6 }
else if(opponentClass == "SHAMAN"){ index = 7 }
else if(opponentClass == "WARLOCK"){ index = 8 }
else if(opponentClass == "WARRIOR"){ index = 9 }
if(index != 1)
await page.click('#tier-list > div > section.navs > section.tierlist-selection > nav > ul > li:nth-child(' + index)
const content=await page.content()
browser.close()
return content
......@@ -157,21 +116,17 @@ exports.GetResults=(req,res)=>{
const GetDeckInfo=(content)=>{
return new Promise((resolve,reject)=>{
const $=cheerio.load(content)
let deckNames=$('.deck-name')
let deckGames=$('.game-count')
let decks=[]
for(let i=0;decks.length<3;i++) {
let deckName = $(deckNames[i]).text()
let deckGame = $(deckGames[i]).text()
let j=0
for(;j<decks.length;j++){
if(deckName===decks[j].deckTitle)
break
}
if(j===decks.length){
decks.push({deckTitle:deckName,deckGame:deckGame})
let deckNames=$('li > dl')
let decks=[0,0,0]
for(let i=0; i < deckNames.length; i++){
if($(deckNames[i]).attr('class') != 'empty'){
let temp = $(deckNames[i].children[0]).text().split('\n')
if(temp[0] == name1) decks[0] = $(deckNames[i].children[1]).text()
else if(temp[0] == name2) decks[1] = $(deckNames[i].children[1]).text()
else if(temp[0] == name3) decks[2] = $(deckNames[i].children[1]).text()
}
}
req.session.decks = decks
resolve(decks)
})
}
......@@ -200,7 +155,6 @@ exports.GetResults=(req,res)=>{
.then(()=>{
return new Promise((resolve,reject)=>{
let result={}
result.cards=globalMulligan
result.decks=globalDecks
resolve(result)
})
......@@ -209,8 +163,9 @@ exports.GetResults=(req,res)=>{
fs.readFile('./views/ejs/score_result.ejs','utf-8',(err,data)=>{
res.writeHead(200,{'Content-Type':'text/html'})
res.end(ejs.render(data,{
cards:globalMulligan || [],
decks:globalDecks || [],
MineClass:opponentClass || [],
Names:names || [],
}))
})
})
......
......@@ -5,18 +5,20 @@ const cheerio=require('cheerio')
const mysql=require('mysql')
const fs=require('fs')
const ejs=require('ejs')
let globalMulligan
let globalDecks
//result.ejs 렌더링 전 수행됨. 현재 덱 ID와 상대 직업을 가지고 상대의 점유율 상위 3개 덱과, 내 덱의 추천 멀리건 출력
//return : 렌더링 된 result.ejs
exports.GetResult=(req,res)=>{
const opponentClass=req.session.opponentClass
const deck=req.session.decks
const Name=req.session.names
try{
fs.readFile('./views/ejs/score_result.ejs','utf-8',(err,data)=>{
res.writeHead(200,{'Content-Type':'text/html'})
res.end(ejs.render(data,{
MineClass:opponentClass || []
MineClass:opponentClass || [],
decks: deck || [0,0,0],
Names: Name || ["", "", ""],
}))
})
}finally{
......
......@@ -5,4 +5,8 @@ const setOpponentClass=require('./setOpponentClass')
router.post('/setopponentclass',setOpponentClass.SetOpponentClass)
const getResultMine = require('./getResultMine')
router.post('/getresultmine', getResultMine.GetResults)
module.exports=router
\ No newline at end of file
......
const puppeteer=require('puppeteer')
const cheerio=require('cheerio')
const fs=require('fs')
const ejs=require('ejs')
exports.getDeckname=(req,res)=>{
const deckname=req.session.deckname
const name1 = req.body.value1
const name2 = req.body.value2
const name3 = req.body.value3
const name4 = req.body.value4
const names=[name1, name2, name3, name4]
req.session.mulName = names
let mulRates
let WinRate=req.session.winRate
const info={'비밀 사냥꾼':'Secret Hunter', '기계 사냥꾼':'Mech Hunter', '멀록 주술사':'Murloc Shaman', '토큰 드루이드':'Token Druid', '컨트롤 전사':'Control Warrior',
'폭탄 전사':'Bomb Warrior', '기계 성기사':'Mech Paladin', '위니 흑마':'Zoo Warlock', '미드레인지 사냥꾼':'Midrange Hunter', '용 마법사':'Dragon Mage',
'죽음의 메아리 사냥꾼':'Deathrattle Hunter', 'Cyclone Mage':'Cyclone Mage', '빅 주술사':'Big Shaman', '부활 사제':'Resurrect Priest','컨트롤 주술사':'Control Shaman',
'빅 성기사':'Big Paladin', '신의 격노 성기사':'Holy Wrath Paladin', '템포 도적':'Tempo Rogue', '빙결 마법사':'Freeze Mage', '주문 마법사':'Spell Mage',
'회복 드루이드':'Heal Druid', '침묵 사제':'Silence Priest', '노미 사제':'Nomi Priest', '거인 흑마법사':'Handlock', '첩보 도적':'Thief Rogue'}
const GetMulContent=()=>{
return new Promise((resolve,reject)=>{
const asyncFunc=async ()=>{
const browser=await puppeteer.launch()
try{
const page=await browser.newPage()
await page.setViewport({width:1366,height:768})
await page.goto(`https://hsreplay.net/meta`,{waitUntil: 'networkidle2'})
const content=await page.content()
browser.close()
return content
}
catch(err)
{
console.log(err)
browser.close()
}
}
resolve(asyncFunc())
})
}
const GetDeckInfo=(content)=>{
return new Promise((resolve,reject)=>{
const $=cheerio.load(content)
let i = 0
let deckNames=$('.archetype-info')
for(; i < deckNames.length; i++){
if($(deckNames[i].children[0]).text() == info[deckname]){
WinRate = $(deckNames[i].children[1]).text()
req.session.winRate = WinRate
break
}
}
let deckaddress=$($('a.btn')[i+1]).attr('href')
resolve(deckaddress)
})
}
const GetMulRate=(deckaddress)=>{
return new Promise((resolve,reject)=>{
const asyncFunc=async ()=>{
const browser=await puppeteer.launch()
try{
const page=await browser.newPage()
await page.setViewport({width:1366,height:768})
await page.goto(`https://hsreplay.net` + deckaddress,{waitUntil: 'networkidle2'})
const content=await page.content()
browser.close()
return content
}
catch(err)
{
console.log(err)
browser.close()
}
}
resolve(asyncFunc())
})
}
const GetMulInfo=(content)=>{
return new Promise((resolve,reject)=>{
const $=cheerio.load(content)
let MulNames=$('span.card-name')
let MulRates=$('#mulligan-guide > div > div:nth-child(1) > div:nth-child(4) > div > div > div')
mulRates=['', '' ,'' ,'']
let USname = []
let KRname = []
USname = JSON.parse(fs.readFileSync('./cardsenUS.json'))
KRname = JSON.parse(fs.readFileSync('./cardskoKR.json'))
for(let i = 0 ;i < MulNames.length; i++){
let j =0
for(; j < USname.length; j++){
if(USname[j].name == $(MulNames[i].children[0]).text())
break
}
//$(MulNames[i].children[0]).text()
if(j != USname.length){
if(name1 == KRname[j].name) mulRates[0] = $(MulRates[6*i]).text()
else if(name2 == KRname[j].name) mulRates[1] = $(MulRates[6*i]).text()
else if(name3 == KRname[j].name) mulRates[2] = $(MulRates[6*i]).text()
else if(name4 == KRname[j].name) mulRates[3] = $(MulRates[6*i]).text()
}
}
req.session.mulwinRate = mulRates
resolve(mulRates)
})
}
GetMulContent()
.then(GetDeckInfo)
.then(GetMulRate)
.then(GetMulInfo)
.then(()=>{
fs.readFile('./views/ejs/prob_result.ejs','utf-8',(err,data)=>{
res.writeHead(200,{'Content-Type':'text/html'})
res.end(ejs.render(data,{
deckName : deckname || [],
winRate:WinRate || [],
mulNames:names || ["", "", "", ""],
mulwinRate:mulRates || [0, 0, 0, 0]
}))
})
})
.catch((err)=>{
console.log(err)
})
}
\ No newline at end of file
const puppeteer=require('puppeteer')
const cheerio=require('cheerio')
const fs=require('fs')
const ejs=require('ejs')
exports.getDeckname=(req,res)=>{
const deckname=req.body.value
const DataCheck=()=>{
return new Promise((resolve,reject)=>{
if(!deckname){
reject(({
query:'request_body_error'
}))
}
else resolve()
})
}
const Set=()=>{
req.session.deckname=req.body.value
return
}
DataCheck()
.then(Set)
.then(()=>{
res.status(200).json({message:'complete setting opponent class'})
})
.catch((err)=>{
res.status(500).json(err||err.message)
})
}
\ No newline at end of file
const puppeteer=require('puppeteer')
const cheerio=require('cheerio')
const fs=require('fs')
const ejs=require('ejs')
exports.getDeckname=(req,res)=>{
const deckname=req.session.deckname
const winRate=req.session.winRate
const mulName=req.session.mulName
const mulwinRate=req.session.mulwinRate
try{
fs.readFile('./views/ejs/prob_result.ejs','utf-8',(err,data)=>{
res.writeHead(200,{'Content-Type':'text/html'})
res.end(ejs.render(data,{
deckName : deckname || [],
winRate:winRate || [0],
mulNames:mulName || ["", "", "", ""],
mulwinRate:mulwinRate || [0, 0, 0, 0]
}))
})
}finally{}
}
\ No newline at end of file
......@@ -2,7 +2,15 @@ const express=require('express')
const router=express.Router()
const newDeck=require('./newDeck')
router.post('/newdeck',newDeck.NewDeck)
const getdeckname=require('./getdeckname')
router.post('/getdeckname',getdeckname.getDeckname)
const getdeckname1=require('./getdeckname1')
router.post('/getdeckname1',getdeckname1.getDeckname)
const getdeckname2=require('./getdeckname2')
router.post('/getdeckname2',getdeckname2.getDeckname)
module.exports=router
\ No newline at end of file
......
......@@ -43,7 +43,7 @@ app.use(session({
}))
app.get('/',(req,res)=>{
res.redirect('/decklist')
res.redirect('/login')
})
......@@ -171,14 +171,15 @@ app.get('/score_result_',(req,res)=>{
}
})
app.get('/prob_result/:deckId',(req,res)=>{
const getdeckname=require('./api/deck/getdeckname2')
app.get('/prob_result',(req,res)=>{
if(!req.session.sid)
res.redirect('/login')
else{
fs.readFile('./views/html/prob_result.html',(err,data)=>{
res.writeHead(200,{'Content-Type':'text/html'})
res.end(data)
})
(async ()=>{
await getdeckname.getDeckname(req,res)
})()
}
})
......
......@@ -32,13 +32,158 @@
}
})
})
for ( var i=0;i<decks.length;i++) {
$('#delButton_'+(i+1)).click(function () {
let sql = "select * from deck"
$('#value_1').click(function () {
let obj = new Object()
obj.value = $('#value_1').val()
const stringData = JSON.stringify(obj)
$.ajax({
type:'POST',
url:'/api/deck/getdeckname1',
data:stringData,
async:false,
dataType:'JSON',
contentType:'application/json; charset=utf-8',
traditional:true,
processdata:false,
success:function(result){
window.location.href='/prob_result'
},
error:function(request,status,error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
})
})
$('#value_2').click(function () {
let obj = new Object()
obj.value = $('#value_2').val()
const stringData = JSON.stringify(obj)
$.ajax({
type:'POST',
url:'/api/deck/getdeckname1',
data:stringData,
async:false,
dataType:'JSON',
contentType:'application/json; charset=utf-8',
traditional:true,
processdata:false,
success:function(result){
window.location.href='/prob_result'
},
error:function(request,status,error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
})
})
$('#value_3').click(function () {
let obj = new Object()
obj.value = $('#value_3').val()
const stringData = JSON.stringify(obj)
$.ajax({
type:'POST',
url:'/api/deck/getdeckname1',
data:stringData,
async:false,
dataType:'JSON',
contentType:'application/json; charset=utf-8',
traditional:true,
processdata:false,
success:function(result){
window.location.href='/prob_result'
},
error:function(request,status,error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
})
})
$('#value_4').click(function () {
let obj = new Object()
obj.value = $('#value_4').val()
const stringData = JSON.stringify(obj)
$.ajax({
type:'POST',
url:'/api/deck/getdeckname1',
data:stringData,
async:false,
dataType:'JSON',
contentType:'application/json; charset=utf-8',
traditional:true,
processdata:false,
success:function(result){
window.location.href='/prob_result'
},
error:function(request,status,error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
})
})
$('#value_5').click(function () {
let obj = new Object()
obj.value = $('#value_5').val()
const stringData = JSON.stringify(obj)
$.ajax({
type:'POST',
url:'/api/deck/getdeckname1',
data:stringData,
async:false,
dataType:'JSON',
contentType:'application/json; charset=utf-8',
traditional:true,
processdata:false,
success:function(result){
window.location.href='/prob_result'
},
error:function(request,status,error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
})
})
$('#value_6').click(function () {
let obj = new Object()
obj.value = $('#value_6').val()
const stringData = JSON.stringify(obj)
$.ajax({
type:'POST',
url:'/api/deck/getdeckname1',
data:stringData,
async:false,
dataType:'JSON',
contentType:'application/json; charset=utf-8',
traditional:true,
processdata:false,
success:function(result){
window.location.href='/prob_result'
},
error:function(request,status,error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
})
})
/*for ( var i=0;i<decks.length;i++) {
$('#value_'+(i+1)).click(function () {
let obj = new Object()
obj.value = $('#value_' + (i+1)).val()
const stringData = JSON.stringify(obj)
$.ajax({
type:'POST',
url:'/api/deck/getdeckname',
data:stringData,
async:false,
//dataType:'JSON',
contentType:'application/json; charset=utf-8',
traditional:true,
processdata:false,
success:function(result){
alert('검색 성공')
window.location.href='/prob_result'
},
error:function(request,status,error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
})
})
}*/
})
</script>
</head>
......@@ -75,8 +220,7 @@
<table class="table" style="width:100%">
<% for ( var i=0;i<decks.length;i++) { %>
<tr id="rm<%=(i+1)%>">
<td style="text-align: center; width:500px"><a class="list-group-item" href="/prob_result/<%= decks[i].id %>"><%= decks[i].deckTitle %></a></td>
<td><input type="button" class="btn btn-lg btn-info" style="width:100px; height:42px" value=삭제 id ="delButton_<%= (i+1)%> "/></td>
<td><input type=button style="text-align: center; width:100%; height:42px" id ="value_<%= (i+1)%>" value ="<%= decks[i].deckTitle %>"></input></td>
</tr>
<% } %>
</table>
......
......@@ -32,6 +32,32 @@
}
})
})
$('#show_prob').click(function(){
var obj = new Object()
obj.value1 = $('#Btn1').val()
obj.value2 = $('#Btn2').val()
obj.value3 = $('#Btn3').val()
obj.value4 = $('#Btn4').val()
const stringData = JSON.stringify(obj)
let temp
$.ajax({
type:'POST',
url:'/api/deck/getdeckname',
data:stringData,
async:false,
//dataType:'JSON',
contentType:'application/json; charset=utf-8',
traditional:true,
processdata:false,
success:function(result){
alert('검색 성공')
window.location.href='/prob_result'
},
error:function(request,status,error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
})
})
})
</script>
</head>
......@@ -67,12 +93,10 @@
<td>승률</td>
</thead>
<tbody>
<% for(var i=0;i<decks.length;i++){%>
<tr>
<td><a class="list-group-item"><%= decks[i].deckTitle %></a></td>
<td><a class="list-group-item"><%= decks[i].deckWinRate %></a></td>
<td><a class="list-group-item"><%= deckName %></a></td>
<td><a class="list-group-item"><%= winRate %></a></td>
</tr>
<%}%>
</tbody>
</table>
</div>
......@@ -80,23 +104,31 @@
<br>
<h3 class="form-signin-heading">멀리건 승률</h3>
<div id="yourMulligan">
<form method="get" action="/save.php">
<table class="table" style="text-align: center;">
<thead>
<td>카드 이름</td>
<td>멀리건 승률</td>
</thead>
<tbody>
<% for(var i=0;i<cards.length;i++){%>
<tr>
<td><input type="text" class="btn-block" name="keyword" style="height:42px; text-align:center;"/></td>
<td><a class="list-group-item"><%= cards[i].cardWinRate %></a></td>
<td><input type="text" class="btn-block" id='Btn1' name="keyword" style="height:42px; text-align:center;" value="<%=mulNames[0]%>"/></td>
<td><a class="list-group-item" id='Text1' ><%= mulwinRate[0] %></a></td>
</tr>
<tr>
<td><input type="text" class="btn-block" id='Btn2' name="keyword" style="height:42px; text-align:center;" value="<%=mulNames[1]%>"/></td>
<td><a class="list-group-item" id='Text2'><%= mulwinRate[1] %></a></td>
</tr>
<tr>
<td><input type="text" class="btn-block" id='Btn3' name="keyword" style="height:42px; text-align:center;" value="<%=mulNames[2]%>"/></td>
<td><a class="list-group-item" id='Text3'><%= mulwinRate[2] %></a></td>
</tr>
<tr>
<td><input type="text" class="btn-block" id='Btn4' name="keyword" style="height:42px; text-align:center;" value="<%=mulNames[3]%>"/></td>
<td><a class="list-group-item" id='Text4'><%= mulwinRate[3] %></a></td>
</tr>
<%}%>
</tbody>
</table>
<button type="submit" class="btn btn-primary btn-block" id="show_prob">멀리건 승률 표출하기</button>
</form>
</div>
<br>
<br>
......
......@@ -38,17 +38,19 @@
obj.value2 = $('#btn2').val()
obj.value3 = $('#btn3').val()
const stringData = JSON.stringify(obj)
let temp
$.ajax({
type:'POST',
url:'/api/card/setopponentclass',
url:'/api/card/getresultmine',
data:stringData,
dataType:'JSON',
async:false,
//dataType:'JSON',
contentType:'application/json; charset=utf-8',
traditional:true,
processdata:false,
success:function(result){
alert('검색 성공')
window.location.href='/score_result_'
window.location.href='/score_result'
},
error:function(request,status,error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
......@@ -106,16 +108,16 @@
</thead>
<tbody>
<tr>
<td><input type="text" class="btn-block" id="btn1" name="keyword" style="height:42px; text-align:center;" /></td>
<td><a class="list-group-item">카드</a></td>
<td><input type="text" class="btn-block" id="btn1" name="keyword" style="height:42px; text-align:center;" value= "<%=Names[0]%>" /></td>
<td><a class="list-group-item" id='text1'><%= decks[0] %></a></td>
</tr>
<tr>
<td><input type="text" class="btn-block" id="btn2" name="keyword" style="height:42px; text-align:center;" /></td>
<td><a class="list-group-item">이름</a></td>
<td><input type="text" class="btn-block" id="btn2" name="keyword" style="height:42px; text-align:center;" value="<%= Names[1] %>" /></td>
<td><a class="list-group-item" id='text2'><%= decks[1] %></a></td>
</tr>
<tr>
<td><input type="text" class="btn-block" id="btn3" name="keyword" style="height:42px; text-align:center;" /></td>
<td><a class="list-group-item">입력!!</a></td>
<td><input type="text" class="btn-block" id="btn3" name="keyword" style="height:42px; text-align:center;" value="<%= Names[2] %>" /></td>
<td><a class="list-group-item" id='text3'><%= decks[2] %></a></td>
</tr>
</tbody>
</table>
......
......@@ -32,27 +32,30 @@
}
})
})
$('#show_prob').click(function(){
var Data = new Object()
Data.value1 = $('#btn1').val()
Data.value2 = $('#btn2').val()
Data.value3 = $('#btn3').val()
const stringData = JSON.stringify(Data)
alert('검색중입니다!')
$('#showprob').click(function(){
var obj = new Object()
obj.value1 = $('#btn1').val()
obj.value2 = $('#btn2').val()
obj.value3 = $('#btn3').val()
obj.MinClass = $('#mineclass').val()
obj.MinClass1 = $('#mineclass1').val()
const stringData = JSON.stringify(obj)
$.ajax({
typ:'GET',
url:'/api/card/getResultMine',
type:'POST',
url:'/api/card/getresultmine',
data:stringData,
dataType:'JSON',
async:false,
//dataType:'JSON',
contentType:'application/json; charset=utf-8',
traditional:true,
processdata:false,
success:function(result){
alert('검색 성공!')
alert('검색 성공')
//let temp = JSON.stringify(result)
//$('text1').text(temp)
},
error:function(result){
alert('검색 실패!')
return false
error:function(request,status,error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
})
})
......@@ -100,9 +103,6 @@
<br>
<h3 class="form-signin-heading">투기장 카드 점수</h3>
<div id="yourMulligan">
<form method="get" action="/save.php">
<!-- method - 통신 방식의 메소드를 결정하며 get/post에서 선택함
action - 값을 전달할 서버 페이지 위치 -->
<table class="table" style="text-align: center;">
<thead>
<td>카드 이름</td>
......@@ -124,7 +124,6 @@
</tbody>
</table>
<button type="submit" class="btn btn-primary btn-block" id="show_prob">카드 점수 표출하기</button>
</form>
</div>
<br>
<br>
......