File

src/client/app/modules/puzzle/services/board/board.service.ts

Index

Properties
Methods

Constructor

constructor()

Methods

canShiftY
canShiftY(up: boolean, square: Square)
Returns : boolean
init
init(stateService: StateServiceInterface, model: Board)
Returns : void
isSquarePersisted
isSquarePersisted(id: string)
Returns : boolean
persist
persist(options: Square)
Returns : void
restoreSquareOptions
restoreSquareOptions(id: string)
Returns : Square
sequence
sequence(model: Board, expect: boolean)
Returns : number[]
shiftX
shiftX(left: boolean, square: Square)
Returns : void
shiftY
shiftY(up: boolean, square: Square)
Returns : void
slide
slide(left: boolean, square: Square, reps: number)
Returns : void
transform
transform(model: Board)
Returns : []
transformStore
transformStore(store: [])
Returns : []
unPersist
unPersist()
Returns : void

Properties

Private _board
_board: Board
Type : Board
Private _boardObserver
_boardObserver: Observer<Board>
Type : Observer<Board>
Private _emptySquare
_emptySquare: Square
Type : Square
board
board: Board
Type : Board
boardChange$
boardChange$: Observable<Board>
Type : Observable<Board>
database
database: DatabaseServiceInterface
Type : DatabaseServiceInterface
emptySquare
emptySquare: Square
Type : Square
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {Observer} from 'rxjs/Observer';

import {Board} from './board.model';
import {Row} from './row.model';
import {Square} from './square.model';
import {Utils} from '../../common/utils.common';
import {StateServiceInterface} from '../state/state-service.interface';
import {DatabaseServiceInterface} from '../database/database-service.interface';

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/share';


@Injectable()
export class BoardService {

  boardChange$: Observable<Board>;
  database: DatabaseServiceInterface;

  private _board: Board;
  private _boardObserver: Observer<Board>;
  private _emptySquare: Square;


  set board(board: Board) {
    if (this._board.toString() !== board.toString()) {
      this._board = board;
      if (this._boardObserver) {
        this._boardObserver.next(board);
      }
    }
  }

  get board(): Board {
    return this._board;
  }

  get emptySquare(): Square {
    return this._emptySquare;
  }

  set emptySquare(value: Square) {
    this._emptySquare = value;
  }

  constructor() {
    this.database = null;
    this._board = new Board();
    this.boardChange$ = new Observable<Board>(
      (observer: any) => this._boardObserver = observer
    ).share();
  }

  init(stateService: StateServiceInterface, model: Board = null) {

    let board: Board = model ? new Board(model.rowCount, model.colCount, model.isSolved, model.sequence, model.expectedSequence) : null;

    if (stateService && stateService.databaseService) {
      this.database = stateService.databaseService;
    }
    if (board) {
      board.squares = this.transform(board);
      this.board = board;
    }
  }

  sequence(model: Board, expect: boolean = false): number[] {
    let min: number = 1,
      rows: number = model ? model.rowCount : null,
      cols: number = model ? model.colCount : null,
      max: number = rows && cols ? rows * cols : 0,
      seq: number[] = [];

    if (max > 0) {
      if (!expect) {
        seq = Utils.generateSequence(min, max, max);
      } else {
        seq = Utils.generateSequentialSequence(min, max);
      }
    }

    return seq;

  }

  transform(model: Board): Square[] {
    let row: number = 1,
      i: number = 1,
      pos: number = 0,
      rows: number = model.rowCount,
      cols: number = model.colCount,
      isSolved: boolean = model.isSolved,
      seq: number[] = model.sequence && model.sequence.length ? model.sequence : this.sequence(model),
      expectedSeq: number[] = model.expectedSequence && model.expectedSequence.length ? model.expectedSequence :
        this.sequence(model, true),
      subSeq: number[] = [],
      expectedSubSeq: number[] = [],
      store: Row[] = [];

    for (; row <= rows; row++) {
      if (isSolved) {
        subSeq = Utils.parseSubSequence(expectedSeq, pos, cols);
      } else {
        subSeq = Utils.parseSubSequence(seq, pos, cols);
      }
      expectedSubSeq = Utils.parseSubSequence(expectedSeq, pos, cols);

      store.push(<Row>{
        index: i,
        isLast: row === rows ? true : false,
        seq: subSeq,
        expectedSeq: expectedSubSeq
      });
      i++;
      pos += cols;
    }

    return this.transformStore(store);
  }

