过年正赶上新冠病毒不让出门,在家闲着没事,偶尔玩了一下老家流行的游戏(走四棋),然后就想把这个游戏用JS写出来,先练了一下贪吃蛇,等下也会在我的博客中单独贴出来,按照贪吃蛇动态生成dom元素的方法,粗略的写了一下走四棋,有很多地方存在代码冗余,设计也有待优化,但是基本效果是有了,首次效果做成这样,我也很满意了,话不多说,上代码,仅供大家参考。
<html>
<body>
步数:<input type="text" value="0" id="stepCount" disabled></input>
<button id="rule" onclick="rule()">玩法说明</button>
<script>
var stepCount = 0;
var user;
//创建棋盘
function Map(){
//属性
this.width = 30;
this.height = 30;
this.jianju = 100;//每个棋子之间的间距
this.backgroundColor = "gray";
//棋盘的每一个可走点,定义为二维数组
this.route = [[1,1,"gray",null],[2,1,"gray",null],[3,1,"gray",null],[4,1,"gray",null],[1,2,"gray",null],[2,2,"gray",null],[3,2,"gray",null],[4,2,"gray",null],[1,3,"gray",null],[2,3,"gray",null],[3,3,"gray",null],[4,3,"gray",null],[1,4,"gray",null],[2,4,"gray",null],[3,4,"gray",null],[4,4,"gray",null]];
//显示所有点
if(!Map.prototype.showRoute){
Map.prototype.showRoute = function(){
//显示线段
//横向
for(var m = 1;m<=4;m++){
var lineX = document.createElement("div");
lineX.style.width = this.jianju * 3 + "px";
lineX.style.height = "2px";
lineX.style.position = "absolute";
lineX.style.left = this.jianju + this.width/2 + "px";
lineX.style.top = this.jianju * m + this.width/2 + "px";
lineX.style.backgroundColor = "black";
document.body.appendChild(lineX);
}
//纵向
for(var m = 1;m<=4;m++){
var lineY = document.createElement("div");
lineY.style.width = "2px";
lineY.style.height = this.jianju * 3 + "px";
lineY.style.position = "absolute";
lineY.style.left = this.jianju * m + this.width/2 + "px";
lineY.style.top = this.jianju + this.width/2 + "px";
lineY.style.backgroundColor = "black";
document.body.appendChild(lineY);
}
//创建div
for(var i = 0;i < this.route.length;i++){
var div = document.createElement("div");
div.id = "div"+(i+1);
div.className="div";
div.style.width = this.width + "px";
div.style.height = this.height + "px";
div.style.position = "absolute";
div.style.borderRadius = "50%";
div.style.left = this.route[i][0] * this.jianju + "px";
div.style.top = this.route[i][1] * this.jianju + "px";
div.style.backgroundColor = this.route[i][2];
//添加div到body
document.body.appendChild(div);
}
}
}
}
var map = new Map();
map.showRoute();
//创建棋子
function Chess(map){
this.width = map.width;
this.height = map.height;
this.backColor1 = "red";
this.backColor2 = "blue";
this.hasSelected1 = false;//标识红方有一个已被选中
this.hasSelected2 = false;//标识蓝方有一个已被选中
//显示棋子的方法
if(!Chess.prototype.showChess){
Chess.prototype.showChess = function(){
//创建div,红方
for(let i=0;i<4;i++){
var user1 = document.createElement("div");
user1.id = "red"+(i+1);
user1.className="red";
user1.style.width = this.width + "px";
user1.style.height = this.height + "px";
user1.style.position = "absolute";
user1.style.borderRadius = "50%";
user1.style.left = map.route[i][0] * map.jianju + "px";
user1.style.top = map.route[i][1] * map.jianju + "px";
user1.style.backgroundColor = this.backColor1;
document.body.appendChild(user1);
}
//蓝方
for(var i=12;i<16;i++){
var user2 = document.createElement("div");
user2.id="blue"+(i-11);
user2.className="blue";
user2.style.width = this.width + "px";
user2.style.height = this.height + "px";
user2.style.position = "absolute";
user2.style.borderRadius = "50%";
user2.style.left = map.route[i][0] * map.jianju + "px";
user2.style.top = map.route[i][1] * map.jianju + "px";
user2.style.backgroundColor = this.backColor2;
document.body.appendChild(user2);
}
}
}
}
var chess = new Chess(map);
chess.showChess();
function recoverAllColor(){
var redDiv=document.getElementsByClassName('red');
var blueDiv=document.getElementsByClassName('blue');
for(var i=0;i<redDiv.length;i++){
redDiv[i].style.backgroundColor = "red";
}
for(var i=0;i<blueDiv.length;i++){
blueDiv[i].style.backgroundColor = "blue";
}
}
//核心算法
function isKilled(dom){
//步数
stepCount++;
document.getElementById("stepCount").value = stepCount;
//判断是否可以吃掉对方棋子
var doms = [];
var redDiv=document.getElementsByClassName('red');
var blueDiv=document.getElementsByClassName('blue');
for(var i=0;i<redDiv.length;i++){
doms.push(redDiv[i]);
}
for(var i=0;i<blueDiv.length;i++){
doms.push(blueDiv[i]);
}
/*
每移动一次,只需判断当前移动的这个棋子所在的两条线上是否达成吃子的条件即可
*/
var countX = 0;//X轴的棋子数
var countY = 0;//Y轴的棋子数
var domX = [];//同一X轴的棋子
var domY = [];//同一Y轴的棋子
for(var i=0;i<doms.length;i++){
//判断当前棋子所在的横向是否满足条件
if(dom.style.top == doms[i].style.top){
domX.push(doms[i]);
countX ++;
}
if(dom.style.left == doms[i].style.left){
domY.push(doms[i]);
countY ++;
}
}
//只有同一轴上棋子数量为3时才有可能击杀
if(countX == 3){
//先按照x轴坐标给元素排序
domX = sortDomByX(domX);
if(parseInt(domX[0].style.left.replace("px","")) + 100 == parseInt(domX[1].style.left.replace("px","")) && parseInt(domX[1].style.left.replace("px","")) +100 == parseInt(domX[2].style.left.replace("px",""))){
//位置正确
if(domX[0].className=="red" && domX[1].className=="red" && domX[2].className=="blue" && dom.className != "blue"){
//红,红,蓝
domX[2].remove();
}else if(domX[0].className=="blue" && domX[1].className=="blue" && domX[2].className=="red" && dom.className != "red"){
//蓝,蓝,红
domX[2].remove();
}else if(domX[0].className=="red" && domX[1].className=="blue" && domX[2].className=="blue" && dom.className != "red"){
//红,蓝,蓝
domX[0].remove();
}else if(domX[0].className=="blue" && domX[1].className=="red" && domX[2].className=="red" && dom.className != "blue"){
//蓝,红,红
domX[0].remove();
}
}
}
if(countY == 3){
//先按照y轴坐标给元素排序
domY = sortDomByY(domY);
if(parseInt(domY[0].style.top.replace("px","")) + 100 == parseInt(domY[1].style.top.replace("px","")) && parseInt(domY[1].style.top.replace("px","")) +100 == parseInt(domY[2].style.top.replace("px",""))){
//位置正确
if(domY[0].className=="red" && domY[1].className=="red" && domY[2].className=="blue" && dom.className != "blue"){
//红,红,蓝
domY[2].remove();
}else if(domY[0].className=="blue" && domY[1].className=="blue" && domY[2].className=="red" && dom.className != "red"){
//蓝,蓝,红
domY[2].remove();
}else if(domY[0].className=="red" && domY[1].className=="blue" && domY[2].className=="blue" && dom.className != "red"){
//红,蓝,蓝
domY[0].remove();
}else if(domY[0].className=="blue" && domY[1].className=="red" && domY[2].className=="red" && dom.className != "blue"){
//蓝,红,红
domY[0].remove();
}
}
}
//判断游戏是否结束
isGameOver();
}
function isGameOver(){
var redDiv=document.getElementsByClassName('red');
var blueDiv=document.getElementsByClassName('blue');
if(redDiv.length==1){
alert("游戏结束!蓝方获胜!");
}else if(blueDiv.length==1){
alert("游戏结束!红方获胜!");
}
}
function sortDomByX(domX){
var x0 = parseInt(domX[0].style.left.replace("px",""));
var x1 = parseInt(domX[1].style.left.replace("px",""));
var x2 = parseInt(domX[2].style.left.replace("px",""));
var dom0 = domX[0];
var dom1 = domX[1];
var dom2 = domX[2];
domX = [];
if(x0 > x1 && x1 > x2){
domX.push(dom2);
domX.push(dom1);
domX.push(dom0);
}else if(x0 > x2 && x2 > x1){
domX.push(dom1);
domX.push(dom2);
domX.push(dom0);
}else if(x1 > x0 && x0 > x2){
domX.push(dom2);
domX.push(dom0);
domX.push(dom1);
}else if(x1 > x2 && x2 > x0){
domX.push(dom0);
domX.push(dom2);
domX.push(dom1);
}else if(x2 > x0 && x0 > x1){
domX.push(dom1);
domX.push(dom0);
domX.push(dom2);
}else if(x2 > x1 && x1 > x0){
domX.push(dom0);
domX.push(dom1);
domX.push(dom2);
}
return domX;
}
function sortDomByY(domY){
var y0 = parseInt(domY[0].style.top.replace("px",""));
var y1 = parseInt(domY[1].style.top.replace("px",""));
var y2 = parseInt(domY[2].style.top.replace("px",""));
var dom0 = domY[0];
var dom1 = domY[1];
var dom2 = domY[2];
domY = [];
if(y0 > y1 && y1 > y2){
domY.push(dom2);
domY.push(dom1);
domY.push(dom0);
}else if(y0 > y2 && y2 > y1){
domY.push(dom1);
domY.push(dom2);
domY.push(dom0);
}else if(y1 > y0 && y0 > y2){
domY.push(dom2);
domY.push(dom0);
domY.push(dom1);
}else if(y1 > y2 && y2 > y0){
domY.push(dom0);
domY.push(dom2);
domY.push(dom1);
}else if(y2 > y0 && y0 > y1){
domY.push(dom1);
domY.push(dom0);
domY.push(dom2);
}else if(y2 > y1 && y1 > y0){
domY.push(dom0);
domY.push(dom1);
domY.push(dom2);
}
return domY;
}
function isCanMove(divs){
if(!user){
user = divs.className;
}else if(user == "red" && divs.className=="red"){
alert("轮到蓝方!");
e.preventDefault();
}else if(user == "blue" && divs.className=="blue"){
alert("轮到红方!");
e.preventDefault();
}else if(user == "red" && divs.className=="blue"){
user = "blue";
}else if(user == "blue" && divs.className=="red"){
user = "red";
}
}
//绑定点击事件
function init(){
//棋子数组
var doms = [];
var redDiv=document.getElementsByClassName('red');
for(var i=1;i<=redDiv.length;i++){
doms.push(redDiv[i-1]);
(function(val){
redDiv[i-1].onclick=function(){
//重新获取元素
var divs = document.getElementById("red"+val);
if(divs.style.backgroundColor=="red"){
recoverAllColor();
divs.style.backgroundColor = "#cc0000";
}else{
divs.style.backgroundColor = "red";
}
}
})(i);
}
var blueDiv=document.getElementsByClassName('blue');
for(var i=1;i<=blueDiv.length;i++){
doms.push(blueDiv[i-1]);
(function(val){
blueDiv[i-1].onclick=function(){
//重新获取元素
var divs = document.getElementById("blue"+val);
if(divs.style.backgroundColor=="blue"){
recoverAllColor();
divs.style.backgroundColor = "#000099";
}else{
divs.style.backgroundColor = "blue";
}
}
})(i);
}
//绑定其他地图div的点击事件
var div=document.getElementsByClassName('div');
for(var i=1;i<=16;i++){
(function(val){
div[i-1].onclick=function(){
//重新获取元素
var divs = document.getElementById("div"+val);
//点击时,判断这个坐标的四周有没有被选中的棋子,有则移动
for(var i=0;i<doms.length;i++){
//四周是否有相等的x和y
var left = parseInt(divs.style.left.replace("px",""))-100+"px";
var top = parseInt(divs.style.top.replace("px",""))-100+"px";
var right = parseInt(divs.style.left.replace("px",""))+100+"px";
var down = parseInt(divs.style.top.replace("px",""))+100+"px";
var com=window.getComputedStyle?window.getComputedStyle(doms[i],null):doms[i].currentStyle;
if(doms[i].style.left == left && doms[i].style.top == divs.style.top){
//左边有棋子
if(com.backgroundColor == "rgb(204, 0, 0)"){
//判断是否可以移动
isCanMove(doms[i]);
doms[i].style.backgroundColor = "red";
doms[i].style.left = divs.style.left;
//移动过后,判断
isKilled(doms[i]);
}else if(com.backgroundColor == "rgb(0, 0, 153)"){
//需要移动到此处坐标
isCanMove(doms[i]);
doms[i].style.backgroundColor = "blue";
doms[i].style.left = divs.style.left;
isKilled(doms[i]);
}
}
if(doms[i].style.top == top && doms[i].style.left == divs.style.left){
//上边有棋子
if(com.backgroundColor == "rgb(204, 0, 0)"){
isCanMove(doms[i]);
doms[i].style.backgroundColor = "red";
doms[i].style.top = divs.style.top;
isKilled(doms[i]);
}else if(com.backgroundColor == "rgb(0, 0, 153)"){
isCanMove(doms[i]);
//需要移动到此处坐标
doms[i].style.backgroundColor = "blue";
doms[i].style.top = divs.style.top;
isKilled(doms[i]);
}
}
if(doms[i].style.left == right && doms[i].style.top == divs.style.top){
//右边有棋子
if(com.backgroundColor == "rgb(204, 0, 0)"){
isCanMove(doms[i]);
doms[i].style.backgroundColor = "red";
doms[i].style.left = divs.style.left;
isKilled(doms[i]);
}else if(com.backgroundColor == "rgb(0, 0, 153)"){
isCanMove(doms[i]);
//需要移动到此处坐标
doms[i].style.backgroundColor = "blue";
doms[i].style.left = divs.style.left;
isKilled(doms[i]);
}
}
if(doms[i].style.top == down && doms[i].style.left == divs.style.left){
//下边有棋子
if(com.backgroundColor == "rgb(204, 0, 0)"){
isCanMove(doms[i]);
doms[i].style.backgroundColor = "red";
doms[i].style.top = divs.style.top;
isKilled(doms[i]);
}else if(com.backgroundColor == "rgb(0, 0, 153)"){
isCanMove(doms[i]);
//需要移动到此处坐标
doms[i].style.backgroundColor = "blue";
doms[i].style.top = divs.style.top;
isKilled(doms[i]);
}
}
}
}
})(i);
}
}
function rule(){
alert("玩法说明\n玩家手持红方或蓝方棋子,每次各走一步,当同一条直线上存在三个棋子相邻,两个颜色相同的棋子可以吃掉另一方,直至对方还剩一个棋子获胜。主动移动的棋子,即使满足条件,也不会被吃掉");
}
//初始化
init();
</script>
</body>
</html>