-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathknight.js
156 lines (148 loc) · 5.03 KB
/
knight.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Knight function holds all the data for a knight entity
function Knight(chromosome) {
// initialize the knight entity
// x, y holds the current knight position (currently pre-set to 0,0)
this.x=0;
this.y=0;
this.steps=0;
// use existing cross over parent chromosome if it does exist
if(chromosome) {
this.chromosome = chromosome;
}
else {
// initialize a new random chromosome
this.chromosome = new Chromosome();
}
// initialize variables
this.path = [];
this.fitness = 0;
// the first path will start on (0, 0)
this.path.push(createVector(this.x, this.y));
// findForward will determine how the knight cycles possible steps to fix illegal moves
this.findForward = boolean(Math.round(random(1)));
// calcFitness goes through the paths and adds the fitness value until it reaches an invalid move
this.calcFitness = function() {
// default state for legal is true
legal=true;
this.fitness = 0;
// loops through paths taken by the knight
for(var i = 0; i<this.path.length; i++) {
// check whether the knight is outside of the board
if(this.path[i].x<0 || this.path[i].x>cols-1 || this.path[i].y<0 || this.path[i].y>cols-1) {
legal=false;
}
// check whether the current square has been visited before
for(var j=0; j<i; j++) {
if(this.path[i].x == this.path[j].x && this.path[i].y == this.path[j].y) {
legal=false;
}
}
// return when we have found an illegal move
if(!legal) {
return
}
// increment fitness value
this.fitness++;
}
}
// move forward holds the possible moves of a knight in all direction
this.moveForward = function(direction) {
switch(direction) {
case 1: this.x+=1; this.y-=2; break;
case 2: this.x+=2; this.y-=1; break;
case 3: this.x+=2; this.y+=1; break;
case 4: this.x+=1; this.y+=2; break;
case 5: this.x-=1; this.y+=2; break;
case 6: this.x-=2; this.y+=1; break;
case 7: this.x-=2; this.y-=1; break;
case 8: this.x-=1; this.y-=2; break;
}
}
// trace back a move
this.traceBack = function(direction) {
switch(direction) {
case 1: this.x-=1; this.y+=2; break;
case 2: this.x-=2; this.y+=1; break;
case 3: this.x-=2; this.y-=1; break;
case 4: this.x-=1; this.y-=2; break;
case 5: this.x+=1; this.y-=2; break;
case 6: this.x+=2; this.y-=1; break;
case 7: this.x+=2; this.y+=1; break;
case 8: this.x+=1; this.y+=2; break;
}
}
// move the knight given its current turn
this.move = function() {
// set default variables
legal=false;
limit = 0
// we check if the move is either illegal or havent cycled through all of the possible moves
// if we can't find a legal move, we continue
while(!legal && limit++<8) {
this.moveForward(this.chromosome.genes[this.steps]);
if((this.x>=0 && this.x<cols) && (this.y>=0 && this.y<cols)) {
legal=true;
for(var i=0; i<this.path.length; i++) {
if((this.path[i].x==this.x) && (this.path[i].y==this.y)){
legal=false;
}
}
}
// if the last move was illegal, attempt to trace back
if(!legal) {
this.traceBack(this.chromosome.genes[this.steps]);
if(this.findForward) {
this.chromosome.genes[this.steps] = (this.chromosome.genes[this.steps]%8)+1;
}
else {
this.chromosome.genes[this.steps] = ((this.chromosome.genes[this.steps]+6)%8)+1;
}
}
}
// add the last move's coordinates to the knight's path array
this.path[this.steps+1] = createVector(this.x, this.y);
// increment the number of steps taken by the knight
this.steps++;
}
// show function is used to display the knight's moves on the board
// the moves will be displayed until an illegal move is encountered.
this.show = function() {
legal=true;
noStroke();
for(var i=0; i < this.path.length; i++) {
if(this.path[i].x<0 || this.path[i].x>cols-1 || this.path[i].y<0 || this.path[i].y>cols-1) {
legal=false;
}
for(var j=0; j<i; j++) {
if(this.path[i].x == this.path[j].x && this.path[i].y == this.path[j].y) {
legal=false;
}
}
if(legal) {
fill(0,255,0,150);
}
else {
fill(255,0,0,150);
}
rect(this.path[i].x*scl,this.path[i].y*scl, scl, scl);
fill(0,255,0);
ellipse(this.path[i].x*scl+scl/2, this.path[i].y*scl+scl/2, scl/6, scl/6);
fill(255);
text(i+1, this.path[i].x*scl,this.path[i].y*scl, scl, scl);
}
strokeWeight(scl/20);
stroke(0,255,0);
noFill();
beginShape();
for(var i = 0; i < this.path.length; i++) {
for(var j=0; j < i; j++) {
if((this.path[i].x === this.path[j].x) && (this.path[i].y === this.path[j].y)) {
legal=false;
}
}
vertex(this.path[i].x*scl+scl/2,this.path[i].y*scl+scl/2);
}
endShape();
chromosomes.html(this.chromosome.genes);
}
}