﻿/*--
标题：六子棋
设计：王集鹄
博客：http://blog.csdn.net/zswang
日期：2009年5月27日
--*/

//2009年06月28日 王集鹄 添加 大棋盘处理
//2010年07月01日 王集鹄 添加 演示

if (!Common.scripts["connect6"]) {
	loadCss("/Scripts/connect6.css?version=2010081801");
	Common.scripts["connect6"] = true;
}

function Connect6Board(parent, button_parent, manual_parent, big) {
	if (!parent) parent = document.body;
	if (!button_parent) button_parent = parent;
	var self = this;
	this.big = !!big;
	this.review = !!manual_parent;
	this.manual_parent = manual_parent;
	this.documentTitle = document.title;
	this.parent = parent;
	this.button_parent = button_parent;
	this.channel = {};
	this.rocks = {};
	this.state = "waiting"; // 游戏状态
	this.manuals = []; // 棋谱
	this.flash = true; // 是否闪烁
	this.chess = {}; // 棋子列表
	this.currPlace = 0;
	this.echoPlace = 0; // 当前执棋方
	this.currPlayer = -1; // 当前玩家执棋类型
	this.repentPlace = - 1; // 首先请求悔棋的玩家
	this.fallIndex = 0; // 执棋序号
	this.lastChess = {}; // 最后落子
	this.clock = 0; // 步时
	this.gameTime = {}; // 局时
	this.rowCount = this.big ? 25 : 19;
	this.colCount = this.big ? 25 : 19;
	
	this.div_desktop = document.createElement("div");
	this.div_desktop.className = "div_desktop" + (this.big ? "_big" : "");
	this.parent.appendChild(this.div_desktop);

	this.table_board = document.createElement("table");
	this.table_board.className = "table_board" + (this.big ? "_big" : "");
	this.div_desktop.appendChild(this.table_board);

	this.table_board.cellPadding = "0px";
	this.table_board.cellSpacing = "0px";
	for (var i = 0; i < this.rowCount; i++) {
		var tr = this.table_board.insertRow(-1);
		for (var j = 0; j < this.colCount; j++) {
			var td = tr.insertCell(-1);
			td.position = i * this.colCount + j;
			this.chess[td.position] = new Connect6Chess(this, td.position, td, "space");
		}
	}		 
	if (!this.review) {
		this.button_start = document.createElement("input");
		this.button_start.type = "button";
		this.button_start.value = "我要下六子棋";
		this.button_start.onclick = function() {
			publics.counter('click_start', location);
			this.disabled = true;
			if (typeof self.onaction == "function") self.onaction("apply", "");
		}
		this.button_parent.appendChild(this.button_start);

		this.button_discard = document.createElement("input");
		this.button_discard.type = "button";
		this.button_discard.value = "认输";
		this.button_discard.onclick = function() {
			publics.counter('click_discard', location);
			if (self.state != "playing" || self.currPlayer < 0) return;
			if (!confirm("确定是否认输？")) return;
			this.disabled = true;
			if (typeof self.onaction == "function") self.onaction("discard", "");
		}
		this.button_parent.appendChild(this.button_discard);
		
		this.button_repent = document.createElement("input");
		this.button_repent.type = "button";
		this.button_repent.value = "悔棋";
		this.button_repent.onclick = function() {
			publics.counter('click_repent', location);
			if (self.state != "playing" || self.currPlayer < 0) return;
			this.disabled = true;
			if (typeof self.onaction == "function") self.onaction("repent", "");
		}
		this.button_parent.appendChild(this.button_repent);

		this.button_peace = document.createElement("input");
		this.button_peace.type = "button";
		this.button_peace.value = "和棋";
		this.button_peace.onclick = function() {
			publics.counter('click_peace', location);
			if (self.state != "playing" || self.currPlayer < 0) return;
			this.disabled = true;
			if (typeof self.onaction == "function") self.onaction("peace", "");
		}
		this.button_parent.appendChild(this.button_peace);

		this.button_exit = document.createElement("input");
		this.button_exit.type = "button";
		this.button_exit.value = "我闪了，再见";
		this.button_exit.style.color = "Red";
		this.button_exit.onclick = function() {
			publics.counter('click_exit', location);
			if (self.state == "playing" && self.currPlayer != -1 && 
				!confirm("中途退出将导致游戏结束，是否确定？")) return;
			this.disabled = true;
			self.state = "waiting";
			self.currPlayer = -1;
			if (typeof self.onaction == "function") self.onaction("exit", "");
		}
		this.button_parent.appendChild(this.button_exit);
	} else {
		this.div_manual = document.createElement("div");
		this.div_manual.multiple = true;
		this.div_manual.className = "div_manual" + (this.big ? "_big" : "");
		this.manual_parent.appendChild(this.div_manual);

		this.button_first = document.createElement("input");
		this.button_first.type = "button";
		this.button_first.value = "最前";
		this.button_first.onclick = function() {
			publics.counter('click_first', location);
			self.navigator("first", true);
		}
		this.button_parent.appendChild(this.button_first);
		
		this.button_prior = document.createElement("input");
		this.button_prior.type = "button";
		this.button_prior.value = "向前";
		this.button_prior.onclick = function() {
			publics.counter('click_prior', location);
			self.navigator("prior", true);
		}
		this.button_parent.appendChild(this.button_prior);

		this.button_next = document.createElement("input");
		this.button_next.type = "button";
		this.button_next.value = "向后";
		this.button_next.onclick = function() {
			publics.counter('click_next', location);
			self.navigator("next", true);
		}
		this.button_parent.appendChild(this.button_next);

		this.button_last = document.createElement("input");
		this.button_last.type = "button";
		this.button_last.value = "最后";
		this.button_last.onclick = function() {
			publics.counter('click_last', location);
			self.navigator("last", true);
		}
		this.button_parent.appendChild(this.button_last);
	}

	this.button_number = document.createElement("input");
	this.button_number.type = "button";
	this.button_number.value = "数字";
	this.button_number.onclick = function() {
		publics.counter('click_number', location);
		self.hideNumber = !self.hideNumber;
		for (var i in self.chess) {
			if (self.chess[i].fallIndex < 0) continue;
			self.chess[i].doChange();
		}
	}
	this.button_parent.appendChild(this.button_number);

	this.players = [{}, {}];
	this.players[0].div_player = document.createElement("div");
	this.players[0].div_player.className = "div_player";
	this.div_desktop.appendChild(this.players[0].div_player);
	
	this.players[1].div_player = document.createElement("div");
	this.players[1].div_player.className = "div_player";
	this.div_desktop.insertBefore(this.players[1].div_player, this.div_desktop.firstChild)
	
	this.players[0].div_gameTime = document.createElement("div");
	this.players[0].div_gameTime.className = "div_gameTime";
	this.div_desktop.appendChild(this.players[0].div_gameTime);

	this.players[1].div_gameTime = document.createElement("div");
	this.players[1].div_gameTime.className = "div_gameTime";
	this.div_desktop.appendChild(this.players[1].div_gameTime);

	this.div_clock = document.createElement("div");
	this.div_clock.className = "div_clock";
	this.div_desktop.appendChild(this.div_clock);

	this.doChange();
	this.boardMousedown = function(e) {
		addEventHandler(self.table_board, "mouseup", self.boardMouseup);
		addEventHandler(self.table_board, "mousemove", self.boardMousemove);
	}
	this.boardMousemove = function(e) {
		if (window.getSelection)
			getSelection().removeAllRanges();
		else if (document.selection && document.selection.empty)
			try { document.selection.empty(); } catch (ex) { }
	}
	this.boardMouseup = function(e) {
		removeEventHandler(self.table_board, "mousemove", self.boardMousemove);
		removeEventHandler(self.table_board, "mouseup", self.boardMouseup);
	}
	addEventHandler(this.table_board, "mousedown", this.boardMousedown);
}

