diff --git a/Ludo-Champs/README.md b/Ludo-Champs/README.md
new file mode 100644
index 000000000..5d407327d
--- /dev/null
+++ b/Ludo-Champs/README.md
@@ -0,0 +1,35 @@
+
+ 🎲 Ludo Game
+
+
+- This project is a web-based **Ludo game** where players can compete against each other in a classic Ludo board game experience.
+
+### ✨ ***Features***
+- "🎮 **Multiplayer Support**: Play with 4 players in an interactive game of Ludo."
+- "🎲 **Dice Rolling**: Roll the dice to move tokens across the board."
+- "🏠 **Player Tokens**: Each player controls four tokens that must race to the finish."
+- "📱 **Responsive Design**: The game adjusts to different screen sizes, ensuring a smooth experience on any device."
+
+### ⌨️ ***How to Play***
+1. **Roll the Dice**: Click the "Roll" button or press the "Enter" key to roll the dice.
+2. **Move Tokens**: Move your token by the number rolled on the dice.
+3. **Race to the Finish**: Be the first player to get all your tokens to the "Home" area.
+4. **Activate Turns**: Players take turns, and each token is moved based on the dice rolls.
+
+### 🔧 **Technologies Used**
+- **HTML**: The structure of the game board and user interface.
+- **CSS**: Styling and layout for the board, tokens, and game buttons.
+- **JavaScript**: Handles the game logic, dice rolls, token movements, and player turns.
+
+### ⚙️ **How It Works**
+1. **Rolling the Dice**: When you click the "Roll" button or press the "Enter" key, the dice rolls and the result is displayed.
+2. **Moving Tokens**: Players move their tokens based on the dice roll. Each player has four tokens that they must move across the board.
+3. **Turn-Based Gameplay**: Players take turns rolling the dice and moving their tokens. The first player to get all their tokens to the "Home" area wins.
+
+### 📂 ***File Structure***
+- `index.html`: The main HTML file that structures the Ludo game, including the board and player tokens.
+- `style.css`: Contains all the styles for the game, including the layout, colors, and animations.
+- `main.js`: The JavaScript file that handles the game logic, such as rolling dice, moving tokens, and player turns.
+- `script.js`: Additional JavaScript for user interface interactions and game controls.
+
+
diff --git a/Ludo-Champs/index.html b/Ludo-Champs/index.html
new file mode 100644
index 000000000..b64070037
--- /dev/null
+++ b/Ludo-Champs/index.html
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+ Ludo Game
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Roll Dice
+
+
+
Result: 0
+
+
+
+
+
+
+
+
+
diff --git a/Ludo-Champs/ludo/Ludo.js b/Ludo-Champs/ludo/Ludo.js
new file mode 100644
index 000000000..c087df9a1
--- /dev/null
+++ b/Ludo-Champs/ludo/Ludo.js
@@ -0,0 +1,281 @@
+import { BASE_POSITIONS, HOME_ENTRANCE, HOME_POSITIONS, PLAYERS, SAFE_POSITIONS, START_POSITIONS, STATE, TURNING_POINTS } from './constants.js';
+import { UI } from './UI.js';
+
+// Define the custom turn order
+const TURN_ORDER = [0, 2, 1, 3];
+
+// Dice roll elements and function
+const dice = document.querySelector('.dice');
+const rollBtn = document.querySelector('.roll');
+const resultDisplay = document.querySelector('.result');
+
+const randomDice = () => {
+ const random = Math.floor(Math.random() * 6) + 1; // Generates a number between 1 and 6
+ rollDice(random);
+ return random;
+}
+
+const rollDice = (random) => {
+ dice.style.animation = 'rolling 1s'; // Set a faster animation duration
+
+ setTimeout(() => {
+ // Show the dice face based on the random number
+ switch (random) {
+ case 1:
+ dice.style.transform = 'rotateX(0deg) rotateY(0deg)';
+ break;
+ case 2:
+ dice.style.transform = 'rotateX(-90deg) rotateY(0deg)';
+ break;
+ case 3:
+ dice.style.transform = 'rotateX(0deg) rotateY(90deg)';
+ break;
+ case 4:
+ dice.style.transform = 'rotateX(0deg) rotateY(-90deg)';
+ break;
+ case 5:
+ dice.style.transform = 'rotateX(90deg) rotateY(0deg)';
+ break;
+ case 6:
+ dice.style.transform = 'rotateX(180deg) rotateY(0deg)';
+ break;
+ default:
+ break;
+ }
+
+ dice.style.animation = 'none'; // Stop the animation after it completes
+
+ // Display the result
+ resultDisplay.textContent = `Result: ${random}`;
+ }, 1050); // Slightly more than the animation duration
+}
+
+export class Ludo {
+ currentPositions = {
+ P1: [],
+ P2: [],
+ P3: [],
+ P4: []
+ };
+
+ _diceValue;
+ get diceValue() {
+ return this._diceValue;
+ }
+ set diceValue(value) {
+ this._diceValue = value;
+ UI.setDiceValue(value);
+ }
+
+ _turn;
+ get turn() {
+ return this._turn;
+ }
+ set turn(value) {
+ this._turn = value;
+ UI.setTurn(value);
+ }
+
+ _state;
+ get state() {
+ return this._state;
+ }
+ set state(value) {
+ this._state = value;
+
+ if (value === STATE.DICE_NOT_ROLLED) {
+ UI.enableDice();
+ UI.unhighlightPieces();
+ } else {
+ UI.disableDice();
+ }
+ }
+
+ constructor() {
+ console.log('Hello World! Lets play Ludo!');
+
+ // Initialize the turn index to -1, so the first call to incrementTurn sets it to the first player
+ this.turnIndex = -1;
+ this.incrementTurn(); // Start the game with the first player
+ this.listenRollButtonClick();
+ this.listenResetClick();
+ this.listenPieceClick();
+
+ this.resetGame();
+ }
+
+ listenRollButtonClick() {
+ rollBtn.addEventListener('click', this.onDiceClick.bind(this));
+ }
+
+ onDiceClick() {
+ console.log('dice clicked!');
+ this.diceValue = randomDice(); // Animate the dice and set the value
+ this.state = STATE.DICE_ROLLED;
+ this.checkForEligiblePieces();
+ }
+
+ checkForEligiblePieces() {
+ const player = PLAYERS[this.turn];
+ const eligiblePieces = this.getEligiblePieces(player);
+ if (eligiblePieces.length) {
+ // Highlight the pieces
+ UI.highlightPieces(player, eligiblePieces);
+ } else {
+ this.incrementTurn();
+ }
+ }
+
+ incrementTurn() {
+ // Increment the turn index and follow the custom turn order
+ this.turnIndex = (this.turnIndex + 1) % TURN_ORDER.length;
+ this.turn = TURN_ORDER[this.turnIndex];
+ this.state = STATE.DICE_NOT_ROLLED;
+ }
+
+ getEligiblePieces(player) {
+ return [0, 1, 2, 3].filter(piece => {
+ const currentPosition = this.currentPositions[player][piece];
+
+ if (currentPosition === HOME_POSITIONS[player]) {
+ return false;
+ }
+
+ if (
+ BASE_POSITIONS[player].includes(currentPosition) &&
+ this.diceValue !== 6
+ ) {
+ return false;
+ }
+
+ if (
+ HOME_ENTRANCE[player].includes(currentPosition) &&
+ this.diceValue > HOME_POSITIONS[player] - currentPosition
+ ) {
+ return false;
+ }
+
+ return true;
+ });
+ }
+
+ listenResetClick() {
+ UI.listenResetClick(this.resetGame.bind(this));
+ }
+
+ resetGame() {
+ console.log('reset game');
+ this.currentPositions = structuredClone(BASE_POSITIONS);
+ PLAYERS.forEach(player => {
+ [0, 1, 2, 3].forEach(piece => {
+ this.setPiecePosition(player, piece, this.currentPositions[player][piece]);
+ });
+ });
+ this.turnIndex = -1; // Start from the first player on reset
+ this.incrementTurn(); // Ensure the first player is selected
+ this.state = STATE.DICE_NOT_ROLLED;
+ }
+
+ listenPieceClick() {
+ UI.listenPieceClick(this.onPieceClick.bind(this));
+ }
+
+
+ onPieceClick(event) {
+ const target = event.target;
+
+ if (!target.classList.contains('player-piece') || !target.classList.contains('highlight')) {
+ return;
+ }
+ console.log('piece clicked');
+
+ const player = target.getAttribute('player-id');
+ const piece = target.getAttribute('piece');
+ this.handlePieceClick(player, piece);
+ }
+
+ handlePieceClick(player, piece) {
+ console.log(player, piece);
+ const currentPosition = this.currentPositions[player][piece];
+
+ if (BASE_POSITIONS[player].includes(currentPosition)) {
+ this.setPiecePosition(player, piece, START_POSITIONS[player]);
+ this.state = STATE.DICE_NOT_ROLLED;
+ return;
+ }
+
+ UI.unhighlightPieces();
+ this.movePiece(player, piece, this.diceValue);
+ }
+
+ setPiecePosition(player, piece, newPosition) {
+ this.currentPositions[player][piece] = newPosition;
+ UI.setPiecePosition(player, piece, newPosition);
+ }
+
+ movePiece(player, piece, moveBy) {
+ const interval = setInterval(() => {
+ this.incrementPiecePosition(player, piece);
+ moveBy--;
+
+ if (moveBy === 0) {
+ clearInterval(interval);
+
+ // Check if player won
+ if (this.hasPlayerWon(player)) {
+ alert(`Player: ${player} has won!`);
+ this.resetGame();
+ return;
+ }
+
+ const isKill = this.checkForKill(player, piece);
+
+ if (isKill || this.diceValue === 6) {
+ this.state = STATE.DICE_NOT_ROLLED;
+ return;
+ }
+
+ this.incrementTurn();
+ }
+ }, 200);
+ }
+
+ checkForKill(player, piece) {
+ const currentPosition = this.currentPositions[player][piece];
+ let kill = false;
+
+ PLAYERS.forEach(opponent => {
+ if (opponent !== player) {
+ [0, 1, 2, 3].forEach(piece => {
+ const opponentPosition = this.currentPositions[opponent][piece];
+
+ if (currentPosition === opponentPosition && !SAFE_POSITIONS.includes(currentPosition)) {
+ this.setPiecePosition(opponent, piece, BASE_POSITIONS[opponent][piece]);
+ kill = true;
+ }
+ });
+ }
+ });
+
+ return kill;
+ }
+
+ hasPlayerWon(player) {
+ return [0, 1, 2, 3].every(piece => this.currentPositions[player][piece] === HOME_POSITIONS[player]);
+ }
+
+ incrementPiecePosition(player, piece) {
+ this.setPiecePosition(player, piece, this.getIncrementedPosition(player, piece));
+ }
+
+ getIncrementedPosition(player, piece) {
+ const currentPosition = this.currentPositions[player][piece];
+
+ if (currentPosition === TURNING_POINTS[player]) {
+ return HOME_ENTRANCE[player][0];
+ } else if (currentPosition === 51) {
+ return 0;
+ }
+ return currentPosition + 1;
+ }
+}
diff --git a/Ludo-Champs/ludo/UI.js b/Ludo-Champs/ludo/UI.js
new file mode 100644
index 000000000..c7006165d
--- /dev/null
+++ b/Ludo-Champs/ludo/UI.js
@@ -0,0 +1,102 @@
+import { COORDINATES_MAP, PLAYERS, STEP_LENGTH } from './constants.js';
+
+const diceButtonElement = document.querySelector('#dice-btn');
+const playerPiecesElements = {
+ P1: document.querySelectorAll('[player-id="P1"].player-piece'),
+ P2: document.querySelectorAll('[player-id="P2"].player-piece'),
+ P3: document.querySelectorAll('[player-id="P3"].player-piece'),
+ P4: document.querySelectorAll('[player-id="P4"].player-piece'),
+}
+
+
+export class UI {
+ static listenDiceClick(callback) {
+ diceButtonElement.addEventListener('click', callback);
+ }
+
+ static listenResetClick(callback) {
+ document.querySelector('button#reset-btn').addEventListener('click', callback);
+ }
+
+ static listenPieceClick(callback) {
+ document.querySelector('.player-pieces').addEventListener('click', callback);
+ }
+
+ /**
+ *
+ * @param {string} player
+ * @param {Number} piece
+ * @param {Number} newPosition
+ */
+ static setPiecePosition(player, piece, newPosition) {
+ if (!playerPiecesElements[player] || !playerPiecesElements[player][piece]) {
+ console.error(`Player element of given player: ${player} and piece: ${piece} not found`);
+ return;
+ }
+
+ const [x, y] = COORDINATES_MAP[newPosition];
+
+ const pieceElement = playerPiecesElements[player][piece];
+ pieceElement.style.top = y * STEP_LENGTH + '%';
+ pieceElement.style.left = x * STEP_LENGTH + '%';
+ }
+
+ static setTurn(index) {
+ if (index < 0 || index >= PLAYERS.length) {
+ console.error('index out of bound!');
+ return;
+ }
+
+ const player = PLAYERS[index];
+
+ // Display player ID
+ document.querySelector('.active-player span').innerText = player;
+
+ const activePlayerBase = document.querySelector('.player-base.highlight');
+ if (activePlayerBase) {
+ activePlayerBase.classList.remove('highlight');
+ }
+ // highlight
+ document.querySelector(`[player-id="${player}"].player-base`).classList.add('highlight');
+ }
+
+ static enableDice() {
+ diceButtonElement.removeAttribute('disabled');
+ }
+
+ static disableDice() {
+ diceButtonElement.setAttribute('disabled', '');
+ }
+
+ /**
+ *
+ * @param {string} player
+ * @param {Number[]} pieces
+ */
+ static highlightPieces(player, pieces) {
+ pieces.forEach(piece => {
+ const pieceElement = playerPiecesElements[player][piece];
+ pieceElement.classList.add('highlight');
+ });
+ }
+
+ static unhighlightPieces() {
+ document.querySelectorAll('.player-piece.highlight').forEach(ele => {
+ ele.classList.remove('highlight');
+ });
+ }
+
+ static setDiceValue(value) {
+ document.querySelector('.dice-value').innerText = value;
+ }
+}
+
+// UI.setPiecePosition('P1', 0, 0);
+// UI.setTurn(0);
+// UI.setTurn(1);
+
+// UI.disableDice();
+// UI.enableDice();
+// UI.highlightPieces('P1', [0]);
+// UI.unhighlightPieces();
+// UI.setDiceValue(5);
diff --git a/Ludo-Champs/ludo/constants.js b/Ludo-Champs/ludo/constants.js
new file mode 100644
index 000000000..58b9bc3e3
--- /dev/null
+++ b/Ludo-Champs/ludo/constants.js
@@ -0,0 +1,160 @@
+export const COORDINATES_MAP = {
+ 0: [6, 13],
+ 1: [6, 12],
+ 2: [6, 11],
+ 3: [6, 10],
+ 4: [6, 9],
+ 5: [5, 8],
+ 6: [4, 8],
+ 7: [3, 8],
+ 8: [2, 8],
+ 9: [1, 8],
+ 10: [0, 8],
+ 11: [0, 7],
+ 12: [0, 6],
+ 13: [1, 6],
+ 14: [2, 6],
+ 15: [3, 6],
+ 16: [4, 6],
+ 17: [5, 6],
+ 18: [6, 5],
+ 19: [6, 4],
+ 20: [6, 3],
+ 21: [6, 2],
+ 22: [6, 1],
+ 23: [6, 0],
+ 24: [7, 0],
+ 25: [8, 0],
+ 26: [8, 1],
+ 27: [8, 2],
+ 28: [8, 3],
+ 29: [8, 4],
+ 30: [8, 5],
+ 31: [9, 6],
+ 32: [10, 6],
+ 33: [11, 6],
+ 34: [12, 6],
+ 35: [13, 6],
+ 36: [14, 6],
+ 37: [14, 7],
+ 38: [14, 8],
+ 39: [13, 8],
+ 40: [12, 8],
+ 41: [11, 8],
+ 42: [10, 8],
+ 43: [9, 8],
+ 44: [8, 9],
+ 45: [8, 10],
+ 46: [8, 11],
+ 47: [8, 12],
+ 48: [8, 13],
+ 49: [8, 14],
+ 50: [7, 14],
+ 51: [6, 14],
+
+ // HOME ENTRANCE
+
+ // P1
+ 100: [7, 13],
+ 101: [7, 12],
+ 102: [7, 11],
+ 103: [7, 10],
+ 104: [7, 9],
+ 105: [7, 8],
+
+ // P2
+ 200: [7, 1],
+ 201: [7, 2],
+ 202: [7, 3],
+ 203: [7, 4],
+ 204: [7, 5],
+ 205: [7, 6],
+
+ // p3
+ 300: [13, 7],
+ 301: [12, 7],
+ 302: [11, 7],
+ 303: [10, 7],
+ 304: [9, 7],
+ 305: [8, 7],
+
+ // p4
+ 400: [1, 7],
+ 401: [2, 7],
+ 402: [3, 7],
+ 403: [4, 7],
+ 404: [5, 7],
+ 405: [6, 7],
+
+ // BASE POSITIONS
+
+ // P1
+ 500: [1.5, 10.58],
+ 501: [3.57, 10.58],
+ 502: [1.5, 12.43],
+ 503: [3.57, 12.43],
+
+ // P2
+ 600: [10.5, 1.58],
+ 601: [12.54, 1.58],
+ 602: [10.5, 3.45],
+ 603: [12.54, 3.45],
+
+ // p3
+ 700: [10.5, 10.58],
+ 701: [12.57, 10.58],
+ 702: [10.5, 12.43],
+ 703: [12.57, 12.43],
+
+ // p4
+ 800: [1.5, 1.58],
+ 801: [3.57, 1.58],
+ 802: [1.5, 3.45],
+ 803: [3.55, 3.45],
+};
+
+export const STEP_LENGTH = 6.66;
+
+export const PLAYERS = ['P1', 'P2', 'P3', 'P4'];
+
+export const BASE_POSITIONS = {
+ P1: [500, 501, 502, 503],
+ P2: [600, 601, 602, 603],
+ P3: [700, 701, 702, 703],
+ P4: [800, 801, 802, 803],
+}
+
+export const START_POSITIONS = {
+ P1: 0,
+ P2: 26,
+ P3: 39,
+ P4: 13,
+}
+
+export const HOME_ENTRANCE = {
+ P1: [100, 101, 102, 103, 104],
+ P2: [200, 201, 202, 203, 204],
+ P3: [300, 301, 302, 303, 304],
+ P4: [400, 401, 402, 403, 404]
+}
+
+export const HOME_POSITIONS = {
+ P1: 105,
+ P2: 205,
+ P3: 305,
+ P4: 405
+}
+
+export const TURNING_POINTS = {
+ P1: 50,
+ P2: 24,
+ P3: 37,
+ P4: 11
+}
+
+export const SAFE_POSITIONS = [0, 8, 13, 21, 26, 34, 39, 47];
+
+export const STATE = {
+ DICE_NOT_ROLLED: 'DICE_NOT_ROLLED',
+ DICE_ROLLED: 'DICE_ROLLED',
+}
diff --git a/Ludo-Champs/ludo/dice.png b/Ludo-Champs/ludo/dice.png
new file mode 100644
index 000000000..1a141509e
Binary files /dev/null and b/Ludo-Champs/ludo/dice.png differ
diff --git a/Ludo-Champs/ludo/ludo-bggg.png b/Ludo-Champs/ludo/ludo-bggg.png
new file mode 100644
index 000000000..2e060fa66
Binary files /dev/null and b/Ludo-Champs/ludo/ludo-bggg.png differ
diff --git a/Ludo-Champs/ludo/script.js b/Ludo-Champs/ludo/script.js
new file mode 100644
index 000000000..9179ea9dd
--- /dev/null
+++ b/Ludo-Champs/ludo/script.js
@@ -0,0 +1,47 @@
+const dice = document.querySelector('.dice');
+const rollBtn = document.querySelector('.roll');
+const resultDisplay = document.querySelector('.result');
+
+const randomDice = () => {
+ const random = Math.floor(Math.random() * 6) + 1; // Generates a number between 1 and 6
+ rollDice(random);
+}
+
+
+const rollDice = (random) => {
+ dice.style.animation = 'rolling 1s'; // Set a faster animation duration
+
+ setTimeout(() => {
+ // Show the dice face based on the random number
+ switch (random) {
+ case 1:
+ dice.style.transform = 'rotateX(0deg) rotateY(0deg)';
+ break;
+ case 2:
+ dice.style.transform = 'rotateX(-90deg) rotateY(0deg)';
+ break;
+ case 3:
+ dice.style.transform = 'rotateX(0deg) rotateY(90deg)';
+ break;
+ case 4:
+ dice.style.transform = 'rotateX(0deg) rotateY(-90deg)';
+ break;
+ case 5:
+ dice.style.transform = 'rotateX(90deg) rotateY(0deg)';
+ break;
+ case 6:
+ dice.style.transform = 'rotateX(180deg) rotateY(0deg)';
+ break;
+ default:
+ break;
+ }
+
+ dice.style.animation = 'none'; // Stop the animation after it completes
+
+ // Display the result
+ resultDisplay.textContent = `Result: ${random}`;
+ }, 1050); // Slightly more than the animation duration
+}
+
+// Add event listener to the roll button
+rollBtn.addEventListener('click', randomDice);
diff --git a/Ludo-Champs/ludo/style.css b/Ludo-Champs/ludo/style.css
new file mode 100644
index 000000000..5a0fbe088
--- /dev/null
+++ b/Ludo-Champs/ludo/style.css
@@ -0,0 +1,368 @@
+* {
+ box-sizing: border-box;
+}
+
+.ludo-container {
+ width: 450px;
+ margin: 20px auto;
+ /* background-color: red; */
+}
+
+.ludo-container .ludo {
+ height: 450px;
+ width: 100%;
+ /* background-image: url('./ludo-bg.jpg'); */
+ background-image: url(./ludo-bggg.png);
+ background-size: contain;
+ position: relative;
+
+}
+
+
+.player-pieces {
+ height: 100%;
+ width: 100%;
+ /* background-color: red; */
+}
+
+.player-piece {
+ width: 3%;
+ height: 3%;
+ border: 2px solid;
+ border-radius: 10px;
+ position: absolute;
+ transform: translate(50%, 50%);
+ transition: all .2s;
+ z-index: 1;
+}
+
+.player-piece.highlight {
+ cursor: pointer;
+ border: 2px dashed;
+ animation: spin 1s infinite linear;
+}
+
+@keyframes spin {
+ 0% {
+ transform: translate(50%, 50%) rotate(0deg);
+ }
+ 50% {
+ transform: translate(50%, 50%) rotate(180deg) scale(1.4);
+ }
+ 100% {
+ transform: translate(50%, 50%) rotate(360deg);
+ }
+}
+
+[player-id="P1"].player-piece {
+ background-color: #2eafff;
+
+}
+
+[player-id="P2"].player-piece {
+ background-color: #00b550;
+}
+
+[player-id="P3"].player-piece {
+ background-color: #ff4757;
+
+}
+
+[player-id="P4"].player-piece {
+ background-color: #ffa502;
+}
+
+.player-base {
+ width: 40%;
+ height: 40%;
+ border: 30px solid;
+ position: absolute;
+
+}
+
+.player-bases [player-id="P1"].player-base {
+ /* bottom: 0; */
+ /* left: 0; */
+
+ border-color: #1295e7;
+ height: 38%;
+ width: 38.5%;
+ margin-top: -177px;
+ margin-left: 6px;
+ border-width: 22px;
+ border-right-width: 26px;
+ border-top-width: 24px;
+
+
+
+
+}
+
+.player-bases [player-id="P2"].player-base {
+ /* top: 0; */
+ /* right: 0; */
+ border-color: #049645;
+ margin-top: -445px;
+ margin-left: 275px;
+ height: 38%;
+ width: 37.5%;
+ border-width: 22px;
+ border-top-width: 24px;
+}
+
+.player-bases [player-id="P3"].player-base {
+ /* bottom: 0;
+ right: 0; */
+ height: 38%;
+ width: 38%;
+ border-width: 22px;
+ border-top-width: 24px;
+ border-color: #d63031;
+ margin-left: 273px;
+ margin-top: -178px;
+ border-left-width: 24px;
+ border-bottom-width: 23px;
+}
+
+.player-bases [player-id="P4"].player-base {
+ /* top: 0;
+ left: 0; */
+ border-color: #f39c12;
+ height: 38%;
+ width: 38.5%;
+ margin-top: -444.6px;
+ margin-left: 6px;
+ border-width: 22px;
+ border-right-width: 27px;
+ border-top-width: 23px;
+ border-bottom-width: 24px;
+}
+
+.player-base.highlight {
+ animation: border-blink .7s infinite ease-in-out;
+}
+
+@keyframes border-blink {
+ 50% {
+ border-color: rgba(255, 255, 255, 0.8);
+ }
+}
+
+.btn {
+ padding: 8px 20px;
+ border: none;
+ cursor: pointer;
+ font-size: 16px;
+ display: none;
+}
+
+.btn:disabled {
+ opacity: 0.5;
+ display: none;
+}
+
+.btn-dice {
+ background-color: #009d60;
+ color: white;
+ display: none;
+}
+
+.row {
+ display: flex;
+ justify-content: space-between;
+ margin-top: 15px;
+}
+
+.dice-value {
+ font-size: 24px;
+ font-weight: bold;
+ display: none;
+}
+
+
+* {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ box-sizing: border-box;
+}
+
+body {
+ height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ /* background: #b33951; */
+}
+
+.containeer {
+ display: grid;
+ place-items: center;
+ width: 250px;
+ padding: 60px 0 40px;
+ border-radius: 30px;
+ background: #eeeeee;
+ box-shadow: 0 0 20px rgba(0, 0, 0, .1);
+ margin-left: 1000px;
+ position: absolute;
+}
+.result {
+ margin-top: 20px;
+ font-size: 20px;
+ font-weight: bold;
+ color: #b33951;
+ font-family: 'Montserrat', sans-serif;
+}
+
+.dice {
+ position: relative;
+ width: 100px;
+ height: 100px;
+ transform-style: preserve-3d;
+ transition: 1s ease;
+ /* margin-left: -100px; */
+}
+
+@keyframes rolling {
+ 50% {
+ transform: rotateX(455deg) rotateY(455deg);
+ }
+}
+
+.face {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ border-radius: 20px;
+ border: 5px solid #f6f3f0;
+ transform-style: preserve-3d;
+ background: linear-gradient(
+ 145deg, #dddbd8, #fff
+ );
+}
+
+.face::before {
+ position: absolute;
+ content: '';
+ width: 100%;
+ height: 100%;
+ border-radius: 20px;
+ background: #f6f3f0;
+ transform: translateZ(-1px);
+}
+
+.face::after {
+ position: absolute;
+ content: '';
+ top: 50%;
+ left: 50%;
+ width: 18px;
+ height: 18px;
+ border-radius: 50%;
+ background: #131210;
+}
+
+.front {
+ transform: translateZ(50px);
+}
+
+.back {
+ transform: rotateX(180deg) translateZ(50px);
+}
+
+.top {
+ transform: rotateX(90deg) translateZ(50px);
+}
+
+.bottom {
+ transform: rotateX(-90deg) translateZ(50px);
+}
+
+.right {
+ transform: rotateY(90deg) translateZ(50px);
+}
+
+.left {
+ transform: rotateY(-90deg) translateZ(50px);
+}
+
+.front::after {
+ width: 30px;
+ height: 30px;
+ background: #f63330;
+ margin: -15px 0 0 -15px;
+}
+
+.back::after {
+ margin: -35px 0 0 -30px;
+ box-shadow: 40px 0,
+ 0 25px,
+ 40px 25px,
+ 0 50px,
+ 40px 50px;
+}
+
+.top::after {
+ margin: -30px 0 0 -30px;
+ box-shadow: 40px 40px;
+}
+
+.bottom::after {
+ margin: -36px 0 0 -36px;
+ box-shadow: 26px 26px,
+ 52px 52px,
+ 52px 0,
+ 0 52px;
+}
+
+.right::after {
+ margin: -30px 0 0 -30px;
+ box-shadow: 40px 0,
+ 0 40px,
+ 40px 40px;
+}
+
+.left::after {
+ margin: -35px 0 0 -35px;
+ box-shadow: 25px 25px,
+ 50px 50px;
+}
+
+.roll {
+ cursor: pointer;
+ color: #b33951;
+ margin-top: 60px;
+ padding: 6px 12px;
+ border-radius: 3px;
+ font: 700 16px 'Montserrat';
+ border: 2px solid #b33951;
+ transition: .4s;
+}
+
+.roll:hover {
+ color: #fff;
+ background: #b33951;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ludo-Champs/main.js b/Ludo-Champs/main.js
new file mode 100644
index 000000000..e7690a105
--- /dev/null
+++ b/Ludo-Champs/main.js
@@ -0,0 +1,3 @@
+import { Ludo } from './ludo/Ludo.js';
+
+const ludo = new Ludo();