Commit b2a15326 authored by 佚名's avatar 佚名 🎅🏼

feat

parents
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tab
{
"extends": "umi"
}
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
# production
/dist
# misc
.DS_Store
npm-debug.log*
export default {
};
This diff is collapsed.
{
"private": true,
"scripts": {
"start": "roadhog server",
"build": "roadhog build",
"lint": "eslint --ext .js src test",
"precommit": "npm run lint"
},
"dependencies": {
"dva": "^2.4.1",
"history": "^4.9.0",
"less": "^3.9.0",
"react": "^16.2.0",
"react-dom": "^16.2.0"
},
"devDependencies": {
"babel-plugin-dva-hmr": "^0.3.2",
"eslint": "^4.14.0",
"eslint-config-umi": "^0.1.1",
"eslint-plugin-flowtype": "^2.34.1",
"eslint-plugin-import": "^2.6.0",
"eslint-plugin-jsx-a11y": "^5.1.1",
"eslint-plugin-react": "^7.1.0",
"husky": "^0.12.0",
"redbox-react": "^1.4.3",
"roadhog": "^2.5.0-beta.4"
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>chess game</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<div id="root"></div>
<script src="index.js"></script>
</body>
</html>
import React, { Component } from 'react';
import Square from './Square';
import './styles/board.css';
class Board extends Component {
renderSquare(i) {
return (
<Square
value={this.props.squares[i]}
onClick={() => this.props.onClick(i)}
/>
)
}
render() {
return (
<div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
)
}
}
export default Board;
\ No newline at end of file
import React from 'react';
import './styles/square.css';
//import 样式未生效,问题查找中,暂且定义行内样式
const style = {
width: '34px',
height: '34px',
border: '1px solid #999',
fontSize: '24px',
fontWeight: 'bold',
lineHeight: '34px',
marginTop: '-1px',
marginRight: '-1px',
padding: '0',
textAlign: 'center',
background: '#fff',
}
const Square = (props) => {
return (
<button
style={style}
className="square"
onClick={props.onClick}
>
{props.value}
</button>
);
};
Square.propTypes = {
};
export default Square;
.board-row:after {
clear: both;
content: "";
display: table;
}
\ No newline at end of file
.square {
width: 34px;
height: 34px;
border: 1px solid #999;
font-size: 24px;
font-weight: bold;
line-height: 34px;
margin-top: -1px;
margin-right: -1px;
padding: 0;
text-align: center;
background: #fff;
}
.square:focus {
outline: none;
}
\ No newline at end of file
html, body, :global(#root) {
height: 100%;
}
import dva from 'dva';
import './index.css';
import createHistory from 'history/createBrowserHistory';
// 1. Initialize
const app = dva({
history: createHistory()
});
// 2. Plugins
// app.use({});
// 3. Model
app.model(require('./models/game').default);
// 4. Router
app.router(require('./router').default);
// 5. Start
app.start('#root');
export default {
namespace: 'game',
state: {
history: [
{
squares: Array(9).fill(null)
}
],
stepNumber: 0,
xIsNext: true
},
reducers: {
handleClick(state, action){
function calculateWinner(squares) {
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
for (let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return squares[a];
}
}
return null;
}
const history = state.history.slice(0, state.stepNumber + 1);
const current = history[history.length - 1];
const squares = current.squares.slice();
if (calculateWinner(squares) || squares[action.payload]) {
return;
}
squares[action.payload] = state.xIsNext ? "X" : "O";
return {
history: history.concat([
{
squares: squares
}
]),
stepNumber: history.length,
xIsNext: !state.xIsNext
};
},
jumpTo(state, action){
return {
stepNumber: action.move,
xIsNext: (action.move % 2) === 0
}
}
},
};
import React from 'react';
import { Router, Route, Switch } from 'dva/router';
import Game from './routes/Game';
function RouterConfig({ history }) {
return (
<Router history={history}>
<Switch>
<Route path="/" exact component={Game} />
</Switch>
</Router>
);
}
export default RouterConfig;
import React from 'react';
import { connect } from 'dva';
import Board from '../components/Board';
import './game.css';
function calculateWinner(squares) {
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
for (let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return squares[a];
}
}
return null;
}
const Game = ({ history, stepNumber, xIsNext, dispatch }) => {
const current = history[stepNumber];
const winner = calculateWinner(current.squares);
const moves = history.map((step, move) => {
const desc = move ?
'Go to move #' + move :
'Go to game start';
return (
<li key={move}>
<button onClick={() => dispatch({type: 'game/jumpTo', payload: move})}>{desc}</button>
</li>
)
});
let status;
if (winner) {
status = "Winner: " + winner;
} else {
status = "Next player: " + (xIsNext ? "X" : "O");
}
return (
<div className="game">
<div className="game-board">
<Board
squares={current.squares}
onClick={(i) => dispatch({type: 'game/handleClick', payload: i}) }
/>
<div>样式目前存在较大问题,玩法功能也存在较多问题,正常玩法流程可进行,多次点击目前报错,以及时间回溯功能也报错,下午完善,上午才着手做这个,昨天看了份dva视频教程</div>
</div>
<div className="game-info">
<div>{status}</div>
<ol>{moves}</ol>
</div>
</div>
)
}
Game.propTypes = {
};
const mapStateToProps = (state) => {
return {
history: state.game.history,
stepNumber: state.game.stepNumber,
xIsNext: state.game.xIsNext
}
}
export default connect(mapStateToProps)(Game);
body {
font: 14px "Century Gothic", Futura, sans-serif;
margin: 20px;
}
ol, ul {
padding-left: 30px;
}
.board-row:after {
clear: both;
content: "";
display: table;
}
.status {
margin-bottom: 10px;
}
.square {
background: #fff;
border: 1px solid #999;
float: left;
font-size: 24px;
font-weight: bold;
line-height: 34px;
height: 34px;
margin-right: -1px;
margin-top: -1px;
padding: 0;
text-align: center;
width: 34px;
}
.square:focus {
outline: none;
}
.kbd-navigation .square:focus {
background: #ddd;
}
.game {
display: flex;
flex-direction: row;
}
.game-info {
margin-left: 20px;
}
\ No newline at end of file
import request from '../utils/request';
export function query() {
return request('/api/users');
}
import fetch from 'dva/fetch';
function parseJSON(response) {
return response.json();
}
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new Error(response.statusText);
error.response = response;
throw error;
}
/**
* Requests a URL, returning a promise.
*
* @param {string} url The URL we want to request
* @param {object} [options] The options we want to pass to "fetch"
* @return {object} An object containing either "data" or "err"
*/
export default function request(url, options) {
return fetch(url, options)
.then(checkStatus)
.then(parseJSON)
.then(data => ({ data }))
.catch(err => ({ err }));
}
This diff is collapsed.
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