Skip to content

Commit

Permalink
add forest game
Browse files Browse the repository at this point in the history
  • Loading branch information
shubhagarwal1 committed Nov 8, 2024
1 parent 95b2c81 commit 472eeb1
Show file tree
Hide file tree
Showing 5 changed files with 251 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { ProfileDashboardPageComponent } from './components/profile/profile.comp
import { VisualStackQueueComponent } from './components/visual-stack-queue/visual-stack-queue.component';
import { MazeRunnerVisualizerComponent } from './components/maze-runner-visualizer/maze-runner-visualizer.component';
import { TreasureHuntVisualizerComponent } from './components/treasure-hunt-visualizer/treasure-hunt-visualizer.component';
import { ForestExplorerComponent } from './components/forest-explorer/forest-explorer.component';

export const routes: Routes = [
{
Expand Down Expand Up @@ -121,6 +122,10 @@ export const routes: Routes = [
path: 'tresure',
component: TreasureHuntVisualizerComponent,
},
{
path: 'forest',
component: ForestExplorerComponent,
},
// {
// path: 'algo-compare',
// component: AlgorithmComparisonComponent,
Expand Down
79 changes: 79 additions & 0 deletions src/app/components/forest-explorer/forest-explorer.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
.forest-explorer-container {
width: 80%;
margin: auto;
padding: 20px;
background-color: #f9f9f9;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.title {
text-align: center;
font-size: 2em;
margin-bottom: 20px;
}

.controls {
display: flex;
gap: 10px;
align-items: center;
justify-content: center;
margin-bottom: 20px;
}

.buttons {
display: flex;
gap: 10px;
justify-content: center;
margin-bottom: 20px;
}

.grid {
display: flex;
flex-direction: column;
gap: 5px;
margin: auto;
}

.grid-row {
display: flex;
gap: 5px;
}

.grid-cell {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
background-color: white;
border: 1px solid #ddd;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}

.grid-cell.start {
background-color: #00f;
color: white;
}

.grid-cell.visited {
background-color: #b2fab4;
}

.grid-cell.rare {
background-color: #ffb6c1;
}

.stats {
margin-top: 20px;
padding: 10px;
background-color: #f1f1f1;
border-radius: 5px;
}

.stats h3 {
text-align: center;
margin-bottom: 10px;
}
31 changes: 31 additions & 0 deletions src/app/components/forest-explorer/forest-explorer.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<div class="forest-explorer-container">
<h2>Forest Explorer</h2>
<div class="controls">
<label>Grid Size: {{ gridSize.rows }}x{{ gridSize.cols }}</label>
<input type="range" min="5" max="12" [value]="gridSize.rows" (input)="setGridSize($event)"
[disabled]="exploring" />
<label>Speed: {{ speed }}ms</label>
<input type="range" min="50" max="1000" step="50" [value]="speed" (input)="setSpeed($event)"
[disabled]="exploring" />
</div>
<div class="buttons">
<button (click)="explore(startPos.row, startPos.col)" [disabled]="exploring">Explore</button>
<button (click)="initializeForest()" [disabled]="exploring">Reset Forest</button>
</div>
<div class="grid">
<div *ngFor="let row of grid; let rowIndex = index" class="grid-row">
<div *ngFor="let cell of row; let colIndex = index" (click)="handleCellClick(rowIndex, colIndex)" [ngClass]="{
'start': startPos.row === rowIndex && startPos.col === colIndex,
'visited': visitedCells.has(rowIndex + ',' + colIndex),
'rare': cell === treeTypes.RARE
}" class="grid-cell">
{{ cell }}
</div>
</div>
</div>
<div class="stats">
<h3>Exploration Statistics</h3>
<p>Rare Plants Found: {{ stats.plantsFound }}</p>
<p>Cells Explored: {{ stats.cellsExplored }}</p>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ForestExplorerComponent } from './forest-explorer.component';

describe('ForestExplorerComponent', () => {
let component: ForestExplorerComponent;
let fixture: ComponentFixture<ForestExplorerComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ForestExplorerComponent]
})
.compileComponents();

fixture = TestBed.createComponent(ForestExplorerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
113 changes: 113 additions & 0 deletions src/app/components/forest-explorer/forest-explorer.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { CommonModule } from '@angular/common';

interface Position {
row: number;
col: number;
}

@Component({
selector: 'app-forest-explorer',
templateUrl: './forest-explorer.component.html',
styleUrls: ['./forest-explorer.component.css'],
encapsulation: ViewEncapsulation.None,
imports: [CommonModule],
standalone: true,
})
export class ForestExplorerComponent implements OnInit {
gridSize = { rows: 8, cols: 8 };
grid: string[][] = [];
exploring = false;
startPos: Position = { row: 0, col: 0 };
visitedCells = new Set<string>();
speed = 300;
stats = { plantsFound: 0, cellsExplored: 0 };

treeTypes = {
PINE: '🌲',
OAK: '🌳',
EMPTY: '·',
RARE: '🌺',
};

ngOnInit(): void {
this.initializeForest();
}

initializeForest(): void {
this.grid = Array.from({ length: this.gridSize.rows }, () =>
Array.from({ length: this.gridSize.cols }, () => this.getRandomTreeType())
);
this.visitedCells.clear();
this.stats = { plantsFound: 0, cellsExplored: 0 };
}

getRandomTreeType(): string {
const random = Math.random();
if (random < 0.1) return this.treeTypes.RARE;
if (random < 0.4) return this.treeTypes.PINE;
if (random < 0.7) return this.treeTypes.OAK;
return this.treeTypes.EMPTY;
}

async explore(row: number, col: number): Promise<void> {
if (this.exploring) return;
this.exploring = true;
const queue: Position[] = [{ row, col }];

while (queue.length > 0) {
const { row, col } = queue.shift()!;
if (this.isOutOfBounds(row, col) || this.visitedCells.has(`${row},${col}`)) {
continue;
}

this.visitedCells.add(`${row},${col}`);
this.stats.cellsExplored++;
if (this.grid[row][col] === this.treeTypes.RARE) {
this.stats.plantsFound++;
}
await this.delay(this.speed);

const directions = [
[-1, 0],
[1, 0],
[0, -1],
[0, 1],
];
directions.forEach(([dr, dc]) => queue.push({ row: row + dr, col: col + dc }));
}
this.exploring = false;
}

isOutOfBounds(row: number, col: number): boolean {
return row < 0 || row >= this.gridSize.rows || col < 0 || col >= this.gridSize.cols;
}

delay(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}

handleCellClick(row: number, col: number): void {
if (!this.exploring) {
this.startPos = { row, col };
this.visitedCells.clear();
this.stats = { plantsFound: 0, cellsExplored: 0 };
}
}

setGridSize(event: Event): void {
const target = event.target as HTMLInputElement;
if (target) {
this.gridSize.rows = parseInt(target.value, 10);
this.gridSize.cols = parseInt(target.value, 10);
this.initializeForest();
}
}

setSpeed(event: Event): void {
const target = event.target as HTMLInputElement;
if (target) {
this.speed = parseInt(target.value, 10);
}
}
}

0 comments on commit 472eeb1

Please sign in to comment.