Connect6Board.prototype.setCurrPlayer = function(currPlayer) {
	if (this.currPlayer == currPlayer) return;
	this.currPlayer = currPlayer;
	this.doChange();
}

Connect6Board.prototype.fallChess = function(chess, event, test) {
	if (typeof chess == "undefined" || !chess) return true;
	if (chess.type != "space") return false;
	if (test) return true;

	if (this.research && this.reviewIndex < this.manuals.length - 1) {
		for (var i = this.reviewIndex + 1; i < this.manuals.length; i++) {
			if (!this.div_navigators[i]) continue;
			this.div_manual.removeChild(this.div_navigators[i]);
			delete this.div_navigators[i];
		}
		this.manuals.length = this.reviewIndex + 1;
	}
	if (this.research) this.setStars([]);

	this.fallIndex = this.manuals.length + 1;
	chess.fallIndex = this.fallIndex;
	this.manuals.push(chess.position);
	this.echoPlace = Math.floor((this.fallIndex + 1) / 2) % 2;
	chess.setType(["black", "white"][Math.floor(this.fallIndex / 2) % 2]);
	if (this.illustrate || this.research) this.currPlayer = this.echoPlace;
	if (event) {
		if (this.research) {
			this.addNavigator(this.manuals.length - 1);
			this.navigator(this.manuals.length - 1);
			return;
		}
		
		this.updateLast();
		playSound("fall");
	}
	this.doChange();
	return true;
}

