Skip to content
This repository has been archived by the owner on Nov 11, 2021. It is now read-only.

Commit

Permalink
algorithm complete
Browse files Browse the repository at this point in the history
  • Loading branch information
lochungtin committed May 30, 2021
1 parent 694d1e1 commit 4fd69ca
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 29 deletions.
29 changes: 17 additions & 12 deletions src/components/Board/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,37 @@ 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<ReduxProps> {

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 (
<FlingGestureHandler direction={Directions.UP} onEnded={() => console.log('up')}>
<FlingGestureHandler direction={Directions.DOWN} onEnded={() => console.log('down')} >
<FlingGestureHandler direction={Directions.LEFT} onEnded={() => console.log('left')}>
<FlingGestureHandler direction={Directions.RIGHT} onEnded={() => console.log('right')}>
<FlingGestureHandler direction={Directions.UP} onEnded={() => this.swipe(Direction.up)}>
<FlingGestureHandler direction={Directions.DOWN} onEnded={() => this.swipe(Direction.down)} >
<FlingGestureHandler direction={Directions.LEFT} onEnded={() => this.swipe(Direction.left)}>
<FlingGestureHandler direction={Directions.RIGHT} onEnded={() => this.swipe(Direction.right)}>
<View style={{ ...BoardStyles.root, backgroundColor: darktheme.boardColor }}>
{this.props.board.board.map(row => {
{this.props.game.board.map(row => {
return (
<View key={keygen()} style={BoardStyles.row}>
{row.map(cell => {
Expand All @@ -55,7 +60,7 @@ class BoardView extends React.Component<ReduxProps> {
}

const mapStateToProps = state => ({
board: state.board,
game: state.game,
});

export default connect(mapStateToProps)(BoardView);
16 changes: 9 additions & 7 deletions src/game/board.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { cascade } from "../utils/array";
import { Direction } from "../utils/enums";
import { CoordinatePair, MergingPairs } from "../utils/types";

export default class Board {

dim: number = 0;
board: Array<Array<number>> = [];
score: number = 0;

constructor(dim: number) {
this.dim = dim;
Expand All @@ -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();
Expand Down
8 changes: 4 additions & 4 deletions src/redux/action.ts
Original file line number Diff line number Diff line change
@@ -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,
});
7 changes: 3 additions & 4 deletions src/redux/reducer.ts
Original file line number Diff line number Diff line change
@@ -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,
})
7 changes: 5 additions & 2 deletions src/screens/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<View style={{ ...ScreenStyles.screen, backgroundColor: darktheme.bgColor }}>
<View style={{ height: 200 }} />
<TouchableOpacity onPress={() => store.dispatch(saveBoard(new Board(4)))} style={{ backgroundColor: darktheme.btnColor }}>
<TouchableOpacity onPress={this.newGame} style={{ backgroundColor: darktheme.btnColor }}>
<Text style={{ color: darktheme.textColor }}>
New Game
</Text>
Expand Down
43 changes: 43 additions & 0 deletions src/utils/array.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Direction } from "./enums";

const rotate = (arr: Array<Array<number>>, direction: Direction): Array<Array<number>> => {
let rt: Array<Array<number>> = [];
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<Array<number>>, direction: Direction): Array<Array<number>> => {
let dim: number = arr.length;
// filter all "empty" elements
let rt: Array<Array<number>> = 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<Array<number>>, direction: Direction): Array<Array<number>> => {
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)
);
}

7 changes: 7 additions & 0 deletions src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ export interface MergingPairs {
merger: CoordinatePair,
}

// game config
export interface GameConfig {
board: Array<Array<number>>,
dim: number,
score: number,
}

// redux types
export interface ActionType {
type: ActionName,
Expand Down

0 comments on commit 4fd69ca

Please sign in to comment.