Skip to content

Commit

Permalink
Playable game
Browse files Browse the repository at this point in the history
  • Loading branch information
erenard committed May 19, 2019
1 parent 214b682 commit 4203143
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 139 deletions.
2 changes: 0 additions & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
<div id="app">
<GameBoard :rows="8" :columns="8" />
<!-- <img alt="Vue logo" src="./assets/logo.png"> -->
<!-- <HelloWorld msg="Welcome to Your Vue.js App"/> -->
</div>
</template>

<script>
// import HelloWorld from './components/HelloWorld.vue'
import GameBoard from './components/GameBoard.vue'
export default {
Expand Down
41 changes: 34 additions & 7 deletions src/components/GameBoard.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
<template>
<div>
<div
v-for="(row, rowIndex) in game.board"
v-for="rowIndex in height"
:key="'row' + rowIndex"
class="game-board-row"
>
<game-board-square
v-for="(square, columnIndex) in row"
v-for="columnIndex in width"
:key="'square' + rowIndex + '-' + columnIndex"
:state="square"
@play="handlePlay([rowIndex, columnIndex])"
:disk="board[rowIndex - 1][columnIndex - 1]"
@play="play([rowIndex - 1, columnIndex - 1])"
/>
</div>
<game-score
:score="score"
@restart="restart"
/>
</div>
</template>

Expand All @@ -24,16 +28,39 @@ export default {
'game-board-square': GameBoardSquare
},
data: () => ({
game: new Reversi()
game: null,
score: null
}),
computed: {
width () {
return this.game ? this.game.width : 0
},
height () {
return this.game ? this.game.height : 0
},
board () {
return this.game ? this.game.board : 0
}
},
methods: {
handlePlay (position) {
play (position) {
this.game.clearHints()
this.game.play(position)
this.score = this.game.prepareNextTurn()
},
restart () {
this.game.reset()
this.score = this.game.prepareNextTurn()
}
},
watch: {
score () {
}
},
mounted () {
this.game = new Reversi()
this.game.prepareHints()
this.score = this.game.prepareNextTurn()
}
}
</script>
Expand Down
39 changes: 22 additions & 17 deletions src/components/GameBoardSquare.vue
Original file line number Diff line number Diff line change
@@ -1,33 +1,32 @@
<template>
<div class="square">
<span :style="{ opacity: diskAlpha }">
{{ diskChar }}
<div class="square" @click="handleClick" :class="{ hint: isHint }">
<span>
{{ disk.char }}
</span>
</div>
</template>

<script>
import { fromNumber } from '../models/Disk'
import { DiskConstants } from '../models/Disk'
export default {
props: {
state: {
type: Number,
default: 0
disk: {
type: Object,
required: true
}
},
computed: {
diskChar () {
return fromNumber(this.state)
},
diskAlpha () {
return Math.min(Math.abs(this.state), 1)
},
playable () {
return this.diskAlpha < 1
isHint () {
return Math.abs(this.disk.value) === DiskConstants.hint
}
},
handlePlay () {
methods: {
handleClick () {
if (this.isHint) {
this.$emit('play')
}
}
}
}
</script>
Expand All @@ -46,4 +45,10 @@ export default {
font-size: 7.5vmin;
line-height: 0;
}
.hint {
cursor: pointer;
}
.hint span {
opacity: .5;
}
</style>
59 changes: 0 additions & 59 deletions src/components/HelloWorld.vue

This file was deleted.

26 changes: 16 additions & 10 deletions src/models/Disk.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@

export const light = '⚪'
export const dark = '⚫'

export function fromNumber (value) {
if (value > 0) return light
if (value < 0) return dark
return ''
}

export default {
export const DiskConstants = {
light: 1,
empty: 0,
dark: -1,
hint: 0.5,
fromNumber
hint: 0.5
}

class Disk {
constructor () {
this.value = 0
}

get char () {
if (this.value > 0) return light
if (this.value < 0) return dark
return ''
}
}

export default Disk
67 changes: 50 additions & 17 deletions src/models/Reversi.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Direction from './Direction'
import Disk from './Disk'
import Disk, { DiskConstants } from './Disk'

/**
* The reversi board
Expand All @@ -17,7 +17,12 @@ class Reversi {
this.height = height > 4 ? height : 4
this.width = width > 4 ? width : 4
this.board = Array.from(new Array(this.height), row => new Array(this.width))
this.nextTurnPlayer = Disk.empty
for (let row = 0; row < this.height; row++) {
for (let col = 0; col < this.width; col++) {
this.board[row][col] = new Disk()
}
}
this.currentPlayerDisk = DiskConstants.empty
this.reset()
}

Expand All @@ -41,7 +46,7 @@ class Reversi {
* @return {Number} The value
*/
getValueAt (position) {
return this.board[position[0]][position[1]]
return this.board[position[0]][position[1]].value
}

/**
Expand All @@ -51,28 +56,30 @@ class Reversi {
* @param {Number} value The value
*/
setValueAt (position, value) {
this.board[position[0]][position[1]] = value
this.board[position[0]][position[1]].value = value
}

/**
* Reset the board and the next player's turn
*/
reset () {
this.board.forEach(row => row.fill(0))
for (const position of this.positions()) {
this.setValueAt(position, DiskConstants.empty)
}
const halfHeight = (this.height - 1) / 2
const halfWidth = (this.width - 1) / 2
this.board[Math.floor(halfHeight)][Math.floor(halfWidth)] = Disk.light
this.board[Math.floor(halfHeight)][Math.ceil(halfWidth)] = Disk.dark
this.board[Math.ceil(halfHeight)][Math.floor(halfWidth)] = Disk.dark
this.board[Math.ceil(halfHeight)][Math.ceil(halfWidth)] = Disk.light
this.nextTurnPlayer = Disk.dark
this.setValueAt([Math.floor(halfHeight), Math.floor(halfWidth)], DiskConstants.light)
this.setValueAt([Math.floor(halfHeight), Math.ceil(halfWidth)], DiskConstants.dark)
this.setValueAt([Math.ceil(halfHeight), Math.floor(halfWidth)], DiskConstants.dark)
this.setValueAt([Math.ceil(halfHeight), Math.ceil(halfWidth)], DiskConstants.light)
this.currentPlayerDisk = DiskConstants.dark
}

/**
* Removes all hints from the board
*/
clearHints () {
for (let position of this.positions()) {
for (const position of this.positions()) {
const value = this.getValueAt(position)
this.setValueAt(position, Math.sign(value) * Math.floor(Math.abs(value)))
}
Expand Down Expand Up @@ -106,14 +113,14 @@ class Reversi {
*/
disksToFlipFromPositionInDirection (position, direction) {
let foundOpponentDisk = false
let opponentDisk = this.nextTurnPlayer * -1
let opponentDisk = this.currentPlayerDisk * -1
const flippedDisks = []
for (let walkPosition of this.walkFromPositionInDirection(position, direction)) {
let disk = this.getValueAt(walkPosition)
if (disk === opponentDisk) {
foundOpponentDisk = true
flippedDisks.push(walkPosition)
} else if (foundOpponentDisk && disk === this.nextTurnPlayer) {
} else if (foundOpponentDisk && disk === this.currentPlayerDisk) {
return flippedDisks
} else {
return []
Expand All @@ -129,7 +136,7 @@ class Reversi {
* @return {boolean} True if the play is legal, False otherwise.
*/
isPlayable (position) {
if (this.getValueAt(position) === Disk.empty) {
if (this.getValueAt(position) === DiskConstants.empty) {
for (let direction of Direction) {
if (this.disksToFlipFromPositionInDirection(position, direction).length > 0) {
return true
Expand All @@ -143,16 +150,42 @@ class Reversi {
* Add hints to the board
* @return {Number} The hint count
*/
prepareHints () {
addAndCountHints () {
let count = 0
for (let position of this.positions()) {
for (const position of this.positions()) {
if (this.isPlayable(position)) {
this.setValueAt(position, Disk.hint * this.nextTurnPlayer)
this.setValueAt(position, DiskConstants.hint * this.currentPlayerDisk)
count++
}
}
return count
}

play (position) {
const takenPositions = [ position ]
for (const direction of Direction) {
takenPositions.push(...this.disksToFlipFromPositionInDirection(position, direction))
}
takenPositions.forEach(takenPosition => {
this.setValueAt(takenPosition, this.currentPlayerDisk)
})
this.currentPlayerDisk *= -1
}

prepareNextTurn () {
// Remove hints
this.clearHints()

let hintCount = this.addAndCountHints()
if (hintCount === 0) {
this.currentPlayerDisk *= -1
hintCount = this.addAndCountHints()
if (hintCount === 0) {
return true
}
}
return false
}
}

export default Reversi
Loading

0 comments on commit 4203143

Please sign in to comment.