Connect6Board.prototype.addNavigator = function(index) {
	var self = this;
	var div = document.createElement("div");
	this.div_navigators[index] = div;
	if (index < 0)
		div.innerHTML = "第0手 开始";
	else {
		var col = Math.floor(this.manuals[index] / this.colCount);
		var row = this.manuals[index] % this.colCount;
		div.innerHTML = "第" + Math.floor((index + 3) / 2) + "手 "
			 + (Math.floor((index + 1) / 2) % 2 ? "白子" : "黑子")
			 + " 坐标(" + (col + 1) + ", " + (row + 1) + ")";
	}
	div.style.backgroundColor = index % 2 ? "#eee" : "";
	div.style.cursor = "pointer";
	div.index = index;
	div.onclick = function() {
		self.navigator(this.index);
	}
	this.div_manual.appendChild(div);
}

Connect6Board.prototype.doChange = function() {
	if (typeof this.onchange == "function") this.onchange();
	if (this.currPlayer != -1) {
		if (this.state == "playing")
			this.channel.unloadmessage = "中途退出将导致游戏结束。";
		else this.channel.unloadmessage = "退出将导致举手失效。";
	} else this.channel.unloadmessage = null;
	
	var place = this.currPlace;
	this.players[0].div_player.innerHTML = this.players[place].username ? 
		ubb2Html("[b]" + "先后".charAt(place) + "手：[/b]" + 
			this.players[place].flag + this.players[place].username + 
			" [b]财富：[/b]" + this.players[place].money) : "";
	place = (place + 1) % 2;
	this.players[1].div_player.innerHTML = this.players[place].username ? 
		ubb2Html("[b]" + "先后".charAt(place) + "手：[/b]" + 
			this.players[place].flag + this.players[place].username +
			" [b]财富：[/b]" + this.players[place].money) : "";
	
	if (this.state == "playing" && this.echoPlace == this.currPlayer) {
		this.table_board.className = "table_board" + (this.big ? "_big" : "") + 
			" fall cursor_" + ["black", "white"][this.echoPlace];
	} else {
		this.table_board.className = "table_board" + (this.big ? "_big" : "");
	}
	if (this.review) {
		this.button_first.disabled = this.manuals.length <= 0 || this.reviewIndex <= 0;
		this.button_prior.disabled = this.manuals.length <= 0 || this.reviewIndex <= 0;
		this.button_next.disabled = this.manuals.length <= 0 || this.reviewIndex >= this.manuals.length - 1;
		this.button_last.disabled = this.manuals.length <= 0 || this.reviewIndex >= this.manuals.length - 1;
		return;
	}

	if (this.state == "playing") {
		var point = absolutePoint(this.players[0 ^ this.currPlace].div_player);
		this.players[0].div_gameTime.style.left = (point.x + 445) + "px";
		this.players[0].div_gameTime.style.top = point.y + "px";
		point = absolutePoint(this.players[1 ^ this.currPlace].div_player);
		this.players[1].div_gameTime.style.left = (point.x + 445) + "px";
		this.players[1].div_gameTime.style.top = point.y + "px";
		
		this.div_clock.style.display = "block";
		this.players[0].div_gameTime.style.display = "";
		this.players[1].div_gameTime.style.display = "";
		point = absolutePoint(this.players[this.echoPlace ^ this.currPlace].div_player);
		this.div_clock.style.left = point.x + "px";
		this.div_clock.style.top = point.y + "px";
		if (this.clock > 0)
			this.div_clock.innerHTML = ubb2Html("　　[b][size=12px]"
				+ (this.gameTime[this.echoPlace] > 0 ? "步时" : "读秒")
				+ "[/size][/b]" + formatTime(this.clock));
		else this.div_clock.style.innerHTML = "";
		
		if (this.gameTime[0] > 0)
			this.players[0].div_gameTime.innerHTML = ubb2Html("[b][size=12px]局时[/size][/b]" + formatTime(this.gameTime[0]));
		else this.players[0].div_gameTime.innerHTML = "";
		if (this.gameTime[1] > 0)
			this.players[1].div_gameTime.innerHTML = ubb2Html("[b][size=12px]局时[/size][/b]" + formatTime(this.gameTime[1]));
		else this.players[1].div_gameTime.innerHTML = "";
	} else {
		this.div_clock.style.display = "none";
		this.players[0].div_gameTime.style.display = "none";
		this.players[1].div_gameTime.style.display = "none";
	}

	this.button_start.disabled = this.state != "waiting" || 
		!this.channel.entering || this.currPlayer >= 0;
	this.button_exit.disabled = !this.channel.entering;
	this.button_discard.disabled = !this.channel.entering || this.currPlayer < 0 || this.state != "playing"
		|| this.manuals.length <= 11;
	this.button_repent.disabled = !this.channel.entering || this.currPlayer < 0 || this.state != "playing"
		|| this.manuals.length <= 0 || this.currPlayer == this.repentPlace;
	this.button_peace.disabled = !this.channel.entering || this.currPlayer < 0 || this.state != "playing"
		|| this.currPlayer == this.peacePlace;

	this.button_start.style.display = this.currPlayer >= 0 && this.state != "waiting" ? "none" : "";
	this.button_discard.style.display = this.currPlayer >= 0 && this.state != "waiting" ? "" : "none";
	this.button_repent.style.display = this.currPlayer >= 0 && this.state != "waiting" ? "" : "none";
	this.button_peace.style.display = this.currPlayer >= 0 && this.state != "waiting" ? "" : "none";
	
	if (this.state == "playing" && this.echoPlace == this.currPlayer) {
		if (self.flash)
			document.title = "【请执棋】" + this.documentTitle;
		else document.title = "【　　　】" + this.documentTitle;
	} else {
		document.title = document.title = this.documentTitle.replace(/^【.*?】/, "");
	}
}

