当前位置: 代码迷 >> JavaScript >> 用js写了一个探雷,并封装了ArrayList、伪HashTable
  详细解决方案

用js写了一个探雷,并封装了ArrayList、伪HashTable

热度:243   发布时间:2012-09-09 09:27:54.0
用js写了一个扫雷,并封装了ArrayList、伪HashTable

废话少说,先上代码,以后再慢慢解释!

?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title></title>
		<meta http-equiv="content-type" content="text/html; charset=UTF-8" />

		<style type="text/css">
* {
	margin: 0;
	padding: 0;
}
		</style>

		<script type="text/javascript" charset="UTF-8" language="javascript">

var sinojh = {
	"Version" : "1.0",
	"Copyright" : "Copyright(c) sino-jh 2011",
	"Author" : "Jeff Lan",
	"Email" : "jefflan@live.cn",
	//日期格式化样式
	"dateFormatStyle" : "yyyy-MM-dd hh:mm:ss",
	/**
	 * 获取Url参数
	 * @param parameter
	 */
	"getUrlParameter" : function(parameter) {
		var url = location.href;
		var paraString = url.substring(url.indexOf("?") + 1, url.length).split("&");
		var paraObj = {};
		for (var i in paraString) {
			var j = paraString[i];
			paraObj[j.substring(0, j.indexOf("=")).toLowerCase()] = j.substring(j.indexOf("=") + 1, j.length);
		}
		var returnValue = paraObj[parameter.toLowerCase()];
		if (returnValue == undefined) {
			return "";
		} else {
			return returnValue;
		}
	},
	/**
	 * 日期格式化
	 * @param date
	 * @param format
	 */
	"dateFormat" : function(date, format) {
		format = format ? format : this.dateFormatStyle;
		var o = {
			"M+" : date.getMonth() + 1, //month
			"d+" : date.getDate(), //day
			"h+" : date.getHours(), //hour
			"m+" : date.getMinutes(), //minute
			"s+" : date.getSeconds(), //second
			"q+" : Math.floor((date.getMonth() + 3) / 3), //quarter
			"S" : date.getMilliseconds() //millisecond
		};
		if (/(y+)/.test(format)) {
			format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
		}
		for ( var k in o) {
			if (new RegExp("(" + k + ")").test(format)) {
				format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
			}
		}
		return format;
	},
	/**
	 * 将日期格式的字符串转换成Date
	 * @param dateStr
	 * @param style
	 */
	"toDate" : function(dateStr, style) {
		style = style ? style : this.dateFormatStyle;
		var compare = {
			"y+" : "y",
			"M+" : "M",
			"d+" : "d",
			"h+" : "h",
			"m+" : "m",
			"s+" : "s"
		};
		var result = {
			"y" : "",
			"M" : "",
			"d" : "",
			"h" : "00",
			"m" : "00",
			"s" : "00"
		};
		var tmp = style;
		for ( var k in compare) {
			if (new RegExp("(" + k + ")").test(style)) {
				result[compare[k]] = dateStr.substring(tmp.indexOf(RegExp.$1), tmp.indexOf(RegExp.$1) + RegExp.$1.length);
			}
		}
		return new Date(result["y"], result["M"] - 1, result["d"], result["h"], result["m"], result["s"]);
	},
	/**
	 * 给DOM对象添加事件监听
	 * @param o
	 * @param e
	 * @param l
	 */
	"addEventListener" : function(o, e, l) {
		if (o.addEventListener) {
			o.addEventListener(e, l, false);
		} else if (o.attachEvent) {
			o.attachEvent("on" + e, function() {
				l(window.event);
			});
		}
	},
	/**
	 * 移除DOM对象的监听事件
	 * @param o
	 * @param e
	 * @param l
	 */
	"removeEventListener" : function(o, e, l) {
		if (o.removeEventListener) {
			o.removeEventListener(e, l, false);
		} else if (o.detachEvent) {
			o.detachEvent('on' + e, function() {
				l(window.event);
			});
		}
	},
	/**
	 * 基于数组实现的列表类
	 * @param capacity
	 */
	"ArrayList" : function(capacity) {
		capacity = capacity ? capacity : 10;
		var self = this;
		var increment = 0.75;
		var size = 0;
		var array = new Array(capacity);
		var amplify = function(ic) {
			ic = ic ? ic : Math.round(capacity * increment);
			var amplifyArray = new Array(ic);
			array = array.concat(amplifyArray);
			capacity = array.length;
		};
		this.className = "sinojh.ArrayList";
		this.isEmpty = function() {
			return size == 0;
		};
		this.size = function() {
			return size;
		};
		this.add = function(obj) {
			if (size >= capacity) {
				amplify();
			}
			array[size] = obj;
			size++;
		};
		this.addAll = function(li) {
			if (self.className == li.className) {
				var needCapacity = li.size() + size;
				if (needCapacity > capacity) {
					amplify(needCapacity - capacity + 7);
				}
				li.each(function(obj) {
					array[size] = obj;
					size++;
				});
			} else {
				throw "TypeErrorException:";
			}
		};
		this.get = function(index) {
			if (!self.isEmpty() && index < size) {
				return array[index];
			} else {
				throw "IndexOutOfBoundsException : Index: " + index + ", Size: " + size;
			}
		};
		this.set = function(index, obj) {
			if (!self.isEmpty() && index < size) {
				var o = array[index];
				array[index] = obj;
				return o;
			} else {
				throw "IndexOutOfBoundsException : Index: " + index + ", Size: " + size;
			}
		};
		this.remove = function(index) {
			if (!(typeof index == "number")) {
				index = self.indexOf(index);
				if (index ==-1) {
					return false;
				}
			}
			if (!self.isEmpty() && index < size) {
				for ( var i = index; i < size - 1; i++) {
					array[i] = array[i + 1];
				}
				array[size - 1] = undefined;
				size--;
				return true;
			} else {
				throw "IndexOutOfBoundsException : Index: " + index + ", Size: " + size;
			}
		};
		this.each = function(fun) {
			for ( var i = 0; i < size; i++) {
				fun(array[i], i);
			}
		};
		this.clear = function() {
			for ( var i = 0; i < size; i++) {
				delete array[i];
			}
			size = 0;
		};
		this.indexOf = function(obj) {
            for ( var i = 0; i < size; i++) {
				if (array[i] == obj) {
                    return i;
                }
			}
			return -1;
		};
		this.toArray = function() {
			var a = new Array(size);
			self.each(function(obj, i) {
				a[i] = obj;
			});
			return a;
		};
	},
	/**
	 * 伪哈希表,只是通过js语法技巧模拟哈希表的功能
	 */
	"HashTable" : function() {
		var self = this;
		var size = 0;
		var table = new Object();
		this.className = "sinojh.HashTable";
		this.isEmpty = function() {
			return size == 0;
		};
		this.size = function() {
			return size;
		};
		this.put = function(k, v) {
			if (k == undefined || v === undefined) {
				throw "UndefinedException : Key = " + k + " , Value = " + v;
			} else if (typeof k == "object") {
				throw "TypeErrorException : ";
			} else {
				table[k] = v;
				size++;
			}
		};
		this.putAll = function(map) {
			if (self.className == map.className) {
				map.each(function(k, v) {
					self.put(k, v);
				});
			} else {
				throw "TypeErrorException";
			}
		};
		this.get = function(k) {
			return table[k];
		};
		this.remove = function(k) {
			if (table[k] === undefined) {
				return false;
			} else {
				delete table[k];
				size--;
				return true;
			}
		};
		this.keys = function() {
			var list = new sinojh.ArrayList(size);
			for ( var k in table) {
				list.add(k);
			}
			return list;
		};
		this.values = function() {
			var list = new sinojh.ArrayList(size);
			for ( var k in table) {
				list.add(table[k]);
			}
			return list;
		};
		this.each = function(fun) {
			for ( var k in table) {
				fun(k, table[k]);
			}
		};
		this.clear = function() {
			for (var k in table) {
                delete table[k];
            }
			size = 0;
		};
		this.entrys = function() {
			var list = new sinojh.ArrayList(size);
			self.each(function(key, value) {
				list.add(new Entry(key, value));
			});
			return list;
		};
		function Entry(k, v) {
			this.className = "sinojh.HashTable.Entry";
			this.key = k;
			this.value = v;
		}
	}
};

