////////// Exercice 1 ////////// // Displays a state `s` function stateDisp(s) { return `----- |${s[0]}${s[1]}${s[2]}| |${s[3]}${s[4]}${s[5]}| |${s[6]}${s[7]}${s[8]}| -----`; } let aState = [ 'x', ' ', 'o', 'x', 'o', ' ', 'x', ' ', ' ' ]; console.log(`A state :\n${stateDisp(aState)}`); // stateEmptySlots([ 'x', ' ', 'o', 'x', 'o', ' ', 'x', ' ', ' ' ]); // -> [ 1, 5, 7, 8 ] // stateNexts(['x', 'o', 'x', ' ', ' ', ' ', 'x', 'o', 'x'], 'x'); // -> [ [ 'x', 'o', 'x', 'x', ' ', ' ', 'x', 'o', 'x' ], // [ 'x', 'o', 'x', ' ', 'x', ' ', 'x', 'o', 'x' ], // [ 'x', 'o', 'x', ' ', ' ', 'x', 'x', 'o', 'x' ] ] function otherPlayer(aPlayer) { if (aPlayer === "o") return "x"; else if (aPlayer === "x") return "o"; else throw new Error(`the player is incorrect`); } ////////// Exercice 2 ////////// // Create a tree node function node(aVal, someChildren) { return { val: aVal, children: someChildren }; } function val(node) { return node.val; } function children(node) { return node.children; } function isFrozen(node) { return typeof node.children === 'function'; } function isLeaf(node) { return node.children.length === 0; } let evaluatedTree = node("root", [ node("1st son", []), node("2nd son", []) ]); let frozenTree = node("root", () => [ node("1st son", []), node("2nd son", []) ]); // Thaws a tree up to a certain depth function treeThawAtDepth(root, depth) { if (depth === 0 || depth === 1) return; else { if (isFrozen(root)) nodeThaw(root); root.children.forEach((child) => treeThawAtDepth(child, depth-1)); } } // Displays a tree on the console. function treeDisp(root) { function treeDispIndent(root, indent, prefix, suffix) { const valString = val(root); console.log(`${indent}${prefix}{`); console.log(`${indent} val: ${valString},`); if (isFrozen(root)) { console.log(`${indent} children: `); } else if (!isLeaf(root)) { console.log(`${indent} children: [`); children(root).forEach((child) => treeDispIndent(child, indent + ' ', '', ',')); console.log(`${indent} ],`); } console.log(`${indent}}${suffix}`); } return treeDispIndent(root, "", "", ""); } ////////// Exercice 3 ////////// // Returns ' ' if the game is not won, 'x' or 'o' if there is a // winner, 'D' in a draw, and '?' if both players have won. function stateWinner(s) { function lines(s) { return [0,1,2].map((i) => s.slice(3*i,3*i+3)); } function cols(s) { return [0,1,2].map((i) => [s[i], s[i+3], s[i+6]]); } function diags(s) { return [[s[0], s[4], s[8]], [s[2], s[4], s[6]]]; } function allEqual(arr) { return arr.every( v => v === arr[0] ); } const allLines = lines(s).concat(cols(s)).concat(diags(s)); const winLines = allLines .filter((l) => allEqual(l)) .map((l) => l[0]) .filter((e) => e !== ' '); if (winLines.length === 0) { if (stateEmptySlots(s).length === 0) return 'D'; else return ' '; } else if (allEqual(winLines)) return winLines[0]; else return '?'; } // Predicate telling if the state `s` corresponds to the end of // a game or not (either one player won, or the game is a draw). function stateIsFinal(s) { const possibleWinner = stateWinner(s); return (possibleWinner === 'o' || possibleWinner === 'x' || possibleWinner === 'D'); }