Connect6Board.prototype.setPlayers = function(p0, p1) {
	if (!this.review) return;
	this.players[0].username = p0.username;
	this.players[0].flag = p0.flag;
	this.players[0].money = p0.money;
	this.players[1].username = p1.username;
	this.players[1].flag = p1.flag;
	this.players[1].money = p1.money;
	this.doChange();
}

Connect6Board.prototype.setEnd = function(end) {
	if (!this.review) return;
	var div = document.createElement("div");
	this.end = end;
	div.innerHTML = ubb2Html("[color=#ff00ff]" + end + "[/color]");
	div.style.backgroundColor = this.manuals.length % 2 ? "#eee" : "";
	this.div_navigators[this.manuals.length] = div;
	this.div_manual.appendChild(div);
}

Connect6Board.prototype.setStars = function(stars) {
	if (typeof stars == "undefined") return;
	if (this.timer) clearInterval(this.timer);
	if (this.stars) {
		for (var i = 0; i < this.stars.length; i++)
			if (typeof this.chess[this.stars[i]] != "undefined")
				this.chess[this.stars[i]].setStar(false);
	}
	this.stars = stars;
	this.timer = null;
	if (this.lastChess[0] || this.lastChess[1]) this.flash = true;
	for (i = 0; i < stars.length; i++)
		if (typeof this.chess[stars[i]] != "undefined")
			this.chess[stars[i]].setStar(true);
	this.doChange();
}

