Implement image no-repeat system: Images only repeat after all have been shown

Enhance image selection to prevent repeats until all images are exhausted:

## New Game State Tracking:
- Added usedTaskImages array to gameState
- Added usedConsequenceImages array to gameState
- Tracks which specific images have been displayed

## Smart Image Selection Logic:
1. **Filter Available Images**: Remove already-used images from selection pool
2. **Prevent Repeats**: Only select from images that haven't been shown yet
3. **Auto-Reset**: When all images exhausted, reset tracking and allow repeats
4. **Separate Tracking**: Task and consequence images tracked independently

## Enhanced User Experience:
- Users see all their images before any repeats occur
- Better variety and rotation through image collections
- Automatic cycling ensures no image is permanently excluded
- Visual feedback shows progression (X/Y images used)

## Technical Implementation:
- getRandomImage() enhanced with usage tracking
- Image identification works with both string paths and metadata objects
- Maintains compatibility with existing disabled images system
- Preserves all existing custom image functionality

## Console Logging:
- Shows when image cycles reset: 'All [type] images have been shown, resetting for repeat cycle'
- Tracks usage progression: 'Selected [type] image: [name] (X/Y used)'
- Helps users understand image rotation system

**Now images will cycle through the entire collection before repeating!**
This commit is contained in:
fritzsenpai 2025-09-25 21:50:53 -05:00
parent 411885873a
commit 927c19c45c
1 changed files with 32 additions and 4 deletions

36
game.js
View File

@ -21,7 +21,9 @@ class TaskChallengeGame {
score: 0,
lastSkippedTask: null, // Track the last skipped task for mercy cost calculation
usedMainTasks: [],
usedConsequenceTasks: []
usedConsequenceTasks: [],
usedTaskImages: [], // Track which task images have been shown
usedConsequenceImages: [] // Track which consequence images have been shown
};
this.timerInterval = null;
@ -2381,13 +2383,16 @@ ${usagePercent > 85 ? '⚠️ Storage getting full - consider deleting some imag
getRandomImage(isConsequence = false) {
let imagePool;
let imageType;
let usedImagesArray;
if (isConsequence) {
imagePool = gameData.discoveredConsequenceImages;
imageType = 'consequence';
usedImagesArray = this.gameState.usedConsequenceImages;
} else {
imagePool = gameData.discoveredTaskImages;
imageType = 'task';
usedImagesArray = this.gameState.usedTaskImages;
}
// Add custom images to the pool
@ -2418,12 +2423,35 @@ ${usagePercent > 85 ? '⚠️ Storage getting full - consider deleting some imag
return this.createPlaceholderImage(isConsequence ? 'Consequence Image' : 'Task Image');
}
const randomIndex = Math.floor(Math.random() * imagePool.length);
const selectedImage = imagePool[randomIndex];
// Get image identifiers for tracking
const getImageId = (img) => {
return typeof img === 'string' ? img : (img.cachedPath || img.originalName);
};
// Filter out images that have already been used
let availableImages = imagePool.filter(img => {
const imageId = getImageId(img);
return !usedImagesArray.includes(imageId);
});
// If all images have been used, reset the used array and use all images again
if (availableImages.length === 0) {
console.log(`All ${imageType} images have been shown, resetting for repeat cycle`);
usedImagesArray.length = 0; // Clear the used images array
availableImages = imagePool; // Use all available images again
}
// Select a random image from available images
const randomIndex = Math.floor(Math.random() * availableImages.length);
const selectedImage = availableImages[randomIndex];
const selectedImageId = getImageId(selectedImage);
// Mark this image as used
usedImagesArray.push(selectedImageId);
// Convert to displayable format
const displayImage = this.getImageSrc(selectedImage);
console.log(`Selected ${imageType} image: ${typeof selectedImage === 'string' ? selectedImage : selectedImage.originalName}`);
console.log(`Selected ${imageType} image: ${typeof selectedImage === 'string' ? selectedImage : selectedImage.originalName} (${usedImagesArray.length}/${imagePool.length} used)`);
return displayImage;
}