Skip to content

Instantly share code, notes, and snippets.

@TobiasAxelsson
Last active August 29, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TobiasAxelsson/d3986eefe0b69fad758d to your computer and use it in GitHub Desktop.
Save TobiasAxelsson/d3986eefe0b69fad758d to your computer and use it in GitHub Desktop.
An n-in-a-row game in JS
/*global console, prompt */
var gameBoard = [],
coords,
gameSettings,
player = 0,
winner,
i,
j;
gameSettings = {};
gameSettings.winCondition = 3;
gameSettings.markerPlaceHolder = "_";
gameSettings.boardSize = 5;
function checkClimbingDiagonalMarkers2D(settings, array) {
"use strict";
var inARow = 0,
i,
j,
k,
l;
for (i = 0; i < array.length; i += 1) {
//Loop through the outer array.
for (j = 0; j < array[i].length; j += 1) {
//Loop through each of the inner arrays
//Make sure we start at 0 for each array since any leftovers are now invalid.
inARow = 0;
if (array[i][j] === settings.marker) {
//If we find the supplied marker:
for (k = i, l = j; k >= 0; l -= 1) {
//start looping backwards to 0 in order to step backwards in the inner array following this pattern:
//__X
//_X_
//X__
if (array[k][l] === settings.marker) {
//Since we now step backwards each marker can be matched for the supplied marker and get how many are in a row.
inARow += 1;
if (inARow >= settings.winCondition) {
// We can return out of this function if we find enough markers in a row.
return true;
}
} else {
//If the marker we hit is not the same as the one supplied we need to reset in order for the next iteration to start at 0.
inARow = 0;
}
if (array[k + 1]) {
//Check if the next exists and set the index accordingly
k += 1;
} else {
//Or break the loop if we are out of bounds.
break;
}
}
} else {
// TODO: Is this needed?
inARow = 0;
}
}
}
return false;
}
function checkFallingDiagonalMarkers2D(settings, array) {
//Same as checkClimbingDiagonalMarkers2D except for the comments below
"use strict";
var inARow = 0,
i,
j,
k,
l;
for (i = 0; i < array.length; i += 1) {
for (j = 0; j < array[i].length; j += 1) {
inARow = 0;
if (array[i][j] === settings.marker) {
for (k = i, l = j; k < (array[k].length); l += 1) {
//This loop loops forward for a falling pattern like:
//X__
//_X_
//__X
if (array[k][l] === settings.marker) {
inARow += 1;
if (inARow >= settings.winCondition) {
return true;
}
}
if (array[k + 1]) {
k += 1;
} else {
break;
}
}
} else {
inARow = 0;
}
}
}
return false;
}
function checkForVerticalMarkers2D(settings, array) {
"use strict";
var inARow = 0,
i,
j;
for (i = 0; i < array.length; i += 1) {
inARow = 0;
for (j = 0; j < array[i].length; j += 1) {
if (array[j][i] === settings.marker) {
inARow += 1;
} else {
inARow = 0;
}
if (inARow === settings.winCondition) {
return true;
}
}
}
return false;
}
function checkForHorizontalMarkers2D(settings, array) {
"use strict";
var inARow = 0,
i,
j;
for (i = 0; i < array.length; i += 1) {
inARow = 0;
for (j = 0; j < array[i].length; j += 1) {
if (array[i][j] === settings.marker) {
inARow += 1;
} else {
inARow = 0;
}
if (inARow === settings.winCondition) {
return true;
}
}
}
return false;
}
function getValidUserCoordinates(settings, board) {
"use strict";
function isLessOrEqualToBoardSize(v) {
//TODO: get settingsObject through parameter. How?
return v <= settings.boardSize - 1;
}
function coordsAreFree(coordsArray) {
return (board[coordsArray[0]][coordsArray[1]] === settings.markerPlaceHolder);
}
function coordinateIsValid(coord) {
return !!coord;
}
var coords;
coords = prompt("Player " + (player + 1) + " place your " + (player ? "O" : "X") + " by stating 'y,x' ");
coords = coords.split(",");
//make sure the entered coordinates are valid.
while (!coords.every(coordinateIsValid) || !coords.every(isLessOrEqualToBoardSize) || !coordsAreFree(coords)) {
coords = prompt("Please check your coordinates" + coords + " are invalid, place your mark by stating 'y,x' ");
coords = coords.split(",");
}
return coords;
}
function haveWinner(gameSettings, gameBoard) {
"use strict";
return checkForVerticalMarkers2D(gameSettings, gameBoard) ||
checkForHorizontalMarkers2D(gameSettings, gameBoard) ||
checkFallingDiagonalMarkers2D(gameSettings, gameBoard) ||
checkClimbingDiagonalMarkers2D(gameSettings, gameBoard);
}
//make the board
//rows
for (i = 0; i < gameSettings.boardSize; i += 1) {
gameBoard.push([]);
//columns
for (j = 0; j < gameSettings.boardSize; j += 1) {
gameBoard[i].push(gameSettings.markerPlaceHolder);
}
}
//as long as no winner
while (!winner) {
gameSettings.marker = (player ? "O" : "X");
coords = getValidUserCoordinates(gameSettings, gameBoard);
//Place the marker at the designated spot.
gameBoard[coords[0]][coords[1]] = gameSettings.marker;
console.clear();
// Print the game board for visual representation.
for (i = 0; i < gameSettings.boardSize; i += 1) {
console.log(gameBoard[i]);
}
if (haveWinner(gameSettings, gameBoard)) {
winner = player + 1;
}
player = !player;
}
console.log("Player" + winner + " wins!");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment