1. 程式人生 > >Mr.J--學習五子棋的艱苦之路

Mr.J--學習五子棋的艱苦之路

五子棋大家肯定耳熟能詳,規則簡單易懂,老少皆宜

本次用到的知識有canvas,javascript,html,css

話不多說,程式碼貼上

html(實現程式碼功能,利用瀏覽器):

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>五子棋</title>
		<link rel = "stylesheet" type = "text/css" href="css/style.css"/>
	</head>
	<body>
		<canvas id = "chess" width = "450px" height="450px"></canvas>
		<script type = "text/javascript" src="js/script.js"></script>
	</body>
</html>

CSS模組:

canvas{
	display:block;  
	margin: 50px auto;  /*模組大小*/
	box-shadow: 2px 2px 2px #EFEFEF,5px 5px 5px #B9B9B9;/*設定陰影*/
}

JavaScript模組(實現和電腦下棋以及重要演算法):

var chessBoard  = []; 
var me = true;
var over = false;
//贏法陣列
var wins = [];

//贏法統計陣列
var myWin = [];
var computerWin = [];

for(var i=0;i<15;i++){
	chessBoard[i] = [];
	for(var j=0;j<15;j++){
		chessBoard[i][j] = 0;
	}
}
for(var i=0;i<15;i++){
	wins[i] = [];
	for(var j=0;j<15;j++){
		wins[i][j] = [];
	}
}

var count = 0;
//所有的橫線贏法
for(var i=0;i<15;i++){
	for(var j=0;j<11;j++){
		//wins[0][0][0] = true
		//wins[0][1][0] = true
		//wins[0][2][0] = true
		//wins[0][3][0] = true
		//wins[0][4][0] = true
		
		//wins[0][1][1] = true
		//wins[0][2][1] = true
		//wins[0][3][1] = true
		//wins[0][4][1] = true
		//wins[0][5][1] = true
		for(var k=0;k<5;k++){
			wins[i][j+k][count] = true;
		}
		count++;	
	}
}

//所有的豎線贏法
for(var i=0;i<15;i++){
	for(var j=0;j<11;j++){
		for(var k=0;k<5;k++){
			wins[j+k][i][count] = true;
		}
		count++;	
	}
}
//所有的斜線贏法
for(var i=0;i<11;i++){
	for(var j=0;j<11;j++){
		for(var k=0;k<5;k++){
			wins[i+k][j+k][count] = true;
		}
		count++;	
	}
}
//所有的反斜線贏法
for(var i=0;i<11;i++){
	for(var j=14;j>3;j--){
		for(var k=0;k<5;k++){
			wins[i+k][j-k][count] = true;
		}
		count++;	
	}
}

for(var i=0;i<count;i++){
	myWin[i] =0;
	computerWin[i] =0;
}

var chess = document.getElementById('chess');
var context = chess.getContext('2d');

context.strokeStyle = "#BFBFBF";

var logo = new Image();
logo.src = "img/2B.jpg";  //照片自己可以選擇
logo.onload = function()
{
	context.drawImage(logo,0,0,450,450);
	drawChessBoard();
	
}
var drawChessBoard = function()
{
	for(var i=0;i<15;i++)
	{
	context.moveTo(15+i*30,15);
	context.lineTo(15+i*30,435);
	context.stroke();
	context.moveTo(15,15+i*30);
	context.lineTo(435,15+i*30);
	context.stroke();
	}
}

var oneStep = function(i,j,me)
{
	context.beginPath();
	context.arc(15+i*30,15+j*30,13,0,2*Math.PI);
	context.closePath();
	var gradient = context.createRadialGradient(15+i*30+2,15+j*30-2,13,15+i*30+2,15+j*30-2,0)
	if(me){
		gradient.addColorStop(0,"#0A0A0A");
		gradient.addColorStop(1,"#636766");
	}else{
		gradient.addColorStop(0,"#D1D1D1");
		gradient.addColorStop(1,"#F9F9F9");
	}

	context.fillStyle = gradient;
	context.fill();
}
chess.onclick = function(e)
{
	if(over){
		return;
	}
	if(!me){
		return;
	}
	var x = e.offsetX;
	var y = e.offsetY;
	var i =Math.floor(x/30);
	var j =Math.floor(y/30);
	if(chessBoard[i][j] == 0){
		oneStep(i,j,me);
		chessBoard[i][j] = 1;
	
		for(var k=0;k<count;k++){
			if(wins[i][j][k]){
				myWin[k]++;
				computerWin[k] =6;
				if(myWin[k]  == 5){
					window.alert("You win!");
					over = true;
				}
			}
		}
		if(!over){
			me = !me;
			computerAI();
		}
	}
}	