Connect6Board.prototype.play = function(manuals) {
	var self = this;
	this.echoPlace = 0;
	this.lastChess = {};
	this.fallIndex = 0;
	this.backCount = 0;
	for (var i in this.chess) {
		if (this.chess[i].fallIndex < 0) continue;
		this.chess[i].type = "space";
		this.chess[i].star = false;
		this.chess[i].fallIndex = -1;
		this.chess[i].doChange();
	}
	this.manuals = [];
	this.stars = [];
	this.falls(manuals);
	if (this.illustrate || this.research) this.currPlayer = this.echoPlace;
	if (this.research) this.state = "playing";

	for (var j in this.div_navigators)
		this.div_navigators[j].parentNode.removeChild(this.div_navigators[j]);
	this.div_navigators = [];
	if (this.review) {
		var l = manuals ? manuals.length : 0;
		for (var j = -1; j < l; j++)
			this.addNavigator(j);

		this.reviewIndex = manuals.length - 1;
		this.div_navigators[this.reviewIndex].style.backgroundColor = "#316AC5";
		this.div_navigators[this.reviewIndex].style.color = "White";
	}
	this.doChange();
	if (typeof this.onplay == "function") this.onplay();
}

Connect6Board.prototype.navigator = function(index, scroll) {
	if (!this.review) return;
	switch (index) {
		case "first": index = -1; break;
		case "prior": index = this.reviewIndex - 1; break;
		case "next": index = this.reviewIndex + 1; break;
		case "last": index = this.manuals.length - 1; break;
	}
	if (index < -1 || index >= this.manuals.length) return;
	if (this.reviewIndex == index) return;
	var oldIndex = this.reviewIndex;
	var beginIndex = Math.min(index, oldIndex);
	var endIndex = Math.max(index, oldIndex);
	this.reviewIndex = index;
	this.echoPlace = Math.floor((this.reviewIndex + 2) / 2) % 2;
	if (this.research) this.currPlayer = this.echoPlace;
	
	for (var i = Math.max(beginIndex, 0); i <= endIndex; i++) {
		var chess = this.chess[this.manuals[i]];
		if (i <= this.reviewIndex)
			chess.type = Math.floor((chess.fallIndex + 2) / 2) % 2 ? "black" : "white";
		else chess.type = "space";
		chess.doChange();
	}

	var lastChess;
	if ((this.reviewIndex + 1) % 2 == 0) {
		lastChess = this.lastChess[1];
		this.lastChess[1] = null;
   		if (lastChess) lastChess.doChange();

		lastChess = this.lastChess[0];
		this.lastChess[0] = this.chess[this.manuals[this.reviewIndex]];
		if (this.lastChess[0]) this.lastChess[0].doChange();
   		if (lastChess) lastChess.doChange();
	} else {
		if (this.reviewIndex > 0) {
			lastChess = this.lastChess[0];
			this.lastChess[0] = this.chess[this.manuals[this.reviewIndex - 1]];
			if (this.lastChess[0]) this.lastChess[0].doChange();
   			if (lastChess) lastChess.doChange();
   		}

		lastChess = this.lastChess[1];
		this.lastChess[1] = this.chess[this.manuals[this.reviewIndex]];
		this.lastChess[1].doChange();
   		if (lastChess) lastChess.doChange();
	}
	if (oldIndex >= 0) this.chess[this.manuals[oldIndex]].doChange();
	if (oldIndex > 0) this.chess[this.manuals[oldIndex - 1]].doChange();
	if (this.stars && (beginIndex >= this.manuals.length - 1
		|| endIndex >= this.manuals.length - 1)) {
		for (i = 0; i < this.stars.length; i++) {
			this.chess[this.stars[i]].doChange();
		}
	}

	this.div_navigators[oldIndex].style.backgroundColor = oldIndex % 2 ? "#eee" : "";
	this.div_navigators[oldIndex].style.color = "";

	this.div_navigators[this.reviewIndex].style.backgroundColor = "#316AC5";
	this.div_navigators[this.reviewIndex].style.color = "White";
	//if (scroll) this.div_navigators[this.reviewIndex].scrollIntoView(true);
	if (typeof this.onnavigator == "function") this.onnavigator();
	this.doChange();
}

