Bingo

/*

@startuml
class Bingo {
    - final char letter
    - final int number
    - static final Random rand
    + Bingo()
    + Bingo(letter: char, number: int)
    - generateRandomNumber(letter: char): int
    - isValidLetter(letter: char): boolean
    - isValidNumber(letter: char, number: int): boolean
    + getLetter(): char
    + getNumber(): int
    + toString(): String
}

class BingoGame {
    + main(args: String[]): void
    - testValidBingoCalls(): void
    - testInvalidBingoCalls(): void
}

BingoGame --> Bingo : "Creates & Controls"
Bingo ..> java.util.Random : "Uses"

@enduml

*/

import java.util.Random;

/**
 * Represents a Bingo call with a letter (B, I, N, G, O) and a number
 */
class Bingo {
    private final char letter;  // Stores the letter (B, I, N, G, O)
    private final int number;   // Stores the number corresponding to the letter
    private static final Random rand = new Random(); // Shared Random instance

    /**
     * Default constructor - generates a random Bingo call
     */
    public Bingo() {
        char[] letters = {'B', 'I', 'N', 'G', 'O'};
        this.letter = letters[rand.nextInt(5)];
        this.number = generateRandomNumber(letter);
    }

    /**
     * Constructor with specific letter and number
     * If invalid, defaults to "N, FREE"
     */
    public Bingo(char letter, int number) {
        if (isValidLetter(letter) && isValidNumber(letter, number)) {
            this.letter = letter;
            this.number = number;
        } else {
            this.letter = 'N';
            this.number = 0; // Defaults to "N, FREE" if invalid
        }
    }

    /**
     * Generates a random number based on the Bingo letter category
     */
    private int generateRandomNumber(char letter) {
        return switch (letter) {
            case 'B' -> rand.nextInt(15) + 1;   // 1 to 15
            case 'I' -> rand.nextInt(15) + 16;  // 16 to 30
            case 'N' -> rand.nextInt(15) + 31;  // 31 to 45
            case 'G' -> rand.nextInt(15) + 46;  // 46 to 60
            case 'O' -> rand.nextInt(15) + 61;  // 61 to 75
            default -> 0; // Should not occur
        };
    }

    /**
     * Validate if the letter is in "BINGO"
     */
    private boolean isValidLetter(char letter) {
        return "BINGO".indexOf(letter) != -1;
    }

    /**
     * Validate if the number is within the correct range for the letter
     */
    private boolean isValidNumber(char letter, int number) {
        return switch (letter) {
            case 'B' -> number >= 1 && number <= 15;
            case 'I' -> number >= 16 && number <= 30;
            case 'N' -> number >= 31 && number <= 45;
            case 'G' -> number >= 46 && number <= 60;
            case 'O' -> number >= 61 && number <= 75;
            default -> false;
        };
    }

    /**
     * Converts Bingo object to a string format like "B, 12"
     */
    @Override
    public String toString() {
        return String.format("%s, %s", letter, (number == 0 ? "FREE" : number));
    }
}

/**
 * Main driver class for testing Bingo calls
 */
public class BingoGame {
    public static void main(String[] args) {
        System.out.println("------ 20 Random Bingo Calls ------");
        for (int i = 0; i < 20; i++) {
            Bingo bingoCall = new Bingo();
            System.out.println(bingoCall);
        }

        System.out.println("\n------ Valid Bingo Calls (Boundary & Mid-Range) ------");
        testValidBingoCalls();

        System.out.println("\n------ Invalid Bingo Calls (Should Default to N, FREE) ------");
        testInvalidBingoCalls();
    }

    /**
     * Method to test valid Bingo calls (Boundary & Mid-Range)
     */
    private static void testValidBingoCalls() {
        char[] letters = {'B', 'I', 'N', 'G', 'O'};
        int[][] testNumbers = {
            {1, 7, 15},    // B column
            {16, 22, 30},  // I column
            {31, 38, 45},  // N column
            {46, 53, 60},  // G column
            {61, 69, 75}   // O column
        };

        for (int i = 0; i < letters.length; i++) {
            for (int j = 0; j < testNumbers[i].length; j++) {
                System.out.println(new Bingo(letters[i], testNumbers[i][j]));
            }
        }
    }

    /**
     * Method to test invalid Bingo calls
     */
    private static void testInvalidBingoCalls() {
        Bingo[] invalidCalls = {
            new Bingo('X', 10),  // Invalid letter
            new Bingo('B', 42),  // Invalid number for B
            new Bingo('I', 11),  // Invalid number for I
            new Bingo('N', 75),  // Invalid number for N
            new Bingo('G', 1),   // Invalid number for G
            new Bingo('O', 80)   // Invalid number for O
        };

        for (Bingo call : invalidCalls) {
            System.out.println(call);
        }
    }
}
Scroll to Top