컴퓨터/JavaScript

JavaScript (3) - 텍스트를 인식하는 중복없는 뽑기제작

달서비 2022. 1. 2. 00:04

최근에 동아리 활동으로 '크리스마스 선물교환'을 하였습니다. 시중에도 뽑기 프로그램이 많은데 중복 방지를 넣은 프로그램이 없어 제작하였습니다. 링크는 다음과 같습니다. 

 

https://kmsbio.github.io/presentChoice/

 

선물교환

성탄절 선물교환! 한바퀴 반복으로 진행하고 그 다음 부터는 랜덤으로 진행합니다 주의사항 : 절대(enter)빈칸은 넣지마세요. Play before 지금 까지 나온 인원

kmsbio.github.io

 

뽑기 - Pixabay

중요한 메소드

Document.getElementByID() - html소스의 ID를 받아오는 메소드 입니다.
document.getElementById("A").innerText id가 A라는 HTML소스코드 내부에 글을 추가한다.
document.getElementById("A").innerHTML id가 A라는 HTML소스코드 내부에 소스코드를 추가한다.
document.getElementById("A").remove(); id가 A라는 HTML소스코드를 제거한다.
var String = 'ㄱㄱㄱ,ㄴㄴㄴ,ㄷㄷㄷ';
var Split = jbString.split(',');

예제를 통하여 설명을 하면 split메소드 ', '를 기준으로 나누어 'ㄱㄱㄱ' 'ㄴㄴㄴ' 'ㄷㄷㄷ'으로 나눕니다. 

 

소스코드 (JavaScript)

var count = 0;
var alert_count = 0;

function playGame() {
    var Name;

    //기본 선물 환경에서 사람뽑기 화면으로 바뀐다.
    if (count == 0) {
        document.getElementById("startIMG").remove();
        document.getElementById("board").innerHTML = "<span id=" + "winning" + "></span>";
        document.getElementById("log").innerText = "";
        count++;
    }

    if (validation()) {
        Name = initName();
        Game(Name);
    }

    //textarea에서 입력후 enter 단위로 나누는 함수
    function initName() {
        var text = document.getElementById("inputName").value;
        var splitText = text.split("\n");
        return splitText;
    }

    //실질적으로 Game을 주도하는 함수
    function Game(Name) {
        var count, tempNum;
        count = Name.length;

        while (1) {
            tempNum = Math.floor(Math.random() * count);
            if (checkRepeat(Name[tempNum], count)) {
                document.getElementById("winning").innerText = Name[tempNum];
                document.getElementById("log").innerText += Name[tempNum] + ",";
                break;
            }
        }
    }

    function validation() {
        var text = document.getElementById("inputName").value;
        var splitText = text.split("\n");
        for (var i = 0; i <= splitText.length; i++)
            if (splitText[i] == "") {
                alert("빈칸은 안됩니다.");
                return 0;
            }
        return 1;
    }

    //선물은 한사람이 여러분 줄 수 없다 log 값을 인식하여 중복을 피한다.
    function checkRepeat(Name, count) {
        var text = $("#log").text();
        var splitText = text.split(",");
        if (count < splitText.length) {
            //한번 반복을 돌리면 경고후 다음부터는 자유롭게 돌린다.
            if (alert_count == 0) {
                alert("한번 실행을 완료하였고 이제부터는 중복합니다.");
                alert_count++;
            }
            return 1;
        }
        for (var i = 0; i < splitText.length; i++) {
            if (splitText[i] == Name) return 0; //같으면 0을 다시한번 돌린다.
        }
        return 1;
    }
}

function before() {
    //before버튼을 누르는 경우 마지막 log를 지운다.
    var text = $("#log").text();
    var splitText = text.split(",");

    document.getElementById("log").innerText = "";

    for (var i = 0; i < splitText.length - 2; i++) {
        document.getElementById("log").innerText += splitText[i] + ",";
    }
}

 

제작한 함수의 기능 및 의미

playGame() - 게임을 총괄적으로 정리한 함수
- initName() - '\n' 단위로 텍스트를 분리하는 함수
- Game() - 랜덤으로 지정하여 당첨자를 출력하는 함수
- validation() - 빈칸인지 확인하는 함수
- checkRepeat() - Game함수를 통하여 뽑은 사람을 인식하고 'log' 값을 통해 나와 있는 사람이 중복되어있는지 검사한다.

before() - 지정한 사람 이전 순서를 제거한다. (본인이 지정된 경우에 입력)

 

결과

해당 웹사이트를 들어가면 선물교환이 나옵니다. 여기서 '\n'(enter)를 기준으로 입력하였습니다. 처음에는 디자인으로 버튼으로 클릭하는 것을 생각했는데 빠르게 하기 위하여 넣었습니다.

입력 칸에 '김모씨', '이모씨', '박모씨'를 넣었습니다. 그 후 play 버튼을 누르면 3개의 텍스트중 하나를 인식합니다. 그리고 밑에 log를 통해 당첨된 사람을 출력합니다. log를 통해 이미 당첨된 사람을 알고 한 바퀴 돌아간 경우에는 아래의 경고창을 출력합니다.