function Mine() {
	var self = this;
	var doc = document.createElement("div");
	doc.style.backgroundColor = "blue";
	doc.style.width = "50px";
	doc.style.height = "50px";
	doc.style.display = "inline-block";
	doc.style.margin = "2px";
	doc.style.fontSize = "40px";
	doc.style.textAlign = "center";
	doc.style.color = "white";
	doc.innerHTML = "●";

	this.doc = doc;
	this.isflag = false;
	this.isMine = 0.2 > Math.random();
	this.roundMine = 0;

	this.click = function() {
		if (self.isMine) {
			doc.style.backgroundColor = "black";
			alert("%>_<%你踩着地雷啦!炸死你O(∩_∩)O哈哈~");
			mineContext.show();
		} else {
			doc.innerHTML = self.roundMine;
			doc.style.backgroundColor = "green";
		}
	};
	this.rClick = function(e) {
		e = e ? e : window.event;
		if (e.button == 2) {
			doc.innerHTML = "★";
			doc.style.backgroundColor = "yellow";
			self.isflag = true;
		}
	};
	this.show = function() {
		if (self.isMine) {
			doc.style.backgroundColor = "black";
		}
	};
	this.startListener = function() {
		sinojh.addEventListener(doc, "click", this.click);
		sinojh.addEventListener(doc, "mousedown", this.rClick);
	};
	this.endListener = function() {
		sinojh.removeEventListener(doc, "click", this.click);
		sinojh.removeEventListener(doc, "mousedown", this.rClick);
	};

}

