User prompt
bu seferde çok az olduğu matchlenecek şeker yok
User prompt
çok sık aynı şekerden olmasın oyunu kolaylaştırıyor
User prompt
hala matchleme sorununu yaşıyorum bazen şekerler aynı olmasına rağmen matchlenmiyor
User prompt
eğer yanlış matchlersem scorem 300 eksilsin ve bi ses çıkarsın
User prompt
bazı şekerler aynı tür olmasına rağmen matchlenmiyorlar
User prompt
eğer şekerler kendiliğinden matchlencek pozisyondaysa otomatik matchlensinler
User prompt
dedect the bugs like a pro dev and fix it
User prompt
add mute music section
User prompt
candies cant match
User prompt
Sometimes the candies do not matchs even after being tripled and there may be a bug.
User prompt
make game harder
User prompt
When the bomb explodes it affects a 3x3 area.
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading '0')' in or related to this line: 'if (grid[row][col] && grid[row][col].candyType) {' Line Number: 96
User prompt
Set a limit on the types of candy, there can be a maximum of 6 of each candy block
User prompt
bombs explode 3x3 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make game harder
User prompt
Generate a balanced initial game board for a match-3 puzzle with the following strict constraints: No immediate matches: There must be no 3 or more identical blocks consecutively aligned horizontally or vertically at the start. Limited quantity per block type: Each block type must appear no more than a specified maximum count on the board, distributed as evenly as possible. Placement validation: When placing a block, check neighbors to prevent forming 3-in-a-row or 3-in-a-column matches. Random but controlled: Use randomization within these constraints to keep the board fresh and fair. Re-generation if needed: If no suitable block can be placed in a cell without breaking constraints, backtrack or reshuffle the board to ensure validity. Implement a robust board generation algorithm that respects these rules to avoid starting boards with clusters or imbalanced block counts.
User prompt
When generating the game board (seed) for the match-3 game, ensure the following constraints to avoid large clusters of identical blocks: No initial matches: The board should never start with 3 or more identical blocks aligned horizontally or vertically. Diverse distribution: Implement a placement algorithm that places blocks one by one, checking the neighbors of each placed block to avoid creating immediate matches. Controlled randomness: Use a shuffled pool of block types and place them iteratively, validating after each placement that no match occurs. Board validation: After filling the board, scan for any accidental matches and reshuffle or adjust if any are found. Seed reproducibility: Use a seeded random number generator for consistency but ensure enough variation. The goal is to produce a fair, playable board at the start of each seed with no immediate matches or overly repetitive patterns.
User prompt
When generating a new seed (board layout) for the match-3 game, ensure the following: The blocks are randomly distributed but balanced — avoid long runs or clusters of only one block type. Each seed must include a diverse mix of block types, with no single block type dominating more than 25-30% of the board. Guarantee that at least one valid match is possible at the start of the seed. The randomization should be seeded to allow reproducibility but also varied enough to keep gameplay fresh. Implement logic to prevent impossible boards or those that break game mechanics (e.g., full rows or columns of the same block). This will ensure the game remains fair, challenging, and fun as the player progresses through multiple seeds.
User prompt
Create a loop system where the player progresses through consecutive seeds (board setups) by reaching a target score. Each new seed should increase difficulty slightly, making the game progressively harder. The game continues indefinitely until the player fails to meet the score goal. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Fix the bug where matched blocks don’t mix or clear properly. Ensure reliable match detection and grid updates. Also, make the mixing effects extremely satisfying — with juicy particles, sound, and smooth animations that enhance the player experience without causing lag or delays. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add background music
User prompt
add image to background too
Code edit (1 edits merged)
Please save this source code
User prompt
Sweet Swap Match
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Candy = Container.expand(function (type, gridX, gridY) {
var self = Container.call(this);
self.candyType = type;
self.gridX = gridX;
self.gridY = gridY;
self.isSpecial = false;
self.specialType = null; // 'lineH', 'lineV', 'explosive'
self.falling = false;
var assetId = 'candy' + type;
var candyGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.setSpecialType = function (specialType) {
self.isSpecial = true;
self.specialType = specialType;
self.removeChild(candyGraphics);
var newAssetId;
if (specialType === 'lineH') newAssetId = 'lineCandyH';else if (specialType === 'lineV') newAssetId = 'lineCandyV';else if (specialType === 'explosive') newAssetId = 'explosiveCandy';else newAssetId = 'candy' + type;
candyGraphics = self.attachAsset(newAssetId, {
anchorX: 0.5,
anchorY: 0.5
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2a1810
});
/****
* Game Code
****/
var GRID_SIZE = 8;
var CELL_SIZE = 200;
var CANDY_TYPES = 6;
var TARGET_SCORE = 5000;
var MAX_MOVES = 30;
var grid = [];
var score = 0;
var moves = 0;
var selectedCandy = null;
var isProcessing = false;
var gridOffsetX = (2048 - GRID_SIZE * CELL_SIZE) / 2;
var gridOffsetY = 400;
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var movesTxt = new Text2('Moves: ' + MAX_MOVES, {
size: 80,
fill: 0xFFFFFF
});
movesTxt.anchor.set(0.5, 0);
movesTxt.y = 100;
LK.gui.top.addChild(movesTxt);
var targetTxt = new Text2('Target: ' + TARGET_SCORE, {
size: 60,
fill: 0xFFFF00
});
targetTxt.anchor.set(0.5, 0);
targetTxt.y = 200;
LK.gui.top.addChild(targetTxt);
// Music mute button
var isMusicMuted = false;
var muteButton = new Text2('🔊', {
size: 80,
fill: 0xFFFFFF
});
muteButton.anchor.set(1, 0);
muteButton.x = -50; // Position from right edge
muteButton.y = 50;
LK.gui.topRight.addChild(muteButton);
// Create grid background
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
var bgTile = game.addChild(LK.getAsset('gridBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: gridOffsetX + col * CELL_SIZE + CELL_SIZE / 2,
y: gridOffsetY + row * CELL_SIZE + CELL_SIZE / 2,
alpha: 0.3
}));
}
}
function getBalancedCandyType(row, col) {
// First check for immediate matches that would be created
var forbiddenTypes = [];
// Check horizontal matches (left and right)
if (col >= 2 && grid[row] && grid[row][col - 1] && grid[row][col - 2] && grid[row][col - 1].candyType === grid[row][col - 2].candyType) {
forbiddenTypes.push(grid[row][col - 1].candyType);
}
// Check vertical matches (up)
if (row >= 2 && grid[row - 1] && grid[row - 1][col] && grid[row - 2] && grid[row - 2][col] && grid[row - 1][col].candyType === grid[row - 2][col].candyType) {
forbiddenTypes.push(grid[row - 1][col].candyType);
}
// Count only immediate neighbors to prevent excessive clustering
var typeCounts = {};
for (var i = 1; i <= CANDY_TYPES; i++) {
typeCounts[i] = 0;
}
// Check only direct adjacent cells (not 3x3 area)
var adjacentPositions = [{
r: row - 1,
c: col
}, {
r: row + 1,
c: col
}, {
r: row,
c: col - 1
}, {
r: row,
c: col + 1
}];
for (var i = 0; i < adjacentPositions.length; i++) {
var pos = adjacentPositions[i];
if (pos.r >= 0 && pos.r < GRID_SIZE && pos.c >= 0 && pos.c < GRID_SIZE && grid[pos.r] && grid[pos.r][pos.c] && grid[pos.r][pos.c].candyType) {
typeCounts[grid[pos.r][pos.c].candyType]++;
}
}
// Create available types list, excluding forbidden and over-represented types
var availableTypes = [];
for (var type = 1; type <= CANDY_TYPES; type++) {
// Don't use forbidden types (would create immediate matches)
if (forbiddenTypes.indexOf(type) !== -1) continue;
// Don't use types that appear in 3+ adjacent cells
if (typeCounts[type] >= 3) continue;
availableTypes.push(type);
}
// If all types are forbidden/over-represented, allow types with fewer adjacent occurrences
if (availableTypes.length === 0) {
var minCount = Math.min.apply(Math, Object.values(typeCounts));
for (var type = 1; type <= CANDY_TYPES; type++) {
if (forbiddenTypes.indexOf(type) === -1 && typeCounts[type] === minCount) {
availableTypes.push(type);
}
}
}
// If still no available types, just pick randomly (should not happen)
if (availableTypes.length === 0) {
availableTypes = [1, 2, 3, 4, 5, 6];
}
// Return random type from available ones
return availableTypes[Math.floor(Math.random() * availableTypes.length)];
}
function initializeGrid() {
grid = [];
for (var row = 0; row < GRID_SIZE; row++) {
grid[row] = [];
for (var col = 0; col < GRID_SIZE; col++) {
var candyType = getBalancedCandyType(row, col);
var candy = new Candy(candyType, col, row);
candy.x = gridOffsetX + col * CELL_SIZE + CELL_SIZE / 2;
candy.y = gridOffsetY + row * CELL_SIZE + CELL_SIZE / 2;
grid[row][col] = candy;
game.addChild(candy);
}
}
// Remove initial matches
var hasMatches = true;
while (hasMatches) {
hasMatches = false;
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
if (checkMatch(row, col).length >= 3) {
grid[row][col].candyType = getBalancedCandyType(row, col);
hasMatches = true;
}
}
}
}
}
function getGridPosition(x, y) {
var col = Math.floor((x - gridOffsetX) / CELL_SIZE);
var row = Math.floor((y - gridOffsetY) / CELL_SIZE);
if (col >= 0 && col < GRID_SIZE && row >= 0 && row < GRID_SIZE) {
return {
row: row,
col: col
};
}
return null;
}
function checkMatch(row, col) {
// Validate input parameters
if (row < 0 || row >= GRID_SIZE || col < 0 || col >= GRID_SIZE) {
return [];
}
var candy = grid[row][col];
if (!candy || candy.falling || !candy.candyType) return [];
var type = candy.candyType;
var horizontalMatches = [candy];
var verticalMatches = [candy];
// Check horizontal matches
var left = col - 1;
while (left >= 0 && grid[row] && grid[row][left] && !grid[row][left].falling && grid[row][left].candyType && grid[row][left].candyType === type) {
horizontalMatches.push(grid[row][left]);
left--;
}
var right = col + 1;
while (right < GRID_SIZE && grid[row] && grid[row][right] && !grid[row][right].falling && grid[row][right].candyType && grid[row][right].candyType === type) {
horizontalMatches.push(grid[row][right]);
right++;
}
// Check vertical matches
var up = row - 1;
while (up >= 0 && grid[up] && grid[up][col] && !grid[up][col].falling && grid[up][col].candyType && grid[up][col].candyType === type) {
verticalMatches.push(grid[up][col]);
up--;
}
var down = row + 1;
while (down < GRID_SIZE && grid[down] && grid[down][col] && !grid[down][col].falling && grid[down][col].candyType && grid[down][col].candyType === type) {
verticalMatches.push(grid[down][col]);
down++;
}
// Return the larger match group if either is 3 or more
if (horizontalMatches.length >= 3 && verticalMatches.length >= 3) {
// Return combined matches for cross patterns
var allMatches = [];
for (var i = 0; i < horizontalMatches.length; i++) {
if (allMatches.indexOf(horizontalMatches[i]) === -1) {
allMatches.push(horizontalMatches[i]);
}
}
for (var i = 0; i < verticalMatches.length; i++) {
if (allMatches.indexOf(verticalMatches[i]) === -1) {
allMatches.push(verticalMatches[i]);
}
}
return allMatches;
} else if (horizontalMatches.length >= 3) {
return horizontalMatches;
} else if (verticalMatches.length >= 3) {
return verticalMatches;
}
return [];
}
function findAllMatches() {
var allMatches = [];
var processed = [];
for (var row = 0; row < GRID_SIZE; row++) {
processed[row] = [];
for (var col = 0; col < GRID_SIZE; col++) {
processed[row][col] = false;
}
}
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
if (!processed[row][col] && grid[row] && grid[row][col] && !grid[row][col].falling) {
var matches = checkMatch(row, col);
if (matches.length >= 3) {
allMatches.push(matches);
for (var i = 0; i < matches.length; i++) {
var match = matches[i];
if (match && match.gridY >= 0 && match.gridY < GRID_SIZE && match.gridX >= 0 && match.gridX < GRID_SIZE) {
processed[match.gridY][match.gridX] = true;
}
}
}
}
}
}
return allMatches;
}
function removeMatches(matchGroups) {
var totalScore = 0;
for (var g = 0; g < matchGroups.length; g++) {
var matches = matchGroups[g];
var matchScore = 0;
if (matches.length === 3) matchScore = 100;else if (matches.length === 4) matchScore = 200;else if (matches.length >= 5) matchScore = 500;
totalScore += matchScore;
// Create special candy for 4+ matches
var specialCandy = null;
if (matches.length >= 4) {
var centerCandy = matches[Math.floor(matches.length / 2)];
if (matches.length === 4) {
// Create line candy based on match direction
var isHorizontal = matches[0].gridY === matches[1].gridY;
centerCandy.setSpecialType(isHorizontal ? 'lineH' : 'lineV');
} else if (matches.length >= 5) {
centerCandy.setSpecialType('explosive');
}
specialCandy = centerCandy;
}
// Animate candy destruction with satisfying effects
for (var i = 0; i < matches.length; i++) {
var candy = matches[i];
if (matches.length < 4 || candy !== specialCandy) {
// Create particle effect before destroying
createParticleEffect(candy.x, candy.y, candy.candyType);
// Animate candy scaling down with bounce
tween(candy, {
scaleX: 0,
scaleY: 0,
rotation: Math.PI * 2,
alpha: 0
}, {
duration: 300,
easing: tween.bounceIn,
onFinish: function onFinish() {
if (candy.parent) {
candy.destroy();
}
}
});
// Set grid position to null immediately
grid[candy.gridY][candy.gridX] = null;
} else {
// Special candy creation effect
tween(candy, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(candy, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeOut
});
}
});
LK.effects.flashObject(candy, 0xFFD700, 500);
}
}
}
if (totalScore > 0) {
LK.getSound('match').play();
LK.effects.flashScreen(0xFFFFFF, 200);
}
return totalScore;
}
function applyGravity() {
var moved = false;
var animationDelay = 0;
for (var col = 0; col < GRID_SIZE; col++) {
var writePos = GRID_SIZE - 1;
var colDelay = col * 30; // Stagger columns slightly
for (var row = GRID_SIZE - 1; row >= 0; row--) {
if (grid[row][col] !== null) {
if (row !== writePos) {
var candy = grid[row][col];
grid[writePos][col] = candy;
grid[row][col] = null;
candy.gridY = writePos;
candy.gridX = col;
candy.falling = true;
var fallDistance = writePos - row;
var fallDuration = 200 + fallDistance * 50; // Longer falls take more time
LK.setTimeout(function (candy, writePos, fallDuration) {
return function () {
tween(candy, {
y: gridOffsetY + writePos * CELL_SIZE + CELL_SIZE / 2
}, {
duration: fallDuration,
easing: tween.bounceOut,
onFinish: function onFinish() {
candy.falling = false;
}
});
};
}(candy, writePos, fallDuration), colDelay);
moved = true;
}
writePos--;
}
}
// Fill empty spaces with new candies
for (var emptyRow = writePos; emptyRow >= 0; emptyRow--) {
var candyType = getBalancedCandyType(emptyRow, col);
var newCandy = new Candy(candyType, col, emptyRow);
newCandy.x = gridOffsetX + col * CELL_SIZE + CELL_SIZE / 2;
newCandy.y = gridOffsetY + (emptyRow - GRID_SIZE) * CELL_SIZE + CELL_SIZE / 2;
newCandy.falling = true;
grid[emptyRow][col] = newCandy;
game.addChild(newCandy);
var dropDelay = colDelay + (GRID_SIZE - emptyRow) * 50;
LK.setTimeout(function (newCandy, emptyRow) {
return function () {
tween(newCandy, {
y: gridOffsetY + emptyRow * CELL_SIZE + CELL_SIZE / 2
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
newCandy.falling = false;
}
});
};
}(newCandy, emptyRow), dropDelay);
moved = true;
}
}
return moved;
}
function swapCandies(candy1, candy2) {
if (isProcessing) return false;
// Validate candies exist and have proper grid positions
if (!candy1 || !candy2 || candy1.falling || candy2.falling) return false;
if (candy1.gridX < 0 || candy1.gridX >= GRID_SIZE || candy1.gridY < 0 || candy1.gridY >= GRID_SIZE) return false;
if (candy2.gridX < 0 || candy2.gridX >= GRID_SIZE || candy2.gridY < 0 || candy2.gridY >= GRID_SIZE) return false;
var tempGridX = candy1.gridX;
var tempGridY = candy1.gridY;
candy1.gridX = candy2.gridX;
candy1.gridY = candy2.gridY;
candy2.gridX = tempGridX;
candy2.gridY = tempGridY;
grid[candy1.gridY][candy1.gridX] = candy1;
grid[candy2.gridY][candy2.gridX] = candy2;
var pos1 = {
x: gridOffsetX + candy1.gridX * CELL_SIZE + CELL_SIZE / 2,
y: gridOffsetY + candy1.gridY * CELL_SIZE + CELL_SIZE / 2
};
var pos2 = {
x: gridOffsetX + candy2.gridX * CELL_SIZE + CELL_SIZE / 2,
y: gridOffsetY + candy2.gridY * CELL_SIZE + CELL_SIZE / 2
};
isProcessing = true;
tween(candy1, pos1, {
duration: 200,
easing: tween.easeInOut
});
tween(candy2, pos2, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
var matches1 = checkMatch(candy1.gridY, candy1.gridX);
var matches2 = checkMatch(candy2.gridY, candy2.gridX);
if (matches1.length >= 3 || matches2.length >= 3) {
LK.getSound('swap').play();
moves++;
movesTxt.setText('Moves: ' + (MAX_MOVES - moves));
processMatches();
} else {
// Wrong match - penalize score and play sound
score -= 300;
if (score < 0) score = 0; // Don't let score go negative
scoreTxt.setText('Score: ' + score);
LK.getSound('wrongMatch').play();
// Flash screen red to indicate wrong match
LK.effects.flashScreen(0xFF0000, 300);
// Swap back
var tempGridX = candy1.gridX;
var tempGridY = candy1.gridY;
candy1.gridX = candy2.gridX;
candy1.gridY = candy2.gridY;
candy2.gridX = tempGridX;
candy2.gridY = tempGridY;
grid[candy1.gridY][candy1.gridX] = candy1;
grid[candy2.gridY][candy2.gridX] = candy2;
tween(candy1, pos2, {
duration: 200
});
tween(candy2, pos1, {
duration: 200,
onFinish: function onFinish() {
isProcessing = false;
}
});
}
}
});
return true;
}
function processMatches() {
LK.setTimeout(function () {
var matchGroups = findAllMatches();
if (matchGroups.length > 0) {
var matchScore = removeMatches(matchGroups);
score += matchScore;
scoreTxt.setText('Score: ' + score);
LK.setTimeout(function () {
var moved = applyGravity();
if (moved) {
LK.setTimeout(function () {
processMatches();
}, 400);
} else {
isProcessing = false;
checkGameEnd();
}
}, 100);
} else {
isProcessing = false;
checkGameEnd();
}
}, 100);
}
function createParticleEffect(x, y, candyType) {
// Create multiple particle sprites for a juicy effect
var colors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0x96CEB4, 0xFECE2F, 0xFF8A80];
var particleColor = colors[candyType - 1] || 0xFFFFFF;
for (var i = 0; i < 8; i++) {
var particle = game.addChild(LK.getAsset('candy' + candyType, {
anchorX: 0.5,
anchorY: 0.5,
x: x,
y: y,
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.8
}));
// Random direction and distance for particles
var angle = Math.PI * 2 * i / 8;
var distance = 50 + Math.random() * 100;
var targetX = x + Math.cos(angle) * distance;
var targetY = y + Math.sin(angle) * distance;
// Animate particles flying out and fading
tween(particle, {
x: targetX,
y: targetY,
scaleX: 0,
scaleY: 0,
alpha: 0,
rotation: Math.random() * Math.PI * 4
}, {
duration: 400 + Math.random() * 200,
easing: tween.easeOut,
onFinish: function onFinish() {
if (particle.parent) {
particle.destroy();
}
}
});
}
}
function checkGameEnd() {
if (score >= TARGET_SCORE) {
LK.showYouWin();
} else if (moves >= MAX_MOVES) {
LK.showGameOver();
}
}
function isAdjacent(candy1, candy2) {
var dx = Math.abs(candy1.gridX - candy2.gridX);
var dy = Math.abs(candy1.gridY - candy2.gridY);
return dx === 1 && dy === 0 || dx === 0 && dy === 1;
}
// Mute button click handler
muteButton.down = function (x, y, obj) {
if (isMusicMuted) {
LK.playMusic('backgroundMusic');
muteButton.setText('🔊');
isMusicMuted = false;
} else {
LK.stopMusic();
muteButton.setText('🔇');
isMusicMuted = true;
}
// Add visual feedback
tween(muteButton, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(muteButton, {
scaleX: 1,
scaleY: 1
}, {
duration: 100,
easing: tween.easeOut
});
}
});
};
game.down = function (x, y, obj) {
if (isProcessing) return;
var gridPos = getGridPosition(x, y);
if (!gridPos) return;
var candy = grid[gridPos.row][gridPos.col];
if (!candy || candy.falling) return;
if (selectedCandy === null) {
selectedCandy = candy;
tween(candy, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
easing: tween.bounceOut
});
LK.effects.flashObject(candy, 0xFFFFFF, 300);
} else if (selectedCandy === candy) {
tween(candy, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeOut
});
selectedCandy = null;
} else if (isAdjacent(selectedCandy, candy)) {
tween(selectedCandy, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeOut
});
swapCandies(selectedCandy, candy);
selectedCandy = null;
} else {
tween(selectedCandy, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeOut
});
selectedCandy = candy;
tween(candy, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
easing: tween.bounceOut
});
LK.effects.flashObject(candy, 0xFFFFFF, 300);
}
};
// Add background image
var backgroundImage = game.addChild(LK.getAsset('gameBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0.8
}));
// Initialize the game
initializeGrid();
// Start background music after mute button is set up
LK.playMusic('backgroundMusic');
// Game update function to automatically detect and process matches
game.update = function () {
// Only check for automatic matches when not processing and no candies are falling
if (!isProcessing) {
var anyFalling = false;
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
if (grid[row][col] && grid[row][col].falling) {
anyFalling = true;
break;
}
}
if (anyFalling) break;
}
// If no candies are falling, check for automatic matches
if (!anyFalling) {
var matchGroups = findAllMatches();
if (matchGroups.length > 0) {
// Automatically process the matches found
processMatches();
}
}
}
};
; ===================================================================
--- original.js
+++ change.js
@@ -98,30 +98,66 @@
}));
}
}
function getBalancedCandyType(row, col) {
- // Count nearby candy types to avoid clustering
+ // First check for immediate matches that would be created
+ var forbiddenTypes = [];
+ // Check horizontal matches (left and right)
+ if (col >= 2 && grid[row] && grid[row][col - 1] && grid[row][col - 2] && grid[row][col - 1].candyType === grid[row][col - 2].candyType) {
+ forbiddenTypes.push(grid[row][col - 1].candyType);
+ }
+ // Check vertical matches (up)
+ if (row >= 2 && grid[row - 1] && grid[row - 1][col] && grid[row - 2] && grid[row - 2][col] && grid[row - 1][col].candyType === grid[row - 2][col].candyType) {
+ forbiddenTypes.push(grid[row - 1][col].candyType);
+ }
+ // Count only immediate neighbors to prevent excessive clustering
var typeCounts = {};
for (var i = 1; i <= CANDY_TYPES; i++) {
typeCounts[i] = 0;
}
- // Check 3x3 area around current position
- for (var r = Math.max(0, row - 1); r <= Math.min(GRID_SIZE - 1, row + 1); r++) {
- for (var c = Math.max(0, col - 1); c <= Math.min(GRID_SIZE - 1, col + 1); c++) {
- if (grid[r] && grid[r][c] && grid[r][c].candyType) {
- typeCounts[grid[r][c].candyType]++;
- }
+ // Check only direct adjacent cells (not 3x3 area)
+ var adjacentPositions = [{
+ r: row - 1,
+ c: col
+ }, {
+ r: row + 1,
+ c: col
+ }, {
+ r: row,
+ c: col - 1
+ }, {
+ r: row,
+ c: col + 1
+ }];
+ for (var i = 0; i < adjacentPositions.length; i++) {
+ var pos = adjacentPositions[i];
+ if (pos.r >= 0 && pos.r < GRID_SIZE && pos.c >= 0 && pos.c < GRID_SIZE && grid[pos.r] && grid[pos.r][pos.c] && grid[pos.r][pos.c].candyType) {
+ typeCounts[grid[pos.r][pos.c].candyType]++;
}
}
- // Find least common types in the area
- var minCount = Math.min.apply(Math, Object.values(typeCounts));
+ // Create available types list, excluding forbidden and over-represented types
var availableTypes = [];
for (var type = 1; type <= CANDY_TYPES; type++) {
- if (typeCounts[type] === minCount) {
- availableTypes.push(type);
+ // Don't use forbidden types (would create immediate matches)
+ if (forbiddenTypes.indexOf(type) !== -1) continue;
+ // Don't use types that appear in 3+ adjacent cells
+ if (typeCounts[type] >= 3) continue;
+ availableTypes.push(type);
+ }
+ // If all types are forbidden/over-represented, allow types with fewer adjacent occurrences
+ if (availableTypes.length === 0) {
+ var minCount = Math.min.apply(Math, Object.values(typeCounts));
+ for (var type = 1; type <= CANDY_TYPES; type++) {
+ if (forbiddenTypes.indexOf(type) === -1 && typeCounts[type] === minCount) {
+ availableTypes.push(type);
+ }
}
}
- // Return random type from least common ones
+ // If still no available types, just pick randomly (should not happen)
+ if (availableTypes.length === 0) {
+ availableTypes = [1, 2, 3, 4, 5, 6];
+ }
+ // Return random type from available ones
return availableTypes[Math.floor(Math.random() * availableTypes.length)];
}
function initializeGrid() {
grid = [];
green gummy bear candy shiny and cute (sitting). No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
blue foot candy looks funny and shiny. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
yellow appetite enhancer candy looks shiny and delicous. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
pink cotton candy looks shiny and delicous. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
blue shiny and delicous lollipop, no stick. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
bomb and lollipop mix candy . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
blurry beautiful snow view background image. In-Game asset. 2d. High contrast. No shadows
blurry ice block texture. In-Game asset. 2d. High contrast. No shadows
stick candy. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
stick candy with green lines . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
bean candy red and shiny . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat