Extracting a function
registerOnclick((x, y) => {
let winner = null;
let r;
let c;
// Check if there's a winner already.
for (let i = 0; i < lines.length; i++) {
r = lines[i][0][0];
c = lines[i][0][1];
const m0 = board[r][c];
r = lines[i][1][0];
c = lines[i][1][1];
const m1 = board[r][c];
r = lines[i][2][0];
c = lines[i][2][1];
const m2 = board[r][c];
if (m0 !== '' && m0 === m1 && m0 === m2) {
winner = lines[i];
}
}
r = Math.floor((y - boardTop) / cellSize);
c = Math.floor((x - boardLeft) / cellSize);
// Only do anything if it's a legal move and the game isn't over.
if (winner === null && 0 <= r && r < 3 && 0 <= c && c < 3 && board[r][c] === '') {
// Draw the mark and record the move
const marker = move % 2 === 0 ? 'X' : 'O';
const x = boardLeft + c * cellSize + cellSize / 2;
const y = boardTop + r * cellSize + cellSize / 2;
const nudge = marker === 'O' ? cellSize / 9 : cellSize / 19;
drawText(marker, x - (fontSize * 0.3 + nudge), y + fontSize * 0.3, 'black', fontSize);
board[r][c] = marker;
move++;
// Check if there's a winner now
winner = null;
for (let i = 0; i < lines.length; i++) {
r = lines[i][0][0];
c = lines[i][0][1];
const m0 = board[r][c];
r = lines[i][1][0];
c = lines[i][1][1];
const m1 = board[r][c];
r = lines[i][2][0];
c = lines[i][2][1];
const m2 = board[r][c];
if (m0 !== '' && m0 === m1 && m0 === m2) {
winner = lines[i];
}
}
if (winner !== null) {
// Draw the line through three in a row
const [r1, c1] = winner[0];
const [r2, c2] = winner[winner.length - 1];
const x1 = boardLeft + c1 * cellSize + cellSize / 2;
const y1 = boardTop + r1 * cellSize + cellSize / 2;
const x2 = boardLeft + c2 * cellSize + cellSize / 2;
const y2 = boardTop + r2 * cellSize + cellSize / 2;
let adjX1 = x1;
let adjX2 = x2;
let adjY1 = y1;
let adjY2 = y2;
if (y1 === y2 || x1 !== x2) {
adjX1 -= lineEndAdjustment;
adjX2 += lineEndAdjustment;
}
if (x1 === x2 || y1 !== y2) {
const slope = y1 < y2 ? 1 : -1;
adjY1 -= (slope * lineEndAdjustment);
adjY2 += (slope * lineEndAdjustment);
}
drawLine(adjX1, adjY1, adjX2, adjY2, 'red', 15);
}
}
});
const findWinner = () => {
for (let i = 0; i < lines.length; i++) {
r = lines[i][0][0];
c = lines[i][0][1];
const m0 = board[r][c];
r = lines[i][1][0];
c = lines[i][1][1];
const m1 = board[r][c];
r = lines[i][2][0];
c = lines[i][2][1];
const m2 = board[r][c];
if (m0 !== '' && m0 === m1 && m0 === m2) {
winner = lines[i];
}
}
}
Variables that were declared in the original context
In particular variables from the original context that are assigned to
const findWinner = () => {
for (let i = 0; i < lines.length; i++) {
r = lines[i][0][0];
c = lines[i][0][1];
const m0 = board[r][c];
r = lines[i][1][0];
c = lines[i][1][1];
const m1 = board[r][c];
r = lines[i][2][0];
c = lines[i][2][1];
const m2 = board[r][c];
if (m0 !== '' && m0 === m1 && m0 === m2) {
winner = lines[i];
}
}
}
Make them arguments to the new function
Make them local variables declared in the new function
Instead of assigning to a variable, return the value
const findWinner = () => {
for (let i = 0; i < lines.length; i++) {
let r = lines[i][0][0];
let c = lines[i][0][1];
const m0 = board[r][c];
r = lines[i][1][0];
c = lines[i][1][1];
const m1 = board[r][c];
r = lines[i][2][0];
c = lines[i][2][1];
const m2 = board[r][c];
if (m0 !== '' && m0 === m1 && m0 === m2) {
return lines[i];
}
}
return null;
}
const findWinner = () => {
for (let i = 0; i < lines.length; i++) {
let r = lines[i][0][0];
let c = lines[i][0][1];
const m0 = board[r][c];
r = lines[i][1][0];
c = lines[i][1][1];
const m1 = board[r][c];
r = lines[i][2][0];
c = lines[i][2][1];
const m2 = board[r][c];
if (m0 !== '' && m0 === m1 && m0 === m2) {
return lines[i];
}
}
return null;
}
registerOnclick((x, y) => {
let winner = findWinner();
let r;
let c;
r = Math.floor((y - boardTop) / cellSize);
c = Math.floor((x - boardLeft) / cellSize);
// Only do anything if it's a legal move and the game isn't over.
if (winner === null && 0 <= r && r < 3 && 0 <= c && c < 3 && board[r][c] === '') {
// Draw the mark and record the move
const marker = move % 2 === 0 ? 'X' : 'O';
const x = boardLeft + c * cellSize + cellSize / 2;
const y = boardTop + r * cellSize + cellSize / 2;
const nudge = marker === 'O' ? cellSize / 9 : cellSize / 19;
drawText(marker, x - (fontSize * 0.3 + nudge), y + fontSize * 0.3, 'black', fontSize);
board[r][c] = marker;
move++;
// Check if there's a winner now
winner = findWinner();
if (winner !== null) {
// Draw the line through three in a row
const [r1, c1] = winner[0];
const [r2, c2] = winner[winner.length - 1];
const x1 = boardLeft + c1 * cellSize + cellSize / 2;
const y1 = boardTop + r1 * cellSize + cellSize / 2;
const x2 = boardLeft + c2 * cellSize + cellSize / 2;
const y2 = boardTop + r2 * cellSize + cellSize / 2;
let adjX1 = x1;
let adjX2 = x2;
let adjY1 = y1;
let adjY2 = y2;
if (y1 === y2 || x1 !== x2) {
adjX1 -= lineEndAdjustment;
adjX2 += lineEndAdjustment;
}
if (x1 === x2 || y1 !== y2) {
const slope = y1 < y2 ? 1 : -1;
adjY1 -= (slope * lineEndAdjustment);
adjY2 += (slope * lineEndAdjustment);
}
drawLine(adjX1, adjY1, adjX2, adjY2, 'red', 15);
}
}
});
registerOnclick((x, y) => {
let winner = findWinner();
const r = Math.floor((y - boardTop) / cellSize);
const c = Math.floor((x - boardLeft) / cellSize);
// Only do anything if it's a legal move and the game isn't over.
if (winner === null && 0 <= r && r < 3 && 0 <= c && c < 3 && board[r][c] === '') {
// Draw the mark and record the move
const marker = move % 2 === 0 ? 'X' : 'O';
const x = boardLeft + c * cellSize + cellSize / 2;
const y = boardTop + r * cellSize + cellSize / 2;
const nudge = marker === 'O' ? cellSize / 9 : cellSize / 19;
drawText(marker, x - (fontSize * 0.3 + nudge), y + fontSize * 0.3, 'black', fontSize);
board[r][c] = marker;
move++;
// Check if there's a winner now
winner = findWinner();
if (winner !== null) {
// Draw the line through three in a row
const [r1, c1] = winner[0];
const [r2, c2] = winner[winner.length - 1];
const x1 = boardLeft + c1 * cellSize + cellSize / 2;
const y1 = boardTop + r1 * cellSize + cellSize / 2;
const x2 = boardLeft + c2 * cellSize + cellSize / 2;
const y2 = boardTop + r2 * cellSize + cellSize / 2;
let adjX1 = x1;
let adjX2 = x2;
let adjY1 = y1;
let adjY2 = y2;
if (y1 === y2 || x1 !== x2) {
adjX1 -= lineEndAdjustment;
adjX2 += lineEndAdjustment;
}
if (x1 === x2 || y1 !== y2) {
const slope = y1 < y2 ? 1 : -1;
adjY1 -= (slope * lineEndAdjustment);
adjY2 += (slope * lineEndAdjustment);
}
drawLine(adjX1, adjY1, adjX2, adjY2, 'red', 15);
}
}
});