Last active
December 24, 2019 08:42
-
-
Save angeloreale/38a2ba136c487b83ae0d3833d197c677 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template lang="pug"> | |
.tictactoe | |
.board | |
.row(v-for="(row, y) in currentMatrix", :key="y") | |
button.cell(v-for="(cell, x) in row", :key="x", :position="x, y", @click="userPlays(x,y)", :disabled="end || currentMatrix[y][x] !== 0")="{{setIcon(x,y)}}" | |
.status="{{status}}" | |
button(v-if="end" @click="rebootGame")="Reboot" | |
</template> | |
<script> | |
export default { | |
name: 'app', | |
data: function () { | |
return { | |
currentMatrix: [[0, 0, 0], [0, 0, 0], [0, 0, 0]], | |
status: 'In progress', | |
end: false, | |
userIcon: 'x', | |
machineIcon: 'o' | |
} | |
}, | |
methods: { | |
setIcon (x, y) { | |
return this.currentMatrix[y][x] === 0 ? '' : this.currentMatrix[y][x] === 1 ? this.userIcon : this.machineIcon | |
}, | |
userPlays (myX, myY) { | |
if (this.currentMatrix[myY][myX] === 0) { | |
this.$set(this.currentMatrix[myY], myX, 1) | |
} | |
this.hasAnyPlayerWon(myX, myY) | |
if (!this.end) { | |
this.computerPlays() | |
} | |
}, | |
computerPlays () { | |
let isWinning = this.isUserAboutToWin() | |
if (isWinning && isWinning.isWinning) { | |
let computerX = isWinning.positionToWatch[0] | |
let computerY = isWinning.positionToWatch[1] | |
if (!this.end) { | |
this.$set(this.currentMatrix[computerY], computerX, 2) | |
} | |
this.hasAnyPlayerWon(computerX, computerY) | |
} else { | |
let computerX = Math.floor(Math.random() * 3) | |
let computerY = Math.floor(Math.random() * 3) | |
while (this.currentMatrix[computerY][computerX] !== 0) { | |
computerX = Math.floor(Math.random() * 3) | |
computerY = Math.floor(Math.random() * 3) | |
} | |
this.hasAnyPlayerWon(computerX, computerY) | |
if (!this.end) { | |
this.$set(this.currentMatrix[computerY], computerX, 2) | |
} | |
} | |
}, | |
hasAnyPlayerWon (thisx, thisy) { | |
// verify row victory | |
if (this.currentMatrix[thisy].filter(el => el === 1).length === 3) { | |
this.endGame('1') | |
return true | |
} else if (this.currentMatrix[thisy].filter(el => el === 2).length === 3) { | |
this.endGame('2') | |
return true | |
} | |
// verify column victory | |
if (this.currentMatrix.filter(el => el[thisx] === 1).length === 3) { | |
this.endGame('1') | |
return true | |
} else if (this.currentMatrix.filter(el => el[thisx] === 2).length === 3) { | |
this.endGame('2') | |
return true | |
} | |
// verify diagonal victory | |
let diagonals = [[{ position: [0, 0], value: this.currentMatrix[0][0] }, | |
{ position: [1, 1], value: this.currentMatrix[1][1] }, | |
{ position: [2, 2], value: this.currentMatrix[2][2] }], | |
[{ position: [0, 2], value: this.currentMatrix[0][2] }, | |
{ position: [1, 1], value: this.currentMatrix[1][1] }, | |
{ position: [2, 0], value: this.currentMatrix[2][0] }]] | |
for (let i = 0; i < diagonals.length; i++) { | |
for (let j = 0; j < diagonals[i].length; j++) { | |
if (diagonals[i].filter(el => el.value === 1).length === 3) { | |
this.endGame('1') | |
return true | |
} else if (diagonals[i].filter(el => el.value === 2).length === 3) { | |
this.endGame('2') | |
return true | |
} | |
} | |
} | |
// verify draw | |
for (let k = 0; k < this.currentMatrix.length; k++) { | |
for (let g = 0; g < this.currentMatrix[k].length; g++) { | |
if (this.currentMatrix[k][g] === 0) { | |
return true | |
} | |
} | |
if (k === this.currentMatrix.length - 1) { | |
this.endGame('3') | |
return false | |
} | |
} | |
return false | |
}, | |
isUserAboutToWin () { | |
let newPosition = {} | |
for (let y = 0; y < this.currentMatrix.length; y++) { | |
for (let x = 0; x < this.currentMatrix[y].length; x++) { | |
if (!newPosition.isWinning) { | |
var position = -1 | |
} | |
// verify row | |
if (this.currentMatrix[y][x] === 1 && | |
(this.currentMatrix[y].filter(el => el === 1).length > 1) && | |
(this.currentMatrix[y].indexOf(0) !== -1)) { | |
position = this.currentMatrix[y].findIndex(el => el === 0) | |
return { isWinning: true, positionToWatch: [position, y] } | |
} | |
// verify column | |
if (this.currentMatrix[y][x] === 1 && | |
(this.currentMatrix.filter(el => el[x] === 1).length > 1) && | |
(this.currentMatrix.findIndex(el => el[x] === 0) !== -1)) { | |
position = this.currentMatrix.findIndex(el => el[x] === 0) | |
return { isWinning: true, positionToWatch: [x, position] } | |
} | |
// verify diagonal | |
let diagonals = [[{ position: [0, 0], value: this.currentMatrix[0][0] }, | |
{ position: [1, 1], value: this.currentMatrix[1][1] }, | |
{ position: [2, 2], value: this.currentMatrix[2][2] }], | |
[{ position: [0, 2], value: this.currentMatrix[0][2] }, | |
{ position: [1, 1], value: this.currentMatrix[1][1] }, | |
{ position: [2, 0], value: this.currentMatrix[2][0] }]] | |
for (let i = 0; i < diagonals.length; i++) { | |
for (let j = 0; j < diagonals[i].length; j++) { | |
if (this.currentMatrix[y][x] === 1 && | |
(diagonals[i].filter(el => el.value === 1).length > 1) && | |
(diagonals[i].findIndex(el => el.value === 0) !== -1)) { | |
let positionArr = diagonals[i].filter(el => el.value === 0)[0].position.reverse() | |
return { isWinning: true, positionToWatch: positionArr } | |
} | |
} | |
} | |
} | |
} | |
}, | |
endGame (whoWon) { | |
this.end = true | |
switch (whoWon) { | |
case '1': { | |
this.status = 'You won! :)' | |
break | |
} | |
case '2': { | |
this.status = 'Machine won! :(' | |
break | |
} | |
case '3': { | |
this.status = "It's a draw!" | |
break | |
} | |
} | |
}, | |
rebootGame () { | |
this.end = false | |
this.status = 'In progress' | |
this.currentMatrix = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] | |
} | |
} | |
} | |
</script> | |
<style lang="scss"> | |
.tictactoe { | |
max-width: 300px; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
margin: 0 auto; | |
height: 100vh; | |
flex-direction: column; | |
.board { | |
.row { | |
padding: 1em 0; | |
border-bottom: solid 1px black; | |
width: fit-content; | |
&:last-of-type { | |
border: none; | |
} | |
.cell { | |
margin: 0 1em; | |
width: 2em; | |
height: 2em; | |
border-right: solid 1px black; | |
position: relative; | |
font-size: 1em; | |
&:active, &:focus { | |
border: none; | |
outline: none; | |
} | |
&:after { | |
content: ""; | |
width: 1px; | |
height: 67px; | |
display: -webkit-box; | |
display: -ms-flexbox; | |
display: flex; | |
position: absolute; | |
top: -20px; | |
background: black; | |
left: 45px; | |
} | |
&:last-of-type { | |
&:after { | |
visibility: hidden; | |
} | |
} | |
} | |
} | |
} | |
.status { | |
margin-top: 2em; | |
border-top: solid 1px green; | |
color: green; | |
width: 100%; | |
text-align: center; | |
padding: 1em; | |
} | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment