Refactored canvas clicked function.
[CS-101.git] / finite_automata.html
blobc8e163bb269046bd9c2d029e937896d35ab19906
1 <html>
2 <title>Finite Automata</title>
3 <noscript>
4 <b>Your browser does not support JavaScript or JavaScript is disabled.</b>
5 </noscript>
6 <script>
7 var PI = 3.141592654;
8 var TWO_PI = PI * 2;
10 var BLACK = "#000";
11 var BLUE = "#00f";
12 var GRAY = "#aaa";
13 var GREEN = "#0f0";
14 var RED = "#f00";
15 var YELLOW = "#ff0";
17 var stage = new Array(); /* status of stage - all details stored here */
18 var store = new Array(); /* status of input */
20 var bit_x = null; /* location of current bit in grid */
21 var bit_y = null; /* see above - 0,0 is top left of grid */
23 var stage_rows = 8; /* number of rows on stage */
24 var stage_cols = 9; /* number of columns on stage */
25 var store_bit_count = 10; /* number of bits stored in machine */
27 var input_count = 10; /* number of input bits */
29 var grid_status = 1; /* turn grid lines on and off */
30 var grid_size = 50; /* size in pixels of grid lines - both X and Y */
31 var cont_selected = null; /* current tool selected */
32 var cont_direction = null; /* direction of current tool */
34 var canvas; /* object id of canvas tag */
35 var canvas_input; /* object id of input tag */
36 var canvas_control; /* object id of control tag */
38 var control_panel = new panel("del", GREEN, '1', '1', '1');
40 var ctx; /* context of canvas */
41 var input; /* context of input canvas */
42 var control; /* context of control canvas */
44 function panel(selected, bitadd_col, branch_rb_dir, branch_yg_dir, bus_dir){
45 this.selected = selected; /* current machine part selected */
46 this.bitadd_col = bitadd_col; /* color of bitadd in control panel */
47 this.branch_rb_dir = branch_rb_dir; /* direction of red blue branch in control panel */
48 this.branch_yg_dir = branch_yg_dir;
49 this.bus_dir = bus_dir;
52 /* each square on grid has an associated block of data tied to it */
53 function grid(type, bit, dir, col){
54 this.type = type; /* type of machine part */
55 this.bit = bit; /* data in this block - if any */
56 this.dir = dir; /* direction this item is turned */
57 this.col = col; /* color of machine part (if any) */
60 /* this is used to display all bits on all active items */
61 function test_types(){
62 var i = 0, j = 0, k = 1, l = 2, col = 1;
63 for(i = 0; i < stage_rows; i++) {
64 for(j = 0; j < stage_rows; j++){
65 if(k == 6) { k = 1; }
66 switch(k){
67 case 1: stage[i][j].type = "branch"; break;
68 case 2: stage[i][j].type = "bus"; break;
69 case 3: stage[i][j].type = "input"; break;
70 case 4: stage[i][j].type = "output"; break;
71 case 5:
72 stage[i][j].type = "bitadd";
73 if(col == 5) { col = 1; }
74 switch(col){
75 case 1: stage[i][j].col = RED; break;
76 case 2: stage[i][j].col = GREEN; break;
77 case 3: stage[i][j].col = YELLOW; break;
78 case 4: stage[i][j].col = BLUE; break;
80 col++;
81 break;
83 k++;
84 if(l == 5) { l = 1; }
85 switch(l){
86 case 1: stage[i][j].bit = RED; break;
87 case 2: stage[i][j].bit = GREEN; break;
88 case 3: stage[i][j].bit = YELLOW; break;
89 case 4: stage[i][j].bit = BLUE; break;
91 l++;
96 /* create all output data structures and draw inital values on screen */
97 function init_stage(){
98 var x; var y;
100 /* create blank grid data structure */
101 for(x = 0; x < stage_cols; x++) {
102 stage[x] = new Array();
103 for(y = 0; y < stage_rows; y++) {
104 stage[x][y] = new grid('', '', '', '');
107 stage[5][0].type = "input";
108 stage[5][8].type = "output";
109 //test_types();
112 /* moves automata to next position */
113 function next_move(){
114 // if input is empty - get next bit
115 if(!bit_x){
116 move_getbit();
117 } else {
118 // determine what type of machine part we are on
119 switch(stage[bit_x][bit_y].type){
120 case "bitadd":
121 move_bitadd();
122 break;
123 case "branch":
124 move_branch();
125 break;
126 case "bus":
127 move_bus();
128 break;
129 case "input":
130 move_input();
131 break;
132 case "output":
133 move_output();
134 break;
135 default:
136 alert("Unknown entity.");
141 function move_getbit(){
142 stage[5][0].bit = store.shift();
143 draw_tape();
144 draw_tile(5,0);
145 bit_x = 5; bit_y = 0;
148 function move_bitadd(){
149 // TODO: temove this switch statement
150 store.push(stage[bit_x][bit_y].col);
151 stage[bit_x][bit_y+1].bit = stage[bit_x][bit_y].bit;
152 stage[bit_x][bit_y].bit = "";
153 draw_tile(bit_x,bit_y);
154 draw_tile(bit_x,bit_y+1);
155 draw_tape();
156 bit_y++;
159 // determine which direction to move and move there
160 function move_branch(){
161 if(stage[bit_x][bit_y].bit == BLUE){
162 stage[bit_x+1][bit_y].bit = stage[bit_x][bit_y].bit;
163 stage[bit_x][bit_y].bit = "";
164 draw_tile(bit_x,bit_y);
165 draw_tile(bit_x+1,bit_y);
166 bit_x++;
167 } else if (stage[bit_x][bit_y].bit == RED){
168 stage[bit_x-1][bit_y].bit = stage[bit_x][bit_y].bit;
169 stage[bit_x][bit_y].bit = "";
170 draw_tile(bit_x,bit_y);
171 draw_tile(bit_x-1,bit_y);
172 bit_x--;
173 } else {
174 stage[bit_x][bit_y+1].bit = stage[bit_x][bit_y].bit;
175 stage[bit_x][bit_y].bit = "";
176 draw_tile(bit_x,bit_y);
177 draw_tile(bit_x,bit_y+1);
178 bit_y++;
182 function move_bus(){
183 var x = 0, y = 0;
184 // 1= DOWN; 2= LEFT; 3 = UP; 4 = LEFT
185 switch(stage[bit_x][bit_y].dir){
186 case 1:
187 y++;
188 break;
189 case 2:
190 x--;
191 break;
192 case 3:
193 y--;
194 break;
195 case 4:
196 x++;
197 break;
198 default:
199 alert("Unknown bus direction.");
201 stage[bit_x+x][bit_y+y].bit = stage[bit_x][bit_y].bit;
202 stage[bit_x][bit_y].bit = "";
203 draw_tile(bit_x,bit_y);
204 bit_y += y; bit_x += x;
205 draw_tile(bit_x,bit_y);
208 function move_input(){
209 var i, j;
210 // look for entity next to input.
211 // walk around clockwise until one is found
212 if(stage[bit_x][bit_y+1].type){
213 stage[bit_x][bit_y+1].bit = stage[bit_x][bit_y].bit;
214 stage[bit_x][bit_y].bit = "";
215 draw_tile(bit_x,bit_y);
216 draw_tile(bit_x,bit_y+1);
217 bit_y++;
218 } else { alert("Cannot continue: No connection to input."); }
221 // if we are on an output, remove bit and move to an input
222 function move_output(){
223 stage[bit_x][bit_y].bit = "";
224 draw_tile(bit_x,bit_y);
225 bit_x = null; bit_y = null;
228 /* set initial values for input */
229 function init_input(){
230 store.push(RED);
231 store.push(BLUE);
232 store.push(YELLOW);
233 store.push(GREEN); /* add to end */
234 //store.unshift("red"); /* add to front */
235 //store.pop(); /* remove from end */
236 //store.shift(); /* remove from front */
239 /* draw faint gridlines on stage - used as a guide for the user */
240 function draw_grid(){
241 var x, y; /* current x and y position */
242 var offset = 10; /* x and y maximum offset (far bottom or side of the window) */
243 ctx.strokeStyle = "#ccc";
244 ctx.lineWidth = 1;
245 /* draw vertical lines */
246 for(x = grid_size, y = 0, offset = window.innerWidth; x < window.innerWidth; x = x + grid_size){
247 ctx.beginPath();
248 ctx.moveTo(x,y);
249 ctx.lineTo(x,y+offset);
250 ctx.stroke();
251 stage_cols++;
253 /* draw horizontal lines */
254 for(x = 0, y = grid_size, offset = window.innerWidth; y < window.innerWidth; y = y + grid_size){
255 ctx.beginPath();
256 ctx.moveTo(x,y);
257 ctx.lineTo(x+offset,y);
258 ctx.stroke();
259 stage_rows++;
264 move through each grid in stage and draw contents.
265 this function can be used to refresh the screen at any time.
267 function draw_stage(){
268 var x; var y;
269 /* loop through all grids on stage, drawing contents */
270 for(x=0; x < stage_cols; x++){
271 for(y = 0; y < stage_rows; y++){
272 draw_tile(x,y);
277 /* delete item from stage */
278 function stage_delete(){
282 /* add current item to stage at clicked location */
283 function stage_add(){
287 /* select this item as next item to be placed */
288 function stage_select(){
293 function init_form(){
294 var x; var y;
295 /* initalize canvas element for use */
296 canvas = document.getElementById("stage");
297 ctx = canvas.getContext("2d");
299 canvas_input = document.getElementById("input");
300 input = canvas_input.getContext("2d");
302 canvas_control = document.getElementById("control");
303 control = canvas_control.getContext("2d");
305 /* get width and height of window and set stage (canvas) with it. */
306 canvas.height = window.innerHeight-125;
307 canvas.width = window.innerWidth - 45;
308 if(grid_status){draw_grid(); }
309 init_stage();
310 draw_stage();
311 init_input();
312 draw_tape();
313 draw_control();
316 /* returns coordinates of canvas in pixels */
317 function cnvs_get_coordinates(canvas, e){
318 var x_offset = canvas.offsetLeft;
319 var y_offset = canvas.offsetTop;
320 if(canvas == 'undefined'){ alert("Canvas parameter is undefined"); }
321 x_offset = e.clientX - x_offset;
322 y_offset = e.clientY - y_offset;
323 //document.getElementById("xycoordinates").innerHTML="Coordinates: (" + x_offset + "," + y_offset + ")";
324 return [x_offset,y_offset];
327 /* canvas has been clicked find out which grid and make correct change to square if needed. */
328 function cont_clicked(e){
329 var coords = cnvs_get_coordinates(canvas_control, e);
330 var x_pos = Math.floor(coords[0] / grid_size);
331 var y_pos = Math.floor(coords[1] / grid_size);
332 //alert(x_pos + "," + y_pos);
334 // bit add
335 if(x_pos >= 12 && x_pos <= 14){
336 control_panel.selected = "bitadd";
337 if(x_pos == 13 && y_pos == 2){ control_panel.bitadd_col = GREEN; }
338 if(x_pos == 12 && y_pos == 1){ control_panel.bitadd_col = BLUE; }
339 if(x_pos == 13 && y_pos == 0){ control_panel.bitadd_col = YELLOW; }
340 if(x_pos == 14 && y_pos == 1){ control_panel.bitadd_col = RED; }
343 // branch (red and blue)
344 if(x_pos >= 6 && x_pos <= 8){
345 control_panel.selected = "branch_rb";
346 if(x_pos == 7 && y_pos == 2){ control_panel.branch_rb_dir = 1; }
347 if(x_pos == 6 && y_pos == 1){ control_panel.branch_rb_dir = 2; }
348 if(x_pos == 7 && y_pos == 0){ control_panel.branch_rb_dir = 3; }
349 if(x_pos == 8 && y_pos == 1){ control_panel.branch_rb_dir = 4; }
352 // branch (yellow and greeen)
353 if(x_pos >= 9 && x_pos <= 11){
354 control_panel.selected = "branch_yg";
355 if(x_pos == 10 && y_pos == 2){ control_panel.branch_yg_dir = 1; }
356 if(x_pos == 9 && y_pos == 1){ control_panel.branch_yg_dir = 2; }
357 if(x_pos == 10 && y_pos == 0){ control_panel.branch_yg_dir = 3; }
358 if(x_pos == 11 && y_pos == 1){ control_panel.branch_yg_dir = 4; }
361 // bus button
362 if(x_pos >= 3 && x_pos <= 5){
363 control_panel.selected = "bus";
364 if(x_pos == 4 && y_pos == 2){ control_panel.bus_dir = 1; }
365 if(x_pos == 3 && y_pos == 1){ control_panel.bus_dir = 2; }
366 if(x_pos == 4 && y_pos == 0){ control_panel.bus_dir = 3; }
367 if(x_pos == 5 && y_pos == 1){ control_panel.bus_dir = 4; }
370 // delete button
371 if(x_pos >= 0 && x_pos <= 2){
372 control_panel.selected = "delete";
375 draw_control();
378 /* move through tape and draw bits */
379 function draw_tape(){
380 var i = 0; var x = 50;
381 input.fillStyle = "#f00";
382 input.clearRect(0,0,579,100);
383 while(i < store.length){
384 input.beginPath();
385 input.fillStyle = store[i];
386 input.arc(x,25,20,0,TWO_PI,0);
387 input.fill();
389 input.strokeStyle = "#000";
390 input.lineWidth = 2;
391 input.beginPath();
392 input.arc(x,25,20,0,TWO_PI,0);
393 input.stroke();
394 x += 50;
395 i++;
400 function draw_control(){
401 //control.scale(.75,.75);
402 control.fillStyle = "#fff";
403 control.fillRect(0,0,779,220)
405 /* trash can */
407 control.save();
408 control.translate(grid_size, grid_size);
409 draw_trash(control);
410 control.restore();
412 control.save();
413 control.translate(grid_size*4, grid_size);
414 draw_bus(control, control_panel.bus_dir);
416 control.save();
417 control.translate(grid_size, 0); /* right */
418 draw_bit(control, GRAY);
419 control.restore();
421 control.save();
422 control.translate(-grid_size, 0); /* left */
423 draw_bit(control, GRAY);
424 control.restore();
426 control.save();
427 control.translate(0, grid_size); /* bottom */
428 draw_bit(control, BLACK);
429 control.restore();
431 control.save();
432 control.translate(0, -grid_size); /* top */
433 draw_bit(control, GRAY);
434 control.restore();
436 /* branch icon red and blue */
438 control.restore();
439 control.translate(grid_size*7, grid_size);
440 draw_branch(control, "branch_rb", control_panel.branch_rb_dir);
442 control.save();
443 control.translate(grid_size, 0); /* right */
444 if(control_panel.branch_rb_dir == 4) { draw_bit(control, BLACK); } else { draw_bit(control, GRAY); }
445 control.restore();
447 control.save();
448 control.translate(-grid_size, 0); /* left */
449 if(control_panel.branch_rb_dir == 2) { draw_bit(control, BLACK); } else { draw_bit(control, GRAY); }
450 control.restore();
452 control.save();
453 control.translate(0, grid_size); /* bottom */
454 if(control_panel.branch_rb_dir == 1) { draw_bit(control, BLACK); } else { draw_bit(control, GRAY); }
455 control.restore();
457 control.save();
458 control.translate(0, -grid_size); /* top */
459 if(control_panel.branch_rb_dir == 3) { draw_bit(control, BLACK); } else { draw_bit(control, GRAY); }
460 control.restore();
462 /* branch icon green and yellow */
464 control.restore();
465 control.translate(grid_size*3, 0);
466 draw_branch(control, "branch_yg", control_panel.branch_yg_dir);
468 control.save();
469 control.translate(grid_size, 0); /* right */
470 if(control_panel.branch_yg_dir == 4) { draw_bit(control, BLACK); } else { draw_bit(control, GRAY); }
471 control.restore();
473 control.save();
474 control.translate(-grid_size, 0); /* left */
475 if(control_panel.branch_yg_dir == 2) { draw_bit(control, BLACK); } else { draw_bit(control, GRAY); }
476 control.restore();
478 control.save();
479 control.translate(0, grid_size); /* bottom */
480 if(control_panel.branch_yg_dir == 1) { draw_bit(control, BLACK); } else { draw_bit(control, GRAY); }
481 control.restore();
483 control.save();
484 control.translate(0, -grid_size); /* top */
485 if(control_panel.branch_yg_dir == 3) { draw_bit(control, BLACK); } else { draw_bit(control, GRAY); }
486 control.restore();
488 /* bit add */
490 control.translate(grid_size*3, 0);
491 draw_bitadd(control, control_panel.bitadd_col);
493 control.save();
494 control.translate(grid_size, 0); /* right */
495 draw_bit(control, RED);
496 control.restore();
498 control.save();
499 control.translate(-grid_size, 0); /* left */
500 draw_bit(control, BLUE);
501 control.restore();
503 control.save();
504 control.translate(0, grid_size); /* bottom */
505 draw_bit(control, GREEN);
506 control.restore();
508 control.save();
509 control.translate(0, -grid_size); /* top */
510 draw_bit(control, YELLOW);
511 control.restore();
513 /* highlight currenly selected tool */
514 control.setTransform(1, 0, 0, 1, 0, 0);
515 switch(control_panel.selected){
516 case "bitadd":
517 draw_control_highlight(grid_size*12,0,grid_size*3,grid_size*3);
518 break;
519 case "branch_rb":
520 draw_control_highlight(grid_size*6,0,grid_size*3,grid_size*3);
521 break;
522 case "branch_yg":
523 draw_control_highlight(grid_size*9,0,grid_size*3,grid_size*3);
524 break;
525 case "bus":
526 draw_control_highlight(grid_size*3,0,grid_size*3,grid_size*3);
527 break;
528 case "delete":
529 draw_control_highlight(0,0,grid_size*3,grid_size*3);
530 break;
534 function draw_control_highlight(x_start, y_start, x_stop, y_stop){
535 control.lineWidth = 5;
536 control.strokeStyle = "#000";
537 control.strokeRect(x_start,y_start,x_stop,y_stop);
538 control.stroke;
541 /* (re)draws any map tile on grid */
542 function draw_tile(x,y){
543 ctx.save();
544 ctx.translate(grid_size * x, grid_size * y);
545 switch (stage[x][y].type){
546 case "bitadd":
547 draw_bitadd(ctx, stage[x][y].col);
548 break;
549 case "branch_rb":
550 draw_branch(ctx, stage[x][y].type, stage[x][y].dir);
551 break;
552 case "branch_yg":
553 draw_branch(ctx, stage[x][y].type, stage[x][y].dir);
554 break;
555 case "bus":
556 draw_bus(ctx, stage[x][y].dir);
557 break;
558 case "input":
559 draw_input(ctx);
560 break;
561 case "output":
562 draw_output(ctx);
563 break;
564 default: clear_square(ctx);
566 if(stage[x][y].bit){ draw_bit(ctx, stage[x][y].bit); }
567 ctx.restore();
570 function draw_trash(canvas){
571 canvas.strokeStyle = "#000";
572 canvas.lineCap = "round";
573 canvas.lineWidth = 12;
574 canvas.beginPath();
575 canvas.moveTo(10,10);
576 canvas.lineTo(grid_size-10,grid_size-10);
577 canvas.stroke();
578 canvas.beginPath();
579 canvas.moveTo(10, grid_size-10);
580 canvas.lineTo(grid_size-10, 10);
581 canvas.stroke();
583 canvas.strokeStyle = "#f00";
584 canvas.lineWidth = 8;
585 canvas.beginPath();
586 canvas.moveTo(10,10);
587 canvas.lineTo(grid_size-10,grid_size-10);
588 canvas.stroke();
589 canvas.beginPath();
590 canvas.moveTo(10, grid_size-10);
591 canvas.lineTo(grid_size-10, 10);
592 canvas.stroke();
595 /* draws small bit of correct color on grid */
596 function draw_bit(canvas, color){
597 canvas.fillStyle = "#f00";
598 canvas.beginPath();
599 canvas.fillStyle = color;
600 canvas.arc(25,25,10,0,TWO_PI,0);
601 canvas.fill();
603 canvas.strokeStyle = "#000";
604 canvas.lineWidth = 2;
605 canvas.beginPath();
606 canvas.arc(25,25,10,0,TWO_PI,0);
607 canvas.stroke();
610 /* draw gray square with black outline */
611 function draw_input(canvas){
612 canvas.lineWidth = 1;
613 canvas.strokeStyle = "#000";
614 canvas.strokeRect(0,0,grid_size,grid_size);
615 canvas.fillStyle = "#aaa";
616 canvas.fillRect(0,0,grid_size,grid_size);
619 function drawSpirograph(ctx,R,r,O){
620 var x1 = R-O;
621 var y1 = 0;
622 var i = 1;
623 ctx.beginPath();
624 ctx.moveTo(x1,y1);
625 do {
626 if (i>20000) break;
627 var x2 = (R+r)*Math.cos(i*Math.PI/72) - (r+O)*Math.cos(((R+r)/r)*(i*Math.PI/72))
628 var y2 = (R+r)*Math.sin(i*Math.PI/72) - (r+O)*Math.sin(((R+r)/r)*(i*Math.PI/72))
629 ctx.lineTo(x2,y2);
630 x1 = x2;
631 y1 = y2;
632 i++;
633 } while (x2 != R-O && y2 != 0 );
634 ctx.stroke();
637 function draw_output(canvas){
638 canvas.fillStyle = "#fff";
639 canvas.fillRect(2,2,grid_size-2,grid_size-2); /* clear grid */
641 canvas.translate(grid_size/2,grid_size/2);
642 canvas.strokeStyle = "#d80";
643 canvas.lineWidth = 2;
644 drawSpirograph(canvas,9,2,7);
645 canvas.translate(-(grid_size/2),-(grid_size/2));
648 /* a bus moves bits from one location to another */
649 function draw_bus(canvas, dir){
650 var i = 0;
651 clear_square(canvas);
652 canvas.fillStyle = "#fff";
653 canvas.fillRect(2,2,grid_size-2,grid_size-2); /* clear grid */
655 canvas.lineWidth = 2;
656 canvas.fillStyle = "#aaa";
657 canvas.strokeStyle = "#000";
659 switch(dir){
660 case 2:
661 canvas.translate(grid_size,0);
662 canvas.rotate(PI/2);
663 break;
664 case 3:
665 canvas.translate(grid_size,grid_size);
666 canvas.rotate(PI);
667 break;
668 case 4:
669 canvas.translate(0,grid_size);
670 canvas.rotate(-PI/2);
671 break;
674 while(i < 2){
675 if(i == 1) { canvas.save(); canvas.translate(0, grid_size/2); }
676 canvas.beginPath();
677 canvas.moveTo(0,0);
678 canvas.lineTo(grid_size/2,grid_size/2);
679 canvas.lineTo(grid_size,0);
680 canvas.lineTo(grid_size/2,grid_size/4);
681 canvas.closePath();
682 canvas.fill();
684 canvas.beginPath();
685 canvas.moveTo(0,0);
686 canvas.lineTo(grid_size/2,grid_size/2);
687 canvas.lineTo(grid_size,0);
688 canvas.lineTo(grid_size/2,grid_size/4);
689 canvas.closePath();
690 canvas.stroke();
691 if(i == 1) { canvas.restore(); }
692 i++;
696 /* tiles branch movement of each bit */
697 function draw_branch(canvas, type, dir){
698 var color_1, color_2;
699 if(type == "branch_rb"){
700 color_1 = RED;
701 color_2 = BLUE;
702 } else if(type == "branch_yg"){
703 color_1 = YELLOW;
704 color_2 = GREEN;
705 } else {
706 alert("Incorrect color sent to draw_branch().");
709 canvas.save();
710 switch(dir){
711 case 2:
712 canvas.translate(grid_size,0);
713 canvas.rotate(PI/2);
714 break;
715 case 3:
716 canvas.translate(grid_size,grid_size);
717 canvas.rotate(PI);
718 break;
719 case 4:
720 canvas.translate(0,grid_size);
721 canvas.rotate(-PI/2);
722 break;
725 /* left */
726 canvas.lineWidth = 1;
727 canvas.fillStyle = color_1;
728 canvas.beginPath();
729 canvas.moveTo(0,0);
730 canvas.lineTo(grid_size/2,grid_size/2);
731 canvas.lineTo(0,grid_size);
732 canvas.closePath();
733 canvas.fill();
735 /* top */
736 canvas.fillStyle = "#000";
737 canvas.beginPath();
738 canvas.moveTo(0,0);
739 canvas.lineTo(grid_size/2,grid_size/2);
740 canvas.lineTo(grid_size,0);
741 canvas.closePath();
742 canvas.fill();
744 /* right */
745 canvas.fillStyle = color_2;
746 canvas.beginPath();
747 canvas.moveTo(grid_size,0);
748 canvas.lineTo(grid_size/2,grid_size/2);
749 canvas.lineTo(grid_size,grid_size);
750 canvas.closePath();
751 canvas.fill();
753 /* bottom */
754 canvas.fillStyle = "#aaa";
755 canvas.beginPath();
756 canvas.moveTo(0,grid_size);
757 canvas.lineTo(grid_size/2,grid_size/2);
758 canvas.lineTo(grid_size,grid_size);
759 canvas.closePath();
760 canvas.fill();
762 canvas.restore();
765 function draw_bitadd(canvas, color){
766 var i = 0;
767 clear_square(canvas);
768 while(i < 2){
769 if(i==1){
770 canvas.strokeStyle = color;
771 canvas.lineWidth = 10;
772 } else {
773 canvas.strokeStyle = "#000";
774 canvas.lineWidth = 15;
776 canvas.beginPath();
777 canvas.moveTo(grid_size/2,0);
778 canvas.lineTo(grid_size/2,grid_size);
779 canvas.closePath();
780 canvas.stroke();
782 canvas.beginPath();
783 canvas.moveTo(0, grid_size/2);
784 canvas.lineTo(grid_size,grid_size/2);
785 canvas.closePath();
786 canvas.stroke();
787 i++;
789 canvas.strokeStyle = "#000";
790 canvas.lineWidth = 1;
791 canvas.beginPath();
792 canvas.moveTo(0, 0);
793 canvas.lineTo(0,grid_size);
794 canvas.lineTo(grid_size,grid_size);
795 canvas.lineTo(grid_size,0);
796 canvas.lineTo(0,0);
797 canvas.closePath();
798 canvas.stroke();
801 /* clear this square by setting area to white */
802 function clear_square(canvas){
803 canvas.fillStyle = "#fff";
804 canvas.fillRect(1,1,grid_size-2,grid_size-2);
807 /* canvas has been clicked find out which grid and make correct change to square if needed. */
808 function cnvs_clicked(e){
809 var coords = cnvs_get_coordinates(canvas, e);
810 var x_pos = Math.floor(coords[0] / grid_size);
811 var y_pos = Math.floor(coords[1] / grid_size);
812 if(stage[x_pos][y_pos].type == "input" || stage[x_pos][y_pos].type == "output") { return; }
814 stage[x_pos][y_pos].type = control_panel.selected;
815 switch(control_panel.selected){
816 case "bitadd":
817 stage[x_pos][y_pos].dir = 1;
818 stage[x_pos][y_pos].col = control_panel.bitadd_col;
819 break;
820 case "branch_rb":
821 stage[x_pos][y_pos].dir = control_panel.branch_rb_dir;
822 break;
823 case "branch_yg":
824 stage[x_pos][y_pos].dir = control_panel.branch_yg_dir;
825 break;
826 case "bus":
827 stage[x_pos][y_pos].dir = control_panel.bus_dir;
828 break;
829 case "delete":
830 stage[x_pos][y_pos].type = "";
831 break;
833 draw_tile(x_pos,y_pos);
836 </script>
838 <style type="text/css">
840 </style>
842 <body onLoad="init_form();">
843 <center><h2>Finite Automata</h2></center>
844 <div id="topsection">
846 <center>
847 <button onClick='reset();'><img src="http://opentextbook.info/icons/32x32/resultset_first.png" title="Restart" alt="Restart"></button>
848 &nbsp;&nbsp;
849 <button onClick='step_back();'><img src="http://opentextbook.info/icons/32x32/resultset_previous.png" title="Step Back" alt="Step Back"></button>
850 &nbsp;&nbsp;
851 <button onClick='next_move();'><img src="http://opentextbook.info/icons/32x32/resultset_next.png" title="Next Step" alt="Next Step"></button>
852 &nbsp;&nbsp;
853 <button onClick='run();'><img src="http://opentextbook.info/icons/32x32/resultset_last.png" title="Run" alt="Run"></button>
854 &nbsp;&nbsp;
856 <!--
857 <button onClick='halt();'><img src="http://opentextbook.info/icons/32x32/cancel.png" title="Halt Execution" alt="Halt Execution"></button>
858 &nbsp;&nbsp;
860 <button disabled><img src="http://opentextbook.info/icons/32x32/disk.png" title="Save Code" alt="Save Code"></button>
861 &nbsp;&nbsp;
862 <button onClick='display_docs();'><img src="http://opentextbook.info/icons/32x32/book_open.png" title="Open Documentation" alt="Open Documentation"></button>
864 </center>
866 </div>
868 <!--<div id="xycoordinates">Coordinates:</div>-->
869 <canvas id="input" width="579" height="120"></canvas><br>
870 <canvas id="control" width="779" height="220" onClick="cont_clicked(event);"></canvas>
871 <canvas id="stage" width="579" height="770" onclick="cnvs_clicked(event);">
872 Your browser does not support HTML5 Canvas.
873 </canvas>
875 </body>
876 </html>