-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathShowBoard.js
More file actions
196 lines (181 loc) · 7.12 KB
/
Copy pathShowBoard.js
File metadata and controls
196 lines (181 loc) · 7.12 KB
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
import React, { useState, useEffect } from 'react';
import { View, TouchableOpacity, StyleSheet, ImageBackground, Text, Dimensions, Alert } from 'react-native';
import Board from './src/Board/Board';
import moveChess from './src/Move/moveChess'
import isWin from './src/Check/isWin';
const clone = require('lodash');
const ShowBoard = ({ gameOver, flag, switchPlayer, setGameOver, backMove, setBackMove, refreshBoard, setRefreshBoard }) => {
const [board, setBoard] = useState([]);//棋盘
const [canMoveBoard, setCanMoveBoard] = useState([]);//显示可移动位置
const [selectedPiece, setSelectedPiece] = useState(null);//选中的棋子
const [savedBoard, saveBoard] = useState(Board.init);//保存棋盘,用于悔棋
const initCanMoveBoard = () => { return Array.from(Array(10), () => Array(9).fill(false)); };//初始化可移动位置
useEffect(() => {
setBoard(Board.board);
setCanMoveBoard(initCanMoveBoard());
}, []);
useEffect(() => {
if (backMove === true) {
if (savedBoard === null) {
alert("不允许连续悔棋!");
return;
}
Board.board = savedBoard;
setBoard(Board.board);
switchPlayer();
saveBoard(null);//清除保存的棋盘
setBackMove(false);
}
}, [backMove]);
useEffect(() => {
if (!refreshBoard) return;//是否刷新棋盘判断
Board.board = clone.cloneDeep(Board.init);
setBoard(Board.board);
setCanMoveBoard(initCanMoveBoard());
setSelectedPiece(null);
saveBoard(null);
setBackMove(false);
setGameOver(false);
setRefreshBoard(false);
}, [refreshBoard]);
const { width, height } = Dimensions.get('window');
const numRows = 10;
const numCols = 9;
const aspectRatio = numCols / numRows; //棋盘的宽高比
const ratio = width / height;
let boardWidth, boardHeight;
// 根据屏幕宽高比动态设置棋盘的宽度和高度
if (ratio > aspectRatio) {
// 屏幕更宽,按高度计算
boardHeight = height * 0.8;
boardWidth = boardHeight * aspectRatio;
} else {
// 屏幕更高,按宽度计算
boardWidth = width * 0.95;
boardHeight = boardWidth / aspectRatio;
}
const cellWidth = boardWidth / numCols;
const cellHeight = boardHeight / numRows;
// 渲染棋盘单元格
const renderCell = (cell, rowIndex, colIndex) => {
const fontSize = Math.min(cellWidth, cellHeight) * 0.6;//动态设定大小
const isBlackPiece = cell.type === 1;
const shouldRotate = ratio <= aspectRatio && isBlackPiece; // 屏幕更高且是黑方棋子就将机器旋转180度
return (
<TouchableOpacity //只有子组件才会有变透明的效果,而不是每一个单元格都会有
key={`${rowIndex}-${colIndex}`}
onPress={() => handleCellClick(rowIndex, colIndex)}
style={[styles.cell, { width: cellWidth + 1, height: cellHeight + 1 }]}
>
{cell.type !== 0 && (//位置上有棋子才放置
<Text style={[
styles.chess,
{ fontSize },
{ color: cell.type === 2 ? 'red' : 'black' },//对不同颜色的棋子设置不同样式
shouldRotate && styles.rotatedChess
]}>
{cell.name}
</Text>
)}
{canMoveBoard[rowIndex][colIndex] && (//设置可移动位置的样式
<View style={styles.intersection} />
)}
</TouchableOpacity>
);
};
const handleCellClick = (rowIndex, colIndex) => {
const chess = board[rowIndex][colIndex];
if (gameOver) return;
// 如果点击的是一个可以移动到的位置
if (canMoveBoard[rowIndex][colIndex]) {
// 如果已经点击过了棋子
if (selectedPiece) {
saveBoard(clone.cloneDeep(Board.board));//保存棋盘
if (moveChess(selectedPiece.row, selectedPiece.col, rowIndex, colIndex)) {
setBoard(Board.board);
setCanMoveBoard(initCanMoveBoard());
switchPlayer(); // 切换玩家
setSelectedPiece(null); // 移动后取消选中
}
}
} else {
// 如果点击的是己方棋子,则显示可移动位置
if (chess.type === flag) {
setSelectedPiece({ row: rowIndex, col: colIndex });
let place = chess.canMove(rowIndex, colIndex);
let tmp = initCanMoveBoard();
for (let i = 0; i < place.length; i++) {
tmp[place[i][0]][place[i][1]] = true;
}
setCanMoveBoard(tmp);
}
}
if (isWin(1)) {
alert("黑方获胜");
setGameOver(true);
} else if (isWin(2)) {
alert("红方获胜");
setGameOver(true);
}
};
return (
<ImageBackground
source={require('./images/board.jpg')}
style={[styles.board, { width: boardWidth, height: boardHeight, marginTop: 10, marginHorizontal: (width - boardWidth) / 2 }]}
>
<View style={styles.boardContainer}>
{board.map((row, rowIndex) => (
<View key={rowIndex} style={styles.row}>
{row.map((cell, colIndex) => renderCell(cell, rowIndex, colIndex))}
</View>
))}
</View>
</ImageBackground>
);
};
const styles = StyleSheet.create({
board: {
margin: 0,
alignSelf: 'center',
resizeMode: 'cover', // 确保图片覆盖整个区域
},
boardContainer: {
marginBottom: 15,
marginLeft: -5,
},
row: {
flexDirection: 'row',
},
cell: {
position: 'relative', // 确保子元素的绝对定位相对于当前单元格
justifyContent: 'center', // 垂直居中
alignItems: 'center', // 水平居中
},
rotatedChess: {
transform: [{ rotate: '180deg' }],
},
intersection: {
position: 'absolute',
top: '50%', // 调整垂直位置
left: '50%', // 调整水平位置
width: 5, // 圆点的宽度
height: 5, // 圆点的高度
borderRadius: 2.5, // 圆点的半径
backgroundColor: 'white',
transform: [{ translateX: -2.5 }, { translateY: -2.5 }], // 将圆点居中
},
chess: {
position: 'absolute',
top: '10%', // 调整垂直位置
left: '10%', // 调整水平位置
width: '80%', // 使用百分比确保棋子大小随单元格变化
height: '80%', // 使用百分比确保棋子大小随单元格变化
textAlign: 'center',
borderRadius: 50,
backgroundColor: 'wheat',
fontFamily: 'monospace',
fontWeight: '600',
userSelect: 'none',
},
});
export default ShowBoard;