-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #553 from shubhagarwal1/tresure
Add tresure hunt game for better understanding of dfs and bfs
- Loading branch information
Showing
5 changed files
with
320 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
src/app/components/treasure-hunt-visualizer/treasure-hunt-visualizer.component.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
|
||
.treasure-hunt-container { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
margin-top: 50px; | ||
padding: 20px; | ||
background: #f9f9f9; | ||
border-radius: 12px; | ||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); | ||
max-width: 1000px; | ||
margin: auto; | ||
margin-top: 7rem; | ||
} | ||
|
||
.title { | ||
font-size: 2em; | ||
color: #333; | ||
margin-bottom: 20px; | ||
} | ||
|
||
.description { | ||
font-size: 1.2em; | ||
color: #555; | ||
margin-bottom: 20px; | ||
text-align: center; | ||
} | ||
|
||
.buttons { | ||
display: flex; | ||
gap: 20px; | ||
margin-bottom: 30px; | ||
} | ||
|
||
.algorithm-button, .reset-button { | ||
padding: 10px 20px; | ||
font-size: 1em; | ||
color: #fff; | ||
background: #007bff; | ||
border: none; | ||
border-radius: 8px; | ||
cursor: pointer; | ||
transition: background 0.3s; | ||
} | ||
|
||
.algorithm-button:hover, .reset-button:hover { | ||
background: #0056b3; | ||
} | ||
|
||
.reset-button { | ||
background: #dc3545; | ||
} | ||
|
||
.reset-button:hover { | ||
background: #c82333; | ||
} | ||
|
||
.treasure-grids { | ||
display: flex; | ||
gap: 20px; | ||
justify-content: center; | ||
flex-wrap: wrap; | ||
} | ||
|
||
.treasure-section { | ||
margin: 20px; | ||
text-align: center; | ||
padding: 20px; | ||
background: #ffffff; | ||
border-radius: 12px; | ||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); | ||
flex: 1; | ||
min-width: 300px; | ||
} | ||
|
||
.info-text { | ||
font-size: 1em; | ||
color: #666; | ||
margin-bottom: 15px; | ||
} | ||
|
||
.treasure-grid { | ||
display: grid; | ||
gap: 5px; | ||
justify-content: center; | ||
} | ||
|
||
.row { | ||
display: flex; | ||
} | ||
|
||
.cell { | ||
width: 30px; | ||
height: 30px; | ||
border: 1px solid #ccc; | ||
transition: background-color 0.3s; | ||
} | ||
|
||
.start { | ||
background-color: #28a745; | ||
border-radius: 4px; | ||
} | ||
|
||
.treasure { | ||
background-color: #ffc107; | ||
border-radius: 4px; | ||
} | ||
|
||
.visited { | ||
background-color: #17a2b8; | ||
} | ||
|
||
.found { | ||
background-color: #6f42c1; | ||
border-radius: 4px; | ||
} |
45 changes: 45 additions & 0 deletions
45
src/app/components/treasure-hunt-visualizer/treasure-hunt-visualizer.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// treasure-hunt-visualizer.component.html | ||
<app-navbar></app-navbar> | ||
<div class="treasure-hunt-container"> | ||
<h2 class="title">Treasure Hunt Visualizer</h2> | ||
<p class="description">Select an algorithm to visualize how it searches for the treasures:</p> | ||
<div class="buttons"> | ||
<button class="algorithm-button" (click)="startDFS()">Start DFS</button> | ||
<button class="algorithm-button" (click)="startBFS()">Start BFS</button> | ||
<button class="reset-button" (click)="reset()">Reset</button> | ||
</div> | ||
|
||
<div class="treasure-grids"> | ||
<div class="treasure-section"> | ||
<h3>Depth-First Search (DFS)</h3> | ||
<p class="info-text">DFS explores as far as possible along each branch, making it a great choice for finding | ||
all treasures but not necessarily the closest one first.</p> | ||
<div class="treasure-grid"> | ||
<div *ngFor="let row of gridDFS; let i = index" class="row"> | ||
<div *ngFor="let cell of row; let j = index" [ngClass]="{ | ||
'start': gridDFS[i][j] === 2, | ||
'treasure': gridDFS[i][j] === 3, | ||
'visited': gridDFS[i][j] === 1, | ||
'found': gridDFS[i][j] === 4 | ||
}" class="cell"></div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div class="treasure-section"> | ||
<h3>Breadth-First Search (BFS)</h3> | ||
<p class="info-text">BFS explores all neighbors at the current depth level before moving on, making it ideal | ||
for finding the closest treasure efficiently.</p> | ||
<div class="treasure-grid"> | ||
<div *ngFor="let row of gridBFS; let i = index" class="row"> | ||
<div *ngFor="let cell of row; let j = index" [ngClass]="{ | ||
'start': gridBFS[i][j] === 2, | ||
'treasure': gridBFS[i][j] === 3, | ||
'visited': gridBFS[i][j] === 1, | ||
'found': gridBFS[i][j] === 4 | ||
}" class="cell"></div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> |
23 changes: 23 additions & 0 deletions
23
src/app/components/treasure-hunt-visualizer/treasure-hunt-visualizer.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
|
||
import { TreasureHuntVisualizerComponent } from './treasure-hunt-visualizer.component'; | ||
|
||
describe('TreasureHuntVisualizerComponent', () => { | ||
let component: TreasureHuntVisualizerComponent; | ||
let fixture: ComponentFixture<TreasureHuntVisualizerComponent>; | ||
|
||
beforeEach(async () => { | ||
await TestBed.configureTestingModule({ | ||
imports: [TreasureHuntVisualizerComponent] | ||
}) | ||
.compileComponents(); | ||
|
||
fixture = TestBed.createComponent(TreasureHuntVisualizerComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
131 changes: 131 additions & 0 deletions
131
src/app/components/treasure-hunt-visualizer/treasure-hunt-visualizer.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
// treasure-hunt-visualizer.component.ts | ||
import { Component, OnInit, ViewEncapsulation } from '@angular/core'; | ||
import { CommonModule } from '@angular/common'; | ||
import { NavbarComponent } from '../navbar/navbar.component'; | ||
|
||
@Component({ | ||
selector: 'app-treasure-hunt-visualizer', | ||
templateUrl: './treasure-hunt-visualizer.component.html', | ||
styleUrls: ['./treasure-hunt-visualizer.component.css'], | ||
encapsulation: ViewEncapsulation.None, | ||
imports: [CommonModule, NavbarComponent], | ||
standalone: true, | ||
}) | ||
export class TreasureHuntVisualizerComponent implements OnInit { | ||
gridDFS: number[][] = []; | ||
gridBFS: number[][] = []; | ||
rows: number = 10; | ||
cols: number = 10; | ||
treasures: [number, number][] = []; | ||
start: [number, number] = [0, 0]; | ||
|
||
ngOnInit(): void { | ||
this.createGrid(); | ||
this.placeTreasures(); | ||
} | ||
|
||
createGrid(): void { | ||
this.gridDFS = Array.from({ length: this.rows }, () => Array(this.cols).fill(0)); | ||
this.gridBFS = Array.from({ length: this.rows }, () => Array(this.cols).fill(0)); | ||
this.gridDFS[this.start[0]][this.start[1]] = 2; // Start point | ||
this.gridBFS[this.start[0]][this.start[1]] = 2; // Start point | ||
} | ||
|
||
placeTreasures(): void { | ||
this.treasures = [ | ||
[2, 3], | ||
[5, 6], | ||
[8, 1], | ||
[3, 7], | ||
]; | ||
this.treasures.forEach(([x, y]) => { | ||
this.gridDFS[x][y] = 3; | ||
this.gridBFS[x][y] = 3; | ||
}); | ||
} | ||
|
||
async dfs(x: number, y: number): Promise<void> { | ||
if (x < 0 || y < 0 || x >= this.rows || y >= this.cols || this.gridDFS[x][y] === 1) { | ||
return; | ||
} | ||
|
||
if (this.gridDFS[x][y] === 3) { | ||
// Found a treasure | ||
this.gridDFS[x][y] = 4; // Mark as found | ||
await this.delay(); | ||
} | ||
|
||
this.gridDFS[x][y] = 1; // Mark as visited | ||
await this.delay(); | ||
|
||
const directions = [ | ||
[0, 1], | ||
[1, 0], | ||
[0, -1], | ||
[-1, 0], | ||
]; | ||
|
||
for (const [dx, dy] of directions) { | ||
await this.dfs(x + dx, y + dy); | ||
} | ||
} | ||
|
||
async bfs(): Promise<void> { | ||
const queue: [number, number][] = [this.start]; | ||
const visited: boolean[][] = Array.from({ length: this.rows }, () => Array(this.cols).fill(false)); | ||
visited[this.start[0]][this.start[1]] = true; | ||
|
||
const directions = [ | ||
[0, 1], | ||
[1, 0], | ||
[0, -1], | ||
[-1, 0], | ||
]; | ||
|
||
while (queue.length > 0) { | ||
const [x, y] = queue.shift()!; | ||
await this.delay(); | ||
|
||
if (this.gridBFS[x][y] === 3) { | ||
// Found a treasure | ||
this.gridBFS[x][y] = 4; // Mark as found | ||
continue; | ||
} | ||
|
||
this.gridBFS[x][y] = 1; // Mark as visited | ||
|
||
for (const [dx, dy] of directions) { | ||
const newX = x + dx; | ||
const newY = y + dy; | ||
|
||
if ( | ||
newX >= 0 && | ||
newY >= 0 && | ||
newX < this.rows && | ||
newY < this.cols && | ||
!visited[newX][newY] | ||
) { | ||
visited[newX][newY] = true; | ||
queue.push([newX, newY]); | ||
} | ||
} | ||
} | ||
} | ||
|
||
delay(): Promise<void> { | ||
return new Promise((resolve) => setTimeout(resolve, 100)); | ||
} | ||
|
||
startDFS(): void { | ||
this.dfs(this.start[0], this.start[1]); | ||
} | ||
|
||
startBFS(): void { | ||
this.bfs(); | ||
} | ||
|
||
reset(): void { | ||
this.createGrid(); | ||
this.placeTreasures(); | ||
} | ||
} |