  transformStore(store: Row[]): Square[] {
    let squares: Square[] = [],
      emptySquares: Square[] = [];
    store.forEach((row: Row) => {
      if (row.seq && row.expectedSeq && row.seq.length === row.expectedSeq.length) {
        row.seq.forEach((num, i) => {
          let colClass: string = Utils.mapColClass(num),
            squareValue: number = i < (row.seq.length - 1) || (i < row.seq.length && !row.isLast) ? num : null,
            squareIsEmpty: boolean = squareValue ? false : true,
            squareClass: string = squareValue ? 'btn ' + colClass : 'btn empty',
            squareExpectedValue: number = row.expectedSeq[i],
            squareId: string = 'row-' + row.index + '-square-' + squareExpectedValue,
            squareRow: number = row.index,
            squareCol: number = i,
            squareOptions: Square = this.isSquarePersisted(squareId) ? this.restoreSquareOptions(squareId) :
              <Square>{
                id: squareId,
                isEmpty: squareIsEmpty,
                row: squareRow,
                col: squareCol,
                value: String(i),
                expectedValue: String(squareExpectedValue),
                cssClass: squareClass
              };
          squares.push(squareOptions);
        });
      }
    });

    emptySquares = squares.filter((square: Square) => {
      return square.isEmpty;
    });

    if (emptySquares.length) {
      this.emptySquare = emptySquares[0];
    }

    if (this.emptySquare) {
      console.log('emptySquare');
      console.log(JSON.stringify(this.emptySquare));
    }

    return squares;
  }

  isSquarePersisted(id: string): boolean {
    let databaseService: DatabaseServiceInterface = this.database;
    if (databaseService) {
      return databaseService.exists(id);
    }
    return false;
  }

  restoreSquareOptions(id: string): Square {
    let databaseService: DatabaseServiceInterface = this.database,
      squareState: Square = null;
    if (databaseService) {
      squareState = databaseService.pull(id);
    }
    return squareState;
  }

  unPersist(): void {
    let databaseService: DatabaseServiceInterface = this.database;

    if (databaseService) {
      databaseService.zero('row');
    }
  }

  persist(options: Square = null): void {
    let databaseService: DatabaseServiceInterface = this.database;
    if (databaseService) {
      if (options) {
        databaseService.push(options.id, options);
      } else {
        if (this.board && this.board.squares) {
          this.board.squares.forEach((square: Square) => {
            this.persist(square);
          });
        }
      }
    }
  }

  slide(left: boolean, square: Square, reps: number) {
    for (var i = 0; i < reps; i++) {
      this.shiftX(left, square);
    }
  }

  canShiftY(up: boolean, square: Square) {
    if (up) {
      return square.col === this.emptySquare.col && square.row > this.emptySquare.row ? true : false;
    } else {
      return square.col === this.emptySquare.col && square.row < this.emptySquare.row ? true : false;
    }
  }

