Package kakuro.server.tablefactory

Source Code of kakuro.server.tablefactory.GeneralTable$Cell

package kakuro.server.tablefactory;

import java.util.HashMap;
import kakuro.server.ISkeletonTable;
import kakuro.table.ITable;
import kakuro.table.Position;
import kakuro.table.TableException;

/** Altalános ITable implementáció. A cellákat map-ben tárolja, a felhasználó által beírt értékeket
* egy kétdimenziós int tömbben. */
public class GeneralTable implements ITable {
  /** tábla mögött álló skeleton */
    private ISkeletonTable _skeleton = null;
    /** felhasználó által beírt értékek */
    private int[][] _matrix = null;
    /** cellák */
    private HashMap<Position,Cell> _cellMap;

    /** Alap konstruktor, megjegyzi a kapott paramétereket.
     *
     * @param skeleton váz
     * @param matrix valódi értékek
     * @param user felhasználó által beírt értékek (ez mentésből jöhet pl.)
     * */
  public GeneralTable(ISkeletonTable skeleton, int[][] matrix, int[][] user) {
      _skeleton = skeleton;
      _matrix = matrix;
      _cellMap = new HashMap<Position,Cell>();
      init(user);
  }
 
  /** Alap konstruktor, megjegyzi a kapott paramétereket.
     *
     * @param skeleton váz
     * @param matrix valódi értékek
     * */
  public GeneralTable(ISkeletonTable skeleton, int[][] matrix) {
      _skeleton = skeleton;
      _matrix = matrix;
      _cellMap = new HashMap<Position,Cell>();
      init(null);
  }
 
  /** Kiszámolja az összeg cellák értékét, és berakja őket a fekete cellákba. Felépíti a
   * cella map-et is. */
  private void init(int[][] user) {
      int cols = getColumnCount();
      int rows = getRowCount();
      int[][] vSums = new int[cols][rows];
      int[][] hSums = new int[cols][rows];
      for (int i=cols-1; i>=0; i--) {
        int vSum = 0;
        for (int j=rows-1; j>=0; j--) {
          if (_matrix[i][j]>0) {
            vSum += _matrix[i][j];
          } else {
            if (vSum>0) {
              vSums[i][j] = vSum;
              vSum = 0;
            }
          }
        }
      }
      for (int j=rows-1; j>=0; j--) {
        int hSum = 0;
        for (int i=cols-1; i>=0; i--) {
          if (_matrix[i][j]>0) {
            hSum += _matrix[i][j];
          } else {
            if (hSum>0) {
              hSums[i][j] = hSum;
              hSum = 0;
            }
          }
        }
      }
      for (int i=0; i<cols; i++) {
        for (int j=0; j<rows; j++) {
          Position p = new Position(i, j);
          if (_matrix[i][j]>0) {
            _cellMap.put(p, new WhiteCell(p, _matrix[i][j], (user==null?0:user[i][j])));
          } else {
            _cellMap.put(p, new BlackCell(p, hSums[i][j], vSums[i][j]));
          }
        }
      }
  }

  /** Oszlopszám getter */
  public int getColumnCount() {
    return _skeleton.getColumnCount();
  }

  /** Nehézségi szint getter
   *
   * @return {@link ITable#DIFFICULTY_EASY},{@link ITable#DIFFICULTY_MEDIUM},{@link ITable#DIFFICULTY_HARD}
   * */
  public int getDifficulty() {
        return _skeleton.getDifficulty();
  }

  /** Sorszám getter */
  public int getRowCount() {
    return _skeleton.getRowCount();
  }
 
  /** Belső függvény, ellenőrzi, hogy legális-e a kapott pozíció
   *
   * @param p pozíció
   * @throws IndexOutOfBoundsException ha nem legális
   * */
  private void checkIndex(Position p) throws IndexOutOfBoundsException {
      if (p.x > (getColumnCount()-1) || p.y > (getRowCount()-1))
    throw new IndexOutOfBoundsException("Indexing out! got " + p
        + " out of [" +getColumnCount()+","+getRowCount()+"]");
  }

