advanced-games-library
Version:
Advanced Gaming Library for React Native - Four Complete Games with iOS Compatibility Fixes
206 lines (172 loc) • 5.67 kB
JavaScript
/**
* Game Utilities & Helper Functions
* Version 4.0.0 - Fixed Image Puzzle Generation
*/
// Helper function to shuffle array
const shuffleArray = (array) => {
const newArray = [...array];
for (let i = newArray.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[newArray[i], newArray[j]] = [newArray[j], newArray[i]];
}
return newArray;
};
// Helper function to generate memory cards
const generateMemoryCards = (pairs = 6) => {
const symbols = ['🐕', '🐶', '🦮', '🐕🦺', '🐩', '🐺', '🦊', '🐱', '🐈', '🐈⬛', '🦁', '🐯'];
const cards = [];
for (let i = 0; i < pairs; i++) {
const symbol = symbols[i % symbols.length];
cards.push({ id: i * 2, symbol, matched: false, flipped: false });
cards.push({ id: i * 2 + 1, symbol, matched: false, flipped: false });
}
return shuffleArray(cards);
};
// Helper function to generate puzzle tiles
const generatePuzzleTiles = (gridSize = 3) => {
const totalTiles = gridSize * gridSize;
const tiles = [];
// Create ordered tiles (1, 2, 3, ..., empty)
for (let i = 1; i < totalTiles; i++) {
tiles.push(i);
}
tiles.push(0); // Empty tile
// Shuffle until solvable
let shuffled;
let attempts = 0;
do {
shuffled = shuffleArray([...tiles]);
attempts++;
} while (!isPuzzleSolvable(shuffled, gridSize) && attempts < 100);
return shuffled;
};
// Check if puzzle is solvable
const isPuzzleSolvable = (tiles, gridSize) => {
let inversions = 0;
const emptyRow = Math.floor(tiles.indexOf(0) / gridSize);
for (let i = 0; i < tiles.length - 1; i++) {
for (let j = i + 1; j < tiles.length; j++) {
if (tiles[i] > tiles[j] && tiles[i] !== 0 && tiles[j] !== 0) {
inversions++;
}
}
}
if (gridSize % 2 === 1) {
return inversions % 2 === 0;
} else {
return (inversions + emptyRow) % 2 === 1;
}
};
// Check if puzzle is solved
const isPuzzleSolved = (tiles, gridSize) => {
const totalTiles = gridSize * gridSize;
for (let i = 0; i < totalTiles - 1; i++) {
if (tiles[i] !== i + 1) return false;
}
return tiles[totalTiles - 1] === 0;
};
// Helper function to generate image puzzle pieces - FIXED VERSION
const generateImagePuzzlePieces = (gridSize = 3) => {
console.log('🔄 Generating image puzzle pieces for grid size:', gridSize);
const totalPieces = gridSize * gridSize;
// First create a simple tiles array like the regular puzzle
const simpleTiles = [];
for (let i = 1; i < totalPieces; i++) {
simpleTiles.push(i);
}
simpleTiles.push(0); // Empty tile
// Shuffle until solvable using existing logic
let shuffledTiles;
let attempts = 0;
do {
shuffledTiles = shuffleArray([...simpleTiles]);
attempts++;
} while (!isPuzzleSolvable(shuffledTiles, gridSize) && attempts < 100);
console.log('✅ Found solvable arrangement after', attempts, 'attempts');
// Now convert to pieces format
const pieces = shuffledTiles.map((tileValue, index) => {
if (tileValue === 0) {
// Empty piece
return {
id: totalPieces - 1, // Empty piece has highest ID
position: index,
correctPosition: totalPieces - 1,
isEmpty: true
};
} else {
// Regular piece
return {
id: tileValue - 1, // Convert 1-8 to 0-7 for piece IDs
position: index,
correctPosition: tileValue - 1,
isEmpty: false
};
}
});
console.log('✅ Generated', pieces.length, 'pieces successfully');
return pieces;
};
// Check if image puzzle is solved
const isImagePuzzleSolved = (pieces) => {
if (!pieces || pieces.length === 0) return false;
return pieces.every(piece => {
if (!piece) return false;
return piece.position === piece.correctPosition;
});
};
// Get piece coordinates from index
const getPieceCoordinates = (index, gridSize) => {
const row = Math.floor(index / gridSize);
const col = index % gridSize;
return { row, col };
};
// Check if two pieces are adjacent
const arePiecesAdjacent = (index1, index2, gridSize) => {
const { row: row1, col: col1 } = getPieceCoordinates(index1, gridSize);
const { row: row2, col: col2 } = getPieceCoordinates(index2, gridSize);
return (
(Math.abs(row1 - row2) === 1 && col1 === col2) ||
(Math.abs(col1 - col2) === 1 && row1 === row2)
);
};
// Calculate image piece style based on its correct position
const getImagePieceStyle = (pieceId, gridSize, imageWidth, imageHeight) => {
const { row, col } = getPieceCoordinates(pieceId, gridSize);
const pieceWidth = imageWidth / gridSize;
const pieceHeight = imageHeight / gridSize;
return {
width: pieceWidth,
height: pieceHeight,
backgroundPosition: `-${col * pieceWidth}px -${row * pieceHeight}px`,
backgroundSize: `${imageWidth}px ${imageHeight}px`,
};
};
module.exports = {
// Array utilities
shuffleArray,
// Memory game helpers
generateMemoryCards,
// Puzzle game helpers
generatePuzzleTiles,
isPuzzleSolvable,
isPuzzleSolved,
// Image puzzle helpers
generateImagePuzzlePieces,
isImagePuzzleSolved,
getPieceCoordinates,
arePiecesAdjacent,
getImagePieceStyle,
// General utilities
formatTime: (seconds) => {
const mins = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${mins}:${secs.toString().padStart(2, '0')}`;
},
calculateScore: (baseScore, moves, timeSeconds, bonus = 0) => {
return Math.max(
baseScore - (moves * 10) - (timeSeconds * 2) + bonus,
50
);
}
};
console.log('✅ Game helpers loaded successfully - v4.0.0 FIXED');