Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 38 additions & 14 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,25 +1,49 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta charset="utf-8" />
<title></title>
<script src="index.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<h1>Towers Of Hanoi</h1>
<hr/>
<div id="top-row" data-row="top" class="red row" onclick="selectRow(this)"></div>
<div id="middle-row" data-row="middle" class="yellow row" onclick="selectRow(this)"></div>
<div id="bottom-row" class="green row" data-row="bottom" onclick="selectRow(this)">
<div id="4" data-size="4" data-color="yellow" class="stone" ></div>
<div id="3" data-size="3" data-color="red" class="stone" ></div>
<div id="2" data-size="2" data-color="green" class="stone" ></div>
<div id="1" data-size="1" data-color="blue" class="stone" ></div>
<!-- <hr /> -->
<div class="row-container">
<div
id="top-row"
data-row="top"
class="red row"
onclick="selectRow(this)"
></div>
<div
id="middle-row"
data-row="middle"
class="yellow row"
onclick="selectRow(this)"
></div>
<div
id="bottom-row"
class="green row"
data-row="bottom"
onclick="selectRow(this)"
>
<div id="4" data-size="4" data-color="yellow" class="stone"></div>
<div id="3" data-size="3" data-color="red" class="stone"></div>
<div id="2" data-size="2" data-color="green" class="stone"></div>
<div id="1" data-size="1" data-color="blue" class="stone"></div>
</div>
<hr/>
</div>
<!-- <hr /> -->
<div class="move-counter"></div>
<div class="announce-game-won">
<h2>You Win!</h2>
</div>
</body>
</html>



102 changes: 74 additions & 28 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,88 @@
// * This js file is incomplete. It will log to the console the elements you click
// call another function and set stone. You will have to work through the logic
// of the game as you know it from building it in the terminal. Work through the
// puzzle slowly, stepping through the flow of logic, and making the game work.
// Have fun!!
// call another function and set stone. You will have to work through the logic
// of the game as you know it from building it in the terminal. Work through the
// puzzle slowly, stepping through the flow of logic, and making the game work.
// Have fun!!
// * First run the program in your browser with live server and double-click on the row you'd like to select an element from.
// * Why are you get a warning in your console? Fix it.
// * Delete these comment lines!

const stone = null

// this function is called when a row is clicked.
// Open your inspector tool to see what is being captured and can be used.
let stone = null;
let dropStoneFunction = false;
let moves = 0;
// #This function selects the row and calls the toggle function. When a row is
// #clicked, this function is run.
const selectRow = (row) => {
const currentRow = row.getAttribute("data-row")

console.log("Yay, we clicked an item", row)
console.log("Here is the stone's id: ", row.id)
console.log("Here is the stone's data-size: ", currentRow)
const currentRow = row.getAttribute('data-row');

pickUpStone(row.id)
}
// console.log('Yay, we clicked an item', row);
// console.log("Here is the stone's id: ", row.id);
// console.log("Here is the stone's data-size: ", currentRow);
//# Calling toggle function to determine whether or not we will be picking up a stone or dropping a stone.
toggleFunction(row.id, stone);
console.log(dropStoneFunction);
};

// this function can be called to get the last stone in the stack
// but there might be something wrong with it...
// #Function to pick up the last stone. This is done by removing the last child
// #from the row parent element.
const pickUpStone = (rowID) => {
// console.log(rowID);
const selectedRow = document.getElementById(rowID);
stone = selectedRow.removeChild(selectedRow.lastChild);
console.log(stone)
}

// You could use this function to drop the stone but you'll need to toggle between pickUpStone & dropStone
// Once you figure that out you'll need to figure out if its a legal move...
// Something like: if(!stone){pickupStone} else{dropStone}
// console.log(selectedRow);
stone = selectedRow.removeChild(selectedRow.lastElementChild);
// console.log(stone);
};

// # Function to drop the stone. This is done by selecting the row where the stone needs to be dropped and verifying if there is currently anything in that row. If so, we need to make sure that the existing stone is larger than the stone we want to replace.
const dropStone = (rowID, stone) => {
document.getElementById(rowID).appendChild(stone)
stone = null
}
const movesCounter = document.querySelector('.move-counter');
const selectedRow = document.getElementById(rowID);
const existingStone = selectedRow.lastElementChild;
console.log(stone.getAttribute('data-size'));
// # Conditional to determine if a stone can be dropped.
if (
existingStone === null ||
existingStone.getAttribute('data-size') > stone.getAttribute('data-size')
) {
// #If the stone can be dropped we append the stone element and move the
// #counter up by one.
selectedRow.appendChild(stone);
moves++;
} else {
// #If not, we initiate an alert and keep the dropStoneFunction toggle
// #variable set to false so we can drop the stone in a valid row. We don't
// #want the dropStoneFunction to change because it will make the next move
// #a pick up stone function.
window.alert('Invalid Move!');
dropStoneFunction = false;
}

// * Remember you can use your logic from 'main.js' to maintain the rules of the game. But how? Follow the flow of data just like falling dominoes.
stone = null;

// #Here we are deleting the counter and adding one each time a move is logged.
movesCounter.innerHTML = '';
movesCounter.insertAdjacentHTML(
'afterbegin',
`
<h4>Number of Moves:</h4>
<p>${moves}</p>`
);
checkForWin(selectedRow);
};

