2 <title>Finite Automata
</title>
4 <b>Your browser does not support JavaScript or JavaScript is disabled.
</b>
15 var stage
= new Array(); /* status of stage - all details stored here */
16 var store
= new Array(); /* status of input */
18 var bit_x
= null; /* location of current bit in grid */
19 var bit_y
= null; /* see above - 0,0 is top left of grid */
21 var stage_rows
= 8; /* number of rows on stage */
22 var stage_cols
= 9; /* number of columns on stage */
23 var store_bit_count
= 10; /* number of bits stored in machine */
25 var input_count
= 10; /* number of input bits */
27 var grid_status
= 1; /* turn grid lines on and off */
28 var grid_size
= 50; /* size in pixels of grid lines - both X and Y */
29 var canvas
; /* object id of canvas tag */
30 var canvas_input
; /* object id of input tag */
32 var ctx
; /* context of canvas */
33 var input
; /* context of input canvas */
35 /* each square on grid has an associated block of data tied to it */
36 function grid(type
, bit
, dir
, col
){
37 this.type
= type
; /* type of machine part */
38 this.bit
= bit
; /* data in this block - if any */
39 this.dir
= dir
; /* direction this item is turned */
40 this.col
= col
; /* color of machine part (if any) */
43 /* this is used to display all bits on all active items */
44 function test_types(){
45 var i
= 0, j
= 0, k
= 1, l
= 2, col
= 1;
46 for(i
= 0; i
< stage_rows
; i
++) {
47 for(j
= 0; j
< stage_rows
; j
++){
50 case 1: stage
[i
][j
].type
= "branch"; break;
51 case 2: stage
[i
][j
].type
= "bus"; break;
52 case 3: stage
[i
][j
].type
= "input"; break;
53 case 4: stage
[i
][j
].type
= "output"; break;
55 stage
[i
][j
].type
= "bitadd";
56 if(col
== 5) { col
= 1; }
58 case 1: stage
[i
][j
].col
= RED
; break;
59 case 2: stage
[i
][j
].col
= GREEN
; break;
60 case 3: stage
[i
][j
].col
= YELLOW
; break;
61 case 4: stage
[i
][j
].col
= BLUE
; break;
69 case 1: stage
[i
][j
].bit
= RED
; break;
70 case 2: stage
[i
][j
].bit
= GREEN
; break;
71 case 3: stage
[i
][j
].bit
= YELLOW
; break;
72 case 4: stage
[i
][j
].bit
= BLUE
; break;
79 /* create all output data structures and draw inital values on screen */
80 function init_stage(){
83 /* create blank grid data structure */
84 for(x
= 0; x
< stage_cols
; x
++) {
85 stage
[x
] = new Array();
86 for(y
= 0; y
< stage_rows
; y
++) {
87 stage
[x
][y
] = new grid('', '', '', '');
90 stage
[5][0].type
= "input";
91 stage
[5][1].type
= "branch";
93 stage
[5][2].type
= "bus";
96 stage
[5][8].type
= "output";
98 stage
[5][3].type
= "output";
99 //stage[5][3].col = "red";
101 stage
[5][4].type
= "bus";
104 stage
[5][1].type
= "bus";
110 /* moves automata to next position */
111 function next_move(){
112 // if input is empty - get next bit
116 // determine what type of machine part we are on
117 switch(stage
[bit_x
][bit_y
].type
){
134 alert("Unknown entity.");
139 function move_getbit(){
140 stage
[5][0].bit
= store
.shift();
143 bit_x
= 5; bit_y
= 0;
146 function move_bitadd(){
147 // TODO: temove this switch statement
148 store
.push(stage
[bit_x
][bit_y
].col
);
149 stage
[bit_x
][bit_y
+1].bit
= stage
[bit_x
][bit_y
].bit
;
150 stage
[bit_x
][bit_y
].bit
= "";
151 draw_tile(bit_x
,bit_y
);
152 draw_tile(bit_x
,bit_y
+1);
157 // determine which direction to move and move there
158 function move_branch(){
159 if(stage
[bit_x
][bit_y
].bit
== BLUE
){
160 stage
[bit_x
+1][bit_y
].bit
= stage
[bit_x
][bit_y
].bit
;
161 stage
[bit_x
][bit_y
].bit
= "";
162 draw_tile(bit_x
,bit_y
);
163 draw_tile(bit_x
+1,bit_y
);
165 } else if (stage
[bit_x
][bit_y
].bit
== RED
){
166 stage
[bit_x
-1][bit_y
].bit
= stage
[bit_x
][bit_y
].bit
;
167 stage
[bit_x
][bit_y
].bit
= "";
168 draw_tile(bit_x
,bit_y
);
169 draw_tile(bit_x
-1,bit_y
);
172 stage
[bit_x
][bit_y
+1].bit
= stage
[bit_x
][bit_y
].bit
;
173 stage
[bit_x
][bit_y
].bit
= "";
174 draw_tile(bit_x
,bit_y
);
175 draw_tile(bit_x
,bit_y
+1);
182 // 1= DOWN; 2= LEFT; 3 = UP; 4 = LEFT
183 switch(stage
[bit_x
][bit_y
].dir
){
197 alert("Unknown bus direction.");
199 stage
[bit_x
+x
][bit_y
+y
].bit
= stage
[bit_x
][bit_y
].bit
;
200 stage
[bit_x
][bit_y
].bit
= "";
201 draw_tile(bit_x
,bit_y
);
202 bit_y
+= y
; bit_x
+= x
;
203 draw_tile(bit_x
,bit_y
);
206 function move_input(){
208 // look for entity next to input.
209 // walk around clockwise until one is found
210 if(stage
[bit_x
][bit_y
+1].type
){
211 stage
[bit_x
][bit_y
+1].bit
= stage
[bit_x
][bit_y
].bit
;
212 stage
[bit_x
][bit_y
].bit
= "";
213 draw_tile(bit_x
,bit_y
);
214 draw_tile(bit_x
,bit_y
+1);
216 } else { alert("Cannot continue: No connection to input."); }
219 // if we are on an output, remove bit and move to an input
220 function move_output(){
221 stage
[bit_x
][bit_y
].bit
= "";
222 draw_tile(bit_x
,bit_y
);
223 bit_x
= null; bit_y
= null;
226 /* set initial values for input */
227 function init_input(){
231 store
.push(GREEN
); /* add to end */
232 //store.unshift("red"); /* add to front */
233 //store.pop(); /* remove from end */
234 //store.shift(); /* remove from front */
237 /* draw faint gridlines on stage - used as a guide for the user */
238 function draw_grid(){
239 var x
, y
; /* current x and y position */
240 var offset
= 10; /* x and y maximum offset (far bottom or side of the window) */
241 ctx
.strokeStyle
= "#ccc";
243 /* draw vertical lines */
244 for(x
= grid_size
, y
= 0, offset
= window
.innerWidth
; x
< window
.innerWidth
; x
= x
+ grid_size
){
247 ctx
.lineTo(x
,y
+offset
);
251 /* draw horizontal lines */
252 for(x
= 0, y
= grid_size
, offset
= window
.innerWidth
; y
< window
.innerWidth
; y
= y
+ grid_size
){
255 ctx
.lineTo(x
+offset
,y
);
262 move through each grid in stage and draw contents.
263 this function can be used to refresh the screen at any time.
265 function draw_stage(){
267 /* loop through all grids on stage, drawing contents */
268 for(x
=0; x
< stage_cols
; x
++){
269 for(y
= 0; y
< stage_rows
; y
++){
275 /* delete item from stage */
276 function stage_delete(){
280 /* add current item to stage at clicked location */
281 function stage_add(){
285 /* select this item as next item to be placed */
286 function stage_select(){
291 function init_form(){
293 /* initalize canvas element for use */
294 canvas
= document
.getElementById("stage");
295 ctx
= canvas
.getContext("2d");
297 canvas_input
= document
.getElementById("input");
298 input
= canvas_input
.getContext("2d");
300 /* get width and height of window and set stage (canvas) with it. */
301 canvas
.height
= window
.innerHeight
-125;
302 canvas
.width
= window
.innerWidth
- 45;
303 if(grid_status
){draw_grid(); }
310 /* returns coordinates of canvas in pixels */
311 function cnvs_get_coordinates(e
){
312 var x_offset
= canvas
.offsetLeft
;
313 var y_offset
= canvas
.offsetTop
;
314 if(canvas
== 'undefined'){ alert("Canvas parameter is undefined"); }
315 x_offset
= e
.clientX
- x_offset
;
316 y_offset
= e
.clientY
- y_offset
;
317 document
.getElementById("xycoordinates").innerHTML
="Coordinates: (" + x_offset
+ "," + y_offset
+ ")";
318 return [x_offset
,y_offset
];
321 /* move through tape and draw bits */
322 function draw_tape(){
323 var i
= 0; var x
= 50;
324 input
.fillStyle
= "#f00";
325 input
.clearRect(0,0,579,100);
326 while(i
< store
.length
){
328 input
.fillStyle
= store
[i
];
329 input
.arc(x
,25,20,0,TWO_PI
,0);
332 input
.strokeStyle
= "#000";
335 input
.arc(x
,25,20,0,TWO_PI
,0);
340 /* icons for each type */
342 input
.translate(0, grid_size
);
344 input
.translate(grid_size
, 0);
346 input
.translate(grid_size
, 0);
348 input
.translate(grid_size
, 0);
349 draw_bitadd(input
, GREEN
);
353 /* (re)draws any map tile on grid */
354 function draw_tile(x
,y
){
356 ctx
.translate(grid_size
* x
, grid_size
* y
);
357 switch (stage
[x
][y
].type
){
359 draw_bitadd(ctx
, stage
[x
][y
].col
);
365 draw_bus(ctx
, stage
[x
][y
].dir
);
373 default: clear_square(ctx
);
375 if(stage
[x
][y
].bit
){ draw_bit(ctx
, stage
[x
][y
].bit
); }
379 function draw_trash(canvas
){
380 canvas
.strokeStyle
= "#000";
381 canvas
.lineCap
= "round";
382 canvas
.lineWidth
= 12;
384 canvas
.moveTo(10,10);
385 canvas
.lineTo(grid_size
-10,grid_size
-10);
388 canvas
.moveTo(10, grid_size
-10);
389 canvas
.lineTo(grid_size
-10, 10);
392 canvas
.strokeStyle
= "#f00";
393 canvas
.lineWidth
= 8;
395 canvas
.moveTo(10,10);
396 canvas
.lineTo(grid_size
-10,grid_size
-10);
399 canvas
.moveTo(10, grid_size
-10);
400 canvas
.lineTo(grid_size
-10, 10);
404 /* draws small bit of correct color on grid */
405 function draw_bit(canvas
, color
){
406 canvas
.fillStyle
= "#f00";
408 canvas
.fillStyle
= color
;
409 canvas
.arc(25,25,10,0,TWO_PI
,0);
412 canvas
.strokeStyle
= "#000";
413 canvas
.lineWidth
= 2;
415 canvas
.arc(25,25,10,0,TWO_PI
,0);
419 /* draw gray square with black outline */
420 function draw_input(canvas
){
421 canvas
.lineWidth
= 1;
422 canvas
.strokeStyle
= "#000";
423 canvas
.strokeRect(0,0,grid_size
,grid_size
);
424 canvas
.fillStyle
= "#aaa";
425 canvas
.fillRect(0,0,grid_size
,grid_size
);
428 function drawSpirograph(ctx
,R
,r
,O
){
436 var x2
= (R
+r
)*Math
.cos(i
*Math
.PI
/72) - (r+O)*Math.cos(((R+r)/r
)*(i
*Math
.PI
/72))
437 var y2
= (R
+r
)*Math
.sin(i
*Math
.PI
/72) - (r+O)*Math.sin(((R+r)/r
)*(i
*Math
.PI
/72))
442 } while (x2
!= R
-O
&& y2
!= 0 );
446 function draw_output(canvas
){
447 canvas
.fillStyle
= "#fff";
448 canvas
.fillRect(2,2,grid_size
-2,grid_size
-2); /* clear grid */
450 canvas
.translate(grid_size
/2,grid_size/2);
451 canvas
.strokeStyle
= "#d80";
452 canvas
.lineWidth
= 2;
453 drawSpirograph(canvas
,9,2,7);
454 canvas
.translate(-(grid_size
/2),-(grid_size/2));
457 /* a bus moves bits from one location to another */
458 function draw_bus(canvas
, dir
){
461 canvas
.fillStyle
= "#fff";
462 canvas
.fillRect(2,2,grid_size
-2,grid_size
-2); /* clear grid */
464 canvas
.lineWidth
= 2;
465 canvas
.fillStyle
= "#aaa";
466 canvas
.strokeStyle
= "#000";
470 canvas
.translate(grid_size
,0);
474 canvas
.translate(grid_size
,grid_size
);
478 canvas
.translate(0,grid_size
);
479 canvas
.rotate(-PI
/2);
484 if(i
== 1) { canvas
.save(); canvas
.translate(0, grid_size
/2); }
487 canvas
.lineTo(grid_size
/2,grid_size/2);
488 canvas
.lineTo(grid_size
,0);
489 canvas
.lineTo(grid_size
/2,grid_size/4);
495 canvas
.lineTo(grid_size
/2,grid_size/2);
496 canvas
.lineTo(grid_size
,0);
497 canvas
.lineTo(grid_size
/2,grid_size/4);
500 if(i
== 1) { canvas
.restore(); }
505 /* tiles branch movement of each bit */
506 function draw_branch(canvas
){
508 canvas
.lineWidth
= 1;
509 canvas
.fillStyle
= "#f00";
512 canvas
.lineTo(grid_size
/2,grid_size/2);
513 canvas
.lineTo(0,grid_size
);
518 canvas
.fillStyle
= "#000";
521 canvas
.lineTo(grid_size
/2,grid_size/2);
522 canvas
.lineTo(grid_size
,0);
528 canvas
.fillStyle
= "#00f";
530 canvas
.moveTo(grid_size
,0);
531 canvas
.lineTo(grid_size
/2,grid_size/2);
532 canvas
.lineTo(grid_size
,grid_size
);
537 canvas
.fillStyle
= "#aaa";
539 canvas
.moveTo(0,grid_size
)
540 canvas
.lineTo(grid_size
/2,grid_size/2);
541 canvas
.lineTo(grid_size
,grid_size
);
546 function draw_bitadd(canvas
, color
){
550 canvas
.strokeStyle
= color
;
551 canvas
.lineWidth
= 10;
553 canvas
.strokeStyle
= "#000";
554 canvas
.lineWidth
= 15;
557 canvas
.moveTo(grid_size
/2,0);
558 canvas
.lineTo(grid_size
/2,grid_size
);
563 canvas
.moveTo(0, grid_size
/2);
564 canvas
.lineTo(grid_size
,grid_size
/2);
569 canvas
.strokeStyle
= "#000";
570 canvas
.lineWidth
= 1;
573 canvas
.lineTo(0,grid_size
);
574 canvas
.lineTo(grid_size
,grid_size
);
575 canvas
.lineTo(grid_size
,0);
581 /* clear this square by setting area to white */
582 function clear_square(canvas
){
583 canvas
.fillStyle
= "#fff";
584 canvas
.fillRect(1,1,grid_size
-2,grid_size
-2);
587 /* canvas has been clicked find out which grid and make correct change to square if needed. */
588 function cnvs_clicked(e
){}
592 <style type=
"text/css">
596 <body onLoad=
"init_form();">
598 <div id=
"topsection">
601 <button onClick='reset();'
><img src=
"http://opentextbook.info/icons/32x32/resultset_first.png" title=
"Restart" alt=
"Restart"></button>
603 <button onClick='step_back();'
><img src=
"http://opentextbook.info/icons/32x32/resultset_previous.png" title=
"Step Back" alt=
"Step Back"></button>
605 <button onClick='next_move();'
><img src=
"http://opentextbook.info/icons/32x32/resultset_next.png" title=
"Next Step" alt=
"Next Step"></button>
607 <button onClick='run();'
><img src=
"http://opentextbook.info/icons/32x32/resultset_last.png" title=
"Run" alt=
"Run"></button>
611 <button onClick='halt();'><img src="http://opentextbook.info/icons/32x32/cancel.png" title="Halt Execution" alt="Halt Execution"></button>
614 <button disabled><img src="http://opentextbook.info/icons/32x32/disk.png" title="Save Code" alt="Save Code"></button>
616 <button onClick='display_docs();'><img src="http://opentextbook.info/icons/32x32/book_open.png" title="Open Documentation" alt="Open Documentation"></button>
622 <div id=
"xycoordinates">Coordinates:
</div>
623 <canvas id=
"input" width=
"579" height=
"120"></canvas>
624 <canvas id=
"stage" width=
"579" height=
"770" onmousemove=
"cnvs_get_coordinates(event)" onclick=
"cnvs_clicked(event);">
625 Your browser does not support HTML5 Canvas.