Skip to content

Commit 105bfb0

Browse files
committed
Don't increment move count on no-op moves (ie. moves that did not change the board)
1 parent bbe3488 commit 105bfb0

File tree

3 files changed

+74
-8
lines changed

3 files changed

+74
-8
lines changed

cypress/e2e/game/gameplay.cy.ts

+34
Original file line numberDiff line numberDiff line change
@@ -356,4 +356,38 @@ describe("gameplay", () => {
356356

357357
cy.get("#moveCount").should("have.text", "0");
358358
});
359+
360+
it("should not increment move count on no-op move", () => {
361+
cy.visit("/", {
362+
onBeforeLoad: () => {
363+
const gameState: GameState = {
364+
board: [
365+
[2, 0, 0, 0],
366+
[2, 0, 0, 0],
367+
[2, 0, 0, 0],
368+
[2, 0, 0, 0],
369+
],
370+
ended: false,
371+
won: false,
372+
score: 0,
373+
didUndo: false,
374+
achievedHighscore: false,
375+
moveCount: 0,
376+
};
377+
const persistentState: GamePersistentState = {
378+
highscore: 0,
379+
unlockables: {},
380+
hasPlayedBefore: true,
381+
};
382+
window.localStorage.setItem("game-state", JSON.stringify(gameState));
383+
window.localStorage.setItem("persistent-state", JSON.stringify(persistentState));
384+
},
385+
});
386+
387+
cy.get("#moveCount").should("have.text", "0");
388+
389+
cy.get("body").type("{leftArrow}"); // Perform a no-op move
390+
391+
cy.get("#moveCount").should("have.text", "0"); // Move count should not increment
392+
});
359393
});

src/game.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,6 @@ export const move = (direction: Direction) => {
275275
console.log("prev board is now", prevBoard);
276276

277277
undoManager.pushGameState();
278-
gameState.moveCount++;
279278

280279
animationManager.resetState();
281280

@@ -286,8 +285,13 @@ export const move = (direction: Direction) => {
286285

287286
// Keep looping through movement until no more moves can be made
288287
prevBoard = null;
289-
let numMoves = 0;
288+
let numShifts = 0;
290289
while (!isBoardSame(gameState.board, prevBoard)) {
290+
// If at least one shift was performed, then count as a move.
291+
// But do not count as a move for any subsequent shifts within this move.
292+
if (numShifts === 1) {
293+
gameState.moveCount++;
294+
}
291295
prevBoard = [];
292296
for (let i = 0; i < gameState.board.length; i++) {
293297
prevBoard.push(gameState.board[i].slice());
@@ -371,10 +375,10 @@ export const move = (direction: Direction) => {
371375
}
372376
}
373377
console.log("current board is", gameState.board);
374-
numMoves++;
378+
numShifts++;
375379
}
376380

377-
if (numMoves > 1) {
381+
if (numShifts > 1) {
378382
console.log("spawn next block and check game conditions");
379383

380384
const location = spawnManager.determineNextBlockLocation();

test/game_test.ts

+32-4
Original file line numberDiff line numberDiff line change
@@ -332,14 +332,11 @@ describe("core game logic", () => {
332332
assert.strictEqual(gameState.ended, true);
333333
assert.strictEqual(gameState.moveCount, 1);
334334
// Should not be able to make any more moves upon game over
335-
mockSpawnManager.determineNextBlockValue.mockImplementation(() => {
336-
return 2;
337-
});
338335
move(DIRECTION_RIGHT);
339336
prevBoard = JSON.parse(JSON.stringify(gameState.board));
340337
assert.notStrictEqual(gameState.board, prevBoard);
341338
assert.strictEqual(gameState.ended, true);
342-
assert.strictEqual(gameState.moveCount, 2);
339+
assert.strictEqual(gameState.moveCount, 1);
343340
});
344341
it("should allow player to continue the game if board is full but adjacent blocks can be merged", async () => {
345342
mockSpawnManager.determineNextBlockLocation.mockImplementation(() => {
@@ -572,4 +569,35 @@ describe("core game logic", () => {
572569
assert.strictEqual(gameState.board[2][0], 4);
573570
assert.strictEqual(gameState.board[3][0], 4);
574571
});
572+
it("should not increment move count on no-op move", async () => {
573+
mockSpawnManager.determineNextBlockLocation.mockImplementation(() => {
574+
return {
575+
x: 0,
576+
y: 0,
577+
};
578+
});
579+
mockSpawnManager.determineNextBlockValue.mockImplementation(() => {
580+
return 2;
581+
});
582+
583+
const gameState = await setupGame({
584+
board: [
585+
[2, 0, 0, 0],
586+
[2, 0, 0, 0],
587+
[2, 0, 0, 0],
588+
[2, 0, 0, 0],
589+
],
590+
ended: false,
591+
won: false,
592+
score: 0,
593+
didUndo: false,
594+
achievedHighscore: false,
595+
moveCount: 0,
596+
});
597+
598+
const initialMoveCount = gameState.moveCount;
599+
move(DIRECTION_LEFT); // Perform a no-op move
600+
601+
expect(gameState.moveCount).toBe(initialMoveCount); // Move count should not increment
602+
});
575603
});

0 commit comments

Comments
 (0)