001package ball.game.sudoku; 002/*- 003 * ########################################################################## 004 * Game Applications and Utilities 005 * %% 006 * Copyright (C) 2010 - 2022 Allen D. Ball 007 * %% 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 * ########################################################################## 020 */ 021import lombok.NoArgsConstructor; 022 023import static lombok.AccessLevel.PROTECTED; 024 025/** 026 * Sudoku {@link Puzzle} solution {@link Rule}. 027 * 028 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball} 029 */ 030@NoArgsConstructor(access = PROTECTED) 031public abstract class Rule { 032 033 /** 034 * Method to apply {@link.this} {@link Rule} to the argument 035 * {@link Puzzle}. 036 * 037 * @param puzzle The {@link Puzzle} to solve. 038 * 039 * @return {@code true} if {@link.this} {@link Puzzle} is modified; 040 * {@code false} otherwise. 041 */ 042 public abstract boolean applyTo(Puzzle puzzle); 043 044 /** 045 * Method to get the count of solved {@link Cell}s. 046 * 047 * @param iterable The {@link Iterable} of {@link Cell}s. 048 * 049 * @return The count of solved {@link Cell}s. 050 */ 051 protected int count(Iterable<Cell> iterable) { 052 var count = 0; 053 054 for (var cell : iterable) { 055 if (cell.isSolved()) { 056 count += 1; 057 } 058 } 059 060 return count; 061 } 062 063 /** 064 * Method to get the sum of solved {@link Cell}s. 065 * 066 * @param iterable The {@link Iterable} of {@link Cell}s. 067 * 068 * @return The sum of solved {@link Cell}s. 069 */ 070 protected int sum(Iterable<Cell> iterable) { 071 var sum = 0; 072 073 for (var cell : iterable) { 074 if (cell.isSolved()) { 075 sum += cell.solution(); 076 } 077 } 078 079 return sum; 080 } 081 082 /** 083 * Method to get the solved {@link Digits}. 084 * 085 * @param iterable The {@link Iterable} of {@link Cell}s. 086 * 087 * @return The solved {@link Digits}. 088 */ 089 protected Digits solved(Iterable<Cell> iterable) { 090 var digits = new Digits(); 091 092 digits.clear(); 093 094 for (var cell : iterable) { 095 if (cell.isSolved()) { 096 digits.addAll(cell); 097 } 098 } 099 100 return digits; 101 } 102}