Simple implementation of an eight Queen game with Vue

Eight queens game rules and effect preview

Effect preview:

Implementation steps

Previously created project, note: https://www.cnblogs.com/xiaoxuStudy/p/12663218.html

Current directory structure:

(Note: large hump naming method is used for component naming.)

 

In eightqueen Write template in Vue.

EightQueen.vue:

<template>
    <div>
        <div class="title">Eight queens problem</div>
    </div>
</template>

 

On app Registration, introduction and use of eightqueen in Vue Vue components.

App.vue:

<template>
    <div id="app">
        <eight-queen />
    </div>
</template>
 
<script>
import EightQueen from "./components/EightQueen";
 
export default {
    name: "app",
    components: {
        EightQueen
    }
}
</script>

 

At this point, the page displays:

 

EightQueen.vue :

The chessboard is an 8x8 matrix. Write eight horizontal lines first

First write the eight columns of the first line

 

It doesn't write well. It is better to write through v-if to traverse the data structure.

Here are the improvements:

<template>
    <div>
        <div class="title">Eight queens problem</div>
        
        <div class="gird">
            <div class="row" v-for="(row, r_index) in grids" :key="r_index">
                <div class="cell" v-for="cell in row" :key="cell.key">
                    {{ `${cell.key}` }}
                </div>
            </div>
        </div>
    </div>
</template>

<script>
const grids = new Array(8).fill(1).map((_, r) => {
    return new Array(8).fill(1).map((_, c) => {
        return {
            key: `key-${r*8 + c}`,
            ok: false
        }
    })
})

export default {
    data(){
        return{
            grids
        }
    }
}
</script>

Page performance:

(the page is too long. The screenshot has 64 keys from key-0 to key-63, corresponding to 64 grids in eight rows and eight columns)

View console:

Code Description:

Define the data structure and return the data object grids through the data function

Generate the object girds into an eight horizontal data structure, and newArray(8) generates an empty array with a length of 8. Then fill the eight horizontal data structure, and fill the array with fill(1). The method is to replace the eight elements of the empty array with 1, that is, the array is now [1, 1, 1, 1, 1, 1, 1, 1, 1]. Fill the data structure of eight horizontal columns with eight vertical columns, and use the map method for the array. The parameters of the map method are a function and the parameters of the function_ Is the current value, that is, 1. The parameter r is the current index value. This function acts on each element of [1, 1, 1, 1, 1, 1, 1, 1], because it is necessary to realize eight horizontal and eight vertical checkerboard, so each horizontal corresponds to eight vertical. Therefore, each horizontal returns an eight vertical data structure. The data structure of each vertical returns a data object key and ok. Key represents the unique key value of the cell, and ok represents whether it is clicked or occupied by the queen. grids is an array of 8 elements, and each element is an array of 8 elements.

For ease of understanding, a graph is spent. The key value corresponding to each small cell in the graph is r*8 + c

Line 6: use v-for to traverse each row. grids is the array corresponding code line 16. Row is the current value. Each row is an array containing 8 elements, r_index is the current index value. You need to bind the key value to help the engine render dom nodes better.

Line 7: use v-for to traverse each vertical line in a horizontal line. row is an array containing 8 elements, cell is the current value, corresponding to lines 18-21 of the code, and cell contains the data object key and ok.

Line 8: this statement is mainly written to see the effect of the page. Output cell Key. After the whole traversal, a total of 64 elements from key-0 to key-63 are output, corresponding to each cell of eight horizontal and eight vertical in the chessboard.

 

Next, write the style.

