前言
五子棋是个很有趣的游戏,在用javascript开发之后,我发现其实ai算法才是最难的,这里的ai算法是直接借鉴自其它的ai算法。
代码如下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>五子棋</title>
<script type="text/javascript">
var chess = {
//-----------------构造函数-----------------------------------------
create:function(x, y){
var newDiv = document.createElement("div");
document.body.appendChild(newDiv);
newDiv.style.position = "absolute";
newDiv.style.width = "23px";
newDiv.style.height = "23px";
newDiv.style.top = 100 + 23*y + "px";
newDiv.style.left = document.body.clientWidth/2-23*9+23*x+"px";
newDiv.x = x;
newDiv.y = y;
newDiv.fill = this.fill;
newDiv.manPlay = this.manPlay;
newDiv.pcPlay = this.pcPlay;
newDiv.setVal = this.setVal;
newDiv.isWin = this.isWin;
newDiv.wink = this.wink;
var n;
var borderline = chess.getChessWidth() - 1;
if(x==0&&y==0)
n=0;
else if(x==borderline && y==0)
n=2;
else if(x==0 && y==borderline)
n=6;
else if(x==borderline && y==borderline)
n=8;
else if(x>0 && x<borderline && y==0)
n=1;
else if(x>0 && x<borderline && y==borderline)
n=7;
else if(x==0 && y>0 && y<borderline)
n=3;
else if(x==borderline && y>0 && y<borderline)
n=5;
else
n=4;
(function(){
var _newDiv = newDiv;
var _n = n;
var _y = y;
setTimeout(function(){
_newDiv.style.backgroundImage = "url(images/b"+_n+".gif)";
_newDiv._backImage = _newDiv.style.backgroundImage;
}, _y*69);
})();
return newDiv;
},
//-----------------处理函数-----------------------------------------
fill:function(flag){
this.style.backgroundImage = flag == undefined ? this._backImage : "url(images/d"+flag+".gif)"; //白:0,黑:1
this.flag = flag;
this.setVal(flag);
return this.isWin();
},
setVal:function(flag){
for(var i=0; i<winCount; i++){
if(flag==0){
if(pcTab[this.x][this.y][i] && win[0][i]!=9){
win[0][i]++;
}
if(manTab[this.x][this.y][i]){
manTab[this.x][this.y][i] = false;
win[1][i] = 9;
}
}
if(flag==1){
if(manTab[this.x][this.y][i] && win[1][i]!=9){
win[1][i]++;
}
if(pcTab[this.x][this.y][i]){
pcTab[this.x][this.y][i] = false;
win[0][i] = 9;
}
}
}
},
manPlay:function(){
if(this.flag == undefined){
var isWin = this.fill(1);
if(isWin) return;
this.pcPlay(0);
}
},
pcPlay:function(){
if(this.flag == undefined && arguments.length==0){
this.fill(0);
return;
}
var chessWidth = chess.getChessWidth();
//计算玩家、电脑在每个格子上的分数
for(var x=0; x<chessWidth; x++){
for(var y=0; y<chessWidth; y++){
manScore[x][y] = 0;
pcScore[x][y] = 0;
if(board[x][y].flag == undefined){
for(var z=0; z<winCount; z++){
//计算玩家在每个格子上的分数
if(manTab[x][y][z]){
switch(win[1][z]){
case 1 : manScore[x][y] += 5; break;
case 2 : manScore[x][y] += 50; break;
case 3 : manScore[x][y] += 100; break;
case 4 : manScore[x][y] += 500; break;
}
}
//计算电脑在每个格子上的分数
if(pcTab[x][y][z]){
switch(win[0][z]){
case 1 : pcScore[x][y] += 5; break;
case 2 : pcScore[x][y] += 50; break;
case 3 : pcScore[x][y] += 100; break;
case 4 : pcScore[x][y] += 500; break;
}
}
}
}
}
}
//比较哪个空格子上的分数最高
var menMax = { x:-1, y:-1, val:-1 }
var pcMax = { x:-1, y:-1, val:-1 }
for(var x=0; x<chessWidth; x++){
for(var y=0; y<chessWidth; y++){
if(board[x][y].flag == undefined){
if(manScore[x][y] >= menMax.val){
menMax.val = manScore[x][y];
menMax.x = x;
menMax.y = y;
}
if(pcScore[x][y] >= pcMax.val){
pcMax.val = pcScore[x][y];
pcMax.x = x;
pcMax.y = y;
}
}
}
}
//进攻or防守
var nextX = 0;
var nextY = 0;
if(menMax.val>=pcMax.val && menMax.val>=100){ //防守
nextX = menMax.x;
nextY = menMax.y;
}
else if(pcMax.val==0){
nextX = menMax.x;
nextY = menMax.y;
}
else{
nextX = pcMax.x;
nextY = pcMax.y;
}
chess.fill.call(board[nextX][nextY], 0);
},
isWin:function(){
for(var i=0; i<winCount; i++){
if(win[0][i] == chess.getWinLength()){
this.wink(i, 0);
alert("电脑赢了");
return true;
}
if(win[1][i] == chess.getWinLength()){
this.wink(i, 1);
alert("恭喜,您赢了");
return true;
}
}
return false;
},
wink:function(winIndex, flag){
var chessWidth = chess.getChessWidth();
for(var x=0; x<chessWidth; x++){
for(var y=0; y<chessWidth; y++){
if(flag == 0){
if(pcTab[x][y][winIndex]){
board[x][y].style.zIndex = 100;
board[x][y].style.border = "solid 3px red";
}
}
if(flag == 1){
if(manTab[x][y][winIndex]){
board[x][y].style.zIndex = 100;
board[x][y].style.border = "solid 3px red";
}
}
board[x][y].onclick = function(){
if(confirm("是否重新开始")){
window.location = window.location;
}
}
}
}
},
//-----------------常量-----------------------------------------
getChessWidth:function(){
return 15;
},
getWinLength:function(){
return document.getElementById("rdo5").checked ? 5 : 6;
}
}
var board = new Array(chess.getChessWidth());
var manTab = new Array(chess.getChessWidth()); //用户获胜组合
var pcTab = new Array(chess.getChessWidth());
var manScore = new Array(chess.getChessWidth()); //用户获取的分数
var pcScore = new Array(chess.getChessWidth());
var win = new Array(2); //
var winCount = 0;
function main(){
close();
var winLength = chess.getWinLength();
var chessWidth = chess.getChessWidth();
//计算可能赢的组合个数
for(var x=0; x<chessWidth; x++){
for(var y=0; y<chessWidth; y++){
if((x+winLength-1)<chessWidth) winCount++;
if((y+winLength-1)<chessWidth) winCount++;
if((x+winLength-1)<chessWidth && (y+winLength-1)<chessWidth) winCount++;
if((x+winLength-1)<chessWidth && (y-winLength+1)>=0) winCount++;
}
}
//画棋盘,初始化数据结构
for(var x=0; x<chessWidth; x++){
board[x] = new Array(chessWidth);
manTab[x] = new Array(chessWidth);
pcTab[x] = new Array(chessWidth);
manScore[x] = new Array(chessWidth);
pcScore[x] = new Array(chessWidth);
for(var y=0; y<chessWidth; y++){
board[x][y] = chess.create(x,y);
manTab[x][y] = new Array(winCount);
pcTab[x][y] = new Array(winCount);
}
win[0] = new Array(winCount);
win[1] = new Array(winCount);
}
//初始化
for(var i=0; i<win.length; i++)
for(var j=0; j<win[i].length; j++)
win[i][j] = 0;
//计算可赢的可能的组合
winCount = 0;
var disable = winLength - 1;
//横向组合
for(var x=0; x<chessWidth-disable; x++){
for(var y=0; y<chessWidth; y++){
for(var z=0; z<winLength; z++){
manTab[x+z][y][winCount] = true;
pcTab[x+z][y][winCount] = true;
}
winCount++;
}
}
//纵向组合
for(var x=0; x<chessWidth; x++){
for(var y=0; y<chessWidth-disable; y++){
for(var z=0; z<winLength; z++){
manTab[x][y+z][winCount] = true;
pcTab[x][y+z][winCount] = true;
}
winCount++;
}
}
//斜向下组合
for(var x=0; x<chessWidth-disable; x++){
for(var y=0; y<chessWidth-disable; y++){
for(var z=0; z<winLength; z++){
manTab[x+z][y+z][winCount] = true;
pcTab[x+z][y+z][winCount] = true;
}
winCount++;
}
}
//斜向上组合
for(var x=0; x<chessWidth-disable; x++){
for(var y=winLength-1; y<chessWidth; y++){
for(var z=0; z<winLength; z++){
manTab[x+z][y-z][winCount] = true;
pcTab[x+z][y-z][winCount] = true;
}
winCount++;
}
}
//选项
var level = document.getElementById("radio");
level.style.position = "absolute";
level.style.top = "100px";
level.style.left = document.body.clientWidth/2+23*chessWidth/2+"px";
if(document.getElementById("rdoHard").checked){
setTimeout(function(){
open();
chess.pcPlay.call(board[chessWidth/2][chessWidth/2]);
alert("可以开始啦!!!");
}, 2*1000);
}
else{
open();
}
function open(){
for(var x=0; x<chessWidth; x++){
for(var y=0; y<chessWidth; y++){
board[x][y].onclick = chess.manPlay
}
}
}
function close(){
for(var x=0; x<chessWidth; x++){
for(var y=0; y<chessWidth; y++){
board[x][y].onclick = function(){alert("还不能开始,请稍等...");}
}
}
}
}
window.onload = main;
</script>
</head>
<body>
<form id="form1" runat="server">
<div id="radio">
容易:<input id="rdoEasy" checked="checked" name="onlyOne" onclick="main()" type="radio" /><br />
较难:<input id="rdoHard" name="onlyOne" onclick="main()" type="radio" /><br /><br />
五子棋:<input id="rdo5" checked="checked" onclick="main()" name="only" type="radio" /><br />
六子棋: <input id="rdo6" onclick="main()" name="only" type="radio" />
</div>
</form>
</body>
</html>
图片:
请对照下面的图片命名上面的图片