Skip to content
124 changes: 108 additions & 16 deletions 03week/towersOfHanoi.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,94 @@ let stacks = {
c: []
};

function printStacks() {
const printStacks = () => {
console.log("a: " + stacks.a);
console.log("b: " + stacks.b);
console.log("c: " + stacks.c);
}

function movePiece() {
// Your code here

const movePiece = (startStack, endStack) => {
stacks[endStack].push(stacks[startStack].pop());
}

function isLegal() {
// Your code here

const isLegal = (startStack, endStack) => {
return stacks[startStack].length > 0 &&
stacks[endStack].length == 0 ||
stacks[startStack].slice(-1)[0]<stacks[endStack].slice(-1)[0]
// So where you are choosing from needs to have an element, do not do anything if that isn't true
// In addiation if the place we are putting is empty, go ahead and do it
// if it isn't, then make sure the place we are putting it has a bigger peice than the new one
// I had this broken out into 4 variables to increase redability, compressed it down to a single line
// let me know what is better coding practice in a case like this, want to be a good coder!
}
const validLetter = (letterInput) =>{
switch(letterInput.toLowerCase()){
case "a":
case "b":
case "c":
return true;
default:
return false;
}
// there are likely better ways to do this but I just wanted to use a switch statement, cause I never do!
}

function checkForWin() {
// Your code here

const checkForWin = () => {
return stacks["a"].length == 0 && stacks["b"].length == 0;
// done this way so I could, in theory, expand the number of disks
// for whatever reason I always like making things that can expand!
}

function towersOfHanoi(startStack, endStack) {
// Your code here
const resetGame = () => {
while(stacks['c'].length>0){
stacks['a'].push(stacks['c'].shift());
}

// Not sure if this is prefered as opposed to just setting the object = to the values like
//stacks = {
// a: [4, 3, 2, 1],
// b: [],
// c: []
// will experiment later. Also, need to ask if this causes memory leak if it does work
// this old c programer so afarid of memory misallocation!
}

// let it begin! Code Plan!
// We get user input from where they want to take from to where they want to put to (startStack, endStack)
// We see if this is a legal move isLegal()T/F
// if so we move the peiece movePiece()
// We see if this condition gives them a win (all stacked up properly on stack c) checkForWin()T/F
// After they win reset the game
// self challenge: add harder difficulty by adding a disk after reset
// add turn counter and give user feed back on what a perfect game is compared to theirs

const towersOfHanoi = (startStack, endStack) => {
const formatedStart = startStack.toLowerCase();
const formatedEnd = endStack.toLowerCase();
// since I used these so much, I decided to make variable for them
// could remove if it is a good practice to not make temps for something like this

if(validLetter(formatedStart) && validLetter(formatedEnd)){
if(isLegal(formatedStart, formatedEnd)){
if (formatedStart != formatedEnd){
movePiece(formatedStart, formatedEnd);
if(checkForWin()){
printStacks();
console.log("You win, you rock at computer science!")
resetGame();
}
}else{
console.log("Dude, move the peice don't fondle it")
}
}else{
console.log("Not valid move, can't move bigger numbers on top of smaller numbers and can't move empty rows at all!")
}
}else{
console.log("Invalid letter: Please only a, b or c")
}
}

function getPrompt() {
const getPrompt = () => {
printStacks();
rl.question('start stack: ', (startStack) => {
rl.question('end stack: ', (endStack) => {
Expand All @@ -53,13 +114,43 @@ function getPrompt() {

if (typeof describe === 'function') {

// new

// note: For some of my function's weren't returning false values, but rather undefines. For whatever reason
// mocha will fail the test when it tests for false and sees undefined.
// I modified the tests to undefined when it mattered, though this feels like a poor solution.
// will update them with your recomendations if you have any.

describe('#validLetter()', () => {
it('Should disallow invalid inputs', () => {
assert.equal(validLetter('dog'), false);
});
});
describe('#validLetter()', () => {
it('Shoudl allow for upper case of letters', () => {
assert.equal(validLetter('B'), true);
});
});
describe('#resetGame()', () => {
it('Should correctly reset stacks', () => {
stacks = {
a: [],
b: [],
c: [4, 3, 2, 1]
};
resetGame();
assert.deepEqual(stacks, { a: [4, 3, 2, 1], b: [], c: [] });
});
});

//new

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 = {
Expand All @@ -80,10 +171,11 @@ if (typeof describe === 'function') {
});
describe('#checkForWin()', () => {
it('should detect a win', () => {
stacks = { a: [], b: [4, 3, 2, 1], c: [] };
stacks = { a: [], b: [], c: [4, 3, 2, 1] };
assert.equal(checkForWin(), true);
stacks = { a: [1], b: [4, 3, 2], c: [] };
stacks = { a: [1], b: [], c: [4, 3, 2] };
assert.equal(checkForWin(), false);
// I changed your victory condition to stack C
});
});

Expand Down