이렇게 이상 프로그램을 제작하였습니다.

 

아쉬운 점

제가 만든 프로그램은 CheckRepeat()라는 함수를 이용하여 이름 단위로 인식하여 구현하였습니다. 하지만 해당 방식에는 엄청나게 많은 사람이 있는 경우 이름이 중복하는 경우가 있습니다. 동아리 같은 경우 크기가 작지 않기 때문에 해당 방식이 괜찮았지만 더 많은 경우에는 또 다른 숫자를 지정으로 해야 한다는 생각을 가졌습니다.

 

전체 소스코드

=== 스크롤 압박으로 접은 글로 두었습니다. 아래를 클릭하면 소스코드가 나옵니다. ===

더보기

HTML/CSS

<!DOCTYPE html>
<html lang="kr">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
    <script src="./function.js"></script>
    <title>선물교환</title>
</head>
<body>
    <div class="my-5 text-center">
        <div id="board">
            <img id="startIMG" class="d-block mx-auto" src="./asset/santa-claus.png" height="200px">
        </div>
        <h1 class="fw-bold" style="margin-top: 20px;">성탄절 선물교환!</h1>
        <div class="col-lg-6 mx-auto">
          <p class="lead mb-2">한바퀴 반복으로 진행하고 그 다음 부터는 랜덤으로 진행합니다</p>
          <p>주의사항 : 절대(enter)빈칸은 넣지마세요.</p>
          <textarea id= "inputName" class="form-control" placeholder="이름(enter)로 구분합니다"></textarea>
          <div class="d-grid gap-2 d-sm-flex justify-content-sm-center">
            <button type="button" class="btn btn-primary btn-lg px-4 gap-3" onclick="playGame()">Play</button>
            <button type="button" class="btn btn-outline-secondary btn-lg" onclick="before()">before</button>
          </div>
        </div>
        <div id="log">
            지금 까지 나온 인원 <br>
        </div>
      </div>
</body>

<style>
    body {
        background-image: url(./asset/christmas.jpg);
    }

    #inputName {
        height: 10%;
        margin-bottom: 2%;
        resize: none;
    }

    #winning {
        display: inline-block;
        width: 400px;
        height: 200px;
        border: 10px solid red;

        background-color: whitesmoke;
        opacity: 80%;

        font-size: 60px;
        font-weight: bold;
        line-height: 180px;
    }

    #log {
        color: green;
        font-weight: bold;
    }
    
</style>
</html>

JavaScript

var count = 0;
var alert_count = 0;

function playGame() {
    var Name;

    //기본 선물 환경에서 사람뽑기 화면으로 바뀐다.
    if (count == 0) {
        document.getElementById("startIMG").remove();
        document.getElementById("board").innerHTML = "<span id=" + "winning" + "></span>";
        document.getElementById("log").innerText = "";
        count++;
    }

    if (validation()) {
        Name = initName();
        Game(Name);
    }

    //textarea에서 입력후 enter 단위로 나누는 함수
    function initName() {
        var text = document.getElementById("inputName").value;
        var splitText = text.split("\n");
        return splitText;
    }

    //실질적으로 Game을 주도하는 함수
    function Game(Name) {
        var count, tempNum;
        count = Name.length;

        while (1) {
            tempNum = Math.floor(Math.random() * count);
            if (checkRepeat(Name[tempNum], count)) {
                document.getElementById("winning").innerText = Name[tempNum];
                document.getElementById("log").innerText += Name[tempNum] + ",";
                break;
            }
        }
    }

    function validation() {
        var text = document.getElementById("inputName").value;
        var splitText = text.split("\n");
        for (var i = 0; i <= splitText.length; i++)
            if (splitText[i] == "") {
                alert("빈칸은 안됩니다.");
                return 0;
            }
        return 1;
    }

    //선물은 한사람이 여러분 줄 수 없다 log 값을 인식하여 중복을 피한다.
    function checkRepeat(Name, count) {
        var text = $("#log").text();
        var splitText = text.split(",");
        if (count < splitText.length) {
            //한번 반복을 돌리면 경고후 다음부터는 자유롭게 돌린다.
            if (alert_count == 0) {
                alert("한번 실행을 완료하였고 이제부터는 중복합니다.");
                alert_count++;
            }
            return 1;
        }
        for (var i = 0; i < splitText.length; i++) {
            if (splitText[i] == Name) return 0; //같으면 0을 다시한번 돌린다.
        }
        return 1;
    }
}

function before() {
    //before버튼을 누르는 경우 마지막 log를 지운다.
    var text = $("#log").text();
    var splitText = text.split(",");

    document.getElementById("log").innerText = "";

    for (var i = 0; i < splitText.length - 2; i++) {
        document.getElementById("log").innerText += splitText[i] + ",";
    }
}