ศึกประลอง X-O ชิงเจ้าสนาม(X-O Duel: Battle for the Crown)

จัดทำโดย นาย ก้องภพ มณีสิทธิ์

รหัสวิชา 04-000-104 การโปรแกรมคอมพิวเตอร์

1. ความเป็นมา

เกม XO เป็นเกมที่มีต้นกำเนิดมาจากการเล่นบนกระดาษ ใช้อุปกรณ์ง่ายๆ แต่สามารถสร้างความสนุกและความคิดสร้างสรรค์ได้เสมอ แต่ในยุคปัจจุบันที่เทคโนโลยีและการเขียนโปรแกรมเข้ามามีบทบาทในชีวิตประจำวัน การนำเกมนี้มาอยู่ในรูปแบบดิจิทัลสามารถทำให้การเล่นสะดวกและเข้าถึงง่ายมากยิ่งขึ้นนอกจากนี้ แนวคิดการสร้างเกม XO ยังสามารถนำไปประยุกต์ใช้ในวิศวกรรมไฟฟ้าได้เช่นกัน ตัวอย่างเช่น การเขียนโปรแกรมควบคุมวงจร หรือ ระบบฝังตัว (embedded system) โดยการสร้างตรรกะที่ใช้ในเกมนี้คล้ายคลึงกับการออกแบบ วงจรลอจิก ที่ใช้ในการควบคุมการทำงานของอุปกรณ์อิเล็กทรอนิกส์ต่างๆ เช่น การออกแบบระบบควบคุมที่ต้องให้เงื่อนไขตรงตามที่กำหนด เช่นเดียวกับการตรวจสอบผู้ชนะในเกม XO ที่ต้องตรวจเงื่อนไขต่างๆ ในการเรียงแถว การออกแบบเหล่านี้สามารถช่วยสร้างความเข้าใจเบื้องต้นเกี่ยวกับการออกแบบระบบควบคุมในทางวิศวกรรมไฟฟ้านอกจากนี้ การออกแบบ UI/UX ที่ใช้งานง่ายในเกม XO ยังเป็นแนวคิดที่วิศวกรไฟฟ้าอาจนำไปประยุกต์ใช้กับ แผงควบคุมอุปกรณ์ไฟฟ้า หรือ ระบบอัตโนมัติ ให้ผู้ใช้งานสามารถควบคุมและติดตามผลการทำงานของระบบต่างๆ ได้อย่างชัดเจนและสะดวก

2.วัตถุประสงค์

วัตถุประสงค์หลักของการสร้างเกม XO บนเว็บนี้คือเพื่อจำลองการเล่นเกม XO แบบดั้งเดิมให้มาอยู่ในรูปแบบดิจิทัล เพื่อให้ผู้เล่นสามารถเพลิดเพลินไปกับการเล่นเกมได้ทุกที่ทุกเวลา นอกจากนี้ โปรแกรมนี้ยังช่วยพัฒนาทักษะการคิดวิเคราะห์และการวางแผนล่วงหน้า เป็นการฝึกสมองเล็กๆ น้อยๆ ที่สนุกและไม่ยุ่งยาก

3. ขอบเขต

โปรแกรมเกม XO ที่เราออกแบบมานี้เหมาะสำหรับการเล่นระหว่างผู้เล่นสองคน โดยตัวเกมจะมีกริด 3×3 ที่ให้ผู้เล่นผลัดกันใส่ตัวอักษร “X” และ “O” จนกว่าจะมีผู้ชนะ หรือเกมเสมอกัน หากมีผู้ชนะ โปรแกรมจะสร้างกระดาษสีตกลงมาเพื่อฉลองชัยชนะ และจะแสดงคะแนนของผู้เล่นแต่ละฝั่ง ไม่ได้มีการเล่นกับคอมพิวเตอร์ (AI) หรือการออนไลน์แข่งกับผู้เล่นอื่น แต่ก็เหมาะกับการเล่นในหมู่เพื่อนๆ ได้อย่างดี

