Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draw situation fixed #535

Merged
merged 2 commits into from
Jul 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 94 additions & 79 deletions js/board.js
Original file line number Diff line number Diff line change
@@ -1,64 +1,70 @@
class Board {
static ROWS //number of rows
static COLUMNS //number of columns
static BOXES_COUNT //number of boxes
static ROWS; //number of rows
static COLUMNS; //number of columns
static BOXES_COUNT; //number of boxes

constructor(rows, columns) {
Board.ROWS = rows
Board.COLUMNS = columns
Board.BOXES_COUNT = rows * columns
Board.ROWS = rows;
Board.COLUMNS = columns;
Board.BOXES_COUNT = rows * columns;

//uiRoot is the root element of the board
this.uiRoot = document.querySelector(".board")
this.setEdgeThickness()
this.uiRoot = document.querySelector(".board");
this.setEdgeThickness();

//Below is the code for generation of the board
this.boxes = new Array(rows).fill(null).map(() => new Array(columns).fill(null))
this.boxes = new Array(rows)
.fill(null)
.map(() => new Array(columns).fill(null));

this.adjacentBoxesToFill = []
this.isFillingAdjacentBoxes = false
this.filledBoxes = 0
this.adjacentBoxesToFill = [];
this.isFillingAdjacentBoxes = false;
this.filledBoxes = 0;

this.generate()
this.generate();

this.addEdgeClickEventListener()
this.addEdgeClickEventListener();

Game.instance.addEventListener("edgeFill", (edge) =>
this.onEdgeFill(edge)
)
Game.instance.addEventListener("boxFill", (box) => this.onBoxFill(box))
Game.instance.addEventListener("edgeFill", (edge) => this.onEdgeFill(edge));
Game.instance.addEventListener("boxFill", (box) => this.onBoxFill(box));
}

//Setting up the edge thickness based on the number of boxes.
//Setting up the edge thickness based on the number of boxes.
//We need to set it for Root UI.
setEdgeThickness() {
//The thickness of the edge depends on the number of boxes
let thickness =
(Board.BOXES_COUNT <= 25) ? 10 :
(Board.BOXES_COUNT <= 100) ? 8 :
(Board.BOXES_COUNT <= 200) ? 5 : 3

document.querySelector(":root").style.setProperty("--edge-thikness", `${thickness}px`)
Board.BOXES_COUNT <= 25
? 10
: Board.BOXES_COUNT <= 100
? 8
: Board.BOXES_COUNT <= 200
? 5
: 3;

document
.querySelector(":root")
.style.setProperty("--edge-thikness", `${thickness}px`);
}

//
addEdgeClickEventListener() {
this.uiRoot.addEventListener("click", (e) => {
let click = new Audio('../assets/sounds/click.mp3');
let click = new Audio("../assets/sounds/click.mp3");
click.play();
if (!this.isFillingAdjacentBoxes) {
if (e.target.classList.contains("edge")) {
let edgePosition = e.target.getAttribute("data-position")
let edgePosition = e.target.getAttribute("data-position");
//Getting the row and column of the box so we can write logic to fill the box later
let r = e.target.parentElement.getAttribute("data-row")
let c = e.target.parentElement.getAttribute("data-column")
let box = this.boxes[r][c]
let r = e.target.parentElement.getAttribute("data-row");
let c = e.target.parentElement.getAttribute("data-column");
let box = this.boxes[r][c];
//Getting the edge object from the box
let edge = box.getEdge(edgePosition)
this.onEdgeClick(box, edge)
let edge = box.getEdge(edgePosition);
this.onEdgeClick(box, edge);
}
}
})
});
}
//On click of the edge, we need to fill the edge and check if the adjacent boxes can be filled
// onEdgeClick(box, edge) {
Expand All @@ -78,71 +84,75 @@ class Board {
onEdgeClick(box, edge) {
const currentPlayerColor = Game.instance.currentPlayer.color; // Get the current player's color
box.fillEdge(edge, currentPlayerColor);

// Get the adjacent filled boxes.
const adjacentBox = box.getAdjacentBox(edge.position);
if (adjacentBox != null)

if (adjacentBox != null) {
adjacentBox.fillEdge(edge.inverseEdge, currentPlayerColor);

}

setTimeout(() => {
if (this.adjacentBoxesToFill.length == 0) Game.instance.switchPlayer();
if (this.adjacentBoxesToFill.length == 0) {
Game.instance.switchPlayer();
}
}, 100);
}


//Check for remaining edges in boxes
onEdgeFill(edge) {
const box = edge.box
box.remainingEdges--
const box = edge.box;
box.remainingEdges--;

if (box.remainingEdges == 0) {
this.fillBox(box)
this.fillBox(box);
}
}

//Check for adjacent boxes to fill
fillBox(box) {
this.adjacentBoxesToFill.push(box)
this.adjacentBoxesToFill.push(box);

setTimeout(() => this.checkAdjacentadjacentBoxesToFill(box), 100)
setTimeout(() => this.checkAdjacentadjacentBoxesToFill(box), 100);

if (!this.isFillingAdjacentBoxes) {
this.isFillingAdjacentBoxes = true
this.fillBoxes()
this.isFillingAdjacentBoxes = true;
this.fillBoxes();
}
}

onBoxFill(box) {
this.filledBoxes++
this.filledBoxes++;

//If all the boxes are filled, then the player wins
if (this.filledBoxes == Board.BOXES_COUNT)
Game.instance.invokeEvent("playerWin")
if (this.filledBoxes == Board.BOXES_COUNT) {
Game.instance.invokeEvent("boxFill");
Game.instance.invokeEvent("playerWin");
}
}

//Board boxes
generateBoardBoxes() {
for (let r = 0; r < Board.ROWS; r++)
for (let c = 0; c < Board.COLUMNS; c++) {
const box = new Box(r, c)
this.boxes[r][c] = box
this.uiRoot.appendChild(box.ui)
const box = new Box(r, c);
this.boxes[r][c] = box;
this.uiRoot.appendChild(box.ui);
}

//set each box adjacents and inverses
for (let r = 0; r < Board.ROWS; r++)
for (let c = 0; c < Board.COLUMNS; c++) {
let box = this.boxes[r][c]
box.adjacentBoxes = this.getBoxAdjacents(box)
box.inverseEdges = this.getBoxInverseEdges(box)
this.boxes[r][c] = box
let box = this.boxes[r][c];
box.adjacentBoxes = this.getBoxAdjacents(box);
box.inverseEdges = this.getBoxInverseEdges(box);
this.boxes[r][c] = box;
}
}

generate() {
this.uiRoot.style.gridTemplate = `repeat(${Board.ROWS}, 1fr) / repeat(${Board.COLUMNS}, 1fr)`
this.generateBoardBoxes()
this.uiRoot.style.gridTemplate = `repeat(${Board.ROWS}, 1fr) / repeat(${Board.COLUMNS}, 1fr)`;
this.generateBoardBoxes();
}

getBoxAdjacents(box) {
Expand All @@ -152,59 +162,64 @@ class Board {
//{0,1} means the box is to the right of the current box
//{1,0} means the box is below the current box
//{0,-1} means the box is to the left of the current box
top: (box.row > 0) ? this.boxes[box.row - 1][box.column] : null,
right: (box.column < Board.COLUMNS - 1) ? this.boxes[box.row][box.column + 1] : null,
bottom: (box.row < Board.ROWS - 1) ? this.boxes[box.row + 1][box.column] : null,
left: (box.column > 0) ? this.boxes[box.row][box.column - 1] : null,
}
top: box.row > 0 ? this.boxes[box.row - 1][box.column] : null,
right:
box.column < Board.COLUMNS - 1
? this.boxes[box.row][box.column + 1]
: null,
bottom:
box.row < Board.ROWS - 1 ? this.boxes[box.row + 1][box.column] : null,
left: box.column > 0 ? this.boxes[box.row][box.column - 1] : null,
};
}


