public bool IsValidValue(List<GridCell> puzzle, GridCell gridCell) { var max = (int)Math.Sqrt(puzzle.Count); if (gridCell.Value == Queen && !QueenAlreadyOnRow(puzzle, gridCell) && !QueenAlreadyInColumn(puzzle, gridCell) && !QueenAlreadyOnDiagonal(puzzle, gridCell, max)) { return true; } if (gridCell.Value == NotQueen && !TooManyNotQueensOnRow(puzzle, gridCell, max) && !TooManyNotQueensInColumn(puzzle, gridCell, max) && !TooManyNotQueensOnDiagonal(puzzle, gridCell, max)) { return true; } return false; }
// The next two routines, QueenAlreadyOnDiagonal and TooManyNonQueensOnDiagonal, could be better, right? private static bool QueenAlreadyOnDiagonal(List<GridCell> puzzle, GridCell gridCell, int max) { // move up left var r = gridCell.Row - 1; var c = gridCell.Column - 1; while (r > 0 && c > 0) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == Queen) { return true; } --r; --c; } // move down right r = gridCell.Row + 1; c = gridCell.Column + 1; while (r <= max && c <= max) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == Queen) { return true; } ++r; ++c; } // move up right r = gridCell.Row - 1; c = gridCell.Column + 1; while (r > 0 && c <= max) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == Queen) { return true; } --r; ++c; } // move down left r = gridCell.Row + 1; c = gridCell.Column - 1; while (r <= max && c > 0) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == Queen) { return true; } ++r; --c; } return false; }
private static bool QueenAlreadyInColumn(IEnumerable<GridCell> puzzle, GridCell gridCell) { return puzzle.Count(x => x.Column == gridCell.Column && x.Value == Queen) > 1; }
private static bool TooManyNotQueensOnRow(IEnumerable<GridCell> puzzle, GridCell gridCell, int nonQueensAllowed) { return puzzle.Count(x => x.Row == gridCell.Row && x.Value == NotQueen) >= nonQueensAllowed; }
private static bool QueenAlreadyOnRow(IEnumerable<GridCell> puzzle, GridCell gridCell) { return puzzle.Count(x => x.Row == gridCell.Row && x.Value == Queen) > 1; }
private static bool TooManyNotQueensOnDiagonal(List<GridCell> puzzle, GridCell gridCell, int max) { var count = 0; // move up left var r = gridCell.Row - 1; var c = gridCell.Column - 1; while (r > 0 && c > 0) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == NotQueen) { ++count; } --r; --c; } // move down right r = gridCell.Row + 1; c = gridCell.Column + 1; while (r <= max && c <= max) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == NotQueen) { ++count; } ++r; ++c; } // Escape if first diagonal exceeds count if (count > max) return true; count = 0; // move up right r = gridCell.Row - 1; c = gridCell.Column + 1; while (r > 0 && c <= max) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == NotQueen) { ++count; } --r; ++c; } // move down left r = gridCell.Row + 1; c = gridCell.Column - 1; while (r <= max && c > 0) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == NotQueen) { ++count; } ++r; --c; } return count > max; }
private static bool TooManyNotQueensOnRow(IEnumerable <GridCell> puzzle, GridCell gridCell, int nonQueensAllowed) { return(puzzle.Count(x => x.Row == gridCell.Row && x.Value == NotQueen) >= nonQueensAllowed); }
private static bool QueenAlreadyOnRow(IEnumerable <GridCell> puzzle, GridCell gridCell) { return(puzzle.Count(x => x.Row == gridCell.Row && x.Value == Queen) > 1); }
private static bool TooManyNotQueensOnDiagonal(List <GridCell> puzzle, GridCell gridCell, int max) { var count = 0; // move up left var r = gridCell.Row - 1; var c = gridCell.Column - 1; while (r > 0 && c > 0) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == NotQueen) { ++count; } --r; --c; } // move down right r = gridCell.Row + 1; c = gridCell.Column + 1; while (r <= max && c <= max) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == NotQueen) { ++count; } ++r; ++c; } // Escape if first diagonal exceeds count if (count > max) { return(true); } count = 0; // move up right r = gridCell.Row - 1; c = gridCell.Column + 1; while (r > 0 && c <= max) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == NotQueen) { ++count; } --r; ++c; } // move down left r = gridCell.Row + 1; c = gridCell.Column - 1; while (r <= max && c > 0) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == NotQueen) { ++count; } ++r; --c; } return(count > max); }
// The next two routines, QueenAlreadyOnDiagonal and TooManyNonQueensOnDiagonal, could be better, right? private static bool QueenAlreadyOnDiagonal(List <GridCell> puzzle, GridCell gridCell, int max) { // move up left var r = gridCell.Row - 1; var c = gridCell.Column - 1; while (r > 0 && c > 0) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == Queen) { return(true); } --r; --c; } // move down right r = gridCell.Row + 1; c = gridCell.Column + 1; while (r <= max && c <= max) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == Queen) { return(true); } ++r; ++c; } // move up right r = gridCell.Row - 1; c = gridCell.Column + 1; while (r > 0 && c <= max) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == Queen) { return(true); } --r; ++c; } // move down left r = gridCell.Row + 1; c = gridCell.Column - 1; while (r <= max && c > 0) { if (puzzle.First(x => x.Row == r && x.Column == c).Value == Queen) { return(true); } ++r; --c; } return(false); }
private static bool QueenAlreadyInColumn(IEnumerable <GridCell> puzzle, GridCell gridCell) { return(puzzle.Count(x => x.Column == gridCell.Column && x.Value == Queen) > 1); }