Tango Grid Generator

A JavaScript script that generates and validates 6x6 Tango grids.

Grid Generator with Validation

In this tutorial, we will build a JavaScript-based grid generator that creates random 6x6 grids filled with ‘0’ and ‘1’. The grids will be validated to ensure they follow specific rules and will be saved to a file for future use. Let’s dive into the code and understand how it works step by step.

grid

Overview

The goal of this project is to generate random 6x6 grids, check for specific conditions, and store valid grids in a file. The grid must follow certain rules, such as:

  • No three consecutive 0s or 1s in a row or column.
  • Each row and column must contain exactly three 0s and three 1s.

Key Features

  • Random Grid Generation: Creates random 6x6 grids filled with 0s and 1s.
  • Validation Rules: Ensures that the grid meets the requirements before saving it.
  • File Handling: Reads from and writes to a file to keep track of valid grids.

1. Grid Generation and Validation Functions

const fs = require('fs');

// Function to generate a random 6x6 grid of 0s and 1s
function generateRandomGrid(size) {
    let grid = [];
    for (let i = 0; i < size; i++) {
        let row = '';
        for (let j = 0; j < size; j++) {
            row += Math.random() < 0.5 ? '0' : '1';  // Generates a random 0 or 1
        }
        grid.push(row);
    }
    return grid;
}

// Function to check if a row contains "000" or "111"
function isLineValid(line) {
    return !(line.includes("000") || line.includes("111"));
}

// Function to check if a column contains "000" or "111"
function isColumnValid(grid, colIndex) {
    let column = '';
    for (let i = 0; i < grid.length; i++) {
        column += grid[i][colIndex];
    }
    return !(column.includes("000") || column.includes("111"));
}

// Function to check if a line has exactly 3 '1's and 3 '0's
function hasEqualOnesAndZeros(line) {
    const ones = line.split('').filter(x => x === '1').length;
    const zeros = line.split('').filter(x => x === '0').length;
    return ones === 3 && zeros === 3;
}

Explanation

  • generateRandomGrid(size): Generates a random grid of specified size, filled with ‘0’s and ‘1’s.
  • isLineValid(line): Ensures that there are no sequences of three consecutive ‘0’s or ‘1’s in a row.
  • isColumnValid(grid, colIndex): Checks if a column contains three consecutive ‘0’s or ‘1’s.
  • hasEqualOnesAndZeros(line): Validates that each row or column contains exactly three ‘1’s and three ‘0’s.

2. Checking Grid Validity

// Function to validate a grid
function isValidGrid(grid) {
    // Check each row
    for (let i = 0; i < grid.length; i++) {
        if (!isLineValid(grid[i]) || !hasEqualOnesAndZeros(grid[i])) {
            return false;  // Return false if any row is invalid
        }
    }

    // Check each column
    const numCols = grid[0].length;
    for (let j = 0; j < numCols; j++) {
        if (!isColumnValid(grid, j) || !hasEqualOnesAndZeros(grid.map(row => row[j]).join(''))) {
            return false;  // Return false if any column is invalid
        }
    }

    return true;  // Return true if all rows and columns are valid
}

Explanation

  • isValidGrid(grid): This function checks if both the rows and columns of the grid follow the validation rules (no consecutive 000 or 111 and each row/column contains three ‘0’s and three ‘1’s).

3. Ensuring Grid Uniqueness

// Function to check if a grid is unique
function isGridUnique(grid, validGrids) {
    // Check if the grid already exists in the validGrids array
    for (let i = 0; i < validGrids.length; i++) {
        if (JSON.stringify(validGrids[i]) === JSON.stringify(grid)) {
            console.log("Grid already exists in memory.");
            return false;  // Grid is already in memory
        }
    }

    // Check if the grid exists in the file
    try {
        const data = fs.readFileSync('valid_grids.json', 'utf8');
        const fileGrids = JSON.parse(data);  // Load the valid grids from the file
        for (let i = 0; i < fileGrids.length; i++) {
            if (JSON.stringify(fileGrids[i]) === JSON.stringify(grid)) {
                console.log("Grid already exists in file.");
                return false;  // Grid is already in file
            }
        }
    } catch (err) {
        console.log("No valid grids file found, creating a new one.");
    }

    return true;  // Return true if the grid is unique
}

4. Writing Valid Grids to a File

// Function to save valid grids to a file
function saveValidGrid(grid) {
    const data = fs.readFileSync('valid_grids.json', 'utf8');
    const validGrids = JSON.parse(data);
    
    validGrids.push(grid);  // Add the new grid to the array
    fs.writeFileSync('valid_grids.json', JSON.stringify(validGrids));  // Save the updated array
}

5. Generating and Saving Grids

// Main function to generate, validate, and save grids
function generateAndSaveGrids(numGrids) {
    let validGrids = [];
    let attempts = 0;

    while (validGrids.length < numGrids && attempts < 1000) {
        const grid = generateRandomGrid(6);
        if (isValidGrid(grid) && isGridUnique(grid, validGrids)) {
            validGrids.push(grid);
            saveValidGrid(grid);
        }
        attempts++;
    }

    console.log(`${validGrids.length} valid grids generated and saved.`);
}

6. Conclusion

This project demonstrates how to combine grid generation, validation, and file handling in a JavaScript-based application. You can use this to generate random grids that meet specific criteria and save them for future use. By following the steps above, you can create your own grid generation system with validation logic and storage.