From f0612ca775f1ae59a9dda2201f2f9546b926dcc2 Mon Sep 17 00:00:00 2001 From: Shay Hoffman Date: Tue, 6 Feb 2018 20:22:21 -0600 Subject: [PATCH 1/5] playing with towers --- 03week/towersOfHanoi.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/03week/towersOfHanoi.js b/03week/towersOfHanoi.js index 40b9ebe92..344452321 100644 --- a/03week/towersOfHanoi.js +++ b/03week/towersOfHanoi.js @@ -20,7 +20,7 @@ function printStacks() { } function movePiece() { - // Your code here + console.log() } @@ -50,5 +50,3 @@ function getPrompt() { } getPrompt(); - - From e1c876036260c68eac63757fae1be8ec12f1776b Mon Sep 17 00:00:00 2001 From: Shay Hoffman Date: Thu, 8 Feb 2018 12:58:05 -0600 Subject: [PATCH 2/5] playing with Towers --- 03week/towersOfHanoi.js | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/03week/towersOfHanoi.js b/03week/towersOfHanoi.js index 344452321..36fa33c09 100644 --- a/03week/towersOfHanoi.js +++ b/03week/towersOfHanoi.js @@ -19,25 +19,48 @@ function printStacks() { console.log("c: " + stacks.c); } -function movePiece() { - console.log() +//check if valid input +//check for legal move +//if win, game over, board resets +const movePiece = (startStack, endStack) => { + return stacks[endStack].push(stacks[startStack].pop()); } +//the above movePiece function just makes the game functional, and lets you move pieces around. It allows for the removal of the last item in the first array (or startStack, in this case), through popping it off the end, and pushing it to the endStack, which could be stack b or c. -function isLegal() { +const isLegal = (startStack, endStack) => { // Your code here } +//there should be a test to check to see whether a user's input is valid +//in this case, it would be checking for correct characters, whether its letters or numbers or both. +//it would also be checking to make sure the input suggestion didn't allow cheating. here, that would mean moving the pieces more than one at a time, or too far over, from peg 1 directly to peg 3. -function checkForWin() { - // Your code here - +const checkForWin = (startStack, endStack) => { + if ((stacks.b.length === 4) || (stacks.c.length === 4)) { + return "Hey, you won!"; + } else { + return "Not quite, keep going!"; + } } +//the above checkForWin function checks for when/if stacks b or c have all four pieces on one stack, or 4 items in the array. If this condition is met for either stack b or c, the user wins. -function towersOfHanoi(startStack, endStack) { - // Your code here - +const towersOfHanoi = (startStack, endStack) => { + if (isLegal(startStack, endStack)){ //would it be better to structure this with && to make sure these conditions are both met? + movePiece(startStack, endStack) + } else { + return "Illegal move, try again!"; + } + if (checkForWin()) { + //following code *should* reset the board. + stacks = { + a: [4, 3, 2, 1], + b: [], + c: [] + }; + } } +//I modeled the above function sort of after my tic tac toe function, especially the board reset and its placement. I'd originally placed it in the checkForWin function. function getPrompt() { printStacks(); From e2ea56b53e5cce5d7ae772363c5903f68e45a319 Mon Sep 17 00:00:00 2001 From: Shay Hoffman Date: Sat, 10 Feb 2018 11:54:03 -0600 Subject: [PATCH 3/5] partial isLegal function --- 03week/towersOfHanoi.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03week/towersOfHanoi.js b/03week/towersOfHanoi.js index 36fa33c09..de2853115 100644 --- a/03week/towersOfHanoi.js +++ b/03week/towersOfHanoi.js @@ -29,7 +29,7 @@ const movePiece = (startStack, endStack) => { //the above movePiece function just makes the game functional, and lets you move pieces around. It allows for the removal of the last item in the first array (or startStack, in this case), through popping it off the end, and pushing it to the endStack, which could be stack b or c. const isLegal = (startStack, endStack) => { - // Your code here + return stacks[endStack].push() === 0 } //there should be a test to check to see whether a user's input is valid From d373d9cc7ab98786a1889af67b0512c7668439a6 Mon Sep 17 00:00:00 2001 From: Shay Hoffman Date: Sat, 10 Feb 2018 15:36:34 -0600 Subject: [PATCH 4/5] semi-functional game --- 03week/towersOfHanoi.js | 60 +++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/03week/towersOfHanoi.js b/03week/towersOfHanoi.js index de2853115..493075d65 100644 --- a/03week/towersOfHanoi.js +++ b/03week/towersOfHanoi.js @@ -17,49 +17,52 @@ function printStacks() { console.log("a: " + stacks.a); console.log("b: " + stacks.b); console.log("c: " + stacks.c); -} +}; -//check if valid input -//check for legal move -//if win, game over, board resets const movePiece = (startStack, endStack) => { return stacks[endStack].push(stacks[startStack].pop()); -} +}; //the above movePiece function just makes the game functional, and lets you move pieces around. It allows for the removal of the last item in the first array (or startStack, in this case), through popping it off the end, and pushing it to the endStack, which could be stack b or c. const isLegal = (startStack, endStack) => { - return stacks[endStack].push() === 0 + let startTest = stacks[startStack][stacks[startStack].length - 1]; + let endTest = stacks[endStack][stacks[endStack].length - 1]; + if ((startTest < endTest) || (stacks[endStack].length === 0)) { + return true; + } else { + return false; + } } -//there should be a test to check to see whether a user's input is valid -//in this case, it would be checking for correct characters, whether its letters or numbers or both. -//it would also be checking to make sure the input suggestion didn't allow cheating. here, that would mean moving the pieces more than one at a time, or too far over, from peg 1 directly to peg 3. +//For the above function, you use .length -1 to get the last value in an array. In this case, whatever piece you're trying to move into a new array either has to be a smaller value than the last value in the array or the array has to be empty. -const checkForWin = (startStack, endStack) => { - if ((stacks.b.length === 4) || (stacks.c.length === 4)) { - return "Hey, you won!"; +const checkForWin = () => { + if (stacks.c.length === 4) { + return true; } else { - return "Not quite, keep going!"; + return false; } -} +}; //the above checkForWin function checks for when/if stacks b or c have all four pieces on one stack, or 4 items in the array. If this condition is met for either stack b or c, the user wins. const towersOfHanoi = (startStack, endStack) => { - if (isLegal(startStack, endStack)){ //would it be better to structure this with && to make sure these conditions are both met? + if (isLegal(startStack, endStack)){ //would it be better to structure this with && to make sure these conditions are both met? movePiece(startStack, endStack) - } else { - return "Illegal move, try again!"; - } - if (checkForWin()) { - //following code *should* reset the board. - stacks = { - a: [4, 3, 2, 1], - b: [], - c: [] - }; - } + }else { + return "invalid move"; + }if (checkForWin()){ + console.log('You won the game!') + } } + // } return "You won!"; + // stacks = { + // a: [4, 3, 2, 1], + // b: [], + // c: [] + // }; + // } +// } //I modeled the above function sort of after my tic tac toe function, especially the board reset and its placement. I'd originally placed it in the checkForWin function. function getPrompt() { @@ -73,3 +76,8 @@ function getPrompt() { } getPrompt(); + +//tests: +//there should be a test to check to see whether a user's input is valid +//in this case, it would be checking for correct characters, whether its letters or numbers or both. +//it would also be checking to make sure the input suggestion didn't allow cheating. here, that would mean moving the pieces more than one at a time, or too far over, from peg 1 directly to peg 3. From 052d64ac0ef9e02f7a3af7adfae8c8b790fc2373 Mon Sep 17 00:00:00 2001 From: Shay Hoffman Date: Tue, 13 Feb 2018 13:40:43 -0600 Subject: [PATCH 5/5] finished game yay --- 03week/towersOfHanoi.js | 120 +++++++++++++++++++++++++++++----------- 1 file changed, 87 insertions(+), 33 deletions(-) diff --git a/03week/towersOfHanoi.js b/03week/towersOfHanoi.js index 493075d65..96940403a 100644 --- a/03week/towersOfHanoi.js +++ b/03week/towersOfHanoi.js @@ -13,7 +13,7 @@ let stacks = { c: [] }; -function printStacks() { +const printStacks = () => { console.log("a: " + stacks.a); console.log("b: " + stacks.b); console.log("c: " + stacks.c); @@ -23,49 +23,66 @@ function printStacks() { const movePiece = (startStack, endStack) => { return stacks[endStack].push(stacks[startStack].pop()); }; -//the above movePiece function just makes the game functional, and lets you move pieces around. It allows for the removal of the last item in the first array (or startStack, in this case), through popping it off the end, and pushing it to the endStack, which could be stack b or c. +//the above movePiece function just makes the game functional, and lets you move pieces around. It allows for the removal of the last item in the first array, or the array you want to pull from (or startStack, in this case), through popping it off the end, and pushing it to the endStack, which could be stack b or c (or a, depending on what stack you're trying to move to/from). However, this function does not ensure legality of moves or order in the arrays. It simply allows the user to pop the last value off their targeted array and move it into a different array (or stack, in this case). -const isLegal = (startStack, endStack) => { - let startTest = stacks[startStack][stacks[startStack].length - 1]; - let endTest = stacks[endStack][stacks[endStack].length - 1]; - - if ((startTest < endTest) || (stacks[endStack].length === 0)) { +const validIput = (startStack, endStack) => { + if ((startStack === 'a') && (endStack === 'b' || endStack === 'c')) { + return true; + } else if ((startStack === 'b') && (endStack === 'a' || endStack === 'c')) { + return true; + } else if ((startStack === 'c') && (endStack === 'a' || endStack === 'b')) { return true; } else { return false; } } -//For the above function, you use .length -1 to get the last value in an array. In this case, whatever piece you're trying to move into a new array either has to be a smaller value than the last value in the array or the array has to be empty. +//the above function makes sure that the user is entering a valid input, in this case only a, b, or c. This rules out all other possible letters, and that your start and end stacks correspond. Example: If your startStack is a, then this function necessitates that your endStack can only be one of two options: b or c. The two subsequent else if statements take all other possible start and end points into account and make sure they correspond. It also explicitly specifies what letters can be used. This function also doesn't allow the user to enter nothing or a space into one of the start or end stack options when playing the game in the terminal, and keeps all illegal moves or selections from throwing a messy error that could force the user to start the entire game over instead of making progress from where they made the mistake. (I feel like this also would have worked as a test) + +const isLegal = (startStack, endStack) => { + if (validIput(startStack, endStack)) { + + let movingPieceValue = stacks[startStack][stacks[startStack].length - 1]; + let endPieceValue = stacks[endStack][stacks[endStack].length - 1]; + + if ((movingPieceValue < endPieceValue) || (stacks[endStack].length === 0)) { + return true; + } else { + console.log("That's an invalid move! Try again.") + return false; + } + } else { + console.log("That's an invalid selection! Enter a, b, or c. Try again.") + return false; + } +} +//For the above function, you use .length -1 array method to access the last value in an array so the user can move it as a piece. isLegal incorporates the previous function, validIput, and makes it part of the conditional statement in order for the isLegal function to work. The validIput function must be working in order for isLegal to work. In this case, whatever piece you're trying to move into a new array (movingPieceValue) either has to be a smaller value than the last value in the array (endPieceValue) or the array has to be empty. If the user tries to make an illegal move, the function runs as false. If the user tries to select something other than a, b, or c, the function also returns as false. I added descriptive console logs to aid the user (and myself) in order to help them make a valid move, and so I knew which mistake I was making/which part of the function was returning false. const checkForWin = () => { if (stacks.c.length === 4) { + console.log("You won! Play again!") return true; } else { return false; - } + } }; -//the above checkForWin function checks for when/if stacks b or c have all four pieces on one stack, or 4 items in the array. If this condition is met for either stack b or c, the user wins. +//the above checkForWin function checks for when/if stack c has all four pieces on stack c, or 4 items in the array. This doesn't check for order because the isLegal function makes sure the order is correct, and the validIput function makes sure there can only be three possible letters used. If this condition is met for stack c, the user wins. const towersOfHanoi = (startStack, endStack) => { - if (isLegal(startStack, endStack)){ //would it be better to structure this with && to make sure these conditions are both met? + if (isLegal(startStack, endStack)){ + //note to self: would it be better to structure this with && to make sure isLegal and movePiece conditions are both met? Would this even be functional? not sure. movePiece(startStack, endStack) - }else { - return "invalid move"; - }if (checkForWin()){ - console.log('You won the game!') - } -} - // } return "You won!"; - // stacks = { - // a: [4, 3, 2, 1], - // b: [], - // c: [] - // }; - // } -// } -//I modeled the above function sort of after my tic tac toe function, especially the board reset and its placement. I'd originally placed it in the checkForWin function. - -function getPrompt() { + } + if (checkForWin()){ + stacks = { + a: [4, 3, 2, 1], + b: [], + c: [] + } + } +}; +//I modeled the above function sort of after my tic tac toe function, especially the board reset and its placement. I'd originally placed it inside the checkForWin function. in this function, the code is first checking to see if the move the user makes is legal through the isLegal function, and if it is, then it runs the movePiece function. Then, if winning conditions are detected (all 4 items in stack c), the board resets to its original state, with all 4 pieces in order on stack a, allowing the user to play again. + +const getPrompt = () => { printStacks(); rl.question('start stack: ', (startStack) => { rl.question('end stack: ', (endStack) => { @@ -75,9 +92,46 @@ function getPrompt() { }); } -getPrompt(); +//Tests below -//tests: -//there should be a test to check to see whether a user's input is valid -//in this case, it would be checking for correct characters, whether its letters or numbers or both. -//it would also be checking to make sure the input suggestion didn't allow cheating. here, that would mean moving the pieces more than one at a time, or too far over, from peg 1 directly to peg 3. +if (typeof describe === 'function') { + +  describe('#towersOfHanoi()', () => { +    it('should be able to move a block', () => { +      towersOfHanoi('a', 'b'); +      assert.deepEqual(stacks, { a: [4, 3, 2], b: [1], c: [] }); +    }); +  }); + +  describe('#isLegal()', () => { +    it('should not allow an illegal move', () => { +      stacks = { +        a: [4, 3, 2], +        b: [1], +        c: [] +      }; +      assert.equal(isLegal('a', 'b'), false); +    }); +    it('should allow a legal move', () => { +      stacks = { +        a: [4, 3, 2, 1], +        b: [], +        c: [] +      }; +      assert.equal(isLegal('a', 'c'), true); +    }); +  }); + + describe('#checkForWin()', () => { +    it('should detect a win', () => { +      stacks = { a: [], b: [4, 3, 2, 1], c: [] }; +      assert.equal(checkForWin(), false); +      stacks = { a: [], b: [], c: [4, 3, 2, 1] }; +      assert.equal(checkForWin(), true); +    }); +  }); +} else { + +  getPrompt(); +//side note: I had issues with this FOREVER because this last getPrompt was in the wrong place. I had it above the tests, and had written the tests below it. Woo! Note to self forever: always have the above final getPrompt(); in the right place. UNDER the tests. +}