AngularJS数独求解器:输入值非法时设置红色边框
Solution for 6x6 Sudoku Input Validation in AngularJS
Hey there! Let's implement the validation logic you need for your 6x6 Sudoku solver. We'll add rule checks for rows, columns, and 2×3 boxes, then highlight invalid inputs with a red border. Here's how to do it step by step:
Step 1: Add Validation Logic to the Controller
First, we'll add a helper function to your SudokuController that checks if a cell's value violates any Sudoku rules. Update your controller code like this:
(function (angular) { SudokuController.$inject = ['$scope']; function SudokuController($scope) { var initialized = false; // Fix: Declare the initialized variable properly function Cell(row, column) { this.row = row; this.column = column; } // Initialize our sudoku puzzle object $scope.puzzle = {}; $scope.puzzle.dimensions = 6; $scope.puzzle.board = Array($scope.puzzle.dimensions); // Fix: Proper array initialization $scope.puzzle.moves = []; $scope.initialize = function () { // Initialize the gameboard with empty values for (var i = 0; i < $scope.puzzle.dimensions; i++) { $scope.puzzle.board[i] = Array($scope.puzzle.dimensions); // Fix: Proper row array setup for (var j = 0; j < $scope.puzzle.dimensions; j++) { $scope.puzzle.board[i][j] = undefined; } } initialized = true; } // NEW: Validation function to check if a cell's value is valid $scope.isCellValid = function(row, col, value) { // Reject values outside 1-6, empty, or non-numeric if (!value || isNaN(value) || value < 1 || value > 6) { return false; } // Check for duplicates in the same row for (let c = 0; c < $scope.puzzle.dimensions; c++) { if (c !== col && $scope.puzzle.board[row][c] === value) { return false; } } // Check for duplicates in the same column for (let r = 0; r < $scope.puzzle.dimensions; r++) { if (r !== row && $scope.puzzle.board[r][col] === value) { return false; } } // Check for duplicates in the 2×3 box const boxStartRow = Math.floor(row / 2) * 2; // Split 6 rows into 2-row boxes const boxStartCol = Math.floor(col / 3) * 3; // Split 6 columns into 3-column boxes for (let r = boxStartRow; r < boxStartRow + 2; r++) { for (let c = boxStartCol; c < boxStartCol + 3; c++) { if (r !== row && c !== col && $scope.puzzle.board[r][c] === value) { return false; } } } // All checks passed return true; }; // Add your generate() and solve() functions here if needed angular .module('sudokuApp') .controller('SudokuController', SudokuController); })(window.angular);
Controller Change Notes:
- Fixed array initialization for
$scope.puzzle.boardto avoid length-related bugs - The
isCellValidfunction:- First filters out invalid values (non-numeric, out of 1-6 range)
- Scans the entire row, column, and corresponding 2×3 box for duplicates
- Returns
trueonly if the value follows all Sudoku rules
Step 2: Update the View to Highlight Invalid Inputs
Next, modify your Layout.cshtml input element to use Angular's ng-class directive to apply a red border when the input is invalid. We'll also add min and max attributes to restrict input to valid numbers:
<div ng-controller="SudokuController" class="container"> <div class="row"> <div class="col-xs-12 col-sm-12 col-md-12 col-lg-6"> <style> /* Style for invalid inputs */ .invalid-input { border: 2px solid #dc3545; /* Bootstrap danger red to match your button styles */ } </style> <form role="form" class="center-block" style="width: 1100px; height: 200px; margin-top:100px;"> <div ng-repeat="row in [0,1,2,3,4,5]" class="row solverrow "> <div ng-repeat="column in [0,1,2,3,4,5]" class="col-sm-1 nopadding {{ row | rowFilter }} {{ column | columnFilter }} "> <input oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);" type="number" maxlength="1" min="1" max="6" class="form-control text-center" ng-model="puzzle.board[row][column]" name="cell[]" ng-class="{'invalid-input': puzzle.board[row][column] !== undefined && !isCellValid(row, column, puzzle.board[row][column])}" > </div> </div> </form> <div class="row angmenu"> <button type="button" class="btn btn-primary" ng-click="initialize()">Initialize</button> <button type="button" class="btn btn-generate" ng-click="generate()">Generate new board</button> <button type="button" class="btn btn-success" ng-click="solve()">Solve</button> </div> </div> </div> </div>
View Change Notes:
- Added
min="1"andmax="6"to restrict user input to valid Sudoku values upfront - Used
ng-classto dynamically apply theinvalid-inputclass only when:- The cell has a defined value (not empty)
- The value fails the
isCellValidcheck
- Added inline CSS for the red border (you can move this to your external stylesheet if preferred)
How It Works
- As soon as the user types a number into a cell, Angular runs the
isCellValidfunction for that cell - If the number is duplicate in the row, column, or box, or outside 1-6, the input's border turns red immediately
- Empty cells won't show the red border, since we only apply the class when the cell has a value
内容的提问来源于stack exchange,提问作者Vasi G.
相关产品推荐
相关产品推荐

