-
Notifications
You must be signed in to change notification settings - Fork 23
/
DiagramContainer.js
128 lines (115 loc) · 3.35 KB
/
DiagramContainer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { connect } from 'react-redux';
import { compose, flip, intersection, includes } from 'ramda';
import memoizeOne from 'memoize-one';
import {
Side,
detectEnemyOnTiles,
validateCode,
getPKeyByTile,
detectTurn,
detectPiece,
convertAxisListToTiles,
} from 'chess/es';
import { Diagram } from '~/components';
import { updateSelectedCode, movePiece, capturePiece } from '~/store/actions';
import { ONE_VS_CPU } from '~/presets';
const convertToTiles = memoizeOne(convertAxisListToTiles);
const detectPawn = memoizeOne(detectPiece.Pawn);
const flippedIncludes = flip(includes);
function mapStateToProps({
ai: { cpuTurn },
general: { flip, matchType },
network: { side, connected, awaiting },
ingame: {
present: {
checkData: { kingCode, attackerCode, attackerRoutes, defenders } = {
/* NOTE set default value(empty object) for legacy code */
},
selectedCode,
movableTiles,
snapshot,
turn,
},
future,
},
animate,
}) {
const isUndoAction = future.length > 0;
const isAwating = connected && awaiting;
const isCpuTurn = matchType === ONE_VS_CPU && turn === cpuTurn;
const isBlack = connected && side === Side.black;
return {
detectEnPassantTile(tileName) {
let isEnemyTile = false;
if (selectedCode) {
isEnemyTile = compose(
includes(tileName),
intersection(movableTiles),
convertToTiles(selectedCode)
)([
[1, 1],
[-1, 1],
]);
}
return detectPawn(selectedCode) && isEnemyTile;
},
getPKey: getPKeyByTile(snapshot),
detectOn: flippedIncludes([selectedCode, ...movableTiles]),
detectEnemy: detectEnemyOnTiles(movableTiles, selectedCode),
checkCode: attackerCode ? kingCode : '',
checkRoute: attackerRoutes,
checkDefenders: defenders,
preventEvent: isAwating || isCpuTurn,
animate: isUndoAction ? undefined : animate,
flip: flip || isBlack,
movableTiles,
turn,
};
}
function mapDispatchToProps(dispatch) {
return {
decideAction(getArgs, getState) {
const { nextTileName, pretendCode } = getArgs();
const { turn, detectEnemy, movableTiles } = getState();
const isPieceTile = validateCode(pretendCode);
const isOTW = includes(nextTileName, movableTiles);
const isSameSide = isPieceTile && detectTurn(turn, pretendCode);
const isEnemyTile = isPieceTile && detectEnemy(pretendCode, nextTileName);
const isMovable = !isPieceTile && !isSameSide && isOTW;
if (isSameSide) {
dispatch(updateSelectedCode(pretendCode));
}
if (isEnemyTile) {
dispatch(capturePiece(pretendCode, nextTileName));
}
if (isMovable) {
dispatch(movePiece(nextTileName));
}
},
};
}
function mergeProps(stateProps, dispatchProps, ownProps) {
return {
...stateProps,
...dispatchProps,
...ownProps,
// this callback has been executed from `<Tile />.onClickTile`
onClickTile(nextTileName, pretendCode) {
if (stateProps.preventEvent) {
return;
}
// HOF
dispatchProps.decideAction(
// get arguments from actual callback
() => ({ nextTileName, pretendCode }),
// state from `mapStateToProps`
() => stateProps
);
},
};
}
export default connect(
mapStateToProps,
mapDispatchToProps,
mergeProps
)(Diagram);