Skip to content

Commit 91c8aeb

Browse files
committed
changes states & make statistical dashboard
1 parent c7463ff commit 91c8aeb

File tree

2 files changed

+181
-71
lines changed

2 files changed

+181
-71
lines changed

src/App.js

Lines changed: 157 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import { GAME_WIDTH, GAME_HEIGHT, BIRD_COUNT, PIPE_DISTANCE, GAME_SPEED, PIPE_WI
66
import Pipe from './components/pipe'
77
import Bird from './components/bird'
88

9+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
10+
import { faRecordVinyl, faDove, faAward, faChevronCircleRight } from '@fortawesome/free-solid-svg-icons'
11+
import { faEarlybirds } from '@fortawesome/free-brands-svg-icons'
12+
13+
914

1015
class Game extends Component {
1116

@@ -16,10 +21,10 @@ class Game extends Component {
1621
birds
1722

1823
// Find best bird and train others
19-
bestBird1
20-
bestBird2
24+
bestBirds
2125

2226
//
27+
loopNumber
2328
frameCount
2429
state
2530

@@ -34,13 +39,19 @@ class Game extends Component {
3439
constructor(props) {
3540
super(props)
3641

42+
this.loopNumber = 0
3743
this.recordFlyTime = -1
44+
this.bestBirds = []
3845

3946
this.state = {
4047
gameSpeed: GAME_SPEED,
4148
birdCount: BIRD_COUNT,
4249
pipeWidth: PIPE_WIDTH,
43-
pipeDistance: PIPE_DISTANCE
50+
pipeDistance: PIPE_DISTANCE,
51+
bestBirds: [],
52+
recordFlyTime: 0,
53+
currentFlyTime: 0,
54+
loopNumber: 0
4455
}
4556
}
4657

@@ -59,12 +70,19 @@ class Game extends Component {
5970

6071
this.pipeIndex = 0
6172
this.frameCount = 0
73+
this.loopNumber += 1
74+
75+
// set current best fly time
76+
this.setState({
77+
currentFlyTime: 0,
78+
loopNumber: this.loopNumber
79+
})
6280
}
6381

6482
// Restart Game
6583
restart() {
6684
this.reset()
67-
85+
6886
// generate birds before starting
6987
this.generateBirds()
7088

@@ -102,23 +120,35 @@ class Game extends Component {
102120
// if all birds are dead
103121
if(aliveBirds.length === 0) {
104122
// sort all dead birds by fly time and take best bird
105-
this.birds.forEach(bird => {
106-
if(this.recordFlyTime < bird.flyTime) {
107-
this.recordFlyTime = bird.flyTime
108-
this.bestBird2 = this.bestBird1
109-
this.bestBird1 = bird
110-
}
123+
this.birds.push(this.bestBirds)
124+
this.birds.sort((a, b) => a.flyTime < b.flyTime)
125+
126+
this.bestBirds = []
127+
for(let i = 0; i < 4; i++) {
128+
this.bestBirds.push(this.birds[i])
129+
}
130+
131+
console.log(this.bestBirds)
132+
this.setState({
133+
recordFlyTime: this.birds[0].flyTime,
134+
bestBirds: this.bestBirds
111135
})
112136

137+
// reset unnecessary data
113138
this.reset()
114139

115140
// make mutation using best bird brain
116-
this.bestBird1.mutate()
141+
this.bestBirds[0].mutate()
117142
// generate new birds using best bird
118-
this.generateBirds(this.bestBird1, this.bestBird2)
143+
this.generateBirds(this.bestBirds)
119144

120145
// start game and train again
121146
this.start()
147+
} else {
148+
// set current best fly time
149+
this.setState({
150+
currentFlyTime: aliveBirds[0].flyTime
151+
})
122152
}
123153
}
124154

@@ -127,9 +157,9 @@ class Game extends Component {
127157
this.birds = []
128158
for(let i=0; i<this.state.birdCount; i++) {
129159
if(bestBirds && bestBirds.length && Math.random() < 0.8) {
130-
this.birds.push(new Bird(bestBirds[i%bestBirds.length].brain))
160+
this.birds.push(new Bird(i+1, this.loopNumber, bestBirds[i%bestBirds.length].brain))
131161
} else {
132-
this.birds.push(new Bird())
162+
this.birds.push(new Bird(i+1, this.loopNumber))
133163
}
134164
}
135165
}
@@ -165,75 +195,132 @@ class Game extends Component {
165195
render() {
166196
return (
167197
<div className="App">
168-
<h1>FlappyBird - Self Learning</h1>
169-
<div className="Game">
170-
<div className="Game-left">
171-
<section>
172-
<h2>Statistics</h2>
173-
<div>
174-
<h3>Record</h3>
175-
<p>Best: <span>{this.state.gameSpeed}</span></p>
176-
<p>Current: <span>{this.state.gameSpeed}</span></p>
177-
</div>
178-
<div>
179-
<h3>Best Bird 1</h3>
180-
<p>ID: <span>{this.state.gameSpeed}</span></p>
181-
<p>Fly Time: <span>{this.state.gameSpeed}</span></p>
198+
<div className="App-header">
199+
<div className="site-logo container">
200+
<div className="logo">
201+
<FontAwesomeIcon icon={faDove} />
202+
</div>
203+
<h2>FlappyBird - Self Learning</h2>
204+
</div>
205+
</div>
206+
<div className="App-content container">
207+
<section className="statistics">
208+
<div className="card">
209+
<div className="card-header">
210+
<h2>Statistics</h2>
182211
</div>
183-
<div>
184-
<h3>Best Bird 2</h3>
185-
<p>ID: <span>{this.state.gameSpeed}</span></p>
186-
<p>Fly Time: <span>{this.state.gameSpeed}</span></p>
212+
<div className="card-body">
213+
<div className="card-item">
214+
<h3>Loop Number</h3>
215+
<div>
216+
<div className="item-icon txt-info">
217+
<FontAwesomeIcon icon={faChevronCircleRight} />
218+
</div>
219+
<div className="item-data">
220+
<p>Loop: <span>{this.state.loopNumber}</span></p>
221+
</div>
222+
</div>
223+
</div>
224+
<div className="card-item">
225+
<h3>Record</h3>
226+
<div>
227+
<div className="item-icon txt-primary">
228+
<FontAwesomeIcon icon={faRecordVinyl} />
229+
</div>
230+
<div className="item-data">
231+
<p>Best: <span>{this.state.recordFlyTime}</span></p>
232+
<p>Current: <span>{this.state.currentFlyTime}</span></p>
233+
</div>
234+
{ this.state.currentFlyTime > this.state.recordFlyTime ? (
235+
<div className="record-icon txt-success">
236+
<FontAwesomeIcon icon={faAward} />
237+
</div>
238+
) : ( <span></span> )
239+
}
240+
</div>
241+
</div>
242+
{ this.state.bestBirds.map(function(bird,index) {
243+
return (
244+
<div className="card-item">
245+
<h3>Best Bird {index+1}</h3>
246+
<div>
247+
<div className="item-icon txt-info">
248+
<FontAwesomeIcon icon={faEarlybirds} />
249+
</div>
250+
<div className="item-data">
251+
<p>Name: <span>{bird ? bird.getName() : ""}</span></p>
252+
<p>Current: <span>{bird.flyTime}</span></p>
253+
</div>
254+
</div>
255+
</div>
256+
);
257+
}) }
187258
</div>
188-
</section>
189-
</div>
190-
<div className="Game-center">
191-
<React.Fragment>
192-
<canvas id="gameCanvas" width={GAME_WIDTH} height={GAME_HEIGHT} className="Game-canvas">
259+
</div>
260+
</section>
261+
<section className="game-panel">
262+
<div className="card-game">
263+
<canvas id="gameCanvas" width={GAME_WIDTH} height={GAME_HEIGHT} className="game-canvas">
193264
Your browser does not support the HTML canvas tag.
194265
</canvas>
195-
</React.Fragment>
196-
<section>
197-
<h2>Live Configuration</h2>
198-
<div>
199-
<div>
200-
<h3>Game Speed</h3>
201-
<p>{this.state.gameSpeed}</p>
202-
<input type="range" min="10" max="300"
203-
value={this.state.gameSpeed}
204-
onChange={this.changeGameSpeed}/>
266+
</div>
267+
<div className="live-confg">
268+
<div className="card">
269+
<div className="card-header">
270+
<h2>Game Speed</h2>
271+
</div>
272+
<div className="card-body">
273+
<div className="card-item">
274+
<p>{this.state.gameSpeed}</p>
275+
<input type="range" min="10" max="300"
276+
value={this.state.gameSpeed}
277+
onChange={this.changeGameSpeed}/>
278+
</div>
205279
</div>
206280
</div>
207-
</section>
208-
</div>
209-
<div className="Game-right">
210-
<section>
211-
<h2>Initial Configuration</h2>
212-
<div>
213-
<div>
281+
</div>
282+
</section>
283+
<section className="configurations">
284+
<div className="card">
285+
<div className="card-header">
286+
<h2>Configuration</h2>
287+
</div>
288+
<div className="card-body">
289+
<div className="card-item">
214290
<h3>Bird Count</h3>
215-
<p>{this.state.birdCount}</p>
216-
<input type="number" value=
217-
{this.state.birdCount}
218-
onChange={this.changeBirdCount}/>
291+
<div>
292+
<p>{this.state.birdCount}</p>
293+
<input type="number" value=
294+
{this.state.birdCount}
295+
onChange={this.changeBirdCount}/>
296+
</div>
219297
</div>
220-
<div>
298+
<div className="card-item">
221299
<h3>Pipe Width</h3>
222-
<p>{this.state.pipeWidth}</p>
223-
<input type="range" min="10" max="80"
224-
value={this.state.pipeWidth}
225-
onChange={this.changePipeWidth}/>
300+
<div>
301+
<p>{this.state.pipeWidth}</p>
302+
<input type="range" min="10" max="80"
303+
value={this.state.pipeWidth}
304+
onChange={this.changePipeWidth}/>
305+
</div>
226306
</div>
227-
<div>
307+
<div className="card-item">
228308
<h3>Pipe Distance</h3>
229-
<p>{this.state.pipeDistance}</p>
230-
<input type="range" min="40" max="240"
231-
value={this.state.pipeDistance}
232-
onChange={this.changePipeDistance}/>
309+
<div>
310+
<p>{this.state.pipeDistance}</p>
311+
<input type="range" min="40" max="240"
312+
value={this.state.pipeDistance}
313+
onChange={this.changePipeDistance}/>
314+
</div>
315+
</div>
316+
<div className="card-item">
317+
<div>
318+
<button className="btn bg-primary txt-white">Restart Game</button>
319+
</div>
233320
</div>
234321
</div>
235-
</section>
236-
</div>
322+
</div>
323+
</section>
237324
</div>
238325
</div>
239326
);

src/components/bird.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,15 @@ class Bird extends Component {
1616
brain
1717
flyTime
1818

19-
constructor(brain) {
19+
ID
20+
genID
21+
22+
constructor(ID, genID, brain) {
2023
super()
2124

25+
this.ID = ID
26+
this.genID = genID
27+
2228
this.posX = (Math.random() * 400) + PADDING_SIZE
2329
this.posY = (Math.random() * 100) + PADDING_SIZE
2430
this.isOut = false
@@ -35,6 +41,23 @@ class Bird extends Component {
3541
// this.brain = brain || new NeuralNetwork(6, 10, 2)
3642
}
3743

44+
getName = () => {
45+
console.log(this.genID)
46+
var name = 'G' + this.addZero(this.genID, 4)
47+
name = name + 'N' + this.addZero(this.ID, 4)
48+
49+
return name;
50+
}
51+
52+
addZero = (number, length) => {
53+
var my_string = '' + number;
54+
while (my_string.length < length) {
55+
my_string = '0' + my_string;
56+
}
57+
58+
return my_string;
59+
}
60+
3861
draw = (ctx) => {
3962
if(this.isOut || this.isDead) return
4063

0 commit comments

Comments
 (0)