Commit 3942f498 authored by liangyuetong's avatar liangyuetong

init commit

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": {
"antd": "^3.25.3",
"dva": "^2.4.1",
"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>Dva Demo</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 { Table } from 'antd';
class RecordTable extends Component {
render() {
return (
<Table
dataSource={this.props.data}
columns={this.props.column}
pagination={false}
rowKey={(record, index)=>index}
bordered={false}
/>
)
}
}
export default RecordTable;
import React, {Component} from 'react';
import styles from './square.css';
class Square extends Component {
render() {
return <div className={styles.square} onClick={this.props.onClick}><span className={styles.squareVal}>{this.props.value}</span></div>;
}
}
export default Square;
.square {
display: table-cell;
width: 100px;
height: 100px;
border: 1px solid lightgray;
padding: 0;
font-size: 80px;
font: 300;
color: black;
text-align: center;
position: relative;
}
.squareVal {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
html, body, :global(#root) {
height: 100%;
}
import dva from 'dva';
import './index.css';
// import
// 1. Initialize
const app = dva();
// 2. Plugins
// app.use({});
// 3. Model
app.model(require('./models/container').default);
// 4. Router
app.router(require('./router').default);
// 5. Start
app.start('#root');
export default {
namespace: 'con',
state: {
playerValue: 'x',// x or o
record: [],
step: 0,
winner: '',
history: ''
},
subscriptions: {
setup({ dispatch, history }) { // eslint-disable-line
history.listen(location => {
if (location.pathname === '/con') {
dispatch({
type: 'play'
})
}
})
},
},
effects: {
// *isComplete() {
// }
// *fetch({ payload }, { call, put }) { // eslint-disable-line
// yield put({ type: 'save' });
// },
},
reducers: {
play(state, action) {
return { ...state, ...action.payload };
},
},
};
import React from 'react';
import { Router, Route, Switch } from 'dva/router';
import Container from './routes/Container';
function RouterConfig({ history }) {
return (
<Router history={history}>
<Switch>
<Route path="/con" exact component={Container} />
</Switch>
</Router>
);
}
export default RouterConfig;
import React from 'react';
import { connect } from 'dva';
import styles from './container.css';
import Square from '../components/Square';
import RecordTable from '../components/RecordTable';
import { Button } from 'antd';
function Container({ dispatch, con }) {
const { playerValue, record, step, winner } = con;
const latestMove = step === 0 ? new Array(9).fill(null) : record[step - 1].records;
const array = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
]
const mapSquare = (item, index, row) => {
let chess = [];
const play = (index, row) => {
if (winner === '') {
let next = step % 2 === 0 ? 'o' : 'x';
let newArr = step === 0 ? new Array(9).fill(null) : Object.assign([], record[step - 1].records);//备份数组用作后续修改
const handlerChange = (arr) => {
dispatch({
type: 'con/play',
payload: {
playerValue: next,
record: record.concat({
step: record.length + 1,
coordinate: `[${row}, ${index}]`,
records: chess.concat(arr)
}),
step: record.length + 1
}
})
array.map(items => {
let [a, b, c] = items;
if (arr[a] && arr[b] && arr[c]) {
if (arr[a] === arr[b] && arr[c] === arr[b]) {
dispatch({
type: 'con/play',
payload: {
winner: arr[a]
}
})
alert(`赢了~~`)
}
}
return winner;
})
}
switch (row) {
case 0:
if (latestMove[index] !== null) {
alert('这个位置被占啦,换个地方吧~')
} else {
newArr.splice(index, 1, playerValue);
handlerChange(newArr);
}
break;
case 1:
if (latestMove[index + 3] !== null) {
alert('这个位置被占啦,换个地方吧~')
} else {
newArr.splice(index + 3, 1, playerValue);;
handlerChange(newArr);
}
break;
case 2:
if (latestMove[index + 6] !== null) {
alert('这个位置被占啦,换个地方吧~')
} else {
newArr.splice(index + 6, 1, playerValue);;
handlerChange(newArr);
}
break;
default:
break;
}
// 坐标 00 01 02,10 11 12,20 21 22,00 10 20,01 11 21, 02 10 22,00 11 22,02 11 20
// 行 数组下标
// 0 1 2,3 4 5,6 7 8, 0 3 6, 1 4 7, 2 5 8, 0 4 8, 2 4 6
} else {
alert('你已经赢了,再来一局吧~')
return;
}
}
return <Square key={index} value={item} onClick={() => play(index, row)} />
}
const reset = () => {
dispatch({
type: 'con/play',
payload: {
playerValue: 'x',// x or o
record: [],
step: 0,
winner: ''
}
})
}
const recall = (records, index) => {
dispatch({
type: 'con/play',
payload: {
step: index + 1
}
})
}
const column = [
{
title: '步数',
key: 'step',
dataIndex: 'step',
render: (text, records, index) => <div className={styles.step} onClick={() => recall(records, index)}>{text}</div>
},
{
title: '坐标',
key: 'coordinate',
dataIndex: 'coordinate'
}
]
const chessArr = step === 0 ? new Array(9).fill(null) : record[step - 1].records;
return (
<div className={styles.container}>
<div className={styles.normal}>
<div className={styles.header}>the next player is: {playerValue}</div>
<div>{chessArr.slice(0, 3).map((item, index) => mapSquare(item, index, 0))}</div>
<div>{chessArr.slice(3, 6).map((item, index) => mapSquare(item, index, 1))}</div>
<div>{chessArr.slice(6, 9).map((item, index) => mapSquare(item, index, 2))}</div>
<Button onClick={() => reset()}>重新开始</Button>
<div>the winner is: {winner}</div>
</div>
<div className={styles.table}>
<RecordTable column={column} data={record} />
</div>
</div>
);
}
// IndexPage.propTypes = {
// };
export default connect(({ con }) => ({ con }))(Container);
.container {
width: 100%;
height: 400px;
}
.normal {
display: table;
width: 350px;
display: inline-block;
}
.header {
margin: 10px 0;
font-size: large;
color: goldenrod;
font-family: 'Courier New', Courier, monospace;
}
.table {
margin: 35px;
padding: 0;
position: absolute;
display: inline-block;
}
.step {
color: red;
}
.step:hover {
cursor: pointer;
}
\ 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 }));
}
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