//計算機下棋
var computerAI = function(){
    //記錄人下的棋子
    var myScore = [];
    //記錄計算機下的棋子
    var computerScore = [];
    //儲存最高分數
    var max = 0;
    //最高分數點座標
    var maxX = 0,maxY = 0;
 
    for(var i=0; i<15; i++){
        myScore[i] = [];
        computerScore[i] = [];
        for(var j=0; j<15; j++){
            myScore[i][j] = 0;
            computerScore[i][j] = 0;
        }
    }
 
    //遍歷整個棋盤
    for(var i=0; i<15; i++){
        for(var j=0; j<15; j++){
            //該座標可以落子
            if(chessBoard[i][j] == 0){
                //遍歷所有贏法
                for(var k=0; k<count; k++){
                    //判斷第K種贏法是否有價值
                    if(wins[i][j][k]){
                        //判斷第K種贏發黑棋是否落子
                        //攔截價值判斷
                        if(myWin[k] == 1){
                            //攔截
                            myScore[i][j] += 200;
                        }else if(myWin[k] == 2){
                            //攔截
                            myScore[i][j] += 400;                        
                        }else if(myWin[k] == 3){
                            //攔截
                            myScore[i][j] += 2000;                           
                        }else if(myWin[k] == 4){
                            //攔截
                            myScore[i][j] += 10000;                          
                        }
 
                        //計算機本身落子價值判斷
                        if(computerWin[k] == 1){
                            //落子價值
                            computerScore[i][j] += 220;
                        }else if(computerWin[k] == 2){
                            //落子價值
                            computerScore[i][j] += 420;                          
                        }else if(computerWin[k] == 3){
                            //落子價值 
                            computerScore[i][j] += 2100;                         
                        }else if(computerWin[k] == 4){
                            //落子價值
                            computerScore[i][j] += 20000;                    
                        }
                    }
                }
 
                //儲存最高分數
                if(myScore[i][j] > max){
                    max = myScore[i][j];
                    maxX = i;
                    maxY = j;
                }else if(myScore[i][j] == max){
                    if(computerScore[i][j] > computerScore[maxX][maxY]){
                        maxX = i;
                        maxY = j;
                    }
                }
 
                //儲存最高分數
                if(computerScore[i][j] > max){
                    max = computerScore[i][j];
                    maxX = i;
                    maxY = j;
                }else if(computerScore[i][j] == max){
                    if(myScore[i][j] > myScore[maxX][maxY]){
                        maxX = i;
                        maxY = j;
                    }
                }
 
            }
        }
    }
    //計算機子
    oneStep(maxX, maxY, false);
    chessBoard[maxX][maxY] = 2;
    document.title = 'x'+maxX+' Y'+maxY;
    console.dir(chessBoard[maxX][maxY]);
    //贏法統計
    for(var k=0; k<count; k++){
        if(wins[maxX][maxY][k]){
            //白子贏法更近一步
            computerWin[k]++;
            //該贏法黑棋不可能再贏了
            myWin[k] = 6;
            //
            if(computerWin[k] == 5){
                window.alert("Computer win!");
                over = true;
            }
        }
    }
 
    //如果贏法統計完成棋沒有結束
    if(!over){
        me = !me;
    }
}

 

學習視訊:人機互動介面:點選檢視    人機比賽(贏法陣列以及演算法):點選檢視

At last but not least:學習程式語言以及英語的好地方:click here

繼續與電腦下棋了....