一、遊戲效果圖
二、遊戲說明
- 佈局:玩家、棋盤、規則、按鈕
- 遊戲:玩家落子,電腦根據玩家或者自身的棋子,來進行堵截或成型
- 設計:電腦利用 權重 來判斷哪個點的分值最高
- 遊戲是用 uniapp + uview 寫的,裡面一些樣式,有的我自己定義的全域性的,有的是uview內建的,可自行解決
三、遊戲程式碼
(1) 佈局
<template> <view class="goBang u-border-top"> <!-- 對戰資訊 --> <view class="goBang-user flexItems"> <view class="flexCenter flexColumn flex1 box"> <u-icon class="goBang-chess" name="/static/image/gobang/black.png" size="50"></u-icon> <view class="u-m-t-20 fontBold c757575">電腦</view> </view> <view class="fontBold cmain u-font-40">VS</view> <view class="flexCenter flexColumn flex1 box"> <u-icon class="goBang-chess" name="/static/image/gobang/white.png" size="50"></u-icon> <view class="u-m-t-20 fontBold c757575">玩家</view> </view> </view> <view class="goBang-container boxtb"> <!-- 棋盤底座 --> <view class="goBang-board u-rela"> <!-- 棋盤網格 --> <view class="goBang-grid-box u-rela"> <view class="goBang-grid"> <view class="goBang-grid-tr" v-for="(item,index) in 14" :key="index"> <view class="goBang-grid-td" v-for="(item,index) in 14" :key="index"></view> </view> </view> <view class="point-c"></view> <view class="point-1"></view> <view class="point-2"></view> <view class="point-3"></view> <view class="point-4"></view> </view> <!-- 隱藏的棋盤網格 用於下棋子用的 --> <view class="goBang-check"> <view class="goBang-check-tr" v-for="(item1,index1) in chessBoard" :key="index1"> <view class="goBang-check-td" v-for="(item2,index2) in item1" :key="index2" @click="playerChess(index1,index2)"> <image class="goBang-check-chess" :src="player[item2]" v-if="item2!=0"></image> </view> </view> </view> </view> <!-- 規則說明 --> <view class="boxtb"> <view class="u-m-t-10 fontBold u-font-32 c757575">規則說明:</view> <view class="u-m-t-20 c757575">1、玩家先手</view> <view class="u-m-t-10 c757575">2、其他規則,不知道就百度去,慣得!!!</view> </view> </view> <!-- 功能按鈕 --> <view class="goBang-btns"> <view class="goBang-btn" @click="regret" v-if="!isOver"> <u-icon name="thumb-down-fill" size="30" color="#999"></u-icon> <text>悔棋</text> </view> <view class="goBang-btn" @click="restart"> <u-icon name="reload" size="30" color="#999"></u-icon> <text>重來</text> </view> <view class="goBang-btn" @click="defeat" v-if="!isOver"> <u-icon name="fingerprint" size="30" color="#999"></u-icon> <text>認輸</text> </view> </view> </view> </template>
(2) 樣式
<style> page{background-color: #F3F2F7;} </style> <style scoped> // #F7E7B6 棋盤背景 #C0A47C 網格條紋 .goBang{padding: 30rpx;} .goBang-chess{width: 50rpx;height: 50rpx; border-radius: 50%;box-shadow: 0 0 8rpx 4rpx rgba(0,0,0,.2);} .goBang-board{ width: 100%;height: 690rpx;background-color: #f7e7b6;border-radius: 10rpx;border: 2rpx solid rgba(0,0,0,.05);box-shadow: 0 0 6rpx 2rpx rgba(0,0,0,.1);padding: 20rpx; .goBang-grid-box{ width: 100%;height: 100%; .point-c{position: absolute;width: 14rpx;height: 14rpx;border-radius: 50%;background-color: #C0A47C; top: 50%;left: 50%;transform: translate(-50%,-50%);} .point-1{position: absolute;width: 14rpx;height: 14rpx;border-radius: 50%;background-color: #C0A47C; top: 21.5%;left: 21.5%;transform: translate(-50%,-50%);} .point-2{position: absolute;width: 14rpx;height: 14rpx;border-radius: 50%;background-color: #C0A47C; top: 21.5%;right: 21.5%;transform: translate(50%,-50%);} .point-3{position: absolute;width: 14rpx;height: 14rpx;border-radius: 50%;background-color: #C0A47C; bottom: 21.5%;right: 21.5%;transform: translate(50%,50%);} .point-4{position: absolute;width: 14rpx;height: 14rpx;border-radius: 50%;background-color: #C0A47C; bottom: 21.5%;left: 21.5%;transform: translate(-50%,50%);} } .goBang-grid{ width: 100%;height: 100%;border-top: 2rpx solid #C0A47C;border-left: 2rpx solid #C0A47C;display: flex;flex-direction: column; .goBang-grid-tr{width: 100%;display: flex;flex: 1;} .goBang-grid-td{flex: 1;border-right: 2rpx solid #C0A47C;border-bottom: 2rpx solid #C0A47C;} } .goBang-check{ display: flex;flex-direction: column;position: absolute;width: 100%;height: 100%;top: 0;right: 0;left: 0;bottom: 0;z-index: 1;border-radius: 10rpx; .goBang-check-tr{width: 100%;display: flex;flex: 1;} .goBang-check-td{flex: 1;display: flex;align-items: center;justify-content: center;} .goBang-check-chess{width: 38rpx;height: 38rpx;border-radius: 50%;box-shadow: 0 2rpx 10rpx 0rpx rgba(0,0,0,.5);} } } .goBang-btns{ display: flex;align-items: center;justify-content: center; position: fixed;bottom: 30rpx;right: 0;left: 0;padding: 30rpx; .goBang-btn{ width: 90rpx;height: 90rpx; border-radius: 50%;background-color: #fff;box-shadow: 0 0 10rpx 4rpx rgba(0,0,0,.1); display: flex;align-items: center;justify-content: center;flex-direction: column; margin-left: 30rpx;color: #999;font-size: 24rpx; } } </style>
(3) 邏輯
<script> export default { data() { return { player: { // 0=沒有子 1=電腦 2=玩家 0: null, 1: '/static/image/gobang/black.png', 2: '/static/image/gobang/white.png' }, chessBoard: [], // 棋盤陣列 isWho: true, // 該誰下 isOver: false, // 遊戲是否結束 allWins: [], // 全部贏法的陣列 allCount: 0, // 一共有多少種贏法 playerWins: [], // 玩家贏法的陣列 computerWins: [], // 電腦贏法的陣列 }; }, onLoad() { this.chess_init(); uni.showToast({title: "歡迎來到五子棋~", icon:'none'}); }, methods:{ // 悔棋 regret(){ uni.showToast({title: "世上沒有後悔藥~", icon:'none'}); }, // 重來 restart(){ uni.showToast({title: "歡迎來到五子棋~", icon:'none'}); this.chessBoard = []; this.isOver = false; this.isWho = true; this.chess_init(); }, // 認輸 defeat(){ if(this.isOver){ uni.showToast({title: "遊戲已結束,可以重新開始了", icon:'none'}); }else{ this.isOver = true uni.showToast({title: "就這?就這?就這?回家餵豬吧!", icon:'none'}); } }, // 玩家落子 playerChess(x, y){ // 當此點有棋子 或者 遊戲結束 或者 不論到你時,則不能落子 if(this.chessBoard[x][y] != 0 || !this.isWho || this.isOver){ return; } // 落子 this.chessBoard[x][y] = 2; this.$forceUpdate(); // 判斷輸贏 setTimeout(()=>{ for(let k = 0; k < this.allCount; k++){ if(this.allWins[x][y][k] == true){ this.playerWins[k]++; this.computerWins[k] = 6; if(this.playerWins[k] == 5){ this.isOver = true; uni.showToast({title: "玩家獲勝!!!!"}); } } } },50) // 如果玩家沒獲勝 則該電腦落子 setTimeout(()=>{ if(!this.isOver){ this.isWho = !this.isWho; this.computerChess(); } },100) }, // 電腦落子 computerChess(){ // 電腦落子 利用演演算法————權重值 // 判斷哪一點的值最高,也就是對電腦的利益最大 // 每下一步,就會判斷某點對於玩家利益大還是自身利益大,來進行圍堵和進攻 const playerScore = []; // 對於玩家而言,每一個空點的數值集合 const computerScore = []; // 對於電腦而言,每一個空點的數值集合 let maxScore = 0; // 最大值 let x = 0, y = 0; // 最後決定電腦落子的位置 // 初始化玩家和電腦每個點的數值 for(let i = 0; i < 15; i++){ playerScore[i] = []; computerScore[i] = []; for(let j = 0; j < 15; j++){ playerScore[i][j] = 0; computerScore[i][j] = 0; } } // 開始遍歷棋盤(檢視當前棋盤中所有空點) for(let i = 0; i < 15; i++){ for(let j = 0; j < 15; j++){ if(this.chessBoard[i][j] == 0){ // 此點可落子 // 遍歷所有贏法 給玩家和電腦的每個空點 打分 分值最高的點則是電腦落子點 for(let k = 0; k < this.allCount; k++){ if(this.allWins[i][j][k] == true){ // 判斷當前點的贏法中有沒有玩家或者電腦的棋子 // 如果有玩家的棋子 if(this.playerWins[k] === 1){ // 贏法中包含一個玩家棋子... playerScore[i][j] += 100; }else if(this.playerWins[k] === 2){ playerScore[i][j] += 400; }else if(this.playerWins[k] === 3){ playerScore[i][j] += 800; }else if(this.playerWins[k] === 4){ playerScore[i][j] += 2000; } // 如果有電腦的棋子 // 相同棋子數時,電腦的權重值要比玩家的高,首先考慮自己; // 但是當玩家達到三顆時,自身如果沒有機會,則玩家權重值大 if(this.computerWins[k] === 1){ // 贏法中包含一個電腦棋子... computerScore[i][j] += 150; }else if(this.computerWins[k] === 2){ computerScore[i][j] += 450; }else if(this.computerWins[k] === 3){ computerScore[i][j] += 950; }else if(this.computerWins[k] === 4){ computerScore[i][j] += 10000; } } } // 比較玩家和電腦在某點的分值 // 玩家 if(playerScore[i][j] > maxScore){ maxScore = playerScore[i][j]; x = i; y = j; }else if(playerScore[i][j] == maxScore){ // 如果玩家在當前點的分跟前一個相等,就再跟電腦自身在該點的值進行比較 // 如果電腦在當前點,比在上一個點的分大,說明電腦下這個點的優勢更大, 以此類推,推出所有點的結果 if(computerScore[i][j] > computerScore[x][y]){ maxScore = computerScore[i][j]; x = i; y = j; } } // 電腦 if(computerScore[i][j] > maxScore){ maxScore = computerScore[i][j]; x = i; y = j; }else if(computerScore[i][j] == maxScore){ if(playerScore[i][j] > playerScore[x][y]){ maxScore = playerScore[i][j]; x = i; y = j; } } } } } // 此時電腦就可以落子了 this.chessBoard[x][y] = 1; this.$forceUpdate(); // 判斷電腦是否獲勝 setTimeout(()=>{ for(let k = 0; k < this.allCount; k++){ if(this.allWins[x][y][k] == true){ this.computerWins[k]++; this.playerWins[k] = 6; if(this.computerWins[k] == 5){ this.isOver = true; uni.showToast({title: "電腦獲勝!"}); } } } },50) if(!this.isOver){ this.isWho = !this.isWho; } }, // 初始化 chess_init(){ //棋盤 for(let i = 0; i < 15; i++){ this.chessBoard[i] = []; for(let j = 0; j < 15; j++){ this.chessBoard[i][j] = 0; } } // 初始化所有贏法的陣列 for(let i = 0; i < 15; i++){ this.allWins[i] = []; for(let j = 0; j < 15; j++){ this.allWins[i][j] = []; } } // 橫向贏法 for(let i = 0; i < 15; i++){ for(let j = 0; j < 11; j++){ for(let k = 0; k < 5; k++){ this.allWins[i][j+k][this.allCount] = true; } this.allCount++; } } // 豎向贏法 for(let i = 0; i < 11; i++){ for(let j = 0; j < 15; j++){ for(let k = 0; k < 5; k++){ this.allWins[i+k][j][this.allCount] = true; } this.allCount++; } } // 斜向(左上 -> 右下) for(let i = 0; i < 11; i++){ for(let j = 0; j < 11; j++){ for(let k = 0; k < 5; k++){ this.allWins[i+k][j+k][this.allCount] = true; } this.allCount++; } } // 斜向(右上 -> 左下) for(let i = 0; i < 11; i++){ for(let j = 14; j > 3; j--){ for(let k = 0; k < 5; k++){ this.allWins[i+k][j-k][this.allCount] = true; } this.allCount++; } } // console.log(this.allCount); // 572種贏法 // 統計玩家與電腦的贏法陣列 // 簡單來說,玩家和電腦都有572種贏法,每種贏法初始值是0; // 例如當玩家在第一種贏法中落一顆子,與之對應的贏法就+1,當前加到5的時候,說明第一種贏法中有了玩家五顆子,所以玩家贏。 // 反之,當第一種贏法中玩家落了四顆,但是電腦落了一顆,那麼第一種贏法對應的玩家就+4,電腦+1,這樣在第一種贏法裡,玩家與電腦都不能獲勝。 // 以此類推其他的贏法... for(let i = 0; i < this.allCount; i++){ this.playerWins[i] = 0; this.computerWins[i] = 0; } }, } } </script>
推薦:《》
以上就是看看使用uni-app如何編寫一個五子棋小遊戲(附遊戲程式碼)的詳細內容,更多請關注TW511.COM其它相關文章!