  /** Adott helyhez tartozó összeg lekérő
   *
   * @param p pozíció
   * @param type összeg típus: {@link ITable#SUM_HORIZONTAL},{@link ITable#SUM_VERTICAL}
   * */
  public int getSum(Position p, int type) throws TableException,
      IndexOutOfBoundsException {
        checkIndex(p);
    try {
        BlackCell c = (BlackCell)_cellMap.get(p);
        return (type==ITable.SUM_HORIZONTAL?c.horizontalSum:c.verticalSum);
    } catch (Throwable t) {
        throw new TableException("getSum", t);
    }
  }

  /** Kapott pozíción található cella típusát adja vissza.
   *
   * @param p pozíció
   * @return típus, lehetséges értékek: {@link ITable#WHITE},{@link ITable#BLACK_BOTH},{@link ITable#BLACK_HORIZONTAL},
   *     {@link ITable#BLACK_NONE},{@link ITable#BLACK_VERTICAL}
   * @throws IndexOutOfBoundsException ha a pozíció kívül esik a táblán
   * */
  public int getType(Position p) throws IndexOutOfBoundsException {
    checkIndex(p);
    return _cellMap.get(p).getType();
  }

  /**
   * Jó-e az adott helyen levő cella tartalma. True, ha jó. False, ha rossz,
   * vagy ha üres!
   *
   * @param p pozíció
   * @return korrekt-e a cella tartalma
   */
  public boolean isCorrect(Position p) throws IndexOutOfBoundsException {
        checkIndex(p);
    if (_cellMap.get(p) instanceof BlackCell) return true;
    WhiteCell wc = (WhiteCell)_cellMap.get(p);
    return wc.isCorrect();
  }

  /** Leellenőrzi az állást, true ha kész. Nem azt nézi, hogy egyezik-e a beírt érték az előre
   * megadottal, hanem azt, hogy minden ki van-e töltve és az összeg stimmelnek-e!
   *
   * @return kész-e a tábla
   * */
  public boolean isReady() throws TableException {
    for (int j=0; j<_matrix[0].length; j++) {
          for (int i=0; i<_matrix.length; i++) {
                Position p = new Position(i, j);
                boolean r = true;
                int type = getType(p);
                switch (type) {
                  case ITable.WHITE:
                  case ITable.BLACK_NONE:
                      break;
                  case ITable.BLACK_BOTH:
                      r = checkVertical(p) && checkHorizontal(p);
                      break;
                  case ITable.BLACK_HORIZONTAL:
                      r = checkHorizontal(p);
                      break;
                  case ITable.BLACK_VERTICAL:
                      r = checkVertical(p);
                      break;
                }
                if (!r) return false;
          }
    }
    return true;
  }
 
  /** Leellenőrzi, hogy az adott helytől lefelé eső fehér cellák kiadják-e a kívánt összeget, és mind ki van-e
   * töltve.
   *
   * @param p fekete, függőleges összeget tartalmazó cella helye
   * @return jó-e a szó
   * */
  private boolean checkVertical(Position p) throws TableException {
        int sum = getSum(p, ITable.SUM_VERTICAL);
        for (int j=p.y+1; j<_matrix[0].length; j++) {
              int type = getType(new Position(p.x, j));
              if (type!=ITable.WHITE) break;
              int value = readCell(new Position(p.x, j), ITable.VALUE_NORMAL);
              if (value<1) return false;
              sum -= value;
        }
        return sum==0;
  }
 
  /** Leellenőrzi, hogy az adott helytől jobbra eső fehér cellák kiadják-e a kívánt összeget, és mind ki van-e
   * töltve.
   *
   * @param p fekete, vízszintes összeget tartalmazó cella helye
   * @return jó-e a szó
   * */
  private boolean checkHorizontal(Position p) throws TableException {
        int sum = getSum(p, ITable.SUM_HORIZONTAL);
        for (int i=p.x+1; i<_matrix.length; i++) {
              int type = getType(new Position(i, p.y));
              if (type!=ITable.WHITE) break;
              int value = readCell(new Position(i, p.y), ITable.VALUE_NORMAL);
              if (value<1) return false;
              sum -= value;
        }
        return sum==0;
  }

  /** nincs implementálva */
  public void load(Object state) throws TableException {
  }

