Othello board in JavaScript
White: | 0 |
Black: | 0 |
Remaining: | 64 |
Next: | ● |
This is a JavaScript Othello board. It doesn't play, it just keeps score, highlights the available moves, and provides a playing surface.
function replace_text (parent, text) { clear (parent); append_text (parent, text); } function clear(element) { if (!element) return; while (element.lastChild) element.removeChild (element.lastChild); } // Clear a box function clearbox (boxid) { // alert (boxid); boxid.value = ''; } function create_node(type,parent) { if (!type) { alert ("No type given to create_node"); exit; } if (!parent) { alert ("No parent given to create_node"); exit; } var new_node = document.createElement (type); if (!new_node) { alert ("Creation of node of type '"+type+"' failed."); exit; } parent.appendChild (new_node); return new_node; } // Create a node of type "type", attach it to "parent", then attach // some text to that node. function create_text_node (type,parent,text) { var new_node = create_node (type,parent); var text_node = document.createTextNode (text); if (!text_node) { alert ("Creation of text node with text '"+text+"' failed."); exit; } new_node.appendChild(text_node); return new_node; } // Add some text to a node function append_text (parent,text) { var text_node = document.createTextNode (text); if (!text_node) { alert ("Creation of text node with text '"+text+"' failed."); exit; } parent.appendChild(text_node); } function append_text_by_id (parent_id, text) { var parent = getbyid (parent_id); clear (parent); append_text (parent, text); } // Clear a box function clearbox (boxid) { // alert (boxid); boxid.value = ''; } function clearboxbyname (boxname) { // alert (boxid); var boxid = getbyid (boxname); boxid.value = ''; } function getbyid (id) { var element = document.getElementById (id); if (! element) { alert ("Could not find element with id "+id); exit; } return element; } // Get the value of something. function getvalue (id) { var element = getbyid (id); var value = element.value; if (! value) return; /* BKB 2009-09-20 22:47:43: This is commented out in order to make "canvas3.js" work. alert ("Element with id "+id+" has no value.") exit; } */ return value; } var board=new Array(); for (var i=0;i<=8;i++) board[i]=new Array(); function init() { for (var x=1;x<=8;x++) for (var y=1;y<=8;y++) if (x>3&&y>3&&x<6&&y<6) board[x][y]=(x+y)%2?"b":"w"; else board[x][y]=0; } function piece(x,y,colour) { var square = getbyid ("square"+x+y); append_text (square, String.fromCharCode (parseInt ("25CF",16))); square.className = square.className.replace (/empty/, colour); } function change_piece(x,y,colour) { var square = getbyid ("square"+x+y); square.className = square.className.replace (/b/, "funky"); square.className = square.className.replace (/w/, "b"); square.className = square.className.replace (/funky/, "w"); } var next="b"; /* change_ok if it is OK to change the squares. */ function check_valid (x,y,colour,change_ok) { var min_x = x > 1 ? x - 1 : 1; var min_y = y > 1 ? y - 1 : 1; var max_x = x < 8 ? x + 1 : 8; var max_y = y < 8 ? y + 1 : 8; var found_opposite = false; if (board[x][y]) return false; for (test_x = min_x; test_x <= max_x; test_x++) { for (test_y = min_y; test_y <= max_y; test_y++) { if (test_x == x && test_y == y) continue; var neighbour_colour = board[test_x][test_y]; if (neighbour_colour != 0 && neighbour_colour != colour) { var x_offset = test_x - x; var y_offset = test_y - y; //alert (x_offset +" "+ y_offset); for (t=1;;t++) { var probe_x = x+t*x_offset; var probe_y = y+t*y_offset; //alert ("probing "+t+" "+probe_x +" "+ probe_y); if (probe_x < 1 || probe_y < 1 || probe_x > 8 || probe_y > 8) break; if (board[probe_x][probe_y] == 0) break; if (board[probe_x][probe_y] == colour) { found_opposite = true; var s; if (change_ok) { for (s=1; s < t; s++) { var change_x = x+s*x_offset; var change_y = y+s*y_offset; board[change_x][change_y] = colour; change_piece (change_x, change_y, colour); } } break; } } } } } return found_opposite; } function check_any_valid (colour) { var any_valid = false; for (x=1;x<=8;x++) { for (y=1;y<=8;y++) { var valid = check_valid (x,y,colour, false); if (valid) { any_valid = true; var square = getbyid ("square"+x+y); square.className += " valid"; } // alert (x+" "+y+ " "+valid+" "+any_valid); } } return any_valid; } function declare_victory (white, black) { if (white > black) alert ("White wins"); else if (white < black) alert ("Black wins"); else alert ("Tie"); } function update_game () { var white = 0; var black = 0; var remaining = 0; for (var x = 1; x <= 8; x++) { for (var y = 1; y <= 8; y++) { if (board[x][y]=="w") white++; else if (board[x][y]=="b") black++; else remaining++; } } if (white+black+remaining != 64) { alert ("Inconsistency"); } var wscore = getbyid ("wscore"); var bscore = getbyid ("bscore"); var remaining_td = getbyid ("remaining"); var next_td = getbyid ("next"); replace_text (wscore, white); replace_text (bscore, black); replace_text (remaining_td, remaining); if (remaining == 0) { declare_victory (white, black); } else { next_td.className = "square "+ next; if (!check_any_valid (next)) { alert (next+" has no moves"); next=(next=="b"?"w":"b"); next_td.className = "square "+ next; if (!check_any_valid (next)) { alert ("Neither does "+next+"."); declare_victory (white, black); } } } } function reset_valid () { for (var x = 1; x <= 8; x++) { for (var y = 1; y <= 8; y++) { var square = getbyid ("square"+x+y); if (square.className.match(/valid/)) square.className = "empty square"; } } } function play(x,y) { if (board[x][y]) return; if (!check_valid (x, y, next, true)) { // alert ("No go joe"); return; } // Valid reset_valid (); board[x][y] = next; piece (x,y,next); // alert ("play "+x+","+y+" colour: "+colour); next=(next=="b"?"w":"b"); update_game (); } function create_board () { // alert ("Creating board"); init (); var board_table = getbyid ("board"); var top_tr = create_node ("tr", board_table); for (x=0;x<9;x++) { var th; if (x) th=create_text_node ("th", top_tr, x); else th=create_node ("th", top_tr); th.className = "square"; } for (y=1;y<=8;y++) { var tr = create_node ("tr", board_table); for (x=0;x<9;x++) { if (x) { var td = create_node ("td", tr); td.className="empty square"; td.id="square"+x+y; (function (x,y) { td.onclick = function () {play (x,y);} }(x,y)); if (board[x][y] != 0) { piece (x, y, board[x][y]); } } else { var th = create_text_node ("th", tr, y); th.className="square"; } } } update_game (); }You also need HTML
<table id="board"> </table> <table> <tr> <td class="w">White:</td><td id="wscore">0</td> </tr> <tr> <td class="b">Black:</td><td id="bscore">0</td> </tr> <tr> <td>Remaining:</td><td id="remaining">64</td> </tr> <tr> <td>Next:</td><td class="square b" id="next">●</td> </tr> </table>and CSS
.square {width:50;height:50;font-size:40} .w {background-color:green; color:white;} .b {background-color:green; color:black;} .empty {background-color:green} .valid {background-color:fuchsia}
Copyright © Ben Bullock 2009-2024. All
rights reserved.
For comments, questions, and corrections, please email
Ben Bullock
(benkasminbullock@gmail.com).
/
Privacy /
Disclaimer