Connect6Board.prototype.falls = function(manuals) {
	if (!manuals) return;
	var l = this.manuals.length;
	for (i = 0; i < manuals.length; i++)
		this.fallChess(this.chess[manuals[i]], false);
	if (manuals.length > 0 && manuals[manuals.length - 1] >= 0)
		this.updateLast();
	if (l == this.manuals.length) return;
	playSound("fall");
	if (typeof this.onfalls == "function") this.onfalls();
}

Connect6Board.prototype.updateLast = function() {
	if (this.manuals.length <= 0) return;
	var lastChess;
	if (this.manuals.length % 2 == 0) {
		lastChess = this.lastChess[1];
		this.lastChess[1] = null;
	   	if (lastChess) lastChess.doChange();

		lastChess = this.lastChess[0];
		this.lastChess[0] = this.chess[this.manuals[this.manuals.length - 1]];
		this.lastChess[0].doChange();
	   	if (lastChess) lastChess.doChange();
	} else {
		if (this.manuals.length > 2) {
			lastChess = this.lastChess[0];
			this.lastChess[0] = this.chess[this.manuals[this.manuals.length - 2]];
			this.lastChess[0].doChange();
	   		if (lastChess) lastChess.doChange();
	   	}

		lastChess = this.lastChess[1];
		this.lastChess[1] = this.chess[this.manuals[this.manuals.length - 1]];
		this.lastChess[1].doChange();
	   	if (lastChess) lastChess.doChange();
	}
}