//Inverse edges are the edges of the adjacent boxes
getBoxInverseEdges(box) {
const inverseEdgePositions = {
top: "bottom",
right: "left",
bottom: "top",
left: "right",
}
};
for (const [position, edge] of Object.entries(box.edges)) {
const inversePosition = inverseEdgePositions[position]
const adjacentBox = box.getAdjacentBox(position)
if (adjacentBox != null) //If the adjacent box is not null, then we need to set the inverse edges
box.inverseEdges[position] = adjacentBox.edges[inversePosition] //Setting the inverse edges
const inversePosition = inverseEdgePositions[position];
const adjacentBox = box.getAdjacentBox(position);
if (adjacentBox != null) {
//If the adjacent box is not null, then we need to set the inverse edges
box.inverseEdges[position] = adjacentBox.edges[inversePosition]; //Setting the inverse edges
}
}
return box.inverseEdges
return box.inverseEdges;
}

checkAdjacentadjacentBoxesToFill(box) {
for (const [position, adjacentBox] of Object.entries(box.adjacentBoxes)) {
if (adjacentBox != null) {
if (!adjacentBox.filled && adjacentBox.remainingEdges == 1) {
const edge = adjacentBox.getLastRemainingEdge()
const edge = adjacentBox.getLastRemainingEdge();
if (edge != null) {
this.onEdgeClick(adjacentBox, edge)
this.onEdgeClick(adjacentBox, edge);
}
}
}
}
}

