Skip to content

Commit

Permalink
Merge branch 'main' into feature/add-program-langage-selection
Browse files Browse the repository at this point in the history
  • Loading branch information
Tatehito committed Jan 25, 2024
2 parents ab5797f + ccd74f8 commit 072ad10
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 20 deletions.
30 changes: 30 additions & 0 deletions src/app/lib/Board.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { Cell } from '../../types';

import type { Character } from './Character';

export class Board {
grid: Cell[][];
constructor({
gridSize = [8, 12],
}: {
gridSize?: [number, number];
} = {}) {
this.grid = this.createGrid(gridSize[1], gridSize[0]);
}

createGrid(numRows: number, numColumns: number): Cell[][] {
const grid: Cell[][] = [];
for (let i = 0; i < numRows; i++) {
grid.push([]);
for (let j = 0; j < numColumns; j++) {
grid[i].push({ color: undefined });
}
}
return grid;
}

updateGrid(character: Character): void {
const { cellColor, penDown, x, y } = character;
if (penDown) this.grid[y - 1][x - 1].color = cellColor;
}
}
35 changes: 25 additions & 10 deletions src/app/lib/Character.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { CellColor } from '../../types';

export const CharacterColor = {
Red: 'red',
Blue: 'blue',
Expand All @@ -13,25 +15,38 @@ export class Character {
x: number;
y: number;
direction: string;
cellColor: CellColor;
color: Color;
penDown: boolean;
path: string[];

constructor(
id: number,
name: string,
x: number,
y: number,
direction: string,
color: string,
penDown: boolean,
path: string[]
) {
constructor({
cellColor = 'red',
color = 'red',
direction = 'down',
id = 1,
name = 'Bear',
path = ['1,1'],
penDown = true,
x = 1,
y = 1,
}: {
id?: number;
name?: string;
x?: number;
y?: number;
direction?: string;
cellColor?: CellColor;
color?: Color;
penDown?: boolean;
path?: string[];
} = {}) {
this.id = id;
this.name = name;
this.x = x;
this.y = y;
this.direction = direction;
this.cellColor = cellColor;
this.color = color;
this.penDown = penDown;
this.path = path;
Expand Down
57 changes: 57 additions & 0 deletions src/app/lib/solveProblem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type { SolveProblemResult } from '../../types';

import { Board as BoardClass } from './Board';
import { Character as CharacterClass } from './Character';

export function parseProgram(program: string): string[] {
return program
.split('\n')
.map((line) => line.trim())
.filter((line) => line !== '');
}

export function executeEval(command: string): CharacterClass {
const Character = CharacterClass; // eslint-disable-line
const Board = BoardClass; // eslint-disable-line
const characterVariableName = 'character';
const semicolonEndedCommand = (() => {
if (command.endsWith(';')) return command;
command += ';';
})();
const returnValueCommand = `
${characterVariableName};
`;

const mergedCommand = semicolonEndedCommand + '\n' + returnValueCommand;

return eval(mergedCommand);
}

export function solveProblem(program: string): SolveProblemResult {
const commands = parseProgram(program);
const character = new CharacterClass();
const board = new BoardClass();
const histories = [{ step: 0, character, board }];

for (let i = 0; i < commands.length; i++) {
if (i < commands.length) {
let mergedCommand = '';

for (let j = 0; j <= i; j++) {
mergedCommand += commands[j];
}

const character = executeEval(mergedCommand);

board.updateGrid(character);
histories.push({ step: histories.length + 1, character, board });
}
}

const result = {
character: histories?.at(-1)?.character || character,
board: histories?.at(-1)?.board || board,
histories,
};
return result;
}
11 changes: 1 addition & 10 deletions src/components/organisms/TurtleGraphics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,7 @@ export const TurtleGraphics: React.FC<TurtleGraphicsProps> = ({
setCharacters((prevCharacters) =>
prevCharacters.map((prevCharacter) => {
if (prevCharacter.id === character.id) {
const updatedCharacter = new Character(
character.id,
character.name,
character.x,
character.y,
character.direction,
character.color,
character.penDown,
[...character.path]
);
const updatedCharacter = new Character({ ...character });
updater(updatedCharacter);
return updatedCharacter;
}
Expand Down
20 changes: 20 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
import type React from 'react';

import type { Board } from './app/lib/Board';
import type { Character } from './app/lib/Character';

export interface LayoutProps {
children: React.ReactNode;
}

export type LayoutComponent = React.FC<LayoutProps>;

export type CellColor = 'red' | 'green' | 'blue';
export type Cell = {
color: CellColor | undefined;
};

export type History = {
step: number;
character: Character;
board: Board;
};

export type SolveProblemResult = {
character: Character;
board: Board;
histories: History[] | undefined;
};
63 changes: 63 additions & 0 deletions tests/solveProblem.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { expect, test } from 'vitest';

import { solveProblem, parseProgram } from '../src/app/lib/solveProblem';

test('Parse a program', () => {
const program = `
const character = new Character();
character.moveForward();
character.moveForward();
character.moveForward();
character.moveForward();
character.moveForward();
`;
const parsedProgram = parseProgram(program);

expect(parsedProgram).not.toBeFalsy();
expect(parsedProgram).toEqual([
'const character = new Character();',
'character.moveForward();',
'character.moveForward();',
'character.moveForward();',
'character.moveForward();',
'character.moveForward();',
]);
});

test('Solve a problem', () => {
const problemProgram = `
const character = new Character();
character.moveForward();
character.moveForward();
character.moveForward();
character.moveForward();
character.moveForward();
`;

const answer = solveProblem(problemProgram);

expect(answer).not.toBeFalsy();
expect(answer.character).not.toBeFalsy();
expect(answer.board).not.toBeFalsy();
expect(answer.character.direction).toEqual('down');
expect(answer.character.penDown).toEqual(true);

// prettier-ignore
expect(answer.board.grid).toEqual([
[{ color: 'red' }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }],
[{ color: 'red' }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }],
[{ color: 'red' }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }],
[{ color: 'red' }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }],
[{ color: 'red' }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }],
[{ color: 'red' }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }],
[{ color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }],
[{ color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }],
[{ color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }],
[{ color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }],
[{ color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }],
[{ color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }, { color: undefined }],
]);
expect(answer.histories).not.toBeFalsy();
expect(answer.histories?.at(-1)?.character.x).toEqual(1);
expect(answer.histories?.at(-1)?.character.y).toEqual(6);
});

0 comments on commit 072ad10

Please sign in to comment.