Game now sets up correct tile and pip order!
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
27cf10ad48
commit
7af8d02802
@ -3,95 +3,13 @@ import "./Board.css";
|
||||
|
||||
const base = process.env.PUBLIC_URL;
|
||||
const assetsPath = `${base}/assets`;
|
||||
const images = {};
|
||||
|
||||
const getPlayerColors = (color) => {
|
||||
switch (color) {
|
||||
case "O":
|
||||
return {
|
||||
strokeStyle: "white",
|
||||
fillStyle: "#ff5722"
|
||||
}
|
||||
case "R":
|
||||
return {
|
||||
strokeStyle: "white",
|
||||
fillStyle: "#f44336"
|
||||
}
|
||||
case "W":
|
||||
return {
|
||||
strokeStyle: "black",
|
||||
fillStyle: "#9e9e9e"
|
||||
}
|
||||
case "B":
|
||||
return {
|
||||
strokeStyle: "black",
|
||||
fillStyle: "#03a9f4"
|
||||
}
|
||||
default:
|
||||
return {
|
||||
strokeStyle: "rgb(16, 16, 16)",
|
||||
fillStyle: "rgb(64, 64, 64)"
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const hexagonRatio = 1.1547005,
|
||||
tileHeight = 0.16,
|
||||
tileWidth = tileHeight * hexagonRatio,
|
||||
roadSize = tileHeight * 0.5 * (5. / 8.),
|
||||
settlementSize = tileHeight * 0.5 - roadSize;
|
||||
|
||||
const imageLoaded = (event) => {
|
||||
const image = event.target;
|
||||
console.log(`Done loading ${image.src}`);
|
||||
image.removeEventListener("load", imageLoaded);
|
||||
image.removeEventListener("error", imageLoadError);
|
||||
|
||||
try {
|
||||
if (image.drawFrame) {
|
||||
window.requestAnimationFrame(image.drawFrame);
|
||||
}
|
||||
} catch (error) {
|
||||
image.board = null;
|
||||
}
|
||||
};
|
||||
|
||||
const imageLoadError = (event) => {
|
||||
const image = event.target;
|
||||
console.log(`Error loading ${image.src}`);
|
||||
image.removeEventListener("load", imageLoaded);
|
||||
image.removeEventListener("error", imageLoadError);
|
||||
console.log(`Error loading ${image.src}`);
|
||||
}
|
||||
|
||||
const loadImage = (file, drawFrame) => {
|
||||
if (file in images) {
|
||||
images[file].drawFrame = drawFrame;
|
||||
return images[file];
|
||||
}
|
||||
|
||||
const image = new Image();
|
||||
image.drawFrame = drawFrame;
|
||||
images[file] = image;
|
||||
|
||||
image.addEventListener("load", imageLoaded);
|
||||
image.addEventListener("error", imageLoadError);
|
||||
|
||||
image.src = `${assetsPath}/gfx/${file}`;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
const Board = ({ game }) => {
|
||||
const [closest, setClosest] = useState({
|
||||
info: {},
|
||||
tile: null,
|
||||
road: null,
|
||||
tradeToken: null,
|
||||
settlement: null
|
||||
});
|
||||
|
||||
const center = { x: 300, y: 350 }, rows = [3, 4, 5, 4, 3];
|
||||
const [signature, setSignature] = useState("");
|
||||
const [pips, setPips] = useState(<></>);
|
||||
const [borders, setBorders] = useState(<></>);
|
||||
const [tiles, setTiles] = useState(<></>);
|
||||
|
||||
const generatePips = () => {
|
||||
let row = 0, rowCount = 0;
|
||||
@ -104,7 +22,7 @@ const Board = ({ game }) => {
|
||||
: String.fromCharCode(65 + i);
|
||||
divs.push(
|
||||
<div
|
||||
key={`pip-${code}`}
|
||||
key={`pip-${(i).toString(16)}`}
|
||||
className="Pip"
|
||||
style={{
|
||||
top: `${y}px`,
|
||||
@ -132,7 +50,7 @@ const Board = ({ game }) => {
|
||||
let y = center.y - rows.length * 0.5 * 67,
|
||||
x = center.x - (rows[row] - 1) * 0.5 * 77.5;
|
||||
|
||||
return [ "robber", "brick", "wood", "sheep", "stone", "wheat" ].map((type) => {
|
||||
return [ "wood", "wheat", "stone", "sheep", "brick", "robber" ].map((type) => {
|
||||
let count;
|
||||
switch (type) {
|
||||
case "robber":
|
||||
@ -162,7 +80,7 @@ const Board = ({ game }) => {
|
||||
for (let i = 0; i < count; i++) {
|
||||
divs.push(
|
||||
<div
|
||||
key={`${type}-${i}`}
|
||||
key={`${type}-${(i).toString(16)}`}
|
||||
className="Tile"
|
||||
style={{
|
||||
top: `${y}px`,
|
||||
@ -196,7 +114,7 @@ const Board = ({ game }) => {
|
||||
let prev = (side == 0) ? 6 : side;
|
||||
const file = `borders-${side+1}.${prev}.png`;
|
||||
divs.push(<div
|
||||
key={`border-${side}`}
|
||||
key={`border-${side.toString(16)}`}
|
||||
className="Border"
|
||||
style={{
|
||||
top: `${y}px`,
|
||||
@ -208,9 +126,24 @@ const Board = ({ game }) => {
|
||||
return divs;
|
||||
};
|
||||
|
||||
const tiles = generateTiles(),
|
||||
pips = generatePips(),
|
||||
borders = generateBorders();
|
||||
const updateBorders = () => {
|
||||
for (let i = 0; i < 6; i++) {
|
||||
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
if (game && game.signature != signature) {
|
||||
console.log(`Generate for ${game.signature}`);
|
||||
setPips(generatePips);
|
||||
setBorders(generateBorders);
|
||||
setTiles(generateTiles);
|
||||
setSignature(game.signature);
|
||||
} else {
|
||||
if (!game) {
|
||||
console.log(`No game in Board`);
|
||||
}
|
||||
}
|
||||
}, [ setPips, setBorders, setTiles, setSignature, game]);
|
||||
|
||||
return (
|
||||
<div className="Board" style={{backgroundImage: `url(${assetsPath}/gfx/tabletop.png)`}}>
|
||||
|
@ -360,6 +360,9 @@ const Players = ({ table }) => {
|
||||
|
||||
const players = [];
|
||||
|
||||
if (!table.game) {
|
||||
return (<></>);
|
||||
}
|
||||
for (let color in table.game.players) {
|
||||
const item = table.game.players[color], inLobby = table.game.state === 'lobby';
|
||||
if (!inLobby && item.status === 'Not active') {
|
||||
@ -788,19 +791,19 @@ class Table extends React.Component {
|
||||
return "";
|
||||
}
|
||||
const signature =
|
||||
game.borders.map(border => border.file.replace(/borders-(.).*/, "$1")).join('') +
|
||||
game.pips.map(pip => pip.roll.toString()).join('') +
|
||||
game.tiles.map(tile => tile.type.charAt(0)).join('');
|
||||
game.borderOrder.map(border => Number(border).toString(16)).join('') + '-' +
|
||||
game.pipOrder.map(pip => Number(pip).toString(16)).join('') + '-' +
|
||||
game.tileOrder.map(tile => Number(tile).toString(16)).join('');
|
||||
|
||||
return signature;
|
||||
};
|
||||
|
||||
updateGame(game) {
|
||||
|
||||
if (this.state.signature !== this.gameSignature(game)) {
|
||||
this.setState({ signature: this.gameSignature(game), game: game });
|
||||
game.signature = this.gameSignature(game);
|
||||
}
|
||||
// console.log("Update Game", game);
|
||||
this.setState( { game: game });
|
||||
this.game = game;
|
||||
}
|
||||
|
||||
|
@ -36,54 +36,54 @@ function shuffle(array) {
|
||||
|
||||
const assetData = {
|
||||
tiles: [
|
||||
{ type: "wood", y: 0. / 4. },
|
||||
{ type: "wood", y: 1. / 4. },
|
||||
{ type: "wood", y: 2. / 4. },
|
||||
{ type: "wood", y: 3. / 4. },
|
||||
{ type: "wheat", y: 0. / 4. },
|
||||
{ type: "wheat", y: 1. / 4. },
|
||||
{ type: "wheat", y: 2. / 4. },
|
||||
{ type: "wheat", y: 3. / 4. },
|
||||
{ type: "stone", y: 0. / 4. },
|
||||
{ type: "stone", y: 1. / 4. },
|
||||
{ type: "stone", y: 2. / 4. },
|
||||
{ type: "sheep", y: 0. / 4. },
|
||||
{ type: "sheep", y: 1. / 4. },
|
||||
{ type: "sheep", y: 2. / 4. },
|
||||
{ type: "sheep", y: 3. / 4. },
|
||||
{ type: "brick", y: 0. / 4. },
|
||||
{ type: "brick", y: 1. / 4. },
|
||||
{ type: "brick", y: 2. / 4. },
|
||||
{ type: "robber", y: 0 }
|
||||
"wood",
|
||||
"wood",
|
||||
"wood",
|
||||
"wood",
|
||||
"wheat",
|
||||
"wheat",
|
||||
"wheat",
|
||||
"wheat",
|
||||
"stone",
|
||||
"stone",
|
||||
"stone",
|
||||
"sheep",
|
||||
"sheep",
|
||||
"sheep",
|
||||
"sheep",
|
||||
"brick",
|
||||
"brick",
|
||||
"brick",
|
||||
"robber"
|
||||
],
|
||||
pips: [
|
||||
{ roll: 7, pips: 0, y: 3. / 6., x: 0. / 6. },
|
||||
{ roll: 5, pips: 4, y: 0. / 6., x: 0. / 6. },
|
||||
{ roll: 2, pips: 1, y: 0. / 6., x: 1. / 6. },
|
||||
{ roll: 6, pips: 5, y: 0. / 6., x: 2. / 6. },
|
||||
{ roll: 3, pips: 2, y: 0. / 6., x: 3. / 6. },
|
||||
{ roll: 8, pips: 5, y: 0. / 6., x: 4. / 6. },
|
||||
{ roll: 10, pips: 3, y: 0. / 6., x: 5. / 6. },
|
||||
{ roll: 9, pips: 4, y: 1. / 6., x: 0. / 6. },
|
||||
{ roll: 12, pips: 1, y: 1. / 6., x: 1. / 6. },
|
||||
{ roll: 11, pips: 2, y: 1. / 6., x: 2. / 6. },
|
||||
{ roll: 4, pips: 3, y: 1. / 6., x: 3. / 6. },
|
||||
{ roll: 8, pips: 5, y: 1. / 6., x: 4. / 6. },
|
||||
{ roll: 10, pips: 3, y: 1. / 6., x: 5. / 6. },
|
||||
{ roll: 9, pips: 4, y: 2. / 6., x: 0. / 6. },
|
||||
{ roll: 4, pips: 3, y: 2. / 6., x: 1. / 6. },
|
||||
{ roll: 5, pips: 4, y: 2. / 6., x: 2. / 6. },
|
||||
{ roll: 6, pips: 6, y: 2. / 6., x: 3. / 6. },
|
||||
{ roll: 3, pips: 2, y: 2. / 6., x: 4. / 6. },
|
||||
{ roll: 11, pips: 2, y: 2. / 6., x: 5. / 6. }
|
||||
{ roll: 7, pips: 0 },
|
||||
{ roll: 5, pips: 4 },
|
||||
{ roll: 2, pips: 1 },
|
||||
{ roll: 6, pips: 5 },
|
||||
{ roll: 3, pips: 2 },
|
||||
{ roll: 8, pips: 5 },
|
||||
{ roll: 10, pips: 3 },
|
||||
{ roll: 9, pips: 4 },
|
||||
{ roll: 12, pips: 1 },
|
||||
{ roll: 11, pips: 2 },
|
||||
{ roll: 4, pips: 3 },
|
||||
{ roll: 8, pips: 5 },
|
||||
{ roll: 10, pips: 3 },
|
||||
{ roll: 9, pips: 4 },
|
||||
{ roll: 4, pips: 3 },
|
||||
{ roll: 5, pips: 4 },
|
||||
{ roll: 6, pips: 6 },
|
||||
{ roll: 3, pips: 2 },
|
||||
{ roll: 11, pips: 2 }
|
||||
],
|
||||
borders: [
|
||||
{ file: 'borders-1.6.png', left: "sheep", right: "bank" },
|
||||
{ file: 'borders-2.1.png', center: "sheep" },
|
||||
{ file: 'borders-3.2.png', left: "wheat", right: "bank" },
|
||||
{ file: 'borders-4.3.png', center: "wood" },
|
||||
{ file: 'borders-5.4.png', left: "sheep", right: "bank" },
|
||||
{ file: 'borders-6.5.png', center: "bank" }
|
||||
{ left: "sheep", right: "bank" },
|
||||
{ center: "sheep" },
|
||||
{ left: "wheat", right: "bank" },
|
||||
{ center: "wood" },
|
||||
{ left: "sheep", right: "bank" },
|
||||
{ center: "bank" }
|
||||
],
|
||||
developmentCards: []
|
||||
};
|
||||
@ -201,6 +201,17 @@ const loadGame = async (id) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (!game.pipOrder || !game.borderOrder || !game.tileOrder) {
|
||||
console.log("Shuffling old save file");
|
||||
shuffleBoard(game);
|
||||
}
|
||||
|
||||
if (!game.pips || !game.borders || !game.tiles) {
|
||||
[ "pips", "borders", "tiles" ].forEach((field) => {
|
||||
game[field] = assetData[field]
|
||||
});
|
||||
}
|
||||
|
||||
/* Reconnect session player colors to the player objects */
|
||||
for (let id in game.sessions) {
|
||||
const session = game.sessions[id];
|
||||
@ -590,9 +601,6 @@ const createGame = (id) => {
|
||||
startTime: Date.now(),
|
||||
turns: 0,
|
||||
state: "lobby", /* lobby, active, finished */
|
||||
tiles: [],
|
||||
pips: [],
|
||||
borders: [],
|
||||
tokens: [],
|
||||
players: {
|
||||
R: getPlayer(),
|
||||
@ -612,6 +620,11 @@ const createGame = (id) => {
|
||||
chat: [ { date: Date.now(), message: `New game started for ${id}` } ],
|
||||
id: id
|
||||
};
|
||||
|
||||
[ "pips", "borders", "tiles" ].forEach((field) => {
|
||||
game[field] = assetData[field]
|
||||
});
|
||||
|
||||
games[game.id] = game;
|
||||
shuffleBoard(game);
|
||||
console.log(`New game created: ${game.id}`);
|
||||
@ -633,29 +646,49 @@ router.post("/:id?", (req, res/*, next*/) => {
|
||||
});
|
||||
|
||||
const shuffleBoard = (game) => {
|
||||
[ "tiles", "pips", "borders" ].forEach((field) => {
|
||||
game[field] = []
|
||||
for (let i = 0; i < assetData[field].length; i++) {
|
||||
game[field].push(i);
|
||||
const seq = [];
|
||||
for (let i = 0; i < 6; i++) {
|
||||
seq.push(i);
|
||||
}
|
||||
/* Shuffle an array of indexes */
|
||||
shuffle(game[field]);
|
||||
/* Convert from an index array to a full array */
|
||||
for (let i = 0; i < assetData[field].length; i++) {
|
||||
game[field][i] = assetData[field][game[field][i]];
|
||||
shuffle(seq);
|
||||
game.borderOrder = seq.slice();
|
||||
for (let i = 6; i < 19; i++) {
|
||||
seq.push(i);
|
||||
}
|
||||
});
|
||||
shuffle(seq);
|
||||
game.tileOrder = seq.slice();
|
||||
|
||||
/* Walk through the board looking for the robber and
|
||||
* if it isn't on the desert, swap with the desert to
|
||||
* be under the robber */
|
||||
const robberIndex = game.pips.findIndex((pip) => pip.roll === 7),
|
||||
desertIndex = game.tiles.findIndex((tile) => tile.type === 'robber');
|
||||
/* Pip order is from one of the random corners, then rotate around
|
||||
* and skip over the desert (robber) */
|
||||
|
||||
if (robberIndex !== desertIndex) {
|
||||
let tmp = game.tiles[desertIndex];
|
||||
game.tiles[desertIndex] = game.tiles[robberIndex];
|
||||
game.tiles[robberIndex] = tmp;
|
||||
/* Board:
|
||||
* 0 1 2
|
||||
* 3 4 5 6
|
||||
* 7 8 9 10 11
|
||||
* 12 13 14 15
|
||||
* 16 17 18
|
||||
*/
|
||||
const order = [
|
||||
[ 0, 1, 2, 6, 11, 15, 18, 17, 16, 12, 7, 3, 4, 5, 10, 14, 13, 8, 9 ],
|
||||
[ 2, 6, 11, 15, 18, 17, 16, 12, 7, 3, 0, 1, 5, 10, 14, 13, 8, 4, 9 ],
|
||||
[ 11, 15, 18, 17, 16, 12, 7, 3, 0, 1, 2, 6, 10, 14, 13, 8, 4, 5, 9 ],
|
||||
[ 18, 17, 16, 12, 7, 3, 0, 1, 2, 6, 11, 15, 14, 13, 8, 4, 5, 10, 9 ],
|
||||
[ 16, 12, 7, 3, 0, 1, 2, 6, 11, 15, 18, 17, 13, 8, 4, 5, 10, 14, 9 ],
|
||||
[ 7, 3, 0, 1, 2, 6, 11, 15, 18, 17, 16, 12, 8, 4, 5, 10, 14, 13, 9 ]
|
||||
]
|
||||
const sequence = order[Math.floor(Math.random() * order.length)];
|
||||
game.pipOrder = [];
|
||||
for (let i = 0, p = 0; i < sequence.length; i++) {
|
||||
const target = sequence[i];
|
||||
/* If the target tile is the desert (18), then set the
|
||||
* pip value to the robber (0) otherwise set
|
||||
* the target pip value to the currently incremeneting
|
||||
* pip value. */
|
||||
if (game.tileOrder[target] === 18) {
|
||||
game.pipOrder[target] = 0;
|
||||
} else {
|
||||
game.pipOrder[target] = p++;
|
||||
}
|
||||
}
|
||||
|
||||
shuffle(game.developmentCards)
|
||||
|
Loading…
x
Reference in New Issue
Block a user