diff --git a/api/pexels.php b/api/pexels.php
new file mode 100644
index 0000000..9816ad1
--- /dev/null
+++ b/api/pexels.php
@@ -0,0 +1,29 @@
+ 'assets/images/pexels/'.$p['id'].'.jpg',
+ 'photographer' => $p['photographer'] ?? 'Unknown',
+ 'photographer_url' => $p['photographer_url'] ?? '',
+ ];
+ } else {
+ // Fallback: Picsum
+ $out[] = [
+ 'src' => 'https://picsum.photos/600?random=' . rand(1,1000),
+ 'photographer' => 'Random Picsum',
+ 'photographer_url' => 'https://picsum.photos/'
+ ];
+ }
+}
+echo json_encode($out);
+?>
\ No newline at end of file
diff --git a/assets/css/custom.css b/assets/css/custom.css
new file mode 100644
index 0000000..c926c75
--- /dev/null
+++ b/assets/css/custom.css
@@ -0,0 +1,188 @@
+@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&family=Roboto:wght@300;400&display=swap');
+
+:root {
+ --primary-color: #BDE0FE; /* Baby Blue Eyes */
+ --accent-color: #FFC8B2; /* Pastel Peach */
+ --background-color: #FFFBF7; /* Very light, warm off-white */
+ --text-color: #6D6875; /* Muted, soft gray */
+ --surface-color: #FFFFFF;
+ --board-bg: #A3C4F3;
+ --cell-bg: #EAF4F4;
+ --border-radius: 1rem;
+}
+
+body {
+ background-color: var(--background-color);
+ color: var(--text-color);
+ font-family: 'Roboto', sans-serif;
+ font-weight: 300;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ font-family: 'Poppins', sans-serif;
+ font-weight: 700;
+ color: var(--text-color);
+}
+
+.navbar {
+ background-color: var(--surface-color) !important;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.05) !important;
+}
+
+.navbar-brand {
+ font-family: 'Poppins', sans-serif;
+ font-weight: 700;
+ color: var(--primary-color) !important;
+}
+
+.hero {
+ background: linear-gradient(135deg, var(--primary-color) 0%, var(--accent-color) 100%);
+ color: white;
+ padding: 6rem 0;
+ text-align: center;
+ border-bottom-left-radius: var(--border-radius);
+ border-bottom-right-radius: var(--border-radius);
+}
+
+.hero h1 {
+ font-size: 3.5rem;
+ font-weight: 700;
+ color: white;
+ text-shadow: 1px 1px 3px rgba(0,0,0,0.1);
+}
+
+.btn-primary {
+ background-color: var(--accent-color);
+ border-color: var(--accent-color);
+ border-radius: var(--border-radius);
+ padding: 0.75rem 1.5rem;
+ font-weight: 700;
+ color: white;
+ transition: all 0.3s ease;
+ box-shadow: 0 4px 15px rgba(0,0,0,0.1);
+}
+
+.btn-primary:hover {
+ background-color: white;
+ border-color: white;
+ color: var(--accent-color);
+ transform: translateY(-2px);
+ box-shadow: 0 6px 20px rgba(0,0,0,0.15);
+}
+
+#game-section {
+ padding: 4rem 0;
+}
+
+.game-board {
+ display: grid;
+ gap: 10px;
+ width: 100%;
+ max-width: 500px;
+ margin: 2rem auto;
+ background-color: var(--board-bg);
+ border: 5px solid var(--board-bg);
+ border-radius: var(--border-radius);
+ padding: 10px;
+}
+
+.game-cell {
+ width: 100%;
+ padding-bottom: 100%;
+ position: relative;
+ background-color: var(--cell-bg);
+ border-radius: 0.75rem;
+ cursor: pointer;
+ transition: all 0.3s ease;
+}
+
+.game-cell:hover {
+ transform: scale(1.05);
+ box-shadow: 0 4px 10px rgba(0,0,0,0.1);
+}
+
+.game-cell .symbol {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ font-size: 1rem; /* Default for large boards */
+ font-weight: 400;
+ user-select: none;
+}
+
+/* Board-size specific adjustments */
+.game-board.size-5 {
+ gap: 10px;
+}
+.game-board.size-5 .game-cell .symbol {
+ font-size: 2.5rem;
+}
+
+.game-board.size-18,
+.game-board.size-36 {
+ gap: 2px;
+ padding: 2px;
+ border-width: 2px;
+}
+
+#gallery-section {
+ padding: 4rem 0;
+ background-color: var(--primary-color-light);
+}
+
+.cat-gallery {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
+ gap: 1.5rem;
+}
+
+.cat-gallery-item {
+ border-radius: var(--border-radius);
+ overflow: hidden;
+ box-shadow: 0 4px 15px rgba(0,0,0,0.1);
+ transition: all 0.3s ease;
+ position: relative;
+}
+
+.cat-gallery-item:hover {
+ transform: translateY(-5px) scale(1.03);
+ box-shadow: 0 8px 25px rgba(0,0,0,0.15);
+}
+
+.cat-gallery-item img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.cat-gallery-item .photographer-credit {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background: rgba(0,0,0,0.5);
+ color: white;
+ padding: 0.5rem;
+ text-align: center;
+ font-size: 0.8rem;
+ opacity: 0;
+ transition: opacity 0.3s ease;
+}
+
+.cat-gallery-item:hover .photographer-credit {
+ opacity: 1;
+}
+
+.cat-gallery-item .photographer-credit a {
+ color: var(--accent-color);
+ text-decoration: none;
+}
+
+
+
+footer {
+ background-color: var(--text-color);
+ color: white;
+ padding: 2rem 0;
+}
\ No newline at end of file
diff --git a/assets/images/pexels/10914511.jpg b/assets/images/pexels/10914511.jpg
new file mode 100644
index 0000000..6fd30b6
Binary files /dev/null and b/assets/images/pexels/10914511.jpg differ
diff --git a/assets/images/pexels/11163348.jpg b/assets/images/pexels/11163348.jpg
new file mode 100644
index 0000000..49ec1aa
Binary files /dev/null and b/assets/images/pexels/11163348.jpg differ
diff --git a/assets/images/pexels/11497291.jpg b/assets/images/pexels/11497291.jpg
new file mode 100644
index 0000000..0ad69c4
Binary files /dev/null and b/assets/images/pexels/11497291.jpg differ
diff --git a/assets/images/pexels/12692139.jpg b/assets/images/pexels/12692139.jpg
new file mode 100644
index 0000000..cb83e46
Binary files /dev/null and b/assets/images/pexels/12692139.jpg differ
diff --git a/assets/images/pexels/12915730.jpg b/assets/images/pexels/12915730.jpg
new file mode 100644
index 0000000..c59bc97
Binary files /dev/null and b/assets/images/pexels/12915730.jpg differ
diff --git a/assets/images/pexels/14603745.jpg b/assets/images/pexels/14603745.jpg
new file mode 100644
index 0000000..7a119c7
Binary files /dev/null and b/assets/images/pexels/14603745.jpg differ
diff --git a/assets/images/pexels/14852082.jpg b/assets/images/pexels/14852082.jpg
new file mode 100644
index 0000000..6405fcd
Binary files /dev/null and b/assets/images/pexels/14852082.jpg differ
diff --git a/assets/images/pexels/14904690.jpg b/assets/images/pexels/14904690.jpg
new file mode 100644
index 0000000..b2d3728
Binary files /dev/null and b/assets/images/pexels/14904690.jpg differ
diff --git a/assets/images/pexels/15208769.jpg b/assets/images/pexels/15208769.jpg
new file mode 100644
index 0000000..5783a52
Binary files /dev/null and b/assets/images/pexels/15208769.jpg differ
diff --git a/assets/images/pexels/160722.jpg b/assets/images/pexels/160722.jpg
new file mode 100644
index 0000000..f5f73df
Binary files /dev/null and b/assets/images/pexels/160722.jpg differ
diff --git a/assets/images/pexels/160839.jpg b/assets/images/pexels/160839.jpg
new file mode 100644
index 0000000..d9fea27
Binary files /dev/null and b/assets/images/pexels/160839.jpg differ
diff --git a/assets/images/pexels/16282655.jpg b/assets/images/pexels/16282655.jpg
new file mode 100644
index 0000000..79c5cb5
Binary files /dev/null and b/assets/images/pexels/16282655.jpg differ
diff --git a/assets/images/pexels/16482823.jpg b/assets/images/pexels/16482823.jpg
new file mode 100644
index 0000000..400992c
Binary files /dev/null and b/assets/images/pexels/16482823.jpg differ
diff --git a/assets/images/pexels/16575029.jpg b/assets/images/pexels/16575029.jpg
new file mode 100644
index 0000000..57cb693
Binary files /dev/null and b/assets/images/pexels/16575029.jpg differ
diff --git a/assets/images/pexels/16577552.jpg b/assets/images/pexels/16577552.jpg
new file mode 100644
index 0000000..1e5af78
Binary files /dev/null and b/assets/images/pexels/16577552.jpg differ
diff --git a/assets/images/pexels/17596619.jpg b/assets/images/pexels/17596619.jpg
new file mode 100644
index 0000000..2c6264d
Binary files /dev/null and b/assets/images/pexels/17596619.jpg differ
diff --git a/assets/images/pexels/179222.jpg b/assets/images/pexels/179222.jpg
new file mode 100644
index 0000000..c6ceea3
Binary files /dev/null and b/assets/images/pexels/179222.jpg differ
diff --git a/assets/images/pexels/18002652.jpg b/assets/images/pexels/18002652.jpg
new file mode 100644
index 0000000..9bd0e5f
Binary files /dev/null and b/assets/images/pexels/18002652.jpg differ
diff --git a/assets/images/pexels/18159266.jpg b/assets/images/pexels/18159266.jpg
new file mode 100644
index 0000000..23780da
Binary files /dev/null and b/assets/images/pexels/18159266.jpg differ
diff --git a/assets/images/pexels/18168507.jpg b/assets/images/pexels/18168507.jpg
new file mode 100644
index 0000000..e246af7
Binary files /dev/null and b/assets/images/pexels/18168507.jpg differ
diff --git a/assets/images/pexels/18533500.jpg b/assets/images/pexels/18533500.jpg
new file mode 100644
index 0000000..ec99d3e
Binary files /dev/null and b/assets/images/pexels/18533500.jpg differ
diff --git a/assets/images/pexels/19012985.jpg b/assets/images/pexels/19012985.jpg
new file mode 100644
index 0000000..dde29fc
Binary files /dev/null and b/assets/images/pexels/19012985.jpg differ
diff --git a/assets/images/pexels/19500831.jpg b/assets/images/pexels/19500831.jpg
new file mode 100644
index 0000000..8e5ed5e
Binary files /dev/null and b/assets/images/pexels/19500831.jpg differ
diff --git a/assets/images/pexels/20782645.jpg b/assets/images/pexels/20782645.jpg
new file mode 100644
index 0000000..fad2de4
Binary files /dev/null and b/assets/images/pexels/20782645.jpg differ
diff --git a/assets/images/pexels/24018314.jpg b/assets/images/pexels/24018314.jpg
new file mode 100644
index 0000000..8ed282a
Binary files /dev/null and b/assets/images/pexels/24018314.jpg differ
diff --git a/assets/images/pexels/24600235.jpg b/assets/images/pexels/24600235.jpg
new file mode 100644
index 0000000..9c924cc
Binary files /dev/null and b/assets/images/pexels/24600235.jpg differ
diff --git a/assets/images/pexels/2646483.jpg b/assets/images/pexels/2646483.jpg
new file mode 100644
index 0000000..d962c19
Binary files /dev/null and b/assets/images/pexels/2646483.jpg differ
diff --git a/assets/images/pexels/29235341.jpg b/assets/images/pexels/29235341.jpg
new file mode 100644
index 0000000..d31b1ad
Binary files /dev/null and b/assets/images/pexels/29235341.jpg differ
diff --git a/assets/images/pexels/29983805.jpg b/assets/images/pexels/29983805.jpg
new file mode 100644
index 0000000..61e57e8
Binary files /dev/null and b/assets/images/pexels/29983805.jpg differ
diff --git a/assets/images/pexels/30247451.jpg b/assets/images/pexels/30247451.jpg
new file mode 100644
index 0000000..ab3d511
Binary files /dev/null and b/assets/images/pexels/30247451.jpg differ
diff --git a/assets/images/pexels/30374205.jpg b/assets/images/pexels/30374205.jpg
new file mode 100644
index 0000000..1353a38
Binary files /dev/null and b/assets/images/pexels/30374205.jpg differ
diff --git a/assets/images/pexels/30389394.jpg b/assets/images/pexels/30389394.jpg
new file mode 100644
index 0000000..c09d5c0
Binary files /dev/null and b/assets/images/pexels/30389394.jpg differ
diff --git a/assets/images/pexels/32552958.jpg b/assets/images/pexels/32552958.jpg
new file mode 100644
index 0000000..a754be2
Binary files /dev/null and b/assets/images/pexels/32552958.jpg differ
diff --git a/assets/images/pexels/32849279.jpg b/assets/images/pexels/32849279.jpg
new file mode 100644
index 0000000..b6b9026
Binary files /dev/null and b/assets/images/pexels/32849279.jpg differ
diff --git a/assets/images/pexels/34368085.jpg b/assets/images/pexels/34368085.jpg
new file mode 100644
index 0000000..30d02d0
Binary files /dev/null and b/assets/images/pexels/34368085.jpg differ
diff --git a/assets/images/pexels/3652805.jpg b/assets/images/pexels/3652805.jpg
new file mode 100644
index 0000000..7e36a95
Binary files /dev/null and b/assets/images/pexels/3652805.jpg differ
diff --git a/assets/images/pexels/3780890.jpg b/assets/images/pexels/3780890.jpg
new file mode 100644
index 0000000..202a6b4
Binary files /dev/null and b/assets/images/pexels/3780890.jpg differ
diff --git a/assets/images/pexels/4612722.jpg b/assets/images/pexels/4612722.jpg
new file mode 100644
index 0000000..a94c754
Binary files /dev/null and b/assets/images/pexels/4612722.jpg differ
diff --git a/assets/images/pexels/4790612.jpg b/assets/images/pexels/4790612.jpg
new file mode 100644
index 0000000..a3b999b
Binary files /dev/null and b/assets/images/pexels/4790612.jpg differ
diff --git a/assets/images/pexels/51439.jpg b/assets/images/pexels/51439.jpg
new file mode 100644
index 0000000..8654f77
Binary files /dev/null and b/assets/images/pexels/51439.jpg differ
diff --git a/assets/images/pexels/8597460.jpg b/assets/images/pexels/8597460.jpg
new file mode 100644
index 0000000..ca98a4b
Binary files /dev/null and b/assets/images/pexels/8597460.jpg differ
diff --git a/assets/images/pexels/8861204.jpg b/assets/images/pexels/8861204.jpg
new file mode 100644
index 0000000..77e6318
Binary files /dev/null and b/assets/images/pexels/8861204.jpg differ
diff --git a/assets/images/pexels/8935989.jpg b/assets/images/pexels/8935989.jpg
new file mode 100644
index 0000000..67eb4eb
Binary files /dev/null and b/assets/images/pexels/8935989.jpg differ
diff --git a/assets/images/pexels/9195549.jpg b/assets/images/pexels/9195549.jpg
new file mode 100644
index 0000000..dac9eec
Binary files /dev/null and b/assets/images/pexels/9195549.jpg differ
diff --git a/assets/images/pexels/9195629.jpg b/assets/images/pexels/9195629.jpg
new file mode 100644
index 0000000..cae3991
Binary files /dev/null and b/assets/images/pexels/9195629.jpg differ
diff --git a/assets/images/pexels/9660361.jpg b/assets/images/pexels/9660361.jpg
new file mode 100644
index 0000000..51d285f
Binary files /dev/null and b/assets/images/pexels/9660361.jpg differ
diff --git a/assets/images/pexels/9787888.jpg b/assets/images/pexels/9787888.jpg
new file mode 100644
index 0000000..722b168
Binary files /dev/null and b/assets/images/pexels/9787888.jpg differ
diff --git a/assets/js/main.js b/assets/js/main.js
new file mode 100644
index 0000000..376979b
--- /dev/null
+++ b/assets/js/main.js
@@ -0,0 +1,363 @@
+document.addEventListener('DOMContentLoaded', function() {
+ const playNowButton = document.querySelector('.btn-primary');
+ if (playNowButton) {
+ playNowButton.addEventListener('click', function(e) {
+ e.preventDefault();
+ document.querySelector('#game-section').scrollIntoView({ behavior: 'smooth' });
+ });
+ }
+
+ const gameBoard = document.getElementById('game-board');
+ const resetButton = document.getElementById('reset-button');
+ const gameStatus = document.getElementById('game-status');
+ const boardSizeSelect = document.getElementById('board-size-select');
+ const aiDifficultySelect = document.getElementById('ai-difficulty-select');
+
+ const WIN_CONDITION = 4;
+ const PLAYER_SYMBOL = '🐾';
+ const AI_SYMBOL = '🧶';
+
+ let BOARD_SIZE = 5;
+ let boardState;
+ let currentPlayer;
+ let gameActive;
+ let cells;
+
+ function createBoard(size) {
+ BOARD_SIZE = size;
+ gameBoard.innerHTML = '';
+ gameBoard.className = 'game-board';
+ gameBoard.classList.add(`size-${size}`);
+
+ gameBoard.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
+ gameBoard.style.gridTemplateRows = `repeat(${size}, 1fr)`;
+
+ cells = [];
+ for (let i = 0; i < size * size; i++) {
+ const cell = document.createElement('div');
+ cell.classList.add('game-cell');
+ const row = Math.floor(i / BOARD_SIZE);
+ const col = i % BOARD_SIZE;
+ cell.addEventListener('click', () => handleCellClick(row, col));
+ gameBoard.appendChild(cell);
+ cells.push(cell);
+ }
+ }
+
+ function handleCellClick(row, col) {
+ if (!gameActive || boardState[row][col] !== null || currentPlayer !== 'PLAYER') {
+ return;
+ }
+
+ boardState[row][col] = 'PLAYER';
+ renderBoard();
+
+ if (checkWin('PLAYER')) {
+ endGame('Player');
+ return;
+ }
+
+ if (isDraw()) {
+ endGame('Draw');
+ return;
+ }
+
+ currentPlayer = 'AI';
+ updateStatus("AI's turn...");
+ setTimeout(makeAIMove, 500);
+ }
+
+ function makeAIMove() {
+ if (!gameActive) return;
+
+ const difficulty = aiDifficultySelect.value;
+ let move;
+
+ if (difficulty === 'easy') {
+ move = findRandomMove();
+ } else if (difficulty === 'medium') {
+ move = findBestMoveMedium();
+ } else { // Hard
+ move = findBestMoveHard();
+ }
+
+ if (move) {
+ boardState[move.row][move.col] = 'AI';
+ renderBoard();
+
+ if (checkWin('AI')) {
+ endGame('AI');
+ return;
+ }
+
+ if (isDraw()) {
+ endGame('Draw');
+ return;
+ }
+ }
+
+ currentPlayer = 'PLAYER';
+ updateStatus("Your turn!");
+ }
+
+ function findRandomMove() {
+ let availableCells = [];
+ for (let i = 0; i < BOARD_SIZE; i++) {
+ for (let j = 0; j < BOARD_SIZE; j++) {
+ if (boardState[i][j] === null) {
+ availableCells.push({ row: i, col: j });
+ }
+ }
+ }
+ if (availableCells.length > 0) {
+ return availableCells[Math.floor(Math.random() * availableCells.length)];
+ }
+ return null;
+ }
+
+ function findBestMoveMedium() {
+ // 1. Check if AI can win
+ for (let i = 0; i < BOARD_SIZE; i++) {
+ for (let j = 0; j < BOARD_SIZE; j++) {
+ if (boardState[i][j] === null) {
+ boardState[i][j] = 'AI';
+ if (checkWin('AI')) {
+ boardState[i][j] = null; // Reset
+ return { row: i, col: j };
+ }
+ boardState[i][j] = null; // Reset
+ }
+ }
+ }
+
+ // 2. Check if Player is about to win and block
+ for (let i = 0; i < BOARD_SIZE; i++) {
+ for (let j = 0; j < BOARD_SIZE; j++) {
+ if (boardState[i][j] === null) {
+ boardState[i][j] = 'PLAYER';
+ if (checkWin('PLAYER')) {
+ boardState[i][j] = null; // Reset
+ return { row: i, col: j };
+ }
+ boardState[i][j] = null; // Reset
+ }
+ }
+ }
+
+ // 3. Otherwise, make a random move
+ return findRandomMove();
+ }
+
+ function findBestMoveHard() {
+ let bestScore = -Infinity;
+ let move = null;
+
+ for (let i = 0; i < BOARD_SIZE; i++) {
+ for (let j = 0; j < BOARD_SIZE; j++) {
+ if (boardState[i][j] === null) {
+ boardState[i][j] = 'AI';
+ let score = evaluateBoard();
+ boardState[i][j] = null;
+ if (score > bestScore) {
+ bestScore = score;
+ move = { row: i, col: j };
+ }
+ }
+ }
+ }
+ return move || findRandomMove(); // Fallback to random if no good move
+ }
+
+ function evaluateBoard() {
+ let score = 0;
+ // Prioritize winning moves
+ if (checkWin('AI')) return 10000;
+ // Prioritize blocking player's winning moves
+ if (checkWin('PLAYER')) return -9000;
+
+ // Evaluate lines for potential
+ score += evaluateLinesForPlayer('AI');
+ score -= evaluateLinesForPlayer('PLAYER');
+
+ return score;
+ }
+
+ function evaluateLinesForPlayer(player) {
+ let score = 0;
+ const symbol = player;
+
+ for (let i = 0; i < BOARD_SIZE; i++) {
+ for (let j = 0; j < BOARD_SIZE; j++) {
+ // Horizontal
+ if (j + WIN_CONDITION <= BOARD_SIZE) {
+ score += evaluateLine(i, j, 0, 1, symbol);
+ }
+ // Vertical
+ if (i + WIN_CONDITION <= BOARD_SIZE) {
+ score += evaluateLine(i, j, 1, 0, symbol);
+ }
+ // Diagonal (down-right)
+ if (i + WIN_CONDITION <= BOARD_SIZE && j + WIN_CONDITION <= BOARD_SIZE) {
+ score += evaluateLine(i, j, 1, 1, symbol);
+ }
+ // Diagonal (down-left)
+ if (i + WIN_CONDITION <= BOARD_SIZE && j - WIN_CONDITION + 1 >= 0) {
+ score += evaluateLine(i, j, 1, -1, symbol);
+ }
+ }
+ }
+ return score;
+ }
+
+ function evaluateLine(row, col, dr, dc, player) {
+ let playerCount = 0;
+ let emptyCount = 0;
+ for (let k = 0; k < WIN_CONDITION; k++) {
+ const current = boardState[row + k * dr][col + k * dc];
+ if (current === player) {
+ playerCount++;
+ } else if (current === null) {
+ emptyCount++;
+ }
+ }
+
+ // If the line is blocked by the opponent, it has no potential.
+ if (playerCount + emptyCount < WIN_CONDITION) {
+ return 0;
+ }
+
+ // Assign scores based on the number of pieces in a line
+ if (playerCount === 3 && emptyCount === 1) return 100;
+ if (playerCount === 2 && emptyCount === 2) return 10;
+ if (playerCount === 1 && emptyCount === 3) return 1;
+ return 0;
+ }
+
+
+ function checkWin(player) {
+ const symbol = player;
+
+ for (let i = 0; i < BOARD_SIZE; i++) {
+ for (let j = 0; j < BOARD_SIZE; j++) {
+ // Horizontal
+ if (j + WIN_CONDITION <= BOARD_SIZE) {
+ let count = 0;
+ for (let k = 0; k < WIN_CONDITION; k++) {
+ if (boardState[i][j + k] === symbol) count++;
+ }
+ if (count === WIN_CONDITION) return true;
+ }
+ // Vertical
+ if (i + WIN_CONDITION <= BOARD_SIZE) {
+ let count = 0;
+ for (let k = 0; k < WIN_CONDITION; k++) {
+ if (boardState[i + k][j] === symbol) count++;
+ }
+ if (count === WIN_CONDITION) return true;
+ }
+ // Diagonal (down-right)
+ if (i + WIN_CONDITION <= BOARD_SIZE && j + WIN_CONDITION <= BOARD_SIZE) {
+ let count = 0;
+ for (let k = 0; k < WIN_CONDITION; k++) {
+ if (boardState[i + k][j + k] === symbol) count++;
+ }
+ if (count === WIN_CONDITION) return true;
+ }
+ // Diagonal (down-left)
+ if (i + WIN_CONDITION <= BOARD_SIZE && j - WIN_CONDITION + 1 >= 0) {
+ let count = 0;
+ for (let k = 0; k < WIN_CONDITION; k++) {
+ if (boardState[i + k][j - k] === symbol) count++;
+ }
+ if (count === WIN_CONDITION) return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ function isDraw() {
+ return boardState.every(row => row.every(cell => cell !== null));
+ }
+
+ function endGame(winner) {
+ gameActive = false;
+ if (winner === 'Draw') {
+ updateStatus("It's a draw!");
+ } else {
+ updateStatus(`${winner} wins!`);
+ }
+ }
+
+ function resetGame() {
+ const size = parseInt(boardSizeSelect.value);
+ createBoard(size);
+ boardState = Array(BOARD_SIZE).fill(null).map(() => Array(BOARD_SIZE).fill(null));
+ currentPlayer = 'PLAYER';
+ gameActive = true;
+ renderBoard();
+ updateStatus("Your turn!");
+ }
+
+ function renderBoard() {
+ cells.forEach((cell, index) => {
+ const row = Math.floor(index / BOARD_SIZE);
+ const col = index % BOARD_SIZE;
+ const state = boardState[row][col];
+
+ if (state === 'PLAYER') {
+ cell.innerHTML = `
${PLAYER_SYMBOL}
`;
+ } else if (state === 'AI') {
+ cell.innerHTML = `${AI_SYMBOL}
`;
+ } else {
+ cell.innerHTML = '';
+ }
+ });
+ }
+
+ function updateStatus(message) {
+ gameStatus.textContent = message;
+ }
+
+ if (resetButton) {
+ resetButton.addEventListener('click', resetGame);
+ }
+
+ if (boardSizeSelect) {
+ boardSizeSelect.addEventListener('change', resetGame);
+ }
+
+ if(aiDifficultySelect) {
+ aiDifficultySelect.addEventListener('change', resetGame);
+ }
+
+ resetGame();
+
+ const catGallery = document.getElementById('cat-gallery');
+ if (catGallery) {
+ fetch('api/pexels.php')
+ .then(response => response.json())
+ .then(images => {
+ images.forEach(image => {
+ const galleryItem = document.createElement('div');
+ galleryItem.className = 'cat-gallery-item';
+
+ const img = document.createElement('img');
+ img.src = image.src;
+ img.alt = 'A cute cat';
+
+ const credit = document.createElement('div');
+ credit.className = 'photographer-credit';
+ credit.innerHTML = `Photo by ${image.photographer}`;
+
+ galleryItem.appendChild(img);
+ galleryItem.appendChild(credit);
+ catGallery.appendChild(galleryItem);
+ });
+ })
+ .catch(error => {
+ console.error('Error fetching cat images:', error);
+ catGallery.innerHTML = 'Could not load cat pictures. Meow-be later?
';
+ });
+ }
+});
\ No newline at end of file
diff --git a/includes/pexels.php b/includes/pexels.php
new file mode 100644
index 0000000..ff50279
--- /dev/null
+++ b/includes/pexels.php
@@ -0,0 +1,26 @@
+ 0 ? $k : 'Vc99rnmOhHhJAbgGQoKLZtsaIVfkeownoQNbTj78VemUjKh08ZYRbf18';
+}
+function pexels_get($url) {
+ $ch = curl_init();
+ curl_setopt_array($ch, [
+ CURLOPT_URL => $url,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_HTTPHEADER => [ 'Authorization: '. pexels_key() ],
+ CURLOPT_TIMEOUT => 15,
+ ]);
+ $resp = curl_exec($ch);
+ $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ curl_close($ch);
+ if ($code >= 200 && $code < 300 && $resp) return json_decode($resp, true);
+ return null;
+}
+function download_to($srcUrl, $destPath) {
+ $data = @file_get_contents($srcUrl);
+ if ($data === false) return false;
+ if (!is_dir(dirname($destPath))) mkdir(dirname($destPath), 0775, true);
+ return file_put_contents($destPath, $data) !== false;
+}
+?>
\ No newline at end of file
diff --git a/index.php b/index.php
index 7205f3d..0480bd8 100644
--- a/index.php
+++ b/index.php
@@ -1,150 +1,84 @@
-
-
+
-
-
- New Style
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ Cute-Cat-Toe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
Analyzing your requirements and generating your website…
-
- Loading…
-
-
= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.
-
This page will update automatically as the plan is implemented.
-
Runtime: PHP = htmlspecialchars($phpVersion) ?> — UTC = htmlspecialchars($now) ?>
-
-
-
+
+
+
+
+
+
+
Welcome to Cute-Cat-Toe!
+
The cutest Tic Tac Toe game on the web. Play with paws and yarn!
+
Play a Game
+
+
+
+
+ Let's Play!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Cute Cat Gallery
+
+
+
+
+
+
+
+
+
+
+
-
+