Connect6Board.prototype.action = function(action, param, result) {
	if (!result) return;
	var self = this;
	var playerChanged = false;
	for (var i = 0; i < 2; i++) {
		if (typeof result["p" + i] != "undefined") {
			playerChanged = true;
			this.players[i].id = result["p" + i].id;
			if (this.currPlayer == i) this.currPlayer = -1;
			if (typeof this.players[i].id == "undefined" || parseInt(this.players[i].id) == -1) {
				this.players[i].username = "";
				this.players[i].flag = "";
				this.players[i].money = 0;
			} else {
				this.players[i].username = result["p" + i].username;
				this.players[i].flag = result["p" + i].flag;
				this.players[i].money = result["p" + i].money;
				if (this.players[i].id == publics.passinfo.ident) {
					this.currPlayer = i;
					this.currPlace = i;
				}
			}
		}
	}
	if (playerChanged) {
		this.illustrate = this.currPlayer >= 0 && this.players[0].id == this.players[1].id;
		if (this.illustrate) this.currPlayer = this.echoPlace;
	}

	if (typeof result.state != "undefined")	{
		this.state = result.state;
		self.flash = true;
		clearInterval(this.timer);
		if (this.state != "waiting") {
			this.play();
			this.timer = setInterval(
				function() {
					self.flash = !self.flash;
					if (!Common.ie6) {
						if (self.lastChess[0]) self.lastChess[0].doChange();
						if (self.lastChess[1]) self.lastChess[1].doChange();
					}
					if (self.state != "waiting" && self.echoPlace == self.currPlayer) {
						if (self.flash)
							document.title = "【请执棋】" + self.documentTitle;
						else document.title = "【　　　】" + self.documentTitle;
					}
					if (self.clock > 0) {
						self.clock--;
						self.div_clock.innerHTML = ubb2Html("　　[b][size=12px]"
							+ (self.gameTime[self.echoPlace] > 0 ? "步时" : "读秒")
							+ "[/size][/b]" + formatTime(self.clock));
					}
					if (self.gameTime[self.echoPlace] > 0) {
						self.gameTime[self.echoPlace]--;
						self.players[self.echoPlace].div_gameTime.innerHTML = ubb2Html("[b][size=12px]局时[/size][/b]" + 
							formatTime(self.gameTime[self.echoPlace]));
					}
				}, 1000);
		} else self.flash = true;
	}
	if (result.rocks) this.setRocks(result.rocks);
	if (typeof result.repentPlace != "undefined") this.repentPlace = result.repentPlace;
	if (typeof result.peacePlace != "undefined") this.peacePlace = result.peacePlace;
	if (typeof result.manualCount != "undefined") 
		this.repent(parseInt(result.manualCount) - (result.manuals ? result.manuals.length : 0));
	if (typeof result.manuals != "undefined") this.falls(result.manuals);
	if (typeof result.stars != "undefined") this.setStars(result.stars);
	if (typeof result.clock != "undefined") this.clock = result.clock;
	if (typeof result.gt0 != "undefined") this.gameTime[0] = result.gt0;
	if (typeof result.gt1 != "undefined") this.gameTime[1] = result.gt1;
	this.doChange();
}

Connect6Board.prototype.setRocks = function(rocks) {
	var oldRocks = {};
	for (var p in this.rocks) oldRocks[p] = true;
	this.rocks = {};
	for (var i = 0; i < rocks.length; i++) {
		this.rocks[rocks[i]] = true;
		this.chess[rocks[i]].doChange();
	}
	for (var p in oldRocks) this.chess[p].doChange();
}
Connect6Board.prototype.repent = function(count) {
	count = Math.max(0, count);
	if (this.manuals.length <= count) return;
	for (var i = this.manuals.length - 1; i >= count; i--) {
		var chess = this.chess[this.manuals[i]];
		if (chess) {
			chess.star = false;
			chess.fallIndex = -1;
			chess.type = "space";
			chess.doChange();
		}
	}
	this.manuals.length = count;
	this.fallIndex = this.manuals.length + 1;
	this.echoPlace = Math.floor(this.fallIndex / 2) % 2;
	if (this.illustrate || this.research) this.currPlayer = this.echoPlace;
	this.updateLast();
	this.doChange();
}

Connect6Board.prototype.dispose = function() {
	this.disposed = true;
	for (var i in this) {
		if (this[i].disposed) continue;
		if (typeof this[i].dispose == "function") this[i].dispose();
		if (typeof this[i].parentNode == "object")
			this[i].parentNode.removeChild(this[i]);
		delete this[i];
	}
}

Connect6Board.prototype.manualCode = function() {
	var l = this.review ? this.reviewIndex + 1 : this.manuals.length;
	return manualCode(this.manuals, this.big, l);
}

