Commit 0f1b7b5c authored by Alexander Kotov's avatar Alexander Kotov

redux: move board state to redux

parent 8f60cd66
import { START_NEW_GAME } from "./types";
export const startNewGame = (options) => ({
type: START_NEW_GAME,
payload: options
})
import { COMPLETE_MOVE } from "./types";
import { COMPLETE_MOVE, START_MOVE, UPDATE_MOVE } from "./types";
export const startMove = (move) => ({
type: START_MOVE,
payload: move
})
export const completeMove = (move) => ({
type: COMPLETE_MOVE,
......
export const COMPLETE_MOVE = 'COMPLETE_MOVE'
\ No newline at end of file
export const START_NEW_GAME = 'START_NEW_GAME'
export const START_MOVE = 'START_MOVE'
export const COMPLETE_MOVE = 'COMPLETE_MOVE'
......@@ -5,7 +5,7 @@ import Tower from '../Tower/Tower.jsx'
import Disk from '../Disk/Disk.jsx'
import store from '../../store'
import { completeMove } from '../../actions/moveActions'
import { completeMove, startMove } from '../../actions/moveActions'
const styles = {
air: {
......@@ -31,55 +31,40 @@ const moveStyle = move => {
class Board extends Component {
constructor() {
super()
this.state = {
left: [
{ color: '#F3A712', width: 60 },
{ color: '#29335C', width: 80 },
{ color: '#E4572E', width: 100 }
],
center: [
{ color: '#669BBC', width: 20 }
],
right: [
{ color: '#A8C686', width: 40 }
],
move: null
}
this.state = store.getState()
}
componentDidMount() {
store.subscribe(() => {
const { left, right, center, move} = store.getState();
this.setState({ left, right, center, move})
})
}
startMove(tower) {
let disks = [...this.state[tower]]
let disks = this.state[tower]
if (disks.length) {
let disk = disks.shift()
this.setState({
[tower]: disks,
move: { disk, from: tower, to: tower }
})
let disk = disks[0]
store.dispatch(startMove({ disk, tower }))
}
}
updateMove = tower => () => {
if (this.state.move) {
let move = { ...this.state.move, to: tower }
this.setState({ move })
this.setState({
move: {...this.state.move, to: tower}
})
}
}
completeMove() {
let move = this.state.move
let disks = [...this.state[move.to]]
disks.unshift(move.disk)
this.setState({
[move.to]: disks,
move: null
})
store.dispatch(completeMove(move))
completeMove(tower) {
let { disk } = this.state.move
store.dispatch(completeMove({ disk, tower }))
}
performMove = tower => () => {
if (this.state.move) {
this.completeMove()
this.completeMove(tower)
} else {
this.startMove(tower)
}
......
.Toolbar {
font-size: 2rem;
padding: 1vw 5vw;
font-family: Verdana, Geneva, Tahoma, sans-serif
}
.Toolbar>button {
background-color: darkseagreen;
font-size: 2rem;
cursor: pointer;
font-family: inherit;
}
\ No newline at end of file
import React, { Component } from 'react'
import store from '../../store';
import { startNewGame } from '../../actions/gameActions';
import './Toolbar.css'
const mapStoreState = () => {
let { moves } = store.getState()
......@@ -17,10 +19,17 @@ export default class Toolbar extends Component {
store.subscribe(this.updateState)
}
onStartNewGame() {
store.dispatch(startNewGame())
}
render() {
return (
<div>
Moves: {this.state.moves}
<div className="Toolbar">
<button onClick={this.onStartNewGame}>Start new game</button>
<span>
Moves: {this.state.moves}
</span>
</div>
)
}
......
import { START_NEW_GAME } from "../actions/types";
const initialState = {
left: [],
center: [],
right: [],
moves: 0
}
const createDisks = () => {
return [
{ color: '#669BBC', width: 20 },
{ color: '#A8C686', width: 40 },
{ color: '#F3A712', width: 60 },
{ color: '#29335C', width: 80 },
{ color: '#E4572E', width: 100 }
]
}
export default (state = initialState, action) => {
switch (action.type) {
case START_NEW_GAME:
return {
left: createDisks(action.payload),
center: [],
right: [],
moves: 0
}
default:
return state
}
}
import { combineReducers } from "redux"
import { combineReducers } from 'redux'
import moves from './movesReducer'
import move from './moveReducer'
import gameReducer from './gameReducer'
import towerReducer from './towerReducer';
export default combineReducers({
moves
})
\ No newline at end of file
const chainReducers = (...reducers) => {
return (state, action) => {
const applyReducer = (newState, reducer) => reducer(newState, action)
return reducers.reduce(applyReducer, state)
}
}
export default chainReducers(
gameReducer,
combineReducers({
moves,
move,
left: towerReducer('left'),
center: towerReducer('center'),
right: towerReducer('right')
})
)
\ No newline at end of file
import { START_MOVE, COMPLETE_MOVE, UPDATE_MOVE } from "../actions/types";
export default (state = null, action) => {
switch (action.type) {
case START_MOVE:
return {
disk: action.payload.disk,
from: action.payload.tower,
to: action.payload.tower
}
case COMPLETE_MOVE:
return null
default:
return state
}
}
import { COMPLETE_MOVE, START_MOVE } from "../actions/types";
export default tower => (disks = [], action) => {
let move = action.payload
if (!move || move.tower !== tower) return disks
switch (action.type) {
case START_MOVE:
return disks.slice(1)
case COMPLETE_MOVE:
return [ move.disk, ...disks ]
default:
return disks
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment