The board is a div element with a couple of child button elements. Foreign functions allow to access and modify the board from within Prolog. Each of the 3x3 child buttons gets a different background image depending on a label. This is done via a CSS style sheet that is embedded in the HTML page. The CSS style sheet has the following rules:
[aria-label="x"] {
background-image: url('first.svg');
}
[aria-label="o"] {
background-image: url('second.svg');
}
We use scalable vector graphics (SVG) images for the button backgrounds, since the file for-mat does not occupy much space and they allow adapting their size without losing quality of the graphics. The foreign functions will allow the Prolog code to access and modify the label. An example of such a foreign function is this setter:
function set_button(id, val) {
let help = document.getElementById(id);
if (val === "-") {
help.removeAttribute("aria-label");
help.removeAttribute("disabled");
} else {
help.setAttribute("aria-label", val);
help.setAttribute("disabled", "disabled");
}
}
The Prolog atom '-' serves as an indicator that one of the players has not yet marked a board cell. We do disable a board cell as soon as a player marked it. The Dogelog player offers a JavaScript call to register foreign functions. Besides the JavaScript function set_button(), we also register JavaScript functions get_button() and set_complete():
register("get_button", 2, get_button, FFI_FUNC);
register("set_button", 2, set_button, 0);
register("set_complete", 0, set_complete, 0);