Connect6Board.prototype.starsCode = function() {
	return manualCode(this.stars, this.big);
}

Connect6Board.prototype.rocksCode = function() {
	var rocks = [];
	for (var p in this.rocks) rocks.push(p);
	return manualCode(rocks, this.big);
}

function manualCode(manuals, big, length) {
	var s = "";
	if (manuals && typeof length == "undefined") length = manuals.length;
	if (!manuals || !length) return s;
	for (var i = 0; i < length; i ++) {
		var x = manuals[i] % (big ? 25 : 19);
		var y = Math.floor(manuals[i] / (big ? 25 : 19));
		s += "abcdefghijklmnopqrstuvwxyz".charAt(x) + ((big ? 25 : 19) - y);
	}
	return s;
}

function Connect6Chess(board, position, td, type) {
	this.board = board; // 棋盘
	this.position = position; // 所在坐标
	this.td = td;
	this.type = type; // 棋子类型

	var self = this;
	this.td.onclick = function() {
		if (self.board.state != "playing") return;
		if (self.board.rocks[self.position]) return;
		if (self.board.currPlayer != self.board.echoPlace) return;
		if (self.type != "space") return;
		if (!self.board.fallChess(self, true, !self.board.research)) return;
		if (typeof self.board.onaction == "function") self.board.onaction("fall", self.position);
	}

	this.td.oncontextmenu = function() {
		if (self.board.state != "playing") return;
		if (self.board.currPlayer != self.board.echoPlace) return;
		if (self.board.rocks[self.position]) return;
		if (!self.board.illustrate && !self.board.research) return;
		if (self.fallIndex <= 0) return;
		if (typeof self.board.onaction == "function") self.board.onaction("right", self.fallIndex);
		if (self.board.research) self.board.navigator(self.fallIndex - 2);
		return false;
	}
	
	this.doChange();
}

Connect6Chess.prototype.doChange = function() {
	if (this.board.rocks[this.position]) { // 石子
		this.td.className = "chess_rock";
		return;
	}
	switch (this.type) {
		case "space":
			this.td.className = "chess_space";
			setElementText(this.td, "");
			break;
		case "black":
		case "white":
			if (this.star && (!this.board.review || 
				this.board.reviewIndex >= this.board.manuals.length - 1)) {
				if ((this.board.lastChess[0] == this || this.board.lastChess[1] == this)
					&& (Common.ie6 || this.board.flash))
					this.td.className = this.type == "black" ? "last_black" : "last_white";
				else this.td.className = this.type == "black" ? "start_black" : "start_white";
			} else {
				if ((this.board.lastChess[0] == this || this.board.lastChess[1] == this)
					&& (Common.ie6 || this.board.flash))
					this.td.className = this.type == "black" ? "flash_black" : "flash_white";
				else this.td.className = this.type == "black" ? "chess_black" : "chess_white";
			}
			if (!this.board.hideNumber)
				setElementText(this.td, Math.floor((this.fallIndex + 2) / 2));
			else setElementText(this.td, "");
			if (this.board.lastChess[0] == this || this.board.lastChess[1] == this)
				this.td.className += " last";
			break;
	}
}

Connect6Chess.prototype.setType = function(type) {
	if (this.type == type) return;
	this.type = type;
	this.doChange();
}

Connect6Chess.prototype.setStar = function(star) {
	if (this.star == star) return;
	this.star = star;
	this.doChange();
}

function manualFormat(str, big) {
	if (/^([a-z]\d+)+$/i.test(str)) {
		return str.replace(/([a-z])(\d+)/gi, function($0, $1, $2) {
			var x = $1.toLowerCase().charCodeAt(0) - "a".charCodeAt(0);
			var y = (big ? 25 : 19) - (+$2);
			return y * (big ? 25 : 19) + x + ",";
		}).replace(/^,|,$/g, "");
	}
	return str;
}