My first version met the user story requirements, and accounted for issues such as the user trying to click another grid cell before the computer had taken its turn. I expected completing this first version to take the longest amount of time relative to the other versions. If I had a client with a tight deadline, this version would suffice in meeting the requirements.
But my code was begging to be refactored. I had 244 lines of JavaScript with 13 functions. Less code doesn’t mean better code, but in my case I knew I could be more succinct with my JavaScript. I wanted to break those big functions up into smaller helper functions so I wasn’t repeating myself.
program:--
function checkForWinner() { console.log("checking for winner...") var winner var playerOne = getPlayerOne() //playerOne is always blue! //console.log('checkForWinner, playerOne is: ', playerOne)
var computer = (playerOne === "X") ? "O" : "X"
//there are 8 winningCombos: //three rows, three columns, two diagonals //refactor below.... this is not DRY! var blueWin1 = $("#one.blue, #two.blue, #three.blue").length === 3 var blueWin2 = $("#four.blue, #five.blue, #six.blue").length === 3 var blueWin3 = $("#seven.blue, #eight.blue, #nine.blue").length === 3 var blueWin4 = $("#one.blue, #four.blue, #seven.blue").length === 3 var blueWin5 = $("#two.blue, #five.blue, #eight.blue").length === 3 var blueWin6 = $("#three.blue, #six.blue, #nine.blue").length === 3 var blueWin7 = $("#one.blue, #five.blue, #nine.blue").length === 3 var blueWin8 = $("#seven.blue, #five.blue, #three.blue").length === 3
var redWin1 = $("#one.red, #two.red, #three.red").length === 3 var redWin2 = $("#four.red, #five.red, #six.red").length === 3 var redWin3 = $("#seven.red, #eight.red, #nine.red").length === 3 var redWin4 = $("#one.red, #four.red, #seven.red").length === 3 var redWin5 = $("#two.red, #five.red, #eight.red").length === 3 var redWin6 = $("#three.red, #six.red, #nine.red").length === 3 var redWin7 = $("#one.red, #five.red, #nine.red").length === 3 var redWin8 = $("#seven.red, #five.red, #three.red").length === 3
//var winningCombos = [x] //refactor below too... not DRY at all!!! //note: playerOne is always blue var blueWins = (blueWin1 || blueWin2 || blueWin3 || blueWin4 || blueWin5 || blueWin6 || blueWin7 || blueWin8)
var redWins = (redWin1 || redWin2 || redWin3 || redWin4 || redWin5 || redWin6 || redWin7 || redWin8)
var redCount = getRedCount() //console.log('redCount is: ', redCount) var blueCount = getBlueCount() //console.log('blueCount is: ', blueCount) var fullGrid = redCount + blueCount console.log('fullGrid is: ', fullGrid)
var draw = (fullGrid === 9) && (!blueWins) && (!redWins)
if (blueWins) { //playerOne is always blue winner = blueWins console.log(`${playerOne} wins!`) $("#gameResult, #congratsOrSorry").removeClass("displayNone") $("#gameResult").html(`<span class='yellowBig'>${playerOne} wins!</span>`) $("#congratsOrSorry").html("<span class='yellow'>Congratulations! You won!</span>") $("#gameInfo").addClass("displayNone") disableRemainingItems() return winner } if (redWins) { //red is computer winner = redWins console.log(`${computer} wins!`) $("#gameResult, #congratsOrSorry").removeClass("displayNone") $("#gameResult").html(`<span class='redBig'>${computer} wins!</span>`) $("#congratsOrSorry").html("<span class='red'>Sorry, you lost.</span>") $("#gameInfo").addClass("displayNone") disableRemainingItems() return winner } if (draw) { winner = draw console.log('Draw game!') $("#gameResult, #congratsOrSorry").removeClass("displayNone") $("#gameResult").html(`<span class='redBig'>Game is a draw.</span>`) $("#congratsOrSorry").html("<span>Game ended in a draw.</span>") $("#gameInfo").addClass("displayNone") disableRemainingItems() return winner } else { console.log('game on...') } }
To refactor, I went through my code, and looked for lines that were being repeated multiple times. Those situations presented opportunities to create smaller helper functions, that could then be called from other functions.
I think this is where I could throw around some big words like encapsulation and polymorphism and Object Oriented Programming, but I’m not sure. Maybe this is just an example of functional programming.
For example, in that big checkForWinner function above, I was doing similar things if blue won (playerOne, the human, is blue), or if red won (the computer is red), or if the game ends in a draw.
So, I removed those repeating lines of code and built new functions for checkForWinner to call: playerOneWins, computerWins, and drawGame.
Then I removed the repetitive code from those functions, and created anotherhelper function, winLoseOrDraw, for each of those helper functions to call.
The resulting new functions looked like this:
program:--
function playerOneWins() { var playerOne = getPlayerOne() console.log(`${playerOne} wins!`) $("#gameResult").html(`<span class='yellowBig'>${playerOne} wins!</span>`) $("#congratsOrSorry").html("<span class='yellow'>Congratulations! You won!</span>") winLoseOrDraw() }
function computerWins() { var computer = getComputer() console.log(`${computer} wins!`) $("#gameResult").html(`<span class='redBig'>${computer} wins!</span>`) $("#congratsOrSorry").html("<span class='red'>Sorry, you lost.</span>") winLoseOrDraw() }
function drawGame() { console.log('Draw game!') $("#gameResult").html(`<span class='redBig'>Game is a draw.</span>`) $("#congratsOrSorry").html("<span>Game ended in a draw.</span>") winLoseOrDraw() }
function winLoseOrDraw() { $("#gameResult, #congratsOrSorry").removeClass("displayNone") $("#gameInfo").addClass("displayNone") disableRemainingItems() }
But wait, there’s more! That’s just an example of some of the refactoring I did.
I really didn’t like the way I wrote my 8 winning combos, for red and blue:
var blueWin1 = $("#one.blue, #two.blue, #three.blue").length === 3 var blueWin2 = $("#four.blue, #five.blue, #six.blue").length === 3 var blueWin3 = $("#seven.blue, #eight.blue, #nine.blue").length === 3 var blueWin4 = $("#one.blue, #four.blue, #seven.blue").length === 3 var blueWin5 = $("#two.blue, #five.blue, #eight.blue").length === 3 var blueWin6 = $("#three.blue, #six.blue, #nine.blue").length === 3 var blueWin7 = $("#one.blue, #five.blue, #nine.blue").length === 3 var blueWin8 = $("#seven.blue, #five.blue, #three.blue").length === 3
var redWin1 = $("#one.red, #two.red, #three.red").length === 3 var redWin2 = $("#four.red, #five.red, #six.red").length === 3 var redWin3 = $("#seven.red, #eight.red, #nine.red").length === 3 var redWin4 = $("#one.red, #four.red, #seven.red").length === 3 var redWin5 = $("#two.red, #five.red, #eight.red").length === 3 var redWin6 = $("#three.red, #six.red, #nine.red").length === 3 var redWin7 = $("#one.red, #five.red, #nine.red").length === 3 var redWin8 = $("#seven.red, #five.red, #three.red").length === 3
var blueWins = (blueWin1 || blueWin2 || blueWin3 || blueWin4 || blueWin5 || blueWin6 || blueWin7 || blueWin8)
var redWins = (redWin1 || redWin2 || redWin3 || redWin4 || redWin5 || redWin6 || redWin7 || redWin8)
That code is ugly and super repetitive — the opposite of DRY. It got the job done, but now it was time to refactor, abstract it, make it better.
There are many ways to do this, but the way I chose to do it was with a couple map functions, to create two arrays, a blueWinArray and a redWinArray. Both of these map over my abstracted eightWinningCombos array of strings, replacing “COLOR” with “red” or “blue”, then check for if and when either array goes from containing eight false conditions to a true condition, when one of those arrays does indeed include a winning combo.
function checkForWinner() { console.log("checking for winner...") var winner var playerOne = getPlayerOne() //playerOne is always blue var computer = getComputer() //computer is always red
var eightWinningCombos = [ "#one.COLOR, #two.COLOR, #three.COLOR", "#four.COLOR, #five.COLOR, #six.COLOR", "#seven.COLOR, #eight.COLOR, #nine.COLOR", "#one.COLOR, #four.COLOR, #seven.COLOR", "#two.COLOR, #five.COLOR, #eight.COLOR", "#three.COLOR, #six.COLOR, #nine.COLOR", "#one.COLOR, #five.COLOR, #nine.COLOR", "#seven.COLOR, #five.COLOR, #three.COLOR" ]
var blueWinArray = eightWinningCombos.map(function(combo) { var eachCombo = combo.replace(/COLOR/g, "blue") return eachCombo = $(eachCombo).length === 3 }) var redWinArray = eightWinningCombos.map(function(combo) { var eachCombo = combo.replace(/COLOR/g, "red") return eachCombo = $(eachCombo).length === 3 })
var blueWins = blueWinArray.includes(true) var redWins = redWinArray.includes(true)
var redCount = getRedCount() var blueCount = getBlueCount() var fullGrid = redCount + blueCount var draw = (fullGrid === 9) && (!blueWins) && (!redWins)
if (blueWins) { //playerOne is always blue playerOneWins() return winner = blueWins } if (redWins) { //red is computer computerWins() return winner = redWins } if (draw) { drawGame() return winner = draw } else { console.log('game on...') } }
Of course, this function could be refactored even more, but for my purposes I’m glad that it’s been somewhat abstracted, and is now a bit cleaner.
Ah what the hell, let’s abstract it even more.
I can break out two of those functions into two helper functions:
function getBlueWinArray(array) { return array.map(function(combo) { var eachCombo = combo.replace(/COLOR/g, "blue") return eachCombo = $(eachCombo).length === 3 }) }
function getRedWinArray(array) { return array.map(function(combo) { var eachCombo = combo.replace(/COLOR/g, "red") return eachCombo = $(eachCombo).length === 3 }) }
I can refactor those two functions into one function, that takes a string as a separate argument:
function getWinningArray(array, string) { return array.map(function(combo) { var eachCombo = combo.replace(/COLOR/g, string) return eachCombo = $(eachCombo).length === 3 }) }
Now my checkForWinner function looks like this:
function checkForWinner() { console.log("checking for winner...") var winner
var eightWinningCombos = [ "#one.COLOR, #two.COLOR, #three.COLOR", "#four.COLOR, #five.COLOR, #six.COLOR", "#seven.COLOR, #eight.COLOR, #nine.COLOR", "#one.COLOR, #four.COLOR, #seven.COLOR", "#two.COLOR, #five.COLOR, #eight.COLOR", "#three.COLOR, #six.COLOR, #nine.COLOR", "#one.COLOR, #five.COLOR, #nine.COLOR", "#seven.COLOR, #five.COLOR, #three.COLOR" ]
var blueWinArray = getWinningArray(eightWinningCombos, "blue") var redWinArray = getWinningArray(eightWinningCombos, "red") var blueWins = blueWinArray.includes(true) var redWins = redWinArray.includes(true) var fullGrid = getRedCount() + getBlueCount() var draw = (fullGrid === 9) && (!blueWins) && (!redWins) if (blueWins) { playerOneWins() return winner = blueWins } if (redWins) { computerWins() return winner = redWins } if (draw) { drawGame() return winner = draw } else { console.log('game on...') } }
what’s the code of game Tic-tac-toe by using the Alpha Beta Turing algorithm ? The code...
PYTHON Exercise 2. Tic-Tac-Toe In this exercise we are going to create a Tic-Tac-Toe game. 1. Create the data structure – Nine slots that can each contain an X, an O, or a blank. – To represent the board with a dictionary, you can assign each slot a string-value key. – String values in the key-value pair to represent what’s in each slot on the board: ■ 'X' ■ 'O' ■ ‘ ‘ 2. Create a function to print the...
Please write a tic tac toe game using c++ language and 1D arrays, thank you!
(Game: play a tic-tac-toe game) In a game of tic-tac-toe, two players take turns marking an available cell in a grid with their respective tokens (either X or O). When one player has placed three tokens in a horizontal, vertical, or diagonal row on the grid, the game is over and that player has won. A draw (no winner) occurs when all the cells in the grid have been filled with tokens and neither player has achieved a win. Create...
Create a batch file tic tac toe game written in C code. This code should be able to run through an emulator.
Create a very basic tic tac toe game written in C code. This C code should be able to create a GBA file from using devkit to run in visual boy advance.
1. Use Turtle Graphics to create a tic tac toe game in Python. Write a Python program that allows for one player vs computer to play tic tac toe game, without using turtle.turtle
Tic tac toe game C++ programing using classes, objects, arays
use python to do it implement the tic-tac-toe game. What to submit: 1. Your source code 2. Two runs, one user wins and one user loses.
(Tic-Tac-Toe) Create a class Tic-Tac-Toe that will enable you to write a program to play Tic-Tac-Toe. The class contains a private 3-by-3 two-dimensional array. Use an enumeration to represent the value in each cell of the array. The enumeration’s constants should be named X, O and EMPTY (for a position that does not contain an X or an O). The constructor should initialize the board elements to EMPTY. Allow two human players. Wherever the first player moves, place an X...
tic-tac-toe game. Add functionality to the program so when the button is clicked for the AI to take a turn, a heuristic is applied for each of the possible moves, a possible move is selected and the game state and GUI are properly updated. Once complete, the program should be able to play a single game of tic-tac-toe with the user. C#