// #This function toggles between the dropStone function and the pickUpStone
// #function. This is done by watching the dropStoneFunction boolean value.
const toggleFunction = (row, stone) => {
dropStoneFunction ? dropStone(row, stone) : pickUpStone(row);
dropStoneFunction = !dropStoneFunction;
};

// # We are checking for win by counting the number of child elements. Once child elements equal 4, the game is won.
const checkForWin = (row) => {
if (row.childElementCount === 4) {
document.querySelector('.announce-game-won').classList.add('active');
}
};

const playGame = () => {};
// * Remember you can use your logic from 'main.js' to maintain the rules of the game. But how? Follow the flow of data just like falling dominoes.
111 changes: 75 additions & 36 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,99 @@

const assert = require('assert');
const readline = require('readline');
const { start } = require('repl');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
output: process.stdout,
});

// An object that represents the three stacks of Towers of Hanoi;
// * each key is an array of Numbers:
// * A is the far-left,
// * B is the middle,
// * C is the far-right stack
// * Each number represents the largest to smallest tokens:
// * 4 is the largest,
// * 1 is the smallest
// An object that represents the three stacks of Towers of Hanoi;
// * each key is an array of Numbers:
// * A is the far-left,
// * B is the middle,
// * C is the far-right stack
// * Each number represents the largest to smallest tokens:
// * 4 is the largest,
// * 1 is the smallest

let stacks = {
a: [4, 3, 2, 1],
b: [],
c: []
c: [],
};

// Start here. What is this function doing?
//? Start here. What is this function doing?
// # This function is loggint the array of each of the three object keys.
const printStacks = () => {
console.log("a: " + stacks.a);
console.log("b: " + stacks.b);
console.log("c: " + stacks.c);
}
console.log('a: ' + stacks.a);
console.log('b: ' + stacks.b);
console.log('c: ' + stacks.c);
};

// Next, what do you think this function should do?
const movePiece = () => {
// Your code here

}

// Before you move, should you check if the move it actually allowed? Should 3 be able to be stacked on 2
const isLegal = () => {
// Your code here
const movePiece = (startStack, endStack) => {
// #Use .pop() to remove last item from the stacks array identified by the
// #startStack argument and store it to a variable.
let moveFrom = stacks[startStack].pop();
// #Pushing that variable to a the array in the stacks objects indentified by
// #the endStack argument.
stacks[endStack].push(moveFrom);
// console.log(moveTo);
};

}
// ?Before you move, should you check if the move it actually allowed? Should 3 be able to be stacked on 2
const isLegal = (startStack, endStack) => {
// #Creating a variable to hold the startStack piece by selecting the last
// #element in the startStack array.
let startStackPiece = stacks[startStack].slice(-1);
// #Creating a variable to hold the endStack piece by selecting the last
// #element in the endStack array.
let endStackPiece = stacks[endStack].slice(-1);

// #Comparing the startStack piece to the endStack piece to allow moves only
// #in the event the startStack piece is smaller than the endStack piece.
if (
(startStackPiece > endStackPiece && endStackPiece.length > 0) ||
// #Also confirming that the startStack location is not the same as the
// #endStack location.
startStack === endStack
) {
return false;
}
return true;
};

// What is a win in Towers of Hanoi? When should this function run?
const checkForWin = () => {
// Your code here

}
// # If the array length of stacks b or c is 4, you win.
if (stacks.b.length === 4 || stacks.c.length === 4) {
return true;
} else return false;
};

// When is this function called? What should it do with its argument?
const towersOfHanoi = (startStack, endStack) => {
// Your code here

}
//@ set variables
//@ Check to see if isLegal(start, end)
//@ if true run movePiece() if not run the invalid console.log
// check for win
// #Creating variables to identify the start and end stacks.
let start = startStack;
let end = endStack;

// #Calling the isLegal function inside a conditional statement to determine
// #if a move can be made. The isLegal function is called using the variables
// #above to identify which arrays we will be comparing.
if (isLegal(start, end) == true) {
// #If the isLegal function returns true, call the move piece function to
// #move the piece to the selected array which are identified by the
// #function arguments.
movePiece(start, end);
} else {
console.log(`Invalid move.`);
}
};

const getPrompt = () => {
printStacks();
Expand All @@ -61,12 +104,11 @@ const getPrompt = () => {
getPrompt();
});
});
}
};

// Tests

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

describe('#towersOfHanoi()', () => {
it('should be able to move a block', () => {
towersOfHanoi('a', 'b');
Expand All @@ -79,15 +121,15 @@ if (typeof describe === 'function') {
stacks = {
a: [4, 3, 2],
b: [1],
c: []
c: [],
};
assert.equal(isLegal('a', 'b'), false);
});
it('should allow a legal move', () => {
stacks = {
a: [4, 3, 2, 1],
b: [],
c: []
c: [],
};
assert.equal(isLegal('a', 'c'), true);
});
Expand All @@ -100,9 +142,6 @@ if (typeof describe === 'function') {
assert.equal(checkForWin(), false);
});
});

} else {

getPrompt();

}
Loading