var mineContext = {
	"context" : undefined,
	"mineNumber" : 0,
	"init" : function(x, y) {
		var mc = document.getElementById("mineContext");
		mc.oncontextmenu = function() { return false; };
		var yList = new sinojh.ArrayList(y);
		for ( var i = 0; i < y; i++) {
			var xdiv = document.createElement("div");
			mc.appendChild(xdiv);
			var xList = new sinojh.ArrayList(x);
			for ( var j = 0; j < x; j++) {
				var mine = new Mine();
				if (mine.isMine) {
					this.mineNumber++;
				}
				xList.add(mine);
				xdiv.appendChild(mine.doc);
				mine.startListener();
			}
			yList.add(xList);
		}
		this.context = yList;
		this.countRoundMine();
		document.getElementById("presentation").innerHTML = "里面有" + this.mineNumber + "颗地雷,要小心哦!!O(∩_∩)O~";
	},
	"countRoundMine" : function() {
		this.context.each(function(xList, i) {
			xList.each(function(m, j) {
				mineContext.countMine(i - 1, j - 1, m);
				mineContext.countMine(i - 1, j, m);
				mineContext.countMine(i - 1, j + 1, m);
				mineContext.countMine(i, j - 1, m);
				mineContext.countMine(i, j + 1, m);
				mineContext.countMine(i + 1, j - 1, m);
				mineContext.countMine(i + 1, j, m);
				mineContext.countMine(i + 1, j + 1, m);
			});
		});
	},
	"countMine" : function(i, j, m) {
		if ((i >= 0 && i < this.context.size()) && (j >= 0 && j < this.context.get(i).size())) {
			if (this.context.get(i).get(j).isMine) {
				m.roundMine++;
			}
		}
	},
	"show" : function() {
		this.context.each(function(xList) {
			xList.each(function(mine) {
				mine.show();
				mine.endListener();
			});
		});
	}
};

window.onload = function() {
	var x = sinojh.getUrlParameter("x");
	var y = sinojh.getUrlParameter("y");
	x = x ? x : 10;
	y = y ? y : 10;
	mineContext.init(x, y);
	
};
</script>
	</head>
	<body>
		<div id="presentation" style="font-size: 30px"></div>
		<div id="mineContext"></div>
	</body>
</html>

?

1 楼 悬空90 2011-10-12  
又是一个js牛人
2 楼 JeffLan 2011-10-12  
悬空90 写道
又是一个js牛人

这些面向对象都来自于java,所以代码结构和命名都和java比较类似,做java的人看起来估计会比较眼熟。
3 楼 xihakuyi 2011-10-12  
JS牛
火狐、chrome、opera、safari测试通过
IE7测试不通过
4 楼 JeffLan 2011-10-13  
xihakuyi 写道
JS牛
火狐、chrome、opera、safari测试通过
IE7测试不通过


你的免费测试,小弟不胜感激。
我写的时候根本就没有去考虑兼容,只是谁手写着玩玩,但遵守W3C规范的浏览器应该不会有太大问题。
我已知的问题是在执行endListener的时候,IE不好使。
  相关解决方案