minesweeper-frontend/src/components/Board.jsx
2025-01-21 23:51:02 +01:00

75 lines
2.3 KiB
JavaScript

import PropTypes from 'prop-types';
import './Board.css';
const Board = ({ board, players, handleTileClick, handleTileFlag, setSelectedTile }) => {
const valueColors = {
1: '#6a8cff',
2: '#7fff7f',
3: '#ff6a6a',
4: '#9f7fff',
5: '#ff7f7f',
6: '#7fffff',
7: '#4f4f4f',
8: '#a0a0a0'
}
const playerColors = new Map();
players.forEach(player => playerColors.set(player.socketId, player.color));
const getStyle = (tile) => {
const style = {};
const tombstoneOf = players.find(player => player.tombstone === tile.id);
const selectionOf = players.find(player => player.selection === tile.id);
if (tombstoneOf) style.backgroundColor = playerColors.get(tombstoneOf.socketId);
else if (selectionOf) style.backgroundColor = playerColors.get(selectionOf.socketId);
if (tile.value !== undefined) style.color = valueColors[tile.value];
return style;
}
const getTileDisplay = (tile) => {
const tombstone = players.find(player => player.tombstone === tile.id);
if (tombstone) return '💀';
if (tile.flagged) return '🚩';
if (tile.bomb) return '💣';
if (tile.value) return tile.value;
return '';
}
const clickTile = (tile) => {
setSelectedTile(tile);
handleTileClick(tile);
}
const rightClickTile = (tile) => {
handleTileFlag(tile);
}
return (
<div className="board" style={{ gridTemplateColumns: `repeat(${board.cols}, 1fr)`, gridTemplateRows: `repeat(${board.rows}, 1fr)` }}>
{
board.tiles.map((tile) => (
<button
key={tile.id}
className={tile.value !== undefined ? "tile revealed" : "tile"}
style={getStyle(tile)}
onClick={() => clickTile(tile.id)}
onContextMenu={(evt) => {
evt.preventDefault();
rightClickTile(tile.id);
}}>
<span>{getTileDisplay(tile)}</span>
</button>
))
}
</div>
);
};
Board.propTypes = {
board: PropTypes.object.isRequired,
players: PropTypes.array.isRequired,
handleTileClick: PropTypes.func.isRequired,
handleTileFlag: PropTypes.func.isRequired,
setSelectedTile: PropTypes.func.isRequired
};
export default Board;