Use scoped to prevent global contamination of component styles. (scoped related notes: https://www.cnblogs.com/xiaoxuStudy/p/13235418.html#three)

A div with a class of cell corresponds to one of the 8x8 checkerboard squares. Set a small grid with width and height of 50 px, horizontal and vertical center, and background color of #999.

<template>
    <div>
        <div class="title">Eight queens problem</div>
        
        <div class="gird">
            <div class="row" v-for="(row, r_index) in grids" :key="r_index">
                <div class="cell" v-for="cell in row" :key="cell.key">
                </div>
            </div>
        </div>
    </div>
</template>

<script>
const grids = new Array(8).fill(1).map((_, r) => {
    return new Array(8).fill(1).map((_, c) => {
        return {
            key: `key-${r*8 + c}`,
            ok: false
        }
    })
})

export default {
    data(){
        return{
            grids
        }
    }
}
</script>

<style scoped>
    .cell{
        width: 50px;
        height: 50px;
        line-height: 50px;
        text-align: center;
        background-color: #999;
    }
</style>

Page presentation (64 grids in total):

 

The colors of adjacent checkerboard squares are different. :nth-child(2n)  Indicates that the index is a multiple of 2. class specifies the background color for the div element of cell.

<template>
    <div>
        <div class="title">Eight queens problem</div>
        
        <div class="gird">
            <div class="row" v-for="(row, r_index) in grids" :key="r_index">
                <div class="cell" v-for="cell in row" :key="cell.key">
                </div>
            </div>
        </div>
    </div>
</template>

<script>
const grids = new Array(8).fill(1).map((_, r) => {
    return new Array(8).fill(1).map((_, c) => {
        return {
            key: `key-${r*8 + c}`,
            ok: false
        }
    })
})

export default {
    data(){
        return{
            grids
        }
    }
}
</script>

<style scoped>
    .cell{
        width: 50px;
        height: 50px;
        line-height: 50px;
        text-align: center;
        background-color: #999;
    }
    .cell:nth-child(2n){
        background: #efefef;
    }
</style>

Page presentation (64 grids in total):

 

Set the style so that the grid is displayed in eight rows. A div with class row is equivalent to a row of checkerboard. There are eight div with class row. Set the div with class row to 50px high and 400px wide (i.e. 8x50px), because there are eight grids in a row.

Div with cell class is the sub box of div with row class. If the sub box is set to float, it may cause height collapse. Therefore, it is necessary to set display: flow root in the parent box to trigger BFC.

<template>
    <div>
        <div class="title">Eight queens problem</div>
        
        <div class="gird">
            <div class="row" v-for="(row, r_index) in grids" :key="r_index">
                <div class="cell" v-for="cell in row" :key="cell.key">
                </div>
            </div>
        </div>
    </div>
</template>

<script>
const grids = new Array(8).fill(1).map((_, r) => {
    return new Array(8).fill(1).map((_, c) => {
        return {
            key: `key-${r*8 + c}`,
            ok: false
        }
    })
})

export default {
    data(){
        return{
            grids
        }
    }
}
</script>

<style scoped>
    .cell{
        width: 50px;
        height: 50px;
        line-height: 50px;
        text-align: center;
        background-color: #999;
        float: left;
    }
    .cell:nth-child(2n){
        background: #efefef;
    }
    .row{
        height: 50px;
        width: 400px;
        display: flow-root;
    }
</style>

Page performance:

It was set before cell:nth-child(2n){background: #efefef;}, So each vertical color is the same.

 

Set the style so that the adjacent colors of each grid are different. Set the style of the row whose index is a multiple of 2.

The index of div class is a multiple of the index of div class-cell in row 52, and the color of div class is 999 #2 #

Line 53-55: div element with index of 2 and index of 2n-1. Div element with class of cell has background color of #efef

<template>
    <div>
        <div class="title">Eight queens problem</div>
        
        <div class="gird">
            <div class="row" v-for="(row, r_index) in grids" :key="r_index">
                <div class="cell" v-for="cell in row" :key="cell.key">
                </div>
            </div>
        </div>
    </div>
</template>

<script>
const grids = new Array(8).fill(1).map((_, r) => {
    return new Array(8).fill(1).map((_, c) => {
        return {
            key: `key-${r*8 + c}`,
            ok: false
        }
    })
})

export default {
    data(){
        return{
            grids
        }
    }
}
</script>

<style scoped>
    .cell{
        width: 50px;
        height: 50px;
        line-height: 50px;
        text-align: center;
        background-color: #999;
        float: left;
    }
    .cell:nth-child(2n){
        background: #efefef;
    }
    .row{
        height: 50px;
        width: 400px;
        display: flow-root; 
    }
    .row:nth-child(2n) .cell:nth-child(2n){
        background: #999;
    }
    .row:nth-child(2n) .cell:nth-child(2n-1){
        background: #efefef;
    }
</style>

Page performance:

 

Center the chessboard.

<template>
    <div>
        <div class="title">Eight queens problem</div>
        
        <div class="grid">
            <div class="row" v-for="(row, r_index) in grids" :key="r_index">
                <div class="cell" v-for="cell in row" :key="cell.key">
                </div>
            </div>
        </div>
    </div>
</template>

<script>
const grids = new Array(8).fill(1).map((_, r) => {
    return new Array(8).fill(1).map((_, c) => {
        return {
            key: `key-${r*8 + c}`,
            ok: false
        }
    })
})

export default {
    data(){
        return{
            grids
        }
    }
}
</script>

<style scoped>
    .grid{
        width: 400px;
        margin: 0 auto;
    }
    .cell{
        width: 50px;
        height: 50px;
        line-height: 50px;
        text-align: center;
        background-color: #999;
        float: left;
    }
    .cell:nth-child(2n){
        background: #efefef;
    }
    .row{
        height: 50px;
        width: 400px;
        display: flow-root; 
    }
    .row:nth-child(2n) .cell:nth-child(2n){
        background: #999;
    }
    .row:nth-child(2n) .cell:nth-child(2n-1){
        background: #efefef;
    }
</style>

Page performance:

 

Then, click the checkerboard to place the queen, where the letter "Q" represents the queen.

 

When the cursor moves to the chessboard, the cursor is "one hand".

<template>
    <div>
        <div class="title">Eight queens problem</div>
        
        <div class="grid">
            <div class="row" v-for="(row, r_index) in grids" :key="r_index">
                <div class="cell" v-for="cell in row" :key="cell.key">
                </div>
            </div>
        </div>
    </div>
</template>

<script>
const grids = new Array(8).fill(1).map((_, r) => {
    return new Array(8).fill(1).map((_, c) => {
        return {
            key: `key-${r*8 + c}`,
            ok: false
        }
    })
})

export default {
    data(){
        return{
            grids
        }
    }
}
</script>

<style scoped>
    .grid{
        width: 400px;
        margin: 0 auto;
    }
    .cell{
        width: 50px;
        height: 50px;
        line-height: 50px;
        text-align: center;
        background-color: #999;
        float: left;
        cursor: pointer;
    }
    .cell:nth-child(2n){
        background: #efefef;
    }
    .row{
        height: 50px;
        width: 400px;
        display: flow-root; 
    }
    .row:nth-child(2n) .cell:nth-child(2n){
        background: #999;
    }
    .row:nth-child(2n) .cell:nth-child(2n-1){
        background: #efefef;
    }
</style>

Page performance (Note: the following figure is taken with a camera, and the screenshot does not show the cursor):

 

Add click events for each grid.

Line 8: add a v-if judgment cell Whether OK (corresponding to line 20) is true. If it is true, the Queen "Q" will be displayed

Line 7: use @ Click to add a click event The stop modifier prevents default bubbling and adds a select function. Chessboard eight horizontal and eight vertical, r_index is the current index when traversing the horizontal, c_index is the current index when traversing the vertical. Pass r to the select function_ Index and c_index as a parameter. When a checkerboard is clicked, a click event is triggered to execute the select function.

Line 32: add the select function in methods. grids[rindex][cindex] corresponds to a grid in the chessboard. The select function is used to set ok (corresponding to 20 lines) to true. After ok is true, "Q" will be displayed (corresponding to line 8).

<template>
    <div>
        <div class="title">Eight queens problem</div>
        
        <div class="grid">
            <div class="row" v-for="(row, r_index) in grids" :key="r_index">
                <div class="cell" v-for="(cell, c_index) in row" :key="cell.key" @click.stop="select(r_index, c_index)">
                    <div v-if="cell.ok">Q</div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
const grids = new Array(8).fill(1).map((_, r) => {
    return new Array(8).fill(1).map((_, c) => {
        return {
            key: `key-${r*8 + c}`,
            ok: false
        }
    })
})

export default {
    data(){
        return{
            grids
        }
    },
    methods: {
        select(rindex, cindex) {
            this.grids[rindex][cindex].ok = true;
        }
    }
}
</script>

<style scoped>
    .grid{
        width: 400px;
        margin: 0 auto;
    }
    .cell{
        width: 50px;
        height: 50px;
        line-height: 50px;
        text-align: center;
        background-color: #999;
        float: left;
        cursor: pointer;
    }
    .cell:nth-child(2n){
        background: #efefef;
    }
    .row{
        height: 50px;
        width: 400px;
        display: flow-root; 
    }
    .row:nth-child(2n) .cell:nth-child(2n){
        background: #999;
    }
    .row:nth-child(2n) .cell:nth-child(2n-1){
        background: #efefef;
    }
</style>

Page performance:

Click several grids randomly on the chessboard grid, and "Q" appears in the clicked grid

 

Eight queens games to meet the same horizontal, vertical, skimming and pressing of a queen can not place the queen.

The coordinates of each small grid can be displayed first, which is convenient to find out the law and carry out logical operation.

According to the coordinates, write the validate method to realize that the same horizontal, vertical, skimming and pressing of a queen cannot place the queen.

<template>
    <div>
        <div class="title">Eight queens problem</div>
        
        <div class="grid">
            <div class="row" v-for="(row, r_index) in grids" :key="r_index">
                <div class="cell" v-for="(cell, c_index) in row" :key="cell.key" @click.stop="select(r_index, c_index)">
                    <div v-if="cell.ok">Q</div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
const grids = new Array(8).fill(1).map((_, r) => {
    return new Array(8).fill(1).map((_, c) => {
        return {
            key: `key-${r*8 + c}`,
            ok: false
        }
    })
})

export default {
    data(){
        return{
            grids
        }
    },
    methods: {
        select(rindex, cindex) {
            if(this.validate(rindex, cindex)){
                this.grids[rindex][cindex].ok = !this.grids[rindex][cindex].ok;
            }else{
                alert('Queen cannot be placed in this position!');
            }
        },
        validate(rindex, cindex){
            //transverse
            for(let i=0; i<this.grids[rindex].length; i++){
                if(this.grids[rindex][i].ok){
                    return false;
                }
            }
            //vertical
            for(let i=0; i<this.grids[cindex].length; i++){
                if(this.grids[i][cindex]){
                    return false;
                }
            }
            //Skim
            for(let i=0; i<this.grids[0].length; i++){
                let y = rindex + cindex - i;
                if( y>0 &&  y<this.grids.length && this.grids[y][i].ok){
                    return false;
                }
            }
            //Restrain
            for(let i=0; i<this.grids[0].length; i++){
                let y = rindex - cindex + i;
                if( y>0 && y<this.grids.length && this.grids[i][y].ok ){
                    return false;
                }
            }
        }
    }
}
</script>

<style scoped>
    .grid{
        width: 400px;
        margin: 0 auto;
    }
    .cell{
        width: 50px;
        height: 50px;
        line-height: 50px;
        text-align: center;
        background-color: #999;
        float: left;
        cursor: pointer;
    }
    .cell:nth-child(2n){
        background: #efefef;
    }
    .row{
        height: 50px;
        width: 400px;
        display: flow-root; 
    }
    .row:nth-child(2n) .cell:nth-child(2n){
        background: #999;
    }
    .row:nth-child(2n) .cell:nth-child(2n-1){
        background: #efefef;
    }
</style>

Page performance:

If the queen is placed on the same horizontal, vertical, skimming and pressing of the queen, a prompt will pop up

 

 

So far, I have simply completed an eight queens game.

 

Posted by Kitty on Tue, 24 May 2022 04:30:43 +0300