Blog

Building a Slot Machine using JS

In this project, we will build a simple slot machine game using HTML, CSS, and JavaScript. The slot machine will allow users to deposit money, place bets, and spin the reels to potentially win more money. This project is an excellent demonstration of basic web development concepts, including user interaction, dynamic content updates, and handling game logic. Whether you’re a beginner or looking to polish your skills, this project provides a hands-on approach to learning web development.

Project Overview:

Our slot machine game consists of the following features:

  1. Deposit Money: Users can deposit an amount of money to start the game.
  2. Place Bets: Users can choose the number of lines to bet on (1-3) and enter the bet amount per line.
  3. Spin the Reels: Users can spin the slot machine to see if they win.
  4. Check Winnings: The game calculates if the user has won based on the symbols displayed on the reels and updates their balance accordingly.
  5. Repeat or Quit: Users can continue playing until they run out of money or decide to quit.

HTML Structure:

We start by creating the HTML structure for our game. This includes input fields for depositing money, selecting the number of lines, entering the bet amount, and buttons to start the game, spin the reels, and quit the game.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Slot Machine Game</title>
    <style>
        .hidden { display: none; }
        .visible { display: block; }
        #result { margin-top: 20px; }
    </style>
</head>
<body>
    <h1>Slot Machine Game</h1>

    <div id="deposit-section">
        <label for="deposit">Enter Deposit Amount:</label>
        <input type="number" id="deposit" step="0.01" min="0">
        <button id="startGameButton">Start Game</button>
    </div>

    <div id="game-section" class="hidden">
        <p id="balance"></p>

        <label for="lines">Number of lines to bet (1-3):</label>
        <input type="number" id="lines" min="1" max="3">
        
        <label for="bet">Enter Bet Amount (per line):</label>
        <input type="number" id="bet" step="0.01" min="0">
        
        <button id="playButton">Spin</button>
        
        <div id="result">
            <p id="rows"></p>
            <p id="winnings"></p>
        </div>

        <button id="quitGameButton">Quit Game</button>
    </div>

    <script src="game.js" defer></script>
</body>
</html>

CSS Styling:

For simplicity, the CSS is minimal and focuses on showing or hiding sections of the game with very little styling. We wanted to show off JS and functionality more in this project. We are pulling in Bootstrap for most of the generic styling in our HTML file.

.hidden {
    display: none;
}

.visible {
    display: block;
}

#result {
    margin-top: 20px;
}
.center{
    text-align: center;
    justify-content: center;
    align-items: center;
}
.jumbotron{
    color: #fff;
    background-repeat: no-repeat;
    background-size: cover;
    background-position: 50% 55%;
}

JavaScript Logic:

The JavaScript handles the game logic, including taking user inputs, spinning the reels, checking for winnings, and updating the balance. This is the meat and potatoes of the program.

const ROWS = 3;
const COLS = 3;

const SYMBOLS_COUNT = {
    "A": 3,
    "B": 5,
    "C": 8,
    "D": 10
};

const SYMBOL_VALUES = {
    "A": 20,
    "B": 10,
    "C": 8,
    "D": 3
};

let balance = 0;

function startGame() {
    const depositAmount = parseFloat(document.getElementById('deposit').value);
    if (isNaN(depositAmount) || depositAmount <= 0) {
        alert("Invalid deposit amount");
        return;
    }
    balance = depositAmount;
    document.getElementById('deposit-section').classList.add('hidden');
    document.getElementById('game-section').classList.remove('hidden');
    document.getElementById('balance').innerText = "Balance: $" + balance.toFixed(2);
}

function play() {
    const lines = parseInt(document.getElementById('lines').value);
    const bet = parseFloat(document.getElementById('bet').value);

    if (isNaN(lines) || lines <= 0 || lines > 3) {
        alert("Invalid number of lines. Select 1, 2, or 3 lines.");
        return;
    }
    if (isNaN(bet) || bet <= 0 || bet > balance / lines) {
        alert("Invalid bet amount");
        return;
    }

    balance -= bet * lines;
    document.getElementById('balance').innerText = "Balance: $" + balance.toFixed(2);

    const reels = spin();
    const rows = transpose(reels);
    displayRows(rows);

    const winnings = getWinnings(rows, bet, lines);
    balance += winnings;
    document.getElementById('winnings').innerText = "You won: $" + winnings.toFixed(2);
    document.getElementById('balance').innerText = "Balance: $" + balance.toFixed(2);

    if (balance <= 0) {
        alert("You are out of money!");
        quitGame();
    }
}

function quitGame() {
    document.getElementById('game-section').classList.add('hidden');
    document.getElementById('deposit-section').classList.remove('hidden');
    document.getElementById('deposit').value = '';
    document.getElementById('lines').value = '';
    document.getElementById('bet').value = '';
    document.getElementById('rows').innerText = '';
    document.getElementById('winnings').innerText = '';
    balance = 0;
}

function spin() {
    const symbols = [];
    for (const [symbol, count] of Object.entries(SYMBOLS_COUNT)) {
        for (let i = 0; i < count; i++) {
            symbols.push(symbol);
        }
    }

    const reels = [];
    for (let i = 0; i < COLS; i++) {
        reels.push([]);
        const reelSymbols = [...symbols];
        for (let j = 0; j < ROWS; j++) {
            const randomIndex = Math.floor(Math.random() * reelSymbols.length);
            const selectedSymbol = reelSymbols[randomIndex];
            reels[i].push(selectedSymbol);
            reelSymbols.splice(randomIndex, 1);
        }
    }
    return reels;
}

function transpose(reels) {
    const rows = [];
    for (let i = 0; i < ROWS; i++) {
        rows.push([]);
        for (let j = 0; j < COLS; j++) {
            rows[i].push(reels[j][i]);
        }
    }
    return rows;
}

function displayRows(rows) {
    let rowsString = "";
    for (const row of rows) {
        rowsString += row.join(" | ") + "<br>";
    }
    document.getElementById('rows').innerHTML = rowsString;
}

function getWinnings(rows, bet, lines) {
    let winnings = 0;
    for (let row = 0; row < lines; row++) {
        const symbols = rows[row];
        if (symbols.every(symbol => symbol === symbols[0])) {
            winnings += bet * SYMBOL_VALUES[symbols[0]];
        }
    }
    return winnings;
}

Below is a working JSFiddle of the project for your to play around with! You can also create your own JSFiddle using this code and modify it however you like!

This project demonstrates how to create an interactive slot machine game using basic web technologies. By working on this project, you learn how to handle user inputs, update the DOM dynamically, and implement game logic using JavaScript. It also gives you a practical understanding of how to structure HTML and CSS for a simple web application. Happy coding!