validate.go
changeset 9 4b3436c03726
parent 8 955d3add9426
child 10 8dc05ff5dbe2
equal deleted inserted replaced
8:955d3add9426 9:4b3436c03726
     1 package takuzu
     1 package takuzu
     2 
     2 
     3 import (
     3 // This file contains the takuzu validation functions and methods.
     4 	"fmt"
       
     5 
       
     6 	"github.com/pkg/errors"
       
     7 )
       
     8 
     4 
     9 // checkRange returns true if the range is completely defined, and an error
     5 // checkRange returns true if the range is completely defined, and an error
    10 // if it doesn't follow the rules for a takuzu line or column
     6 // if it doesn't follow the rules for a takuzu line or column
    11 // Note that the boolean might be invalid if the error is not nil.
     7 // Note that the boolean might be invalid if the error is not nil.
    12 func checkRange(cells []Cell) (bool, error) {
     8 func checkRange(cells []Cell) (bool, error) {
    29 			prevCellCount = 1
    25 			prevCellCount = 1
    30 		} else {
    26 		} else {
    31 			if c.Value == prevCell.Value {
    27 			if c.Value == prevCell.Value {
    32 				prevCellCount++
    28 				prevCellCount++
    33 				if prevCellCount > 2 {
    29 				if prevCellCount > 2 {
    34 					return full, errors.Errorf("3+ same values %d", c.Value)
    30 					v := c.Value
       
    31 					return full, validationError{
       
    32 						ErrorType: ErrorTooManyAdjacentValues,
       
    33 						CellValue: &v,
       
    34 					}
    35 				}
    35 				}
    36 			} else {
    36 			} else {
    37 				prevCellCount = 1
    37 				prevCellCount = 1
    38 			}
    38 			}
    39 
    39 
    40 		}
    40 		}
    41 		prevCell = c
    41 		prevCell = c
    42 	}
    42 	}
    43 	if counters[0] > size/2 {
    43 	if counters[0] > size/2 {
    44 		return full, errors.Errorf("too many zeroes")
    44 		v := 0
       
    45 		return full, validationError{
       
    46 			ErrorType: ErrorTooManyValues,
       
    47 			CellValue: &v,
       
    48 		}
    45 	}
    49 	}
    46 	if counters[1] > size/2 {
    50 	if counters[1] > size/2 {
    47 		return full, errors.Errorf("too many ones")
    51 		v := 1
       
    52 		return full, validationError{
       
    53 			ErrorType: ErrorTooManyValues,
       
    54 			CellValue: &v,
       
    55 		}
    48 	}
    56 	}
    49 	return full, nil
    57 	return full, nil
    50 }
    58 }
    51 
    59 
    52 // CheckRangeCounts returns true if all cells of the provided range are defined,
    60 // CheckRangeCounts returns true if all cells of the provided range are defined,
    99 
   107 
   100 		// Let's check line i
   108 		// Let's check line i
   101 		d = b.GetLine(i)
   109 		d = b.GetLine(i)
   102 		full, err = checkRange(d)
   110 		full, err = checkRange(d)
   103 		if err != nil {
   111 		if err != nil {
   104 			return false, errors.Wrapf(err, "line %d", i)
   112 			err := err.(validationError)
       
   113 			err.LineNumber = &i
       
   114 			return false, err
   105 		}
   115 		}
   106 		if full {
   116 		if full {
   107 			hv := computeVal(d)
   117 			hv := computeVal(d)
   108 			if lineVals[hv] {
   118 			if lineVals[hv] {
   109 				return false, fmt.Errorf("duplicate lines (%d)", i)
   119 				err := validationError{
       
   120 					ErrorType:  ErrorDuplicate,
       
   121 					LineNumber: &i,
       
   122 				}
       
   123 				return false, err
   110 			}
   124 			}
   111 			lineVals[hv] = true
   125 			lineVals[hv] = true
   112 		} else {
   126 		} else {
   113 			finished = false
   127 			finished = false
   114 		}
   128 		}
   115 
   129 
   116 		// Let's check column i
   130 		// Let's check column i
   117 		d = b.GetColumn(i)
   131 		d = b.GetColumn(i)
   118 		full, err = checkRange(d)
   132 		full, err = checkRange(d)
   119 		if err != nil {
   133 		if err != nil {
   120 			return false, errors.Wrapf(err, "column %d", i)
   134 			err := err.(validationError)
       
   135 			err.ColumnNumber = &i
       
   136 			return false, err
   121 		}
   137 		}
   122 		if full {
   138 		if full {
   123 			hv := computeVal(d)
   139 			hv := computeVal(d)
   124 			if colVals[hv] {
   140 			if colVals[hv] {
   125 				return false, fmt.Errorf("duplicate columns (%d)", i)
   141 				err := validationError{
       
   142 					ErrorType:    ErrorDuplicate,
       
   143 					ColumnNumber: &i,
       
   144 				}
       
   145 				return false, err
   126 			}
   146 			}
   127 			colVals[hv] = true
   147 			colVals[hv] = true
   128 		} else {
   148 		} else {
   129 			finished = false
   149 			finished = false
   130 		}
   150 		}