Skip to content

Commit

Permalink
feat(engine): updated getNextBoardFinalState function
Browse files Browse the repository at this point in the history
  • Loading branch information
wialy committed Mar 6, 2024
1 parent f3f99c6 commit cca70f9
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { expect, test } from 'vitest';

import { VECTOR_RIGHT, VECTOR_ZERO } from '../../../constants';
import { isDice } from '../../../types/entities';
import { createEntity } from '../../create-entity';
import { getNextBoardFinalState } from '..';

test('two dices moving same direction merge', () => {
const level = [
createEntity('floor', { position: { x: 0, y: 0 } }),
createEntity('floor', { position: { x: 1, y: 0 } }),
createEntity('floor', { position: { x: 2, y: 0 } }),
createEntity('floor', { position: { x: 3, y: 0 } }),
createEntity('dice', {
position: { x: 0, y: 0 },
value: 0,
velocity: VECTOR_RIGHT,
}),
createEntity('dice', {
position: { x: 1, y: 0 },
value: 0,
velocity: VECTOR_ZERO,
}),
];

const result = getNextBoardFinalState({
entities: level,
velocity: VECTOR_RIGHT,
});

expect(result).toBeDefined();
expect(result?.entities).toEqual(
expect.arrayContaining([
expect.objectContaining({
position: { x: 3, y: 0 },
type: 'dice',
value: 1,
velocity: VECTOR_ZERO,
}),
]),
);
expect(result?.entities.filter(isDice)).toHaveLength(1);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { expect, test } from 'vitest';

import { DIRECTIONS, VECTOR_ZERO } from '../../../constants';
import { isDice, Vector } from '../../../types/entities';
import { createEntity } from '../../create-entity';
import { getNextBoardFinalState } from '..';

test.each(DIRECTIONS)(
'two dices moving %o merge and stop',
(velocity: Vector) => {
const level = [
createEntity('floor', { position: { x: 0, y: 0 } }),
createEntity('floor', { position: velocity }),
createEntity('floor', {
position: { x: velocity.x * 2, y: velocity.y * 2 },
}),
createEntity('dice', {
position: { x: 0, y: 0 },
value: 0,
velocity,
}),
createEntity('dice', {
position: velocity,
value: 0,
velocity,
}),
];

const result = getNextBoardFinalState({
entities: level,
velocity,
});

expect(result).toBeDefined();
expect(result?.entities).toHaveLength(4);
expect(result?.entities).toEqual(
expect.arrayContaining([
expect.objectContaining({
position: { x: velocity.x * 2, y: velocity.y * 2 },
type: 'dice',
value: 1,
velocity: VECTOR_ZERO,
}),
]),
);
expect(result?.entities.filter(isDice)).toHaveLength(1);
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { expect, test } from 'vitest';

import { VECTOR_DOWN, VECTOR_LEFT, VECTOR_ZERO } from '../../../constants';
import { createEntity } from '../../create-entity';
import { getNextBoardFinalState } from '..';

test.only('two same dices taking one floor', () => {
const dice1 = createEntity('dice', {
id: 'dice-1',
position: { x: 0, y: 0 },
velocity: VECTOR_DOWN,
});
const dice2 = createEntity('dice', {
id: 'dice-2',
position: { x: 1, y: 1 },
velocity: VECTOR_LEFT,
});
const floors = [
createEntity('floor', { position: { x: 0, y: 0 } }),
createEntity('floor', { position: { x: 1, y: 0 } }),
createEntity('floor', { position: { x: 0, y: 1 } }),
createEntity('floor', { position: { x: 1, y: 1 } }),
];

const entities = [dice1, dice2, ...floors];

const result = getNextBoardFinalState({ entities });

expect(result?.entities).toBeDefined();
expect(result?.entities).toHaveLength(5);
expect(result?.entities).toContainEqual(
expect.objectContaining({
isFresh: true,
position: { x: 0, y: 1 },
type: 'dice',
velocity: VECTOR_ZERO,
}),
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Entity, isMovable, Vector } from '../../types/entities';
import { getNextBoardState } from '../get-next-board-state';
import { getShouldUpdate } from '../get-should-update';

export const getNextBoardFinalState = ({
entities: originalEntities,
velocity,
}: {
entities: Entity[];
velocity?: Vector;
}): { entities: Entity[] } | undefined => {
// apply velocity to all movable entities
const entities = velocity
? originalEntities.map((entity) => {
if (isMovable(entity)) {
return {
...entity,
isForced: true,
velocity,
};
}

return { ...entity };
})
: originalEntities;

for (const entity of entities) {
entity.isFresh = false;
}

let nextEntities: Entity[] = entities;
let previousEntities: Entity[] = [];

let iterations = 30;
do {
previousEntities = nextEntities;
nextEntities = getNextBoardState({ board: { entities: nextEntities } }).board
.entities;
} while (
getShouldUpdate({ entities: nextEntities, previousEntities }) &&
iterations--
);

const result = previousEntities.map((entity) => ({
...entity,
}));

return { entities: result };
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './get-next-board-final-state';

0 comments on commit cca70f9

Please sign in to comment.