EMMA Coverage Report (generated Sat Apr 29 12:52:00 BST 2006)
[all classes][net.sourceforge.pseudoq.solver]

COVERAGE SUMMARY FOR SOURCE FILE [ScanColumnsStrategy.java]

nameclass, %method, %block, %line, %
ScanColumnsStrategy.java100% (1/1)100% (7/7)84%  (285/341)91%  (43/47)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ScanColumnsStrategy100% (1/1)100% (7/7)84%  (285/341)91%  (43/47)
counterValue (String): int 100% (1/1)44%  (11/25)75%  (3/4)
checkColumn (int): SolutionStep 100% (1/1)72%  (46/64)86%  (6/7)
evaluate (): SolutionStep 100% (1/1)83%  (86/104)90%  (9/10)
checkBox (int, int): SolutionStep 100% (1/1)92%  (71/77)91%  (10/11)
<static initializer> 100% (1/1)100% (4/4)100% (1/1)
ScanColumnsStrategy (int, int, int, int, Grid, Map, int, int, int, int): void 100% (1/1)100% (47/47)100% (13/13)
toString (): String 100% (1/1)100% (20/20)100% (1/1)

1/*
2 * Copyright (c) 2005 The PseudoQ Project.
3 *
4 * This file is part of PseudoQ.
5 *
6 * PseudoQ is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
10 *
11 * PseudoQ is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with PseudoQ; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 */
20 
21package net.sourceforge.pseudoq.solver;
22 
23import java.util.Map;
24 
25import net.sourceforge.pseudoq.model.Coordinate;
26import net.sourceforge.pseudoq.model.Grid;
27 
28/**
29 * Puzzle-solving strategy that checks a super-row for values which are only
30 * missing from one row.  If so, this restricts the possibilities to one box,
31 * which is checked to see if it has only one unknown cell in that row.
32 * @author <a href="http://sourceforge.net/users/stevensa">Andrew Stevens</a>
33 */
34public class ScanColumnsStrategy implements Strategy {
35    /** Log4J logger */
36    private static final org.apache.log4j.Logger log =
37            org.apache.log4j.LogManager.getLogger(ScanColumnsStrategy.class);
38 
39    private int superColumn;
40    private int value;
41    private int startColumn;
42    private int endColumn;
43    private Grid grid;
44    protected Map<String, Counter> counters;
45    private int startBox;
46    private int endBox;
47    private int boxOffset;
48    private int cellsPerBox;
49 
50    /** Creates a new instance of ScanColumnsStrategy */
51    public ScanColumnsStrategy(int superColumn, int value, int startColumn, int endColumn,
52            Grid grid, Map<String, Counter> counters,
53            int startBox, int endBox, int boxOffset, int cellsPerBox) {
54        log.debug("Initialising ScanRowsStrategy for value " + value + " on SuperColumn " + superColumn);
55        this.superColumn = superColumn;
56        this.value = value;
57        this.startColumn = startColumn;
58        this.endColumn = endColumn;
59        this.grid = grid;
60        this.counters = counters;
61        this.startBox = startBox;
62        this.endBox = endBox;
63        this.boxOffset = boxOffset;
64        this.cellsPerBox = cellsPerBox;
65    }
66 
67    public SolutionStep evaluate()
68    throws ObsoleteStrategyException, UnsolveablePuzzleException
69    {
70        SolutionStep nextStep = null;
71 
72        if (counterValue("superColumnIndicatorCount-" + superColumn + "-" + value) ==
73                (endColumn - startColumn + 1)) {
74            throw new ObsoleteStrategyException("SuperColumn contains all occurrences of value");
75        } else if (counterValue("superColumnIndicatorCount-" + superColumn + "-" + value) ==
76                (endColumn - startColumn)) {
77            // find column that doesn't contain the value
78            for (int column = startColumn; column <= endColumn; column++) {
79                if (counterValue("columnIndicatorCount-" + column + "-" + value) == 0) {
80                    if (nextStep != null) {
81                        throw new IllegalStateException("Counter out sync with grid for super-column " +
82                                superColumn + ", value " + value);
83                    }
84                    nextStep = checkColumn(column);
85                }
86            }
87 
88//            if ((counterValue("boxIndicatorCount-" + (2 * superRow) + "-" + value) +
89//                    counterValue("boxIndicatorCount-" + ((2 * superRow) + 1) + "-" + value)) != 1) {
90//                throw new IllegalStateException("Counters out of sync for super-row " +
91//                        superRow + " boxes, value " + value);
92//            }
93 
94//            if (counterValue("rowIndicatorCount-" + row1 + "-" + value) == 0 &&
95//                    counterValue("rowIndicatorCount-" + row2 + "-" + value) == 1) {
96//                nextStep = checkRow(row1);
97//            } else if (counterValue("rowIndicatorCount-" + row1 + "-" + value) == 1 &&
98//                    counterValue("rowIndicatorCount-" + row2 + "-" + value) == 0) {
99//                nextStep = checkRow(row2);
100//            } else {
101//                throw new IllegalStateException("Counter out sync with grid for super-row " +
102//                        superRow + ", value " + value);
103//            }
104        }
105 
106        return nextStep;
107    }
108 
109    private int counterValue(String counterKey) {
110        Counter counter = counters.get(counterKey);
111        if (counter == null) {
112            throw new IllegalStateException("Counter " + counterKey + " not found.");
113        } else {
114            return counter.getCount();
115        }
116    }
117 
118    private SolutionStep checkColumn(int column)
119    throws UnsolveablePuzzleException
120    {
121        SolutionStep nextStep = null;
122 
123        // find box that doesn't contain the value
124        for (int box = startBox; box <= endBox; box += boxOffset) {
125            if (counterValue("boxIndicatorCount-" + box + "-" + value) == 0) {
126                if (nextStep != null) {
127                    throw new IllegalStateException("Counters out of sync for super-column " +
128                            superColumn + " boxes, value " + value);
129                }
130                nextStep = checkBox(column, (box - startBox) / boxOffset);
131            }
132        }
133//        if (counterValue("boxIndicatorCount-" + (2 * superRow) + "-" + value) == 1) {
134//            return checkBox(row, 1);
135//        } else {
136//            return checkBox(row, 0);
137//        }
138 
139        return nextStep;
140    }
141 
142    private SolutionStep checkBox(int column, int superRow)
143    throws UnsolveablePuzzleException
144    {
145        SolutionStep nextStep = null;
146        int possibles = 0;
147 
148        for (int row = cellsPerBox * superRow; row < cellsPerBox * (superRow + 1); row++) {
149            if (grid.get(new Coordinate(row, column)).equals(Integer.valueOf(0)) &&
150                    counterValue("rowIndicatorCount-" + row + "-" + value) == 0) {
151                nextStep = new SolutionStep(new Coordinate(row, column),
152                        value, this.toString());
153                possibles++;
154            }
155        }
156        if (possibles == 0) {
157            throw new UnsolveablePuzzleException(this.toString());
158        } else if (possibles > 1) {
159            nextStep = null;
160        }
161 
162        return nextStep;
163    }
164 
165    public String toString() {
166        return "ScanColumns " + startColumn + "-" + endColumn + " for " + value;
167    }
168 
169}

[all classes][net.sourceforge.pseudoq.solver]
EMMA 2.0.5312 (C) Vladimir Roubtsov