메인
home
소프트웨어
home

[나만의 웹사이트 제작하기][한삼고][엄은궁]

웹사이트 링크:
https://codepen.io/pen?template=dPMMNVa
간단한 설명: 주식을 간단하게 즐길수 있는 주식 가상 모의 투자 게임
문제점: 실제로 수익을 낼수 없다는 점과 기능이 한정적임
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>주식 트레이드 시뮬레이터</title> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <style> body { font-family: Arial; background:#111; color:white; padding:20px; } .container { display:flex; gap:20px; } .left { width:700px; } .right { width:300px; background:#222; padding:15px; border-radius:10px; } button { width:100%; padding:10px; margin:5px 0; border:none; cursor:pointer; font-size:16px; border-radius:8px; } .buy { background:#28a745; } .sell { background:#dc3545; } .short { background:#ff7700; } .cover { background:#007bff; } #history { height:200px; overflow-y:auto; background:#000; padding:10px; margin-top:10px; border-radius:8px; font-size:14px; } </style> </head> <body> <h1>📈 국내주식 50+ 실시간 확장형 트레이드 시뮬레이터</h1> <div class="container"> <div class="left"> <canvas id="stockChart" width="700" height="350"></canvas> </div> <div class="right"> <h2>거래 패널</h2> <p id="dayText">Day: -</p> <p id="priceText">현재가: -</p> <p id="assetText">총자산: -</p> <button class="buy" id="buyBtn">📈 매수(Buy)</button> <button class="sell" id="sellBtn">📉 매도(Sell)</button> <button class="short" id="shortSellBtn">🔻 공매도(Short)</button> <button class="cover" id="shortCoverBtn">🔺 공매도 청산(Cover)</button> <button id="nextDayBtn">➡ 다음날</button> <h3>AI 예측</h3> <button id="aiBtn">AI 예측 사용 (3회 남음)</button> <h3>기록</h3> <div id="history"></div> </div> </div> <script> let chart; let day = 0; let aiChance = 3; let cash = 10000000; let shares = 0; let shortShares = 0; let currentPrice = 0; let priceData = []; const FEE = 0.001; function generate50Days(){ let base = 10000 + Math.random()*15000; const arr = []; for(let i=0;i<50;i++){ const r = (Math.random()*4 - 2); base *= (1 + r/100); arr.push(Math.round(base)); } return arr; } function extendByOneDay(){ const last = priceData[priceData.length-1]; const r = (Math.random()*4 - 2); const newPrice = Math.round(last * (1 + r/100)); priceData.push(newPrice); } function startGame(){ priceData = generate50Days(); day = 0; cash = 10000000; shares = 0; shortShares = 0; aiChance = 3; updateTexts(); drawChart(); } function nextDay(){ day++; extendByOneDay(); updateTexts(); drawChart(); addHistory(`📅 Day ${day+1} 진행됨`); } function buy(){ currentPrice = priceData[day]; const qty = Math.floor(cash / (currentPrice * (1 + FEE))); if(qty <= 0) return; cash -= qty * currentPrice * (1 + FEE); shares += qty; addHistory(`매수 ${qty}`); updateTexts(); } function sell(){ if(shares <= 0) return; currentPrice = priceData[day]; cash += shares * currentPrice * (1 - FEE); addHistory(`매도 ${shares}`); shares = 0; updateTexts(); } function shortSell(){ currentPrice = priceData[day]; const qty = Math.floor(cash / (currentPrice * (1 + FEE))); if(qty <= 0) return; shortShares += qty; cash += qty * currentPrice * (1 - FEE); addHistory(`공매도 ${qty}`); updateTexts(); } function shortCover(){ if(shortShares <= 0) return; currentPrice = priceData[day]; const cost = shortShares * currentPrice * (1 + FEE); cash -= cost; addHistory(`공매도 청산 ${shortShares}`); shortShares = 0; updateTexts(); } function useAI(){ if(aiChance <= 0) return alert("AI 사용 불가"); aiChance--; const today = priceData[day]; const future = priceData[Math.max(0, day+1)]; const diff = future - today; const rate = ((diff/today)*100).toFixed(2); const msg = diff>0 ? `상승 +${rate}%` : `하락 ${rate}%`; alert(`AI 예측 결과:\n내일 변동: ${msg}`); document.getElementById("aiBtn").textContent = `AI 예측 사용 (${aiChance}회 남음)`; } function updateTexts(){ currentPrice = priceData[day]; const value = shares * currentPrice - shortShares * currentPrice; const total = cash + value; document.getElementById("dayText").textContent = `Day: ${day+1}`; document.getElementById("priceText").textContent = `현재가: ${currentPrice.toLocaleString()}`; document.getElementById("assetText").textContent = `총자산: ${total.toLocaleString()}`; } function drawChart(){ const ctx = document.getElementById("stockChart").getContext('2d'); if(chart) chart.destroy(); chart = new Chart(ctx, { type:'line', data:{ labels: priceData.map((_,i)=>i+1), datasets:[{ label:'주가', data:priceData, borderColor:'cyan', pointRadius:0 }] }, options:{ responsive:false } }); } function addHistory(text){ const box = document.getElementById("history"); box.innerHTML += `<div>${text}</div>`; box.scrollTop = box.scrollHeight; } // 버튼 연결 document.getElementById("buyBtn").onclick = buy; document.getElementById("sellBtn").onclick = sell; document.getElementById("shortSellBtn").onclick = shortSell; document.getElementById("shortCoverBtn").onclick = shortCover; document.getElementById("nextDayBtn").onclick = nextDay; document.getElementById("aiBtn").onclick = useAI; startGame(); </script> </body> </html>
JavaScript
복사

2. ai를 활용한 인식 관련된 웹사이트 코드펜 작업

간단한 설명: 다양한 유형의 퀴즈를 손 인식으론 정답을 골라 맞추는 웹앱입니다
웹사이트 링크:
https://codepen.io/pen?template=LENNxwK
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>손가락 퀴즈 게임 (Hands Control)</title> <style> body { font-family: Arial; text-align: center; background: #f0f0f0; margin:0; padding:0;} h1 { margin-top: 20px; } #quiz-container { margin: 20px auto; padding: 20px; background: #fff; border-radius: 10px; width: 90%; max-width: 700px; box-shadow: 0 0 10px rgba(0,0,0,0.2);} #feedback { font-size: 1.2em; margin: 10px;} #videoElement { display:none; } #canvas { border:1px solid black; border-radius:10px; margin-top:10px; } #categorySelect { margin-bottom: 15px; padding: 5px; font-size: 1em;} ul { text-align: left; list-style: none; padding-left: 0;} li { margin: 5px 0; padding: 5px; background: #eee; border-radius: 5px;} #fingerCount { font-size: 1.5em; margin: 10px; } button { padding: 10px 20px; font-size: 1em; margin-top: 10px; cursor: pointer;} </style> </head> <body> <h1>손가락 퀴즈 게임</h1> <div id="quiz-container"> <select id="categorySelect"> <option value="all">전체</option> <option value="nonsense">넌센스</option> <option value="korean_history">한국사</option> <option value="world_history">세계사</option> <option value="general">일반상식</option> </select> <div id="question">퀴즈 준비중...</div> <ul id="options"></ul> <div id="fingerCount">손가락: 0</div> <button id="submitBtn">정답 제출</button> <div id="feedback"></div> <video class="input_video" autoplay playsinline></video> <canvas class="output_canvas" width="640" height="480"></canvas> </div> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/hands/hands.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js"></script> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/drawing_utils/drawing_utils.js"></script> <script> // --- 퀴즈 문제 --- const quizData = [ {category:'nonsense', q:"달이 뜨면 안 보이는 것은?", options:["달","해","별","구름","바람"], a:2}, {category:'nonsense', q:"먹으면 살이 안 찌는 음식은?", options:["사탕","과자","물","빵","밥"], a:3}, {category:'korean_history', q:"조선을 건국한 왕은?", options:["세종","태조","광해군","고려","정조"], a:2}, {category:'world_history', q:"피라미드가 있는 나라는?", options:["이집트","멕시코","인도","중국","그리스"], a:1}, {category:'general', q:"한국의 수도는?", options:["부산","서울","인천","대전","광주"], a:2}, ]; let currentQuiz = 0; let selectedCategory = "all"; let currentFingerCount = 0; const questionEl = document.getElementById('question'); const optionsEl = document.getElementById('options'); const feedbackEl = document.getElementById('feedback'); const categorySelect = document.getElementById('categorySelect'); const fingerCountEl = document.getElementById('fingerCount'); const submitBtn = document.getElementById('submitBtn'); function getFilteredQuiz() { return selectedCategory === "all" ? quizData : quizData.filter(q=>q.category===selectedCategory); } function showQuiz() { const filteredQuiz = getFilteredQuiz(); if(filteredQuiz.length===0){ questionEl.innerText = "선택된 카테고리에 문제가 없습니다."; optionsEl.innerHTML = ""; return; } if(currentQuiz >= filteredQuiz.length) currentQuiz = 0; let quiz = filteredQuiz[currentQuiz]; questionEl.innerText = quiz.q; optionsEl.innerHTML = ""; quiz.options.forEach((opt, idx) => { let li = document.createElement('li'); li.innerText = `${idx+1}. ${opt}`; optionsEl.appendChild(li); }); feedbackEl.innerText = ""; } // 손가락에 따른 옵션 하이라이트 function updateFingerSelection() { fingerCountEl.innerText = `손가락: ${currentFingerCount}`; const filteredQuiz = getFilteredQuiz(); if(filteredQuiz.length===0) return; const quiz = filteredQuiz[currentQuiz]; Array.from(optionsEl.children).forEach((li, idx)=>{ li.style.background = (currentFingerCount===idx+1) ? '#a0e0a0' : '#eee'; }); } // 정답 제출 submitBtn.addEventListener('click',()=>{ const filteredQuiz = getFilteredQuiz(); if(filteredQuiz.length===0) return; let quiz = filteredQuiz[currentQuiz]; if(currentFingerCount===quiz.a){ feedbackEl.style.color='green'; feedbackEl.innerText=`정답! 손가락 ${currentFingerCount}`; currentQuiz++; setTimeout(showQuiz,1500); } else { feedbackEl.style.color='red'; feedbackEl.innerText=`오답! 손가락 ${currentFingerCount}`; } }); categorySelect.addEventListener('change',()=>{ selectedCategory = categorySelect.value; currentQuiz=0; showQuiz(); }); showQuiz(); // ===== MediaPipe Hands ===== const videoElement = document.querySelector('.input_video'); const canvasElement = document.querySelector('.output_canvas'); const ctx = canvasElement.getContext('2d'); const hands = new Hands({ locateFile: (file) => `https://cdn.jsdelivr.net/npm/@mediapipe/hands/${file}` }); hands.setOptions({ maxNumHands:1, modelComplexity:1, minDetectionConfidence:0.6, minTrackingConfidence:0.6 }); hands.onResults(onResults); const camera = new Camera(videoElement,{ onFrame: async()=>{ await hands.send({image:videoElement}); }, width:640, height:480 }); camera.start(); let lastStable = 0, lastTime = 0; function onResults(results){ ctx.save(); ctx.clearRect(0,0,canvasElement.width,canvasElement.height); ctx.drawImage(results.image,0,0,canvasElement.width,canvasElement.height); if(results.multiHandLandmarks && results.multiHandLandmarks.length>0){ const lm = results.multiHandLandmarks[0]; drawConnectors(ctx,lm,HAND_CONNECTIONS,{color:'#00FF00',lineWidth:3}); drawLandmarks(ctx,lm,{color:'#FF0000',lineWidth:2}); const fingers = countFingers(lm); // 안정화: 0.3초 유지 시만 확정 const now = performance.now(); if(fingers === lastStable){ lastTime = now; } else if(now - lastTime > 300){ lastStable = fingers; lastTime = now; currentFingerCount = fingers; updateFingerSelection(); } ctx.font="bold 36px Arial"; ctx.fillStyle="#000"; ctx.fillText(`손가락: ${fingers}`,10,40); } ctx.restore(); } function countFingers(lm){ let c=0; if(lm[4].x < lm[3].x) c++; // 엄지 if(lm[8].y < lm[6].y) c++; // 검지 if(lm[12].y < lm[10].y) c++; // 중지 if(lm[16].y < lm[14].y) c++; // 약지 if(lm[20].y < lm[18].y) c++; // 새끼 return c; } </script> </body> </html>
JavaScript
복사