  /** Fehér cella értékét olvassa ki
   *
   * @param p pozíció
   * @param type értékei: {@link ITable#VALUE_TRUE} a valódi értéket, {@link ITable#VALUE_NORMAL} a felhasználó
   * által beírt értéket választja ki
   * @return fehér cella értéke
   * @throws IndexOutOfBoundsException ha a pozíció érvénytelen
   * */
  public int readCell(Position p, int type) throws TableException,
      IndexOutOfBoundsException {
    checkIndex(p);
    try {
        WhiteCell wc = (WhiteCell)_cellMap.get(p);
        switch (type) {
          case ITable.VALUE_NORMAL: return wc.normalValue;
          case ITable.VALUE_TRUE: return wc.trueValue;
          default: throw new TableException("invalid type "+type);
        }
    } catch (Throwable t) {
        throw new TableException("readCell", t);
    }
  }

  /** Nincs implementálva */
  public Object save() throws TableException {
    return null;
  }

  /**
   * Adott érték letárolása. Visszatérési érték true ha
   * helyes az érték, false ha rossz. Type: VALUE_PENCIL v VALUE_NORMAL
   * VALUE_TRUE-ra TableException
   *
   * @param p pozíció
   * @param value érték
   * @param type típus, értékei: {@link ITable#VALUE_NORMAL},{@link ITable#VALUE_PENCIL},{@link ITable#VALUE_TRUE}
   * @return helyes-e az érték
   */
  public boolean writeCell(Position p, int value, int type)
      throws TableException, IndexOutOfBoundsException {
      checkIndex(p);
    try {
        WhiteCell wc = (WhiteCell)_cellMap.get(p);
        switch (type) {
          case ITable.VALUE_NORMAL:  wc.normalValue = value;  break;
          case ITable.VALUE_TRUE:  wc.trueValue = value;  break;
          default: throw new TableException("invalid type "+type);
        }
    } catch (Throwable t) {
        throw new TableException("writeCell", t);
    }
    return false;
  }

  /** Belső absztakt Cella ősosztály */
  abstract class Cell {
    /** hely */
      public Position position = null;
     
      /** Megjegyzi a helyet, mást nem csinál */
      public Cell(Position p) {
        position = p;
      }
     
      /** Típus lekérése
       *
       * @return {@link ITable#WHITE},{@link ITable#BLACK_BOTH},{@link ITable#BLACK_HORIZONTAL},
       * {@link ITable#BLACK_NONE},{@link ITable#BLACK_VERTICAL}
       * */
      public abstract int getType();
  }
 
  /** Fehér cella */
  class WhiteCell extends Cell {
    /** Valódi érték */
      public int trueValue;
      /** beírt érték */
      public int normalValue;
     
      /** Fehér cell konstruktor bejegyzi a kapott értékeket
       *
       * @param p hely
       * @param v valódi
       * @param user beírt
       * */
      public WhiteCell(Position p, int v, int user) {
        super(p);
        trueValue = v;
        normalValue = user;
      }
     
      /** helyes-e */
      public boolean isCorrect() {
        return trueValue==normalValue;
      }
     
      /** Fixen fehér */
      public int getType() {
        return ITable.WHITE;
      }
  }
 
  /** Fekete cella */
  class BlackCell extends Cell {
    /** vízszintes összeg */
      public int horizontalSum;
      /** függőleges összeg */
      public int verticalSum;
     
      /** Megjegyzi az értékeket, mást nem csinál */
      public BlackCell(Position p, int h, int v) {
        super(p);
        horizontalSum = h;
        verticalSum = v;
      }
     
      /** Típus lekérése
       *
       * @return {@link ITable#WHITE},{@link ITable#BLACK_BOTH},{@link ITable#BLACK_HORIZONTAL},
       * {@link ITable#BLACK_NONE},{@link ITable#BLACK_VERTICAL}
       * */
      public int getType() {
        if (horizontalSum+verticalSum==0) return ITable.BLACK_NONE;
        if (horizontalSum>0 && verticalSum>0) return ITable.BLACK_BOTH;
        if (horizontalSum>0 && verticalSum==0) return ITable.BLACK_HORIZONTAL;
        return ITable.BLACK_VERTICAL;
      }
  }
 
  /** Skeleton azonosító getter */
  public int getSkeletonId() {
      return _skeleton.getId();
  }
}
TOP

Related Classes of kakuro.server.tablefactory.GeneralTable$Cell

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.