I am trying to learn how to code by looking a solutions for previous codes and finding out what each part is doing to learn how to use them. I want to become a developer but I do not want to copy and paste everything , I want to actually know what is happening so I can code this myself. I can watch 100 videos but I have questions and I need help, hope someone out there can help me ….
I was wondering if someone could explain to me what is going on in the code below.
* Player 1 and 2 alternate turns. On each turn, a piece is dropped down a * column until a player gets four-in-a-row (horiz, vert, or diag) or until * board fills (tie) */ class Game { constructor(p1, p2, height = 6, width = 7) { this.players = [p1, p2]; this.height = height; this.width = width; this.currPlayer = p1; this.makeBoard(); this.makeHtmlBoard(); this.gameOver = false; } /** makeBoard: create in-JS board structure: * board = array of rows, each row is array of cells (board[y][x]) */ **Question: So I believe that this is creating a board and making it empty by looping through it?** makeBoard() { this.board = []; for (let y = 0; y < this.height; y++) { this.board.push(Array.from({ length: this.width })); } } **Question: Is this grabbing the board element from the HTML Page? board.innerHtml is blank, however didnt we just make a blank a board? Why do we need this?** makeHtmlBoard() { const board = document.getElementById('board'); board.innerHTML = ''; // make column tops (clickable area // for adding a piece to that column) const top = document.createElement('tr'); top.setAttribute('id', 'column-top'); // store a reference to the handleClick bound function // so that we can remove the event listener correctly later this.handleGameClick = this.handleClick.bind(this); top.addEventListener("click", this.handleGameClick); for (let x = 0; x < this.width; x++) { const headCell = document.createElement('td'); headCell.setAttribute('id', x); top.append(headCell); } board.append(top); // make main part of board for (let y = 0; y < this.height; y++) { const row = document.createElement('tr'); for (let x = 0; x < this.width; x++) { const cell = document.createElement('td'); cell.setAttribute('id', `${y}-${x}`); row.append(cell); } board.append(row); } } /** findSpotForCol: given column x, return top empty y (null if filled) */ **Question: I have no idea what this line is doing** findSpotForCol(x) { for (let y = this.height - 1; y >= 0; y--) { if (!this.board[y][x]) { return y; } } return null; } /** placeInTable: update DOM to * place piece into HTML board */ **Question: Im not sure what place in table is doing, however I know the second line is creating a DIV on the table , third line is styling it, however the last three lines i need help with it.** placeInTable(y, x) { const piece = document.createElement('div'); piece.classList.add('piece'); piece.style.backgroundColor = this.currPlayer.color; piece.style.top = -50 * (y + 2); const spot = document.getElementById(`${y}-${x}`); spot.append(piece); } /** endGame: announce game end */ endGame(msg) { alert(msg); const top = document.querySelector("#column-top"); top.removeEventListener("click", this.handleGameClick); } /** handleClick: handle click of column top to play piece */ handleClick(evt) { // get x from ID of clicked cell const x = +evt.target.id; The lines below, I have no idea how I could even think of this logic , please help. ****// get next spot in column (if none, ignore click) const y = this.findSpotForCol(x); if (y === null) { return;** } // place piece in board and add to HTML table this.board[y][x] = this.currPlayer; this.placeInTable(y, x); // check for tie if (this.board.every(row => row.every(cell => cell))) { return this.endGame('Tie!'); } // check for win if (this.checkForWin()) { this.gameOver = true; return this.endGame(`The ${this.currPlayer.color} player won!`); } // switch players this.currPlayer = this.currPlayer === this.players[0] ? this.players[1] : this.players[0];** } /** checkForWin: check board cell-by-cell for "does a win start here?" */ checkForWin() { // Check four cells to see if they're all color of current player // - cells: list of four (y, x) cells // - returns true if all are legal coordinates & all match currPlayer const _win = cells => cells.every( ([y, x]) => y >= 0 && y < this.height && x >= 0 && x < this.width && this.board[y][x] === this.currPlayer ); for (let y = 0; y < this.height; y++) { for (let x = 0; x < this.width; x++) { // get "check list" of 4 cells (starting here) for each of the different // ways to win const horiz = [[y, x], [y, x + 1], [y, x + 2], [y, x + 3]]; const vert = [[y, x], [y + 1, x], [y + 2, x], [y + 3, x]]; const diagDR = [[y, x], [y + 1, x + 1], [y + 2, x + 2], [y + 3, x + 3]]; const diagDL = [[y, x], [y + 1, x - 1], [y + 2, x - 2], [y + 3, x - 3]]; // find winner (only checking each win-possibility as needed) if (_win(horiz) || _win(vert) || _win(diagDR) || _win(diagDL)) { return true; } } } } } class Player { constructor(color) { this.color = color; } } document.getElementById('start-game').addEventListener('click', () => { let p1 = new Player(document.getElementById('p1-color').value); let p2 = new Player(document.getElementById('p2-color').value); new Game(p1, p2); });
Advertisement
Answer
A big part of programming is decomposing problems into smaller ones that you can understand. It’s likely the syntax and size of this problem is a little advanced for a beginner.
In general – here is an overview:
- Correct
- There is a ‘board’ in javascript and a ‘board’ in HTML. The javascript one is for logic, while the HTML one is for display purposes. That’s why you see two boards being created
findSpotForCol
is finding the highest unfilled spot in a given column. This would be a good problem for you to really dive into and try to write it yourself. When you drop a token in a connect 4, it goes to highest spot in that column, that isn’t currently filled.findSpotforCol
is an algorithm to do that.- Each player has their own color. This is putting the checker in the right spot with the correct players color. This is taking our JavaScript logic board, and making it display correctly on the page when a player makes a move
- It’s okay to feel overwhelmed! (“I have no idea how I could even think of this logic”). Think about everything you do when you play connect 4. First you drop in a checker to a column. It goes to the lowest spot available in that column. Then – if the whole board is full, it’s a tie. Then you might check if a player won. (Note – there is a bug in this code you pasted, if a player wins on the last checker, it will say ‘Tie’, since it checks for a tie first). Then, it’s the other players turn.
It took me a long time of doing lots of beginner exercises for me to understand a problem like this, which is getting more advanced, so don’t feel bad about having to review the beginner exercises or learn from other platforms/tools/books. If you feel 100% overwhelmed, that’s not a good spot to learn from, and you should maybe look for a simpler problem. Tic-Tac-Toe for example would be one step easier than connect four.