4.ประโยชน์ที่คาดว่าจะได้รับ

• ช่วยสร้างความเพลิดเพลินในเวลาว่าง
• ฝึกการคิดวิเคราะห์ วางแผน และการสังเกต
• กระตุ้นสมองในรูปแบบเกมเบาๆ โดยไม่ต้องมีความซับซ้อน
• พัฒนาทักษะการเขียนโปรแกรมด้านการจัดการเหตุการณ์ (event-driven programming) และการจัดการ DOM สำหรับนักพัฒนา
• เป็นตัวอย่างที่ดีสำหรับการศึกษาการสร้างเกมด้วย HTML, CSS และ JavaScript

5. ความรู้ที่เกี่ยวข่้อง

    โปรแกรมนี้ใช้ HTML เป็นโครงสร้างของหน้าเว็บ, CSS ในการจัดแต่งรูปแบบและการเคลื่อนไหว และ JavaScript ในการควบคุมการทำงานของเกม ตั้งแต่การตรวจสอบผู้ชนะ การสลับเทิร์น การคำนวณคะแนน ไปจนถึงการสร้างเอฟเฟกต์กระดาษตกเมื่อชนะ นอกจากนี้ยังมีการใช้การออกแบบที่เรียกว่า grid layout สำหรับการจัดวางตำแหน่งกล่องต่างๆ ในเกม รวมถึงการใช้ event listeners ในการจัดการการคลิกของผู้เล่น

    6.สรุปวิธีการใช้โปรแกรม

    1. เปิดเกม XO ผ่านเบราว์เซอร์ใดก็ได้
    2. จะมีกริด 3×3 แสดงบนหน้าจอ ผู้เล่นสองคนสามารถผลัดกันคลิกที่ช่องว่างในกริดเพื่อวาง “X” หรือ “O”
    3. หากผู้เล่นคนใดคนหนึ่งเรียงตัวอักษรครบ 3 ตัวตามเงื่อนไขชนะ (แนวนอน แนวตั้ง หรือแนวทแยง) โปรแกรมจะแสดงผลว่าผู้เล่นคนนั้นชนะ
    4. หลังจากที่มีผู้ชนะหรือเกมเสมอ ปุ่มเล่นอีกครั้งจะปรากฏขึ้น เพื่อให้เริ่มเกมใหม่
    5. โปรแกรมจะนับคะแนนของผู้เล่นแต่ละฝั่งตามจำนวนครั้งที่ชนะ

    7. บทสรุปผลการทดลอง

    หลังจากทดลองเล่นแล้ว พบว่าเกม XO นี้ทำงานได้ดี ไม่มีปัญหาในการเล่น ข้อมูลการสลับเทิร์นและการตรวจสอบผู้ชนะสามารถทำได้อย่างถูกต้อง เอฟเฟกต์กระดาษตกเมื่อมีผู้ชนะทำให้เกมดูสนุกและมีชีวิตชีวามากขึ้น การใช้งานง่าย ผู้เล่นไม่ต้องมีทักษะพิเศษในการเล่น เพราะทุกอย่างถูกจัดการด้วยการคลิกเพียงอย่างเดียว

    8. การทำงานของโปรแกรม

    1. การตั้งค่าเริ่มต้น (HTML + CSS)

    1.1 HTML

    • โค้ดสร้างโครงสร้างพื้นฐานของหน้าเว็บโดยใช้แท็ก HTML ต่างๆ เช่น <div> สำหรับกล่องตาราง 3×3 และ <button> สำหรับปุ่ม “เล่นใหม่”
    • ตัวอย่างการใช้งาน:
      • <div class="turn-container"> ใช้แสดงข้อความ “Turn For” และบอกว่าตอนนี้เป็นตาของผู้เล่นคนใด (X หรือ O)
      • <div class="main-grid"> ใช้สร้างตารางเกม 3×3 (9 กล่อง) ซึ่งเป็นพื้นที่ที่ผู้เล่นจะคลิกเพื่อใส่สัญลักษณ์ X หรือ O
      • <div id="score-container"> ใช้แสดงคะแนนของผู้เล่นทั้งสองคน โดยเริ่มต้นจาก 0

    1.2 CSS

    • การออกแบบและจัดสไตล์หน้าเว็บ เช่น ขนาดกล่องในตาราง สีพื้นหลัง ฟอนต์ และการจัดวางองค์ประกอบต่างๆ ในหน้าจอ
      • CSS กำหนดสีสันของแต่ละองค์ประกอบ เช่น สีของผู้เล่นที่ชนะ (#08D9D6) สีพื้นหลัง (#252A34) และการเปลี่ยนสีเมื่อเมาส์วางเหนือกล่อง (เปลี่ยนเป็นสีแดง)
      • มีการใช้แอนิเมชันสำหรับการสร้าง “กระดาษตก” เพื่อเฉลิมฉลองเมื่อมีผู้ชนะ

    2. การจัดการการเล่นเกม (JavaScript)

    2.1 ตัวแปรและสถานะ

    • ตัวแปรที่สำคัญมีดังนี้:
      • boxes: เก็บกล่องทั้งหมดในตารางเกม
      • turn: เก็บข้อมูลว่าผู้เล่นคนใดกำลังเล่น (เริ่มต้นเป็น “X”)
      • isGameOver: ใช้ตรวจสอบว่าเกมสิ้นสุดแล้วหรือยัง
      • xScore และ oScore: เก็บคะแนนของผู้เล่น X และ O ตามลำดับ

    2.2 การคลิกและการเปลี่ยนผู้เล่น

    • เมื่อผู้เล่นคลิกที่กล่องใดๆ จะทำการตรวจสอบว่า:
      1. กล่องนั้นว่างอยู่หรือไม่
      2. เกมสิ้นสุดแล้วหรือยัง
    • ถ้ากล่องว่างและเกมยังไม่จบ จะทำการใส่สัญลักษณ์ของผู้เล่นปัจจุบัน (X หรือ O) ลงในกล่อง
    • จากนั้นจะสลับตาไปยังผู้เล่นคนถัดไปโดยการเรียกฟังก์ชัน changeTurn() ซึ่งจะเปลี่ยนตัวแปร turn และย้ายแถบสีบอกสถานะผู้เล่น

    2.3 ฟังก์ชันตรวจสอบผู้ชนะ (checkWin)

    • มีเงื่อนไขการชนะทั้งหมด 8 รูปแบบ (3 แนวนอน, 3 แนวตั้ง, 2 แนวทแยง) ซึ่งจะถูกตรวจสอบโดยฟังก์ชัน checkWin()
      • ฟังก์ชันจะตรวจสอบว่าในกล่องที่กำหนดมีสัญลักษณ์ X หรือ O ที่เรียงกันครบสามตัวหรือไม่ ถ้าพบผู้ชนะจะทำการ:
        1. แสดงข้อความบอกผู้ชนะ
        2. เพิ่มคะแนนให้กับผู้เล่นที่ชนะ
        3. เรียกแอนิเมชัน “กระดาษตก” เพื่อเฉลิมฉลอง
        4. เปลี่ยนสีพื้นหลังของกล่องที่ทำให้ชนะ

    2.4 ฟังก์ชันตรวจสอบว่าเสมอหรือไม่ (checkDraw)

    • ถ้าทุกกล่องเต็มและไม่มีผู้ชนะ ฟังก์ชันนี้จะตั้งค่าว่าเกมจบลงด้วยผลเสมอ และแสดงข้อความบอกผู้เล่นว่าเกมเสมอแล้ว

    2.5 การเล่นเกมใหม่ (play again)

    • เมื่อเกมจบลง (ไม่ว่าจะชนะหรือเสมอ) จะมีการแสดงปุ่ม “เล่นใหม่” ซึ่งเมื่อผู้เล่นคลิก ระบบจะทำการรีเซ็ตตารางเกมทั้งหมดและเริ่มเกมใหม่ทันที

    3. สรุปการทำงานโดยรวม

    • เมื่อผู้เล่นคลิกบนกล่องในตาราง 3×3 ระบบจะ:
      1. ใส่สัญลักษณ์ X หรือ O ลงในกล่องนั้น
      2. ตรวจสอบว่ามีผู้ชนะหรือไม่
      3. ถ้าผู้เล่นชนะ ระบบจะเพิ่มคะแนนและฉลองด้วยการแสดง “กระดาษตก”
      4. ถ้าทุกกล่องเต็มและไม่มีผู้ชนะ ระบบจะถือว่าเกมเสมอ
      5. ผู้เล่นสามารถเริ่มเกมใหม่ได้โดยการกดปุ่ม “เล่นใหม่”

    ภาพรวมของโค้ด

    <!DOCTYPE html>
    <html lang="en">
    <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">
    <title>ดวลกันป่าวจ๊ะ</title>
    <style>
    * {
    color: white;
    font-family: sans-serif;
    transition: 0.2s ease-in-out;
    user-select: none;
    }
    .align {
    display: flex;
    justify-content: center;
    align-items: center;
    }
    body {
    background-color: #252A34;
    margin: 0;
    padding: 0;
    width: 100vw;
    text-align: center;
    padding-top: 5vh;
    overflow: hidden; /* Prevent scrollbar from appearing */
    position: relative;
    }
    .turn-container {
    width: 170px;
    height: 80px;
    margin: auto;
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    position: relative;
    }
    .turn-container h3 {
    margin: 0;
    grid-column-start: 1;
    grid-column-end: 3;
    }
    .turn-container .turn-box {
    border: 3px solid #000;
    font-size: 1.6rem;
    font-weight: 700;
    }
    .turn-container .turn-box:nth-child(even) {
    border-right: none;
    }
    .bg {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 85px;
    height: 40px;
    background-color: #FF2E63;
    z-index: -1;
    }
    .main-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(3, 1fr);
    height: 250px;
    width: 250px;
    margin: 30px auto;
    border: 2px solid #000;
    }
    .box {
    cursor: pointer;
    font-size: 2rem;
    font-weight: 700;
    border: 2px solid #000;
    }
    .box:hover {
    background-color: #FF2E63;
    }
    #play-again {
    background-color: #FF2E63;
    padding: 10px 25px;
    border: none;
    font-size: 1.2rem;
    border-radius: 5px;
    cursor: pointer;
    display: none;
    }
    #play-again:hover {
    padding: 10px 40px;
    background-color: #08D9D6;
    color: #000;
    }
    @keyframes fall {
    0% {
    transform: translateY(0);
    opacity: 1;
    }
    100% {
    transform: translateY(100vh);
    opacity: 0;
    }
    }
    .paper {
    position: absolute;
    width: 10px; /* Adjust paper size */
    height: 10px; /* Adjust paper size */
    background-color: red; /* Default color */
    opacity: 0.8;
    animation: fall linear forwards;
    }
    #score-container {
    position: absolute;
    right: 20px; /* Adjust position */
    top: 20px; /* Adjust position */
    text-align: left;
    }
    </style>
    </head>
    <body>
    <div class="turn-container">
    <h3>Turn For</h3>
    <div class="turn-box align">X</div>
    <div class="turn-box align">O</div>
    <div class="bg"></div>
    </div>
    <div id="score-container">
    <h2>Score</h2>
    <p>X: <span id="x-score">0</span></p>
    <p>O: <span id="o-score">0</span></p>
    </div>
    <div class="main-grid">
    <div class="box align">0</div>
    <div class="box align">1</div>
    <div class="box align">2</div>
    <div class="box align">3</div>
    <div class="box align">4</div>
    <div class="box align">5</div>
    <div class="box align">6</div>
    <div class="box align">7</div>
    <div class="box align">8</div>
    </div>
    <h2 id="results"></h2>
    <button id="play-again">ไหวป่าวอีกสักทีไหม</button>
    <script>
    let boxes = document.querySelectorAll(".box");

    let turn = "X";
    let isGameOver = false;
    let xScore = 0;
    let oScore = 0;

    boxes.forEach(e => {
    e.innerHTML = "";
    e.addEventListener("click", () => {
    if (!isGameOver && e.innerHTML === "") {
    e.innerHTML = turn;
    checkWin();
    checkDraw();
    changeTurn();
    }
    });
    });

    function changeTurn() {
    if (turn === "X") {
    turn = "O";
    document.querySelector(".bg").style.left = "85px";
    } else {
    turn = "X";
    document.querySelector(".bg").style.left = "0";
    }
    }

    function createPapers(count) {
    const colors = ["red", "blue", "green", "yellow", "orange", "purple"]; // Define colors for papers
    for (let i = 0; i < count; i++) {
    const paper = document.createElement("div");
    paper.classList.add("paper");
    paper.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]; // Random color
    paper.style.left = Math.random() * 100 + "vw"; // Random horizontal position
    paper.style.top = "80px"; // Start falling from below the "Turn For" bar
    paper.style.animationDuration = Math.random() * 4 + 3 + "s"; // Random duration between 3s to 7s
    document.body.appendChild(paper);

    // Remove paper after falling
    setTimeout(() => {
    paper.remove();
    }, 7000); // Should match the max duration in animation
    }
    }

    function checkWin() {
    let winConditions = [
    [0, 1, 2], [3, 4, 5], [6, 7, 8],
    [0, 3, 6], [1, 4, 7], [2, 5, 8],
    [0, 4, 8], [2, 4, 6]
    ];
    for (let i = 0; i < winConditions.length; i++) {
    let v0 = boxes[winConditions[i][0]].innerHTML;
    let v1 = boxes[winConditions[i][1]].innerHTML;
    let v2 = boxes[winConditions[i][2]].innerHTML;

    if (v0 !== "" && v0 === v1 && v0 === v2) {
    isGameOver = true;
    createPapers(500); // Create 500 papers when someone wins
    if (turn === "X") {
    xScore++;
    document.querySelector("#x-score").innerHTML = xScore;
    } else {
    oScore++;
    document.querySelector("#o-score").innerHTML = oScore;
    }
    document.querySelector("#results").innerHTML = turn + " ชนะใสๆ ง่ายไปป่าว";
    document.querySelector("#play-again").style.display = "inline";

    for (let j = 0; j < 3; j++) {
    boxes[winConditions[i][j]].style.backgroundColor = "#08D9D6";
    boxes[winConditions[i][j]].style.color = "#000";
    }
    }
    }
    }

    function checkDraw() {
    if (!isGameOver) {
    let isDraw = true;
    boxes.forEach(e => {
    if (e.innerHTML === "") isDraw = false;
    });

    if (isDraw) {
    isGameOver = true;
    document.querySelector("#results").innerHTML = "เสมอเอาใหม่ป่ะ";
    document.querySelector("#play-again").style.display = "inline";
    }
    }
    }

    document.querySelector("#play-again").addEventListener("click", () => {
    isGameOver = false;
    turn = "X";
    document.querySelector(".bg").style.left = "0";
    document.querySelector("#results").innerHTML = "";
    document.querySelector("#play-again").style.display = "none";

    boxes.forEach(e => {
    e.innerHTML = "";
    e.style.removeProperty("background-color");
    e.style.color = "#fff";
    });
    });
    </script>
    </body>
    </html>

    You may also like...

    ใส่ความเห็น

    อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *