Last active
August 29, 2015 14:14
-
-
Save TobiasAxelsson/d3986eefe0b69fad758d to your computer and use it in GitHub Desktop.
An n-in-a-row game in JS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*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