  shiftX(left: boolean = false, square: Square): void {
    let squareIndices: number[] = [],
        emptySquareIndices: number[] = [];

    if (this.board && this.board.squares && this.board.squares.length) {
      this.board.squares.forEach((s: Square, index: number) => {
        if (s.row === square.row) {
          squareIndices.push(index);
        }
      });
      if (squareIndices.length === 8) {
        if (left) {
          Utils.swap(this.board.squares[squareIndices[0]], this.board.squares[squareIndices[1]]);
          Utils.swap(this.board.squares[squareIndices[1]], this.board.squares[squareIndices[2]]);
          Utils.swap(this.board.squares[squareIndices[2]], this.board.squares[squareIndices[3]]);
          Utils.swap(this.board.squares[squareIndices[3]], this.board.squares[squareIndices[4]]);
          Utils.swap(this.board.squares[squareIndices[4]], this.board.squares[squareIndices[5]]);
          Utils.swap(this.board.squares[squareIndices[5]], this.board.squares[squareIndices[6]]);
          Utils.swap(this.board.squares[squareIndices[6]], this.board.squares[squareIndices[7]]);
        } else {
          Utils.swap(this.board.squares[squareIndices[7]], this.board.squares[squareIndices[6]]);
          Utils.swap(this.board.squares[squareIndices[6]], this.board.squares[squareIndices[5]]);
          Utils.swap(this.board.squares[squareIndices[5]], this.board.squares[squareIndices[4]]);
          Utils.swap(this.board.squares[squareIndices[4]], this.board.squares[squareIndices[3]]);
          Utils.swap(this.board.squares[squareIndices[3]], this.board.squares[squareIndices[2]]);
          Utils.swap(this.board.squares[squareIndices[2]], this.board.squares[squareIndices[1]]);
          Utils.swap(this.board.squares[squareIndices[1]], this.board.squares[squareIndices[0]]);
        }

        emptySquareIndices = squareIndices.filter((indice: number) => {
            return this.board.squares[indice].isEmpty;
        });

        if (emptySquareIndices.length) {
          this.emptySquare = this.board.squares[emptySquareIndices[0]];
        }
        this.persist();
      }
    }
  }

  shiftY(up: boolean = false, square: Square): void {
    let squareIndices: number[] = [],
      emptySquareIndices: number[] = [];

    if (this.board && this.board.squares && this.board.squares.length) {
      this.board.squares.forEach((s: Square, index: number) => {
        if (s.col === this.emptySquare.col) {
          squareIndices.push(index);
        }
      });
      if (squareIndices.length === 8) {
        if (up) {
          Utils.swap(this.board.squares[squareIndices[0]], this.board.squares[squareIndices[1]]);
          Utils.swap(this.board.squares[squareIndices[1]], this.board.squares[squareIndices[2]]);
          Utils.swap(this.board.squares[squareIndices[2]], this.board.squares[squareIndices[3]]);
          Utils.swap(this.board.squares[squareIndices[3]], this.board.squares[squareIndices[4]]);
          Utils.swap(this.board.squares[squareIndices[4]], this.board.squares[squareIndices[5]]);
          Utils.swap(this.board.squares[squareIndices[5]], this.board.squares[squareIndices[6]]);
          Utils.swap(this.board.squares[squareIndices[6]], this.board.squares[squareIndices[7]]);
        } else {
          Utils.swap(this.board.squares[squareIndices[7]], this.board.squares[squareIndices[6]]);
          Utils.swap(this.board.squares[squareIndices[6]], this.board.squares[squareIndices[5]]);
          Utils.swap(this.board.squares[squareIndices[5]], this.board.squares[squareIndices[4]]);
          Utils.swap(this.board.squares[squareIndices[4]], this.board.squares[squareIndices[3]]);
          Utils.swap(this.board.squares[squareIndices[3]], this.board.squares[squareIndices[2]]);
          Utils.swap(this.board.squares[squareIndices[2]], this.board.squares[squareIndices[1]]);
          Utils.swap(this.board.squares[squareIndices[1]], this.board.squares[squareIndices[0]]);
        }

        emptySquareIndices = squareIndices.filter((indice: number) => {
          return this.board.squares[indice].isEmpty;
        });

        if (emptySquareIndices.length) {
          this.emptySquare = this.board.squares[emptySquareIndices[0]];
        }
        this.persist();
      }
    }
  }

}

results matching ""

    No results matching ""