From 4fd69ca90f6bb14b2ed1f235b3c90e7c7df07724 Mon Sep 17 00:00:00 2001 From: lochungtin Date: Sun, 30 May 2021 01:19:43 +0100 Subject: [PATCH] algorithm complete --- src/components/Board/index.tsx | 29 +++++++++++++---------- src/game/board.ts | 16 +++++++------ src/redux/action.ts | 8 +++---- src/redux/reducer.ts | 7 +++--- src/screens/main.tsx | 7 ++++-- src/utils/array.ts | 43 ++++++++++++++++++++++++++++++++++ src/utils/types.ts | 7 ++++++ 7 files changed, 88 insertions(+), 29 deletions(-) create mode 100644 src/utils/array.ts diff --git a/src/components/Board/index.tsx b/src/components/Board/index.tsx index d9c7baa..6957ab8 100644 --- a/src/components/Board/index.tsx +++ b/src/components/Board/index.tsx @@ -9,12 +9,14 @@ import { darktheme } from '../../data/color'; import { BoardStyles } from './styles'; import Board from '../../game/board'; -import { keygen } from '../../utils/keygen'; import { store } from '../../redux/store'; -import { saveBoard } from '../../redux/action'; +import { saveGameState } from '../../redux/action'; +import { keygen } from '../../utils/keygen'; +import { Direction } from '../../utils/enums'; +import { GameConfig } from '../../utils/types'; interface ReduxProps { - board: Board, + game: GameConfig } class BoardView extends React.Component { @@ -22,19 +24,22 @@ class BoardView extends React.Component { constructor(props) { super(props); - if (props.board === null) - store.dispatch(saveBoard(new Board(4))); + if (props.game === null) + store.dispatch(saveGameState({ ...new Board(4) })); + } + + swipe = (direction: Direction): void => { + } render() { - console.log(this.props.board); return ( - console.log('up')}> - console.log('down')} > - console.log('left')}> - console.log('right')}> + this.swipe(Direction.up)}> + this.swipe(Direction.down)} > + this.swipe(Direction.left)}> + this.swipe(Direction.right)}> - {this.props.board.board.map(row => { + {this.props.game.board.map(row => { return ( {row.map(cell => { @@ -55,7 +60,7 @@ class BoardView extends React.Component { } const mapStateToProps = state => ({ - board: state.board, + game: state.game, }); export default connect(mapStateToProps)(BoardView); diff --git a/src/game/board.ts b/src/game/board.ts index 3370667..a1c7792 100644 --- a/src/game/board.ts +++ b/src/game/board.ts @@ -1,3 +1,4 @@ +import { cascade } from "../utils/array"; import { Direction } from "../utils/enums"; import { CoordinatePair, MergingPairs } from "../utils/types"; @@ -5,6 +6,7 @@ export default class Board { dim: number = 0; board: Array> = []; + score: number = 0; constructor(dim: number) { this.dim = dim; @@ -20,16 +22,16 @@ export default class Board { this.newTile(); } - swipe = (direction: Direction) => { + swipe = (direction: Direction): void => { // merge all - this.getMergableIndices(direction).forEach(pair => { - this.board[pair.mergee.row][pair.mergee.col] += this.board[pair.merger.row][pair.merger.col]; - this.board[pair.merger.row][pair.merger.col] = -1; - }); + // this.getMergableIndices(direction).forEach(pair => { + // this.board[pair.mergee.row][pair.mergee.col] += this.board[pair.merger.row][pair.merger.col]; + // this.board[pair.merger.row][pair.merger.col] = -1; + // }); - // cascade to direction - + console.log(direction); + this.board = (cascade(this.board, direction)); // add new tile let newTile = this.newTile(); diff --git a/src/redux/action.ts b/src/redux/action.ts index 36788eb..b93549f 100644 --- a/src/redux/action.ts +++ b/src/redux/action.ts @@ -1,11 +1,11 @@ import Board from '../game/board'; -import { ActionType } from '../utils/types'; +import { ActionType, GameConfig } from '../utils/types'; export enum ActionName { - SAVE_BOARD + SAVE_GAME_STATE } -export const saveBoard = (payload: Board): ActionType => ({ - type: ActionName.SAVE_BOARD, +export const saveGameState = (payload: GameConfig): ActionType => ({ + type: ActionName.SAVE_GAME_STATE, payload, }); diff --git a/src/redux/reducer.ts b/src/redux/reducer.ts index bd8fe20..a1164c3 100644 --- a/src/redux/reducer.ts +++ b/src/redux/reducer.ts @@ -1,12 +1,11 @@ import { combineReducers } from 'redux'; -import Board from '../game/board'; import { ActionName } from './action'; -import { ActionType } from '../utils/types'; +import { ActionType, GameConfig } from '../utils/types'; -const saveBoard = (board: Board = null, action: ActionType) => action.type === ActionName.SAVE_BOARD ? action.payload : board; +const saveGame = (board: GameConfig = null, action: ActionType) => action.type === ActionName.SAVE_GAME_STATE ? action.payload : board; export default combineReducers({ - board: saveBoard + game: saveGame, }) diff --git a/src/screens/main.tsx b/src/screens/main.tsx index 833f263..8d69c99 100644 --- a/src/screens/main.tsx +++ b/src/screens/main.tsx @@ -8,15 +8,18 @@ import { darktheme } from '../data/color'; import { ScreenStyles } from './styles'; import Board from '../game/board'; -import { saveBoard } from '../redux/action'; +import { saveGameState } from '../redux/action'; import { store } from '../redux/store'; class Screen extends React.Component { + + newGame = () => store.dispatch(saveGameState({ ...new Board(4) })); + render() { return ( - store.dispatch(saveBoard(new Board(4)))} style={{ backgroundColor: darktheme.btnColor }}> + New Game diff --git a/src/utils/array.ts b/src/utils/array.ts new file mode 100644 index 0000000..aba80fb --- /dev/null +++ b/src/utils/array.ts @@ -0,0 +1,43 @@ +import { Direction } from "./enums"; + +const rotate = (arr: Array>, direction: Direction): Array> => { + let rt: Array> = []; + let dim: number = arr.length; + + for (let i = 0; i < dim; ++i) { + let row = []; + for (let j = 0; j < dim; ++j) + row.push(arr[(dim - j - 1) * (1 - direction) + (direction * j)][i * (1 - direction) + (dim - i - 1) * direction]); + + rt.push(row); + } + + return rt; +} + +const cascadeHorizontal = (arr: Array>, direction: Direction): Array> => { + let dim: number = arr.length; + // filter all "empty" elements + let rt: Array> = arr.map(row => row.filter(cell => cell !== -1)); + + // append or insert + if (direction === Direction.left) + return rt.map(row => [...row, ...new Array(dim - row.length).fill(-1)]); + else + return rt.map(row => [...new Array(dim - row.length).fill(-1), ...row]); +} + +export const cascade = (arr: Array>, direction: Direction): Array> => { + if (direction === Direction.left || direction === Direction.right) + return cascadeHorizontal(arr, direction); + else + // rotate, cascade, and rerotate + return rotate( + cascadeHorizontal( + rotate(arr, (direction === Direction.down ? 1 : 0)), + Direction.right + ), + (direction === Direction.up ? 1 : 0) + ); +} + diff --git a/src/utils/types.ts b/src/utils/types.ts index 74fd000..5a395a7 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -11,6 +11,13 @@ export interface MergingPairs { merger: CoordinatePair, } +// game config +export interface GameConfig { + board: Array>, + dim: number, + score: number, +} + // redux types export interface ActionType { type: ActionName,