看看使用uni-app如何編寫一個五子棋小遊戲(附遊戲程式碼)

2021-12-30 22:00:20
使用uni-app如何編寫一個五子棋小遊戲?下面本篇文章給大家分享一個使用uni-app編寫的五子棋小遊戲,希望對大家有所幫助!

一、遊戲效果圖

1.png

二、遊戲說明

  1. 佈局:玩家、棋盤、規則、按鈕
  2. 遊戲:玩家落子,電腦根據玩家或者自身的棋子,來進行堵截或成型
  3. 設計:電腦利用 權重 來判斷哪個點的分值最高
  4. 遊戲是用 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其它相關文章!