diff --git a/Ludo/charishma2k06/README.md b/Ludo/charishma2k06/README.md
new file mode 100644
index 000000000..bbb73fa5f
--- /dev/null
+++ b/Ludo/charishma2k06/README.md
@@ -0,0 +1,19 @@
+# Ludo App - JavaScript Mini Project
+
+A turn-based digital adaptation of the classic board game Ludo, developed using vanilla HTML5, CSS3, and JavaScript.
+
+## Features
+- **Turn-based gameplay:** Supports 4 players (Red, Green, Yellow, Blue).
+- **Dice Roll Mechanics:** Simulates 1–6 rolls with bonus turns awarded on rolling a 6.
+- **Piece Movement & Base Exits:** Tokens exit the starting base when a 6 is rolled and travel clockwise around the track.
+- **Capture Logic:** Landing on an opponent's token sends it back to their base.
+- **Win Condition:** First player to bring their pieces home wins.
+
+## Technologies Used
+- HTML5
+- CSS3 (CSS Grid & Flexbox)
+- JavaScript (Vanilla ES6)
+
+## How to Run Locally
+1. Clone this repository or download the source files.
+2. Open `index.html` directly in any web browser.
diff --git a/Ludo/charishma2k06/index.html b/Ludo/charishma2k06/index.html
new file mode 100644
index 000000000..4fd8dcd48
--- /dev/null
+++ b/Ludo/charishma2k06/index.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+ Ludo Mini Project
+
+
+
+
+
Ludo Game
+
+
+
+ Current Turn:
+ Red
+
+
+
Click "Roll Dice" to start!
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Ludo/charishma2k06/script.js b/Ludo/charishma2k06/script.js
new file mode 100644
index 000000000..a068434b8
--- /dev/null
+++ b/Ludo/charishma2k06/script.js
@@ -0,0 +1,186 @@
+const BOARD_SIZE = 15;
+const boardElement = document.getElementById("board");
+const rollBtn = document.getElementById("roll-btn");
+const diceView = document.getElementById("dice-view");
+const turnIndicator = document.getElementById("turn-indicator");
+const msgElement = document.getElementById("msg");
+
+const PLAYERS = ["red", "green", "yellow", "blue"];
+let currentTurnIdx = 0;
+let lastRoll = 0;
+let hasRolled = false;
+
+// Common outer track coordinates (row, col)
+const TRACK = [
+ [6, 1], [6, 2], [6, 3], [6, 4], [6, 5],
+ [5, 6], [4, 6], [3, 6], [2, 6], [1, 6], [0, 6],
+ [0, 7], [0, 8],
+ [1, 8], [2, 8], [3, 8], [4, 8], [5, 8],
+ [6, 9], [6, 10], [6, 11], [6, 12], [6, 13], [6, 14],
+ [7, 14], [8, 14],
+ [8, 13], [8, 12], [8, 11], [8, 10], [8, 9],
+ [9, 8], [10, 8], [11, 8], [12, 8], [13, 8], [14, 8],
+ [14, 7], [14, 6],
+ [13, 6], [12, 6], [11, 6], [10, 6], [9, 6],
+ [8, 5], [8, 4], [8, 3], [8, 2], [8, 1], [8, 0],
+ [7, 0], [6, 0]
+];
+
+// Token states: -1 means in base home, 0..51 are track positions, 52 is home goal
+const gameState = {
+ red: { basePos: [2, 2], tokens: [-1, -1] },
+ green: { basePos: [2, 12], tokens: [-1, -1] },
+ yellow: { basePos: [12, 12], tokens: [-1, -1] },
+ blue: { basePos: [12, 2], tokens: [-1, -1] }
+};
+
+const START_OFFSETS = { red: 0, green: 13, yellow: 26, blue: 39 };
+
+function initBoard() {
+ boardElement.innerHTML = "";
+ for (let r = 0; r < BOARD_SIZE; r++) {
+ for (let c = 0; c < BOARD_SIZE; c++) {
+ const cell = document.createElement("div");
+ cell.className = "cell";
+ cell.dataset.row = r;
+ cell.dataset.col = c;
+
+ if (r < 6 && c < 6) cell.classList.add("red-base");
+ else if (r < 6 && c > 8) cell.classList.add("green-base");
+ else if (r > 8 && c > 8) cell.classList.add("yellow-base");
+ else if (r > 8 && c < 6) cell.classList.add("blue-base");
+ else if (r >= 6 && r <= 8 && c >= 6 && c <= 8) cell.classList.add("center-cell");
+ else if (r === 7 && c > 0 && c < 6) cell.classList.add("red-path");
+ else if (c === 7 && r > 0 && r < 6) cell.classList.add("green-path");
+ else if (r === 7 && c > 8 && c < 14) cell.classList.add("yellow-path");
+ else if (c === 7 && r > 8 && r < 14) cell.classList.add("blue-path");
+
+ boardElement.appendChild(cell);
+ }
+ }
+ renderTokens();
+}
+
+function getCell(r, c) {
+ return document.querySelector(`[data-row='${r}'][data-col='${c}']`);
+}
+
+function renderTokens() {
+ document.querySelectorAll(".token").forEach((t) => t.remove());
+
+ PLAYERS.forEach((player) => {
+ gameState[player].tokens.forEach((stepPos, tIdx) => {
+ if (stepPos === 52) return; // Reached goal
+
+ const tokenEl = document.createElement("div");
+ tokenEl.className = `token ${player}`;
+ tokenEl.id = `${player}-token-${tIdx}`;
+
+ if (hasRolled && player === PLAYERS[currentTurnIdx]) {
+ if (canMoveToken(player, stepPos, lastRoll)) {
+ tokenEl.classList.add("clickable");
+ tokenEl.onclick = () => moveToken(player, tIdx);
+ }
+ }
+
+ let targetCell = null;
+ if (stepPos === -1) {
+ const [br, bc] = gameState[player].basePos;
+ targetCell = getCell(br, bc + tIdx);
+ } else {
+ const actualIdx = (stepPos + START_OFFSETS[player]) % TRACK.length;
+ const [tr, tc] = TRACK[actualIdx];
+ targetCell = getCell(tr, tc);
+ }
+
+ if (targetCell) targetCell.appendChild(tokenEl);
+ });
+ });
+}
+
+function canMoveToken(player, stepPos, roll) {
+ if (stepPos === -1) return roll === 6;
+ return stepPos + roll <= 52;
+}
+
+rollBtn.addEventListener("click", () => {
+ if (hasRolled) return;
+ lastRoll = Math.floor(Math.random() * 6) + 1;
+ diceView.textContent = lastRoll;
+ hasRolled = true;
+ rollBtn.disabled = true;
+
+ const currentPlayer = PLAYERS[currentTurnIdx];
+ const canAnyMove = gameState[currentPlayer].tokens.some((pos) =>
+ canMoveToken(currentPlayer, pos, lastRoll)
+ );
+
+ if (!canAnyMove) {
+ msgElement.textContent = `No moves possible for ${currentPlayer}. Turn switches.`;
+ setTimeout(switchTurn, 1000);
+ } else {
+ msgElement.textContent = `${currentPlayer.toUpperCase()} rolled a ${lastRoll}! Select a piece.`;
+ renderTokens();
+ }
+});
+
+function moveToken(player, tokenIdx) {
+ const currentPos = gameState[player].tokens[tokenIdx];
+ if (currentPos === -1) {
+ gameState[player].tokens[tokenIdx] = 0;
+ } else {
+ gameState[player].tokens[tokenIdx] = Math.min(52, currentPos + lastRoll);
+ }
+
+ // Check captures
+ checkCapture(player, gameState[player].tokens[tokenIdx]);
+
+ // Check win condition
+ if (gameState[player].tokens.every((pos) => pos === 52)) {
+ msgElement.textContent = `🎉 Player ${player.toUpperCase()} wins the game!`;
+ rollBtn.disabled = true;
+ renderTokens();
+ return;
+ }
+
+ if (lastRoll === 6) {
+ msgElement.textContent = `Rolled a 6! Roll again.`;
+ hasRolled = false;
+ rollBtn.disabled = false;
+ renderTokens();
+ } else {
+ switchTurn();
+ }
+}
+
+function checkCapture(activePlayer, pos) {
+ if (pos <= 0 || pos >= 52) return;
+ const activeActual = (pos + START_OFFSETS[activePlayer]) % TRACK.length;
+
+ PLAYERS.forEach((other) => {
+ if (other === activePlayer) return;
+ gameState[other].tokens.forEach((oPos, idx) => {
+ if (oPos > 0 && oPos < 52) {
+ const otherActual = (oPos + START_OFFSETS[other]) % TRACK.length;
+ if (activeActual === otherActual) {
+ gameState[other].tokens[idx] = -1;
+ msgElement.textContent = `${activePlayer.toUpperCase()} captured ${other.toUpperCase()}!`;
+ }
+ }
+ });
+ });
+}
+
+function switchTurn() {
+ currentTurnIdx = (currentTurnIdx + 1) % PLAYERS.length;
+ hasRolled = false;
+ rollBtn.disabled = false;
+
+ const nextPlayer = PLAYERS[currentTurnIdx];
+ turnIndicator.textContent = nextPlayer.charAt(0).toUpperCase() + nextPlayer.slice(1);
+ turnIndicator.className = `turn-${nextPlayer}`;
+ msgElement.textContent = `Turn switched to ${nextPlayer}. Roll the dice!`;
+ renderTokens();
+}
+
+initBoard();
\ No newline at end of file
diff --git a/Ludo/charishma2k06/style.css b/Ludo/charishma2k06/style.css
new file mode 100644
index 000000000..1c26be2ce
--- /dev/null
+++ b/Ludo/charishma2k06/style.css
@@ -0,0 +1,137 @@
+* {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+}
+
+body {
+ background: #f0f2f5;
+ display: flex;
+ justify-content: center;
+ padding: 20px;
+}
+
+.container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 16px;
+}
+
+h1 {
+ color: #333;
+}
+
+.control-panel {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 8px;
+ background: #fff;
+ padding: 14px 24px;
+ border-radius: 10px;
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);
+}
+
+.status-box {
+ font-size: 1.1rem;
+}
+
+.turn-red { color: #e53935; font-weight: bold; }
+.turn-green { color: #43a047; font-weight: bold; }
+.turn-yellow { color: #fbc02d; font-weight: bold; }
+.turn-blue { color: #1e88e5; font-weight: bold; }
+
+.dice-section {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+#roll-btn {
+ padding: 8px 18px;
+ font-size: 1rem;
+ font-weight: 600;
+ color: #fff;
+ background-color: #2e7d32;
+ border: none;
+ border-radius: 6px;
+ cursor: pointer;
+ transition: 0.2s ease;
+}
+
+#roll-btn:disabled {
+ background-color: #9e9e9e;
+ cursor: not-allowed;
+}
+
+.dice-display {
+ font-size: 2rem;
+ width: 44px;
+ height: 44px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 2px solid #ccc;
+ border-radius: 8px;
+ background: #fafafa;
+}
+
+#msg {
+ font-size: 0.95rem;
+ color: #555;
+}
+
+/* Board styling: 15x15 CSS Grid */
+.ludo-board {
+ display: grid;
+ grid-template-columns: repeat(15, 32px);
+ grid-template-rows: repeat(15, 32px);
+ border: 4px solid #333;
+ background-color: #fff;
+}
+
+.cell {
+ border: 1px solid #ddd;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+}
+
+.cell.red-base { background-color: #ffebee; }
+.cell.green-base { background-color: #e8f5e9; }
+.cell.yellow-base { background-color: #fffde7; }
+.cell.blue-base { background-color: #e3f2fd; }
+
+.cell.red-path { background-color: #ef5350; }
+.cell.green-path { background-color: #66bb6a; }
+.cell.yellow-path { background-color: #ffee58; }
+.cell.blue-path { background-color: #42a5f5; }
+
+.cell.center-cell { background-color: #37474f; }
+
+/* Token styles */
+.token {
+ width: 22px;
+ height: 22px;
+ border-radius: 50%;
+ border: 2px solid #fff;
+ box-shadow: 0 2px 4px rgba(0,0,0,0.3);
+ cursor: pointer;
+}
+
+.token.clickable {
+ animation: pulse 1s infinite alternate;
+}
+
+@keyframes pulse {
+ from { transform: scale(1); }
+ to { transform: scale(1.25); }
+}
+
+.token.red { background-color: #d32f2f; }
+.token.green { background-color: #2e7d32; }
+.token.yellow { background-color: #fbc02d; }
+.token.blue { background-color: #1976d2; }
\ No newline at end of file