fillBoxes() {
let fill = new Audio('../assets/sounds/fill.mp3');
let fill = new Audio("../assets/sounds/fill.mp3");
fill.play();
if (this.adjacentBoxesToFill.length != 0) {
setTimeout(() => {
const box = this.adjacentBoxesToFill.shift()
box.fill(Game.instance.currentPlayer.color)
this.fillBoxes()
}, 150)
const box = this.adjacentBoxesToFill.shift();
box.fill(Game.instance.currentPlayer.color);
this.fillBoxes();
}, 150);
} else {
setTimeout(() => {
this.isFillingAdjacentBoxes = false
this.adjacentBoxesToFill = []
this.isFillingAdjacentBoxes = false;
this.adjacentBoxesToFill = [];
//Switch the player
}, 600)
}, 600);
}
}
}
56 changes: 27 additions & 29 deletions js/box.js
Original file line number Diff line number Diff line change
@@ -1,71 +1,69 @@
class Box {

constructor(row, column) {
this.row = row
this.column = column
this.row = row;
this.column = column;

this.remainingEdges = 4
this.remainingEdges = 4;
this.edges = {
top: new Edge(this, "top"),
right: new Edge(this, "right"),
bottom: new Edge(this, "bottom"),
left: new Edge(this, "left"),
}
};
this.inverseEdges = {
top: null,
right: null,
bottom: null,
left: null,
}
this.adjacentBoxes = {}
this.filled = false
};
this.adjacentBoxes = {};
this.filled = false;

this.ui = this.createUI()
this.ui = this.createUI();
}

getEdge(edgePosition) {
return this.edges[edgePosition]
return this.edges[edgePosition];
}

getAdjacentBox(edgePosition) {
return this.adjacentBoxes[edgePosition]
return this.adjacentBoxes[edgePosition];
}

getLastRemainingEdge() {
for (const [position, edge] of Object.entries(this.edges))
if (!edge.filled) return this.edges[position]
if (!edge.filled) return this.edges[position];

return null
return null;
}

fillEdge(edge, color) {
edge.fill(color)
edge.fill(color);
}

fill(color) {
if (!this.filled) {
this.filled = true
this.remainingEdges = 0
this.ui.style.background = color
this.ui.classList.add("filled")
this.filled = true;
this.remainingEdges = 0;
this.ui.style.background = color;
this.ui.classList.add("filled");

Game.instance.invokeEvent("boxFill", this)
Game.instance.invokeEvent("boxFill", this);
}
}

createUI() {
const ui = document.createElement("div")
const ui = document.createElement("div");

ui.setAttribute("class", "box")
ui.setAttribute("data-row", this.row)
ui.setAttribute("data-column", this.column)
ui.setAttribute("class", "box");
ui.setAttribute("data-row", this.row);
ui.setAttribute("data-column", this.column);

ui.appendChild(this.edges.top.ui)
ui.appendChild(this.edges.right.ui)
ui.appendChild(this.edges.bottom.ui)
ui.appendChild(this.edges.left.ui)
ui.appendChild(this.edges.top.ui);
ui.appendChild(this.edges.right.ui);
ui.appendChild(this.edges.bottom.ui);
ui.appendChild(this.edges.left.ui);

return ui
return ui;
}

}
Loading