Package sudoku.model

Source Code of sudoku.model.SudokuModel

package sudoku.model;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import common.model.Assert;
import common.model.Check;
import common.model.Constant;
import common.model.Declare;
import common.model.Model;
import common.model.Operator;
import common.model.Predicate;
import common.model.Statement;
import common.model.Type;
import common.model.Variable;

public class SudokuModel implements Model {

  private int size;

  private List<int[]> assigned;

  public SudokuModel(int size) {
    super();
    this.size = size;
    reset();
  }

  public void setNumber(int i, int j, int value) {
    if (value > size * size || value <= 0) {
      throw new IllegalArgumentException(MessageFormat.format(
          "Value {0} is not in valid range", value));
    }
    assigned.add(new int[] { i, j, value });
  }

  public void reset() {
    assigned = new ArrayList<int[]>();
  }

  @Override
  public List<Statement> generate() {
    int total = size * size * size * size;
    List<Statement> result = new ArrayList<Statement>();

    String varPattern = "var_{0}";
    // Generate variables
    for (int i = 0; i < total; i++) {
      result.add(new Declare(MessageFormat.format(varPattern, i),
          Type.Int));
    }
    // Range Check
    for (int i = 0; i < total; i++) {
      String var = MessageFormat.format(varPattern, i);
      result.add(new Assert(new Predicate(Operator.AND, new Predicate(
          Operator.GE, new Variable(var), new Constant(1)),
          new Predicate(Operator.LE, new Variable(var), new Constant(
              size * size)))));
    }
    // Assigned values
    for (int[] assign : assigned) {
      String var = MessageFormat.format(varPattern,
          translate(assign[0], assign[1]));
      result.add(new Assert(new Predicate(Operator.EQUAL, new Variable(
          var), new Constant(assign[2]))));
    }
    // Limitations
    // Columns and rows
    for (int i = 0; i < size * size; i++) {
      for (int j = 0; j < size * size; j++) {
        for (int k = j + 1; k < size * size; k++) {
          result.add(new Assert(new Predicate(Operator.NOT,
              new Predicate(Operator.EQUAL, new Variable(
                  MessageFormat.format(varPattern,
                      translate(i, j))), new Variable(
                  MessageFormat.format(varPattern,
                      translate(i, k)))))));
          result.add(new Assert(new Predicate(Operator.NOT,
              new Predicate(Operator.EQUAL, new Variable(
                  MessageFormat.format(varPattern,
                      translate(j, i))), new Variable(
                  MessageFormat.format(varPattern,
                      translate(k, i)))))));
          result.add(new Assert(new Predicate(Operator.NOT,
              new Predicate(Operator.EQUAL, new Variable(
                  MessageFormat.format(varPattern,
                      sqrtranslate(i, j))), new Variable(
                  MessageFormat.format(varPattern,
                      sqrtranslate(i, k)))))));
        }
      }
    }

    result.add(new Check());
    return result;
  }

  private int translate(int i, int j) {
    return i * getWidth() + j;
  }

  private int sqrtranslate(int i, int j) {
    // The j items of the i block
    return translate((i / size) * size + (j / size), (i % size) * size
        + (j % size));
  }

  public int getWidth() {
    return size * size;
  }

  public void setSize(int value) {
    this.size = value;
    reset();
  }
}
TOP

Related Classes of sudoku.model.SudokuModel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.