扫雷源码
<!--
扫雷(仿Windows扫雷)
By: 无心 cuixiping@yeah.net
简述:
规则皆与Windows扫雷相同,支持双键翻雷,标记可疑地区,自定义难度。
-->
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<
html
>
<
head
>
<
title
> 扫雷 </
title
>
<
meta
http-equiv="Content-Type" content="text/html; charset=gb2312">
<
STYLE
TYPE="text/css"
TITLE
="">
#T td {font-size:10pt; text-align:center }
</
STYLE
>
</
head
>
<
body
onload="drawTable()" onselectstart="return false" onkeydown="if(event.keyCode==113){drawTable()}">
<
center
>
<
TABLE
border=1 cellspacing=2 cellpadding=2 bgcolor=buttonface bordercolorlight=#000000 bordercolordark=#FFFFFF
style
="cursor:default" oncontextmenu="return false" onselectstart="return false">
<
TR
>
<
TD
height=16>
<
TABLE
width="100%" border=0 cellspacing=0 cellpadding=2>
<
TR
>
<
TD
height=16>
</
TD
>
</
TR
>
<
TR
>
<
TD
height=1
style
="height:1">
<
div
style
="position:relative">
<
div
id=T_Title
style
="position:absolute;top:-20"
style
="font-size:10pt">
<
font
face='Wingdings' color=black
style
="font-size:12pt">M</
font
>扫雷
</
div
>
</
div
>
</
TD
>
</
TR
>
</
TABLE
>
</
TD
>
</
TR
>
<
TR
>
<
TD
>
<
input
type="button" value="开局" onclick="drawTable2()">
<
input
type="button" value="初级" onclick="SetLevel(1)">
<
input
type="button" value="中级" onclick="SetLevel(2)">
<
input
type="button" value="高级" onclick="SetLevel(3)">
<
input
type="button" value="自定义" onclick="ReDefine()">
<
input
type="button" value="?" onclick="ShowAbout()"
title
="关于…">
</
TD
>
</
TR
>
<
TR
>
<
TD
>
<
TABLE
width="100%" border=0 cellspacing=0 cellpadding=2>
<
TR
>
<
TD
width=40 align=left>
<
TABLE
width="40" height="26" cellspacing=0 cellpadding=0 border=1 bordercolorlight="#FFFFFF" bordercolordark="#000000">
<
TR
><
TD
id=TD_MineRest bordercolorlight="#808080" bordercolordark="buttonface" align="right" bgcolor=black
style
="color:red;font-weight:bold;letter-spacing:2">
120
</
TD
></
TR
>
</
TABLE
>
</
TD
>
<
TD
align=
center
>
<
TABLE
width="26" height="26" cellspacing=0 cellpadding=0 border=1 bordercolorlight="#FFFFFF" bordercolordark="#000000" onmousedown="this.borderColorLight='#000000';this.borderColorDark='#FFFFFF'" onmouseout="this.borderColorLight='#FFFFFF';this.borderColorDark='#000000'" onmouseup="this.borderColorLight='#FFFFFF';this.borderColorDark='#000000'">
<
TR
><
TD
id=TD_Face bordercolorlight="#808080" bordercolordark="buttonface" align="center"
style
="font-size:14pt" onclick="drawTable2()" onmousedown="this.borderColorLight='buttonface';this.borderColorDark='#808080'" onmouseout="this.borderColorLight='#808080';this.borderColorDark='buttonface'" onmouseup="this.borderColorLight='#808080';this.borderColorDark='buttonface'">
</
TD
></
TR
>
</
TABLE
>
</
TD
>
<
TD
width=40 align=right>
<
TABLE
width="40" height="26" cellspacing=0 cellpadding=0 border=1 bordercolorlight="#FFFFFF" bordercolordark="#000000">
<
TR
><
TD
id=TD_TimePast bordercolorlight="#808080" bordercolordark="buttonface" align="right" bgcolor=black
style
="color:red;font-weight:bold;letter-spacing:2">
0
</
TD
></
TR
>
</
TABLE
>
</
TD
>
</
TR
>
</
TABLE
>
</
TD
>
</
TR
>
<
TR
>
<
TD
align=
center
>
<
SPAN
id=T_Span>
<
TABLE
id=T border=1 cellspacing=0 cellpadding=0 bgcolor=buttonface bordercolorlight=#000000 bordercolordark=#FFFFFF>
</
TABLE
>
</
SPAN
>
</
TD
>
</
TR
>
</
TABLE
>
<
script
language="JavaScript">
<!--
//笑脸
var
Face1="<font face='Wingdings' color=black>J</font>"
//高兴
var
Face2="<font face='Wingdings' color=black>K</font>"
//注意
var
Face3="<font face='Wingdings' color=red>L</font>"
//沮丧
// borderColorDark borderColorLight
var
DarkColor="#000000"
,
LightColor="#FFFFFF"
//var Mine="<font face='Webdings' color=red>~</font>" //雷标
var
Mine="<font face='Wingdings' color=red>M</font>"
//雷标
var
Quest="<font face='Webdings' color=blue>s</font>"
//疑问
var
MineEnd="<font face='Wingdings' color=black>M</font>"
//未揭的雷,最后自动排出的
//var Explode="<font face='Webdings' color=yellow>~</font>" //爆炸
var
Explode="<font face='Wingdings' color=yellow>M</font>"
//爆炸
var
ExplodedBgcolor="#ff0000"
var
NMColors=new Array
(
"blue"
,
"green"
,
"red"
,
"darkblue"
,
"darkred"
,
"gold"
,
"purple"
,
"teal"
)
var
rowsCount=8
,
colsCount=12
,
MinesCount=20
var
gridCount=rowsCount*colsCount
var
MinesPos=new Array
(
)
,
NMArr=new Array
(
)
var
Start=0
,
GameOver=0
var
MineRest=0
,
TimePast=0
,
OpenCount=0
var
mouseI=0
//判别鼠标单击、两键同时按下
function
ShowAbout
(
)
{
var
s=""
s += "/n关于/t扫雷(仿Windows扫雷)"
s += "/n/n规则:/t皆与Windows扫雷相同。"
s += "/n/nBy:/t无心"
s += "/nEmail:/tcuixiping"+"@yeah.net"
alert
(
s
)
}
function
getEleTD
(
)
{
var
ele=event
.
srcElement
var
ele2= ele
.
parentElement ? ele
.
parentElement : null
var
ele3= ele2.parentElement ? ele2.parentElement : null
if
(
ele
.
id=="T_TD"
)
{
return
ele
}
else
if
(
ele2 && ele2.id=="T_TD"
)
{
return
ele2
}
else
if
(
ele3 && ele3.id=="T_TD"
)
{
return
ele3
}
else
{
return
null
}
}
function
document
.
onmouseover
(
)
{
var
td=getEleTD
(
)
if
(
td
)
mouseI=0
}
function
document
.
onmouseout
(
)
{
var
td=getEleTD
(
)
if
(
td
)
mouseI=0
}
function
document
.
onmousedown
(
)
{
var
td=getEleTD
(
)
if
(
td
)
mouseI+=1
}
function
document
.
onmouseup
(
)
{
var
td=getEleTD
(
)
if
(
!td
)
{
return
;
}
if
(
mouseI==1
)
{
mouseI=0
SClick
(
td
)
}
else
if
(
mouseI==2
)
{
mouseI=0
DClick
(
td
)
}
else
if
(
mouseI==0
)
{
}
}
function
drawTable
(
)
{
//画表
T
.
style
.
visibility="hidden"
var
ir=0
,
ic=0
,
im=0
,
s=""
TD_Face
.
innerHTML=Face1
TD_MineRest
.
innerHTML=MinesCount
TD_TimePast
.
innerHTML=0
Start=0
GameOver=0
MineRest=MinesCount
TimePast=0
OpenCount=0
gridCount=rowsCount*colsCount
//html
s+='<TABLE id=T border=1 cellspacing=0 cellpadding=0 bgcolor=buttonface bordercolorlight=#000000 bordercolordark=#FFFFFF οncοntextmenu="return false">'
for
(
ir=0
;
ir<rowsCount
;
ir++
)
{
s+='<TR height="20">'
for
(
ic=0
;
ic<colsCount
;
ic++
)
{
s+='<TD width="20" id=T_TD> </TD>'
}
s+='</TR>'
}
s+='</TABLE>'
T_Span
.
innerHTML=s
//随机放雷
MinesPos
.
length=gridCount
var
msl=0
,
ms=""
,
tmpPos=0
,
tmpM=""
msl=gridCount-MinesCount
for
(
im=0
;
im<msl
;
im+=20
)
{
ms+="0000000000"+"0000000000"
}
ms=ms
.
substr
(
0
,
msl
)
for
(
im=0
;
im<MinesCount
;
im++
)
{
tmpPos=Math
.
floor
(
msl*Math
.
random
(
)
)
ms=ms
.
substr
(
0
,
tmpPos
)
+"1"+ms
.
substr
(
tmpPos
)
}
var
td
for
(
im=0
;
im<gridCount
;
im++
)
{
td=T_TD
[
im
]
tmpM=ms
.
charAt
(
im
)
MinesPos
[
im
]
=
(
tmpM=="0" ? 0 : 1
)
td
.
setAttribute
(
"hasMine"
,
tmpM
,
false
)
td
.
setAttribute
(
"NM"
,
"0"
,
false
)
td
.
setAttribute
(
"active"
,
"0"
,
false
)
td
.
setAttribute
(
"sta"
,
""
,
false
)
td
.
setAttribute
(
"BA"
,
""
,
false
)
td
.
setAttribute
(
"i"
,
im
,
false
)
hasUp = im>=colsCount
hasDown = im<=
(
rowsCount-1
)
*colsCount-1
hasLeft =
(
im % colsCount
)
>0
hasRight =
(
im % colsCount
)
<colsCount-1
td
.
setAttribute
(
"UpTD"
,
(
hasUp ? T_TD
[
im-colsCount
]
: null
)
)
td
.
setAttribute
(
"DownTD"
,
(
hasDown ? T_TD
[
im+colsCount
]
: null
)
)
td
.
setAttribute
(
"LeftTD"
,
(
hasLeft ? T_TD
[
im-1
]
: null
)
)
td
.
setAttribute
(
"RightTD"
,
(
hasRight ? T_TD
[
im+1
]
: null
)
)
td
.
setAttribute
(
"LeftUpTD"
,
(
(
hasLeft && hasUp
)
? T_TD
[
im-1-colsCount
]
: null
)
)
td
.
setAttribute
(
"RightUpTD"
,
(
(
hasRight && hasUp
)
? T_TD
[
im+1-colsCount
]
: null
)
)
td
.
setAttribute
(
"LeftDownTD"
,
(
(
hasLeft && hasDown
)
? T_TD
[
im-1+colsCount
]
: null
)
)
td
.
setAttribute
(
"RightDownTD"
,
(
(
hasRight && hasDown
)
? T_TD
[
im+1+colsCount
]
: null
)
)
}
var
NM=0
,
hasLeft
,
hasRight
,
hasUp
,
hasDown
for
(
im=0
;
im<gridCount
;
im++
)
{
NM=0
td=T_TD
[
im
]
if
(
!MinesPos
[
im
]
)
{
if
(
td
.
UpTD && td
.
UpTD
.
hasMine=="1"
)
{
NM++
}
//上
if
(
td
.
DownTD && td
.
DownTD
.
hasMine=="1"
)
{
NM++
}
//下
if
(
td
.
LeftTD && td
.
LeftTD
.
hasMine=="1"
)
{
NM++
}
//左
if
(
td
.
RightTD && td
.
RightTD
.
hasMine=="1"
)
{
NM++
}
//右
if
(
td
.
LeftUpTD && td
.
LeftUpTD
.
hasMine=="1"
)
{
NM++
}
//左上
if
(
td
.
RightUpTD && td
.
RightUpTD
.
hasMine=="1"
)
{
NM++
}
//右上
if
(
td
.
LeftDownTD && td
.
LeftDownTD
.
hasMine=="1"
)
{
NM++
}
//左下
if
(
td
.
RightDownTD && td
.
RightDownTD
.
hasMine=="1"
)
{
NM++
}
//右下
}
T_TD
[
im
]
.
NM=NM
//NMArr[im]=NM
}
T
.
style
.
visibility="visible"
}
function
drawTable2
(
)
{
//画表2
//html
T
.
style
.
visibility="hidden"
var
ir=0
,
ic=0
,
im=0
,
s=""
TD_Face
.
innerHTML=Face1
TD_MineRest
.
innerHTML=MinesCount
TD_TimePast
.
innerHTML=0
Start=0
GameOver=0
MineRest=MinesCount
TimePast=0
OpenCount=0
gridCount=rowsCount*colsCount
//随机放雷
MinesPos
.
length=gridCount
var
msl=0
,
ms=""
,
tmpPos=0
,
tmpM=""
msl=gridCount-MinesCount
for
(
im=0
;
im<msl
;
im+=20
)
{
ms+="0000000000"+"0000000000"
}
ms=ms
.
substr
(
0
,
msl
)
for
(
im=0
;
im<MinesCount
;
im++
)
{
tmpPos=Math
.
floor
(
msl*Math
.
random
(
)
)
ms=ms
.
substr
(
0
,
tmpPos
)
+"1"+ms
.
substr
(
tmpPos
)
}
var
td
for
(
im=0
;
im<gridCount
;
im++
)
{
td=T_TD
[
im
]
setInit
(
td
)
td
.
bgColor=""
tmpM=ms
.
charAt
(
im
)
MinesPos
[
im
]
=
(
tmpM=="0" ? 0 : 1
)
td
.
setAttribute
(
"hasMine"
,
tmpM
,
false
)
td
.
setAttribute
(
"NM"
,
"0"
,
false
)
td
.
setAttribute
(
"active"
,
"0"
,
false
)
td
.
setAttribute
(
"sta"
,
""
,
false
)
td
.
setAttribute
(
"BA"
,
""
,
false
)
td
.
setAttribute
(
"i"
,
im
,
false
)
}
var
NM=0
for
(
im=0
;
im<gridCount
;
im++
)
{
NM=0
td=T_TD
[
im
]
if
(
!MinesPos
[
im
]
)
{
if
(
td
.
UpTD && td
.
UpTD
.
hasMine=="1"
)
{
NM++
}
//上
if
(
td
.
DownTD && td
.
DownTD
.
hasMine=="1"
)
{
NM++
}
//下
if
(
td
.
LeftTD && td
.
LeftTD
.
hasMine=="1"
)
{
NM++
}
//左
if
(
td
.
RightTD && td
.
RightTD
.
hasMine=="1"
)
{
NM++
}
//右
if
(
td
.
LeftUpTD && td
.
LeftUpTD
.
hasMine=="1"
)
{
NM++
}
//左上
if
(
td
.
RightUpTD && td
.
RightUpTD
.
hasMine=="1"
)
{
NM++
}
//右上
if
(
td
.
LeftDownTD && td
.
LeftDownTD
.
hasMine=="1"
)
{
NM++
}
//左下
if
(
td
.
RightDownTD && td
.
RightDownTD
.
hasMine=="1"
)
{
NM++
}
//右下
}
T_TD
[
im
]
.
NM=NM
//NMArr[im]=NM
}
T
.
style
.
visibility="visible"
}
function
ReDefine
(
)
{
//自定义
var
a1=prompt
(
"行数,列数,雷数:"
,
rowsCount+","+colsCount+","+MinesCount
)
if
(
!a1
)
{
return
;
}
// 8 <=行数<=24,8 <=列数<=30
//10 <=雷数<= (行数-1)*(列数-1)
if
(
!a1.search
(
/^
(
/d
{
1
,
2
}
)
,
(
/d
{
1
,
2
}
)
,
(
/d
{
1
,
3
}
)
$/
)
<0
)
{
return
;
}
var
ir=parseInt
(
RegExp
.
$1
)
,
ic=parseInt
(
RegExp
.
$2
)
,
im=parseInt
(
RegExp
.
$3
)
if
(
ir<8
)
ir=8
if
(
ir>24
)
ir=24
if
(
ic<8
)
ic=8
if
(
ic>30
)
ic=30
if
(
im<10
)
im=10
if
(
im>
(
ir-1
)
*
(
ic-1
)
)
im=
(
ir-1
)
*
(
ic-1
)
if
(
rowsCount==ir && colsCount==ic && MinesCount==im
)
{
drawTable2
(
)
}
else
{
rowsCount=ir
,
colsCount=ic
,
MinesCount=im
drawTable
(
)
}
}
function
SetLevel
(
Level
)
{
//Level: 1初级 2中级 3高级
switch
(
Level
)
{
case 1:
rowsCount=8
,
colsCount=8
,
MinesCount=10
break
;
case 2:
rowsCount=16
,
colsCount=16
,
MinesCount=40
break
;
case 3:
rowsCount=16
,
colsCount=30
,
MinesCount=99
break
;
default:
return
;
}
drawTable
(
)
}
function
setInit
(
td
)
//恢复
{
td
.
borderColorLight=DarkColor
td
.
borderColorDark=LightColor
td
.
innerHTML=" "
td
.
sta=""
}
function
setOpen
(
td
)
//翻开
{
if
(
!Start
)
{
Start=1
CountTime
(
)
}
td
.
borderColorLight=LightColor
td
.
borderColorDark=DarkColor
td
.
sta="Open"
OpenCount++
if
(
OpenCount+MinesCount-MineRest==gridCount
)
{
GameOver=1
}
}
//OpenBA 递归调用,打开相邻的空白区
function
OpenBA
(
td
)
{
var
im=td
.
i
if
(
td
.
hasMine=="1"
)
{
return
;
}
if
(
td
.
sta!="" && td
.
sta!="Quest"
)
{
return
;
}
if
(
td
.
NM!="0"
)
{
setOpen
(
td
)
setNM
(
td
)
return
;
}
//翻开本格
if
(
td
.
sta=="Quest"
)
{
setInit
(
td
)
}
setOpen
(
td
)
//翻开相邻的空白区
with
(
td
)
{
if
(
UpTD
)
{
OpenBA
(
UpTD
)
}
//上
if
(
DownTD
)
{
OpenBA
(
DownTD
)
}
//下
if
(
LeftTD
)
{
OpenBA
(
LeftTD
)
}
//左
if
(
RightTD
)
{
OpenBA
(
RightTD
)
}
//右
if
(
LeftUpTD
)
{
OpenBA
(
LeftUpTD
)
}
//左上
if
(
RightUpTD
)
{
OpenBA
(
RightUpTD
)
}
//右上
if
(
LeftDownTD
)
{
OpenBA
(
LeftDownTD
)
}
//左下
if
(
RightDownTD
)
{
OpenBA
(
RightDownTD
)
}
//右下
}
}
function
setMine
(
td
)
//雷标
{
//if(!td){td=event.srcElement}
addMineRest
(
-1
)
td
.
innerHTML=Mine
td
.
sta="Mine"
if
(
OpenCount+MinesCount-MineRest==gridCount
)
{
GameOver=1
}
}
function
setQuest
(
td
)
//疑问
{
td
.
innerHTML=Quest
td
.
sta="Quest"
}
function
setExplode
(
td
)
//爆炸
{
td
.
bgColor=ExplodedBgcolor
td
.
innerHTML=Explode
td
.
sta="Explode"
TD_Face
.
innerHTML=Face3
GameOver=1
showAll
(
)
}
function
CountTime
(
)
//开始计时
{
if
(
GameOver
)
{
if
(
OpenCount+MinesCount-MineRest==gridCount
)
{
alert
(
"成功!"
)
}
return
;
}
if
(
TimePast==999
)
{
return
;
}
setTimeout
(
"CountTime()"
,
1000
)
TimePast+=1
TD_TimePast
.
innerHTML=TimePast
}
function
addMineRest
(
i
)
//剩余雷数,可为负数
{
MineRest+=i
TD_MineRest
.
innerHTML=MineRest
}
function
setNM
(
td
)
//显示雷数
{
var
NM=td
.
NM
if
(
NM>0
)
{
//td.innerHTML='<font color='+NMColors[parseInt(NM)-1]+'><b>'+NM+'</b></font>'
//这里不用<font>而用style是为了使event.srcElement直接捕捉TD
td
.
innerHTML= NM
td
.
style
.
color = NMColors
[
parseInt
(
NM
)
-1
]
td
.
style
.
fontWeight = "bold"
}
}
function
showAll
(
)
//显示全部
{
var
td
for
(
var
im=0
;
im<gridCount
;
im++
)
{
td=T_TD
[
im
]
if
(
td
.
sta=="" && td
.
hasMine=="1"
)
{
td
.
innerHTML=MineEnd
setOpen
(
td
)
}
}
}
function
SClick
(
td
)
//单击
{
if
(
GameOver
)
{
return
;
}
if
(
event
.
button==2
)
{
RClick
(
td
)
//右击
return
;
}
window
.
event
.
returnValue = false
;
if
(
td
.
sta!="" && td
.
sta!="Quest"
)
{
return
;
}
if
(
td
.
hasMine=="1"
)
{
setExplode
(
td
)
}
else
if
(
td
.
NM!=""
)
{
setOpen
(
td
)
setNM
(
td
)
}
else
if
(
td
.
NM=="" && td
.
hasMine=="0"
)
{
OpenBA
(
td
)
}
}
function
DClick
(
td
)
//鼠标左右键都按下
{
if
(
GameOver
)
{
return
;
}
window
.
event
.
returnValue = false
;
var
h=td
.
hasMine
//翻开相邻的空白区
if
(
!
(
td
.
sta=="Open" && td
.
NM>0
)
)
{
return
;
}
var
aroundTDS=new Array
(
)
with
(
td
)
{
var
aroundTDS=new Array
(
UpTD
,
DownTD
,
LeftTD
,
RightTD
,
LeftUpTD
,
RightUpTD
,
LeftDownTD
,
RightDownTD
)
}
var
MCount_Flag=0
//周围已标雷的格数
var
MCount_hide=0
//周围藏有雷的格数
for
(
var
i=0
;
i<aroundTDS
.
length
;
i++
)
{
if
(
!aroundTDS
[
i
]
)
{
continue
;
}
if
(
aroundTDS
[
i
]
.
sta=="Mine"
)
{
MCount_Flag++
}
if
(
aroundTDS
[
i
]
.
sta!="Mine" && aroundTDS
[
i
]
.
hasMine=="1"
)
{
MCount_hide++
}
}
if
(
MCount_Flag!=td
.
NM
)
{
return
;
}
var
tmpTD
for
(
var
i=0
;
i<aroundTDS
.
length
;
i++
)
{
tmpTD=aroundTDS
[
i
]
if
(
!tmpTD
)
{
continue
;
}
if
(
MCount_hide==0
)
{
OpenBA
(
tmpTD
)
}
else
{
if
(
tmpTD
.
hasMine=="1" && tmpTD
.
sta!="Mine"
)
{
setExplode
(
tmpTD
)
return
;
}
}
}
}
function
RClick
(
td
)
//右击
{
window
.
event
.
returnValue = false
;
var
sta=td
.
sta
if
(
sta==""
)
{
setMine
(
td
)
}
else
if
(
sta=="Mine"
)
{
setQuest
(
td
)
addMineRest
(
1
)
}
else
if
(
sta=="Quest"
)
{
setInit
(
td
)
}
}
//未翻,已翻,雷标,疑问
//-->
</
script
>
</
center
>
</
body
>
</
html
>