From c495fb725e337184070b5c78c09a6863b5469c71 Mon Sep 17 00:00:00 2001 From: StevanFreeborn Date: Fri, 27 May 2022 09:33:58 -0500 Subject: [PATCH] finish implementing /api/check route --- controllers/sudoku-solver.js | 18 +++++----- routes/api.js | 66 ++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 9 deletions(-) diff --git a/controllers/sudoku-solver.js b/controllers/sudoku-solver.js index fde741f..3e2dc95 100644 --- a/controllers/sudoku-solver.js +++ b/controllers/sudoku-solver.js @@ -37,9 +37,9 @@ class SudokuSolver { // get existing value placed const existingValue = rowValues[column - 1]; - // make sure placement location doesn't contain a value or contains same value - // make sure placements row does not already have value. - return (existingValue == '.' || existingValue == value) && !rowValues.includes(value); + // make sure placement location doesn't contain a value and row doesn't contain value + // or same value already exists in location + return (existingValue == '.' && !rowValues.includes(value)) || existingValue == value; } @@ -100,9 +100,9 @@ class SudokuSolver { break; } - // make sure placement location doesn't contain a value or contains same value - // make sure placements row does not already have value. - return (existingValue == '.' || existingValue == value) && !columnValues.includes(value); + // make sure placement location doesn't contain a value and column doesn't contain value + // or location already contains value + return (existingValue == '.' && !columnValues.includes(value)) || existingValue == value; } @@ -169,9 +169,9 @@ class SudokuSolver { // get existing value from grid values based on location passed let existingValue = gridValues[locations.indexOf(location)]; - // make sure placement location doesn't contain a value or contains same value - // make sure placements grid does not already have value. - return (existingValue == '.' || existingValue == value) && !gridValues.includes(value); + // make sure placement location doesn't contain a value and grid doesn't contain value + // or location already contains value. + return (existingValue == '.' && !gridValues.includes(value)) || existingValue == value; } diff --git a/routes/api.js b/routes/api.js index e585f37..74e4bf1 100644 --- a/routes/api.js +++ b/routes/api.js @@ -1,6 +1,8 @@ 'use strict'; const SudokuSolver = require('../controllers/sudoku-solver'); +import { columns } from '../models/columns'; +import { rows } from '../models/rows'; module.exports = function (app) { @@ -9,23 +11,87 @@ module.exports = function (app) { app.route('/api/check') .post((req, res) => { + // get puzzle string, coordinate, and value + // from request + const puzzleString = req.body.puzzle; + const coordinate = req.body.coordinate; + const value = req.body.value; + + // if any of the three are not in request return error + if (puzzleString == undefined || coordinate == undefined || value == undefined) return res.status(200).json({error: 'Required field(s) missing'}); + + // attempt to validate puzzle + const validate = solver.validate(puzzleString); + + // if puzzle invalid return error + if (validate != true) return res.status(200).json({error: validate}); + + // get row and col from coordinate value + const row = coordinate.slice(0,1) + const col = coordinate.slice(1, coordinate.length); + + // get the valid rows and cols + const validRows = Object.keys(rows); + const validColumns = Object.keys(columns); + + // if the passed row or col value are not valid return error. + if (!validRows.includes(row) || !validColumns.includes(col)) return res.status(200).json({error: 'Invalid coordinate'}); + + // if the value passed is NaN or less than 1 or greater than 9 return error. + if (parseInt(value) < 1 || parseInt(value) > 9 || isNaN(parseInt(value))) return res.status(200).json({error: 'Invalid value'}); + + // default response + const resObj = { + valid: true + }; + + // check if value can be placed in row, col, and grid according to pass coordinate + const validRow = solver.checkRowPlacement(puzzleString, row, col, value); + const validCol = solver.checkColPlacement(puzzleString, row, col, value); + const validGrid = solver.checkRegionPlacement(puzzleString, row, col, value); + + // if any conflicts build response + // build response indicating invalid placement + // and conflicts causing invalid placement + if (!validRow || !validCol || !validGrid) { + + resObj.valid = false; + resObj.conflict = []; + + if (!validRow) resObj.conflict.push('row'); + if (!validCol) resObj.conflict.push('column'); + if (!validGrid) resObj.conflict.push('grid'); + + return res.status(200).json(resObj); + } + + // if all previous checks pass return default valid response. + return res.status(200).json(resObj); }); app.route('/api/solve') .post((req, res) => { + // get puzzle string from request const puzzleString = req.body.puzzle; + // if no puzzle string in request + // return error if (puzzleString == undefined) return res.status(200).json({error: 'Required field missing' }); + // attempt to validate puzzle const validate = solver.validate(puzzleString); + // if puzzle string invalid return error if (validate != true) return res.status(200).json({error: validate}); + // attempt to solve puzzle const solution = solver.solve(puzzleString); + // if puzzle can't be solved return error if (solution == false) return res.status(200).json({error: 'Puzzle cannot be solved'}); + // otherwise return solution return res.status(200).json({solution: solution}); });