JS小游戏 - 盖房子
来源:互联网 发布:大连软件职业学院地图 编辑:程序博客网 时间:2024/04/28 02:47
写这个JS,源于CSDN上看到的一道思考题,挺有趣的一个算法,于是根据规则写了这个JS。
<html>
<head>
<title>JS小游戏 - 盖房子</title>
<style type="text/css">
body
...{
font-size: 12px;
cursor: default;
}
#tb
...{
text-align: center;
vertical-align: middle;
border: #606066 5px double;
border-collapse: collapse;
}
td
...{
border: #F5F5F5 1px solid;
width: 100px;
height: 100px;
}
#selectDiv
...{
position: absolute;
border: #606066 1px solid;
background-color: #F5F5F5;
z-index: 100;
}
#msg
...{
width: 300px;
top: 15px;
}
#msg #all
...{
width: 100%;
height: 30px;
line-height: 30px;
text-align: left;
vercital-align: middle;
padding-left: 10px;
background-color: #606066;
font-weight: bold;
color: #F5F5F5;
}
.houseList
...{
position: absolute;
cursor: default;
}
.house
...{
width: 50px;
height: 50px;
line-height: 50px;
margin: 5px;
font-family: Wingdings;
font-size: 36px;
text-align: center;
}
.fontDiv
...{
position: absolute;
width: 50px;
height: 20px;
line-height: 20px;
margin: 5px;
float: left;
font-size: 15px;
text-align: center;
cursor: default;
}
.blue
...{
background-color: blue;
}
.red
...{
background-color: red;
}
.green
...{
background-color: green;
}
.yellow
...{
background-color: yellow;
}
</style>
</head>
<body>
<div style="height: 30px; font-weight: bold">场地大小:
<input id="small" name="size" type="radio" checked onclick="reSize(5, 5)" /><label for="small">小(5 * 5)</label>
<input id="middle" name="size" type="radio" onclick="reSize(8, 8)" /><label for="middle">中(8 * 8)</label>
<input id="large" name="size" type="radio" onclick="reSize(10, 10)" /><label for="large">大(10 * 10)</label>
<a href="javascript:" onclick="getHelp()">帮助 / 操作说明 (F1)</a>
<a href="javascript:" onclick="reStart()">重新开始 (Ctrl+G)</a>
<a href="javascript:" onclick="goOn(-1)">←后退一步(Ctrl+Z)</a>
<a href="javascript:" onclick="goOn(1)">前进一步→(Ctrl+Y)</a>
</div>
<div id="houseDiv" style="position: relative; height: 60px; z-index: -10"></div>
<div id="msg">
<div id="all">总人口数: <span id="people">0</span></div>
</div>
<div id="tbDiv"></div>
<script>
//coding by pippe pippe@163.com
function $(objID)
...{
return document.getElementById(objID);
}
var rowCount, cellCount; //行数,列数
var cloneHouse;
var oLeft, oTop, oX, oY;
var previousCell; //存放上一个经过的TD
var houses = new Array(); //所有的房子
var selectCell; //双击选中的TD
var selectDivObj; //房子选择的DIV
var selectedHouse; //选中的房子
var help;
var steps = new Array();
var thisStep = 0;
//创建填充背景的表格
function createTable(rows, cells)
...{
rowCount = rows;
cellCount = cells;
var tb = document.createElement("table");
tb.id = "tb";
var row, cell;
for (var rowIndex = 1; rowIndex <= rowCount; rowIndex++)
...{
row = tb.insertRow(-1);
row.id = "row_" + rowIndex;
for (var cellIndex = 1; cellIndex <= cellCount; cellIndex++)
...{
cell = row.insertCell(-1);
cell.id = "cell_" + rowIndex + "_" + cellIndex;
cell.title = "单击盖房子(Enter),双击拆房子(Delete)";
cell.onclick = function() ...{ selectHouse(this); };
cell.ondblclick = function() ...{ joinSpan(this, false);};
}
}
$("tbDiv").appendChild(tb);
}
function reSize(rows, cells)
...{
$("tbDiv").removeChild($("tb"));
createTable(rows, cells);
}
//创建可供填充的房子
//房子颜色,占用人口数,标识图标,上下左右必须有存在的颜色(多个以_分割)
function createHouse()
...{
var len = arguments.length;
if (len == 4)
...{
var houseDivCount = $("houseDiv").childNodes.length;
var div = document.createElement("div");
div.id = arguments[0];
div.className = "house " + arguments[0];
div.style.left = (20 + (houseDivCount * 30)) + "px";
div.style.top = "0px";
div.style.position = "absolute";
div.style.cursor = "move";
div.onmousedown = function() ...{ mouseDown(this) };
div.people = arguments[1];
div.innerHTML = arguments[2];
div.exist = arguments[3];
$("houseDiv").appendChild(div);
houses.push(arguments);
var span = document.createElement("span");
span.id = arguments[0] + "_span";
span.className = "fontDiv";
span.style.left = (20 + (houseDivCount * 30)) + "px";
span.style.top = "0px";
span.innerHTML = arguments[1] + "人口";
$("houseDiv").appendChild(span);
}
}
//选择房子
function selectHouse(cell)
...{
removeSelect();
if (cell.hasChildNodes())
...{
return;
}
selectCell = cell.id;
cell.style.backgroundColor='#606066';
selectDivObj = document.createElement("div");
selectDivObj.id = "selectDiv";
document.body.appendChild(selectDivObj);
selectDivObj.style.left = (cell.offsetLeft + tbDiv.offsetLeft) + "px";
selectDivObj.style.top = (cell.offsetTop + tbDiv.offsetTop) + "px";
var selectItem = "";
var maxIndex = 0, maxExist = 0;
for(var houseIndex = 0; houseIndex < houses.length; houseIndex++)
...{
var isExist = getNeighborExist(cell.id, houses[houseIndex][3]);
if (isExist)
...{
if (houses[houseIndex][3].split("_").length >= maxExist)
...{
maxExist = houses[houseIndex][3].split("_").length;
maxIndex = houseIndex;
}
selectItem = "<span title="双击选择" ondblclick="houseSelected('" + cell.id + "')"><input type="radio" id="" + houses[houseIndex][0] + "_select" onclick="selectedHouse='" + houses[houseIndex][0] + "'" name="selectHouse" /><label for="" + houses[houseIndex][0] + "_select" class="house " + houses[houseIndex][0] + "">" + houses[houseIndex][2] + "</label></span>" + selectItem;
}
continue;
}
if (selectItem != "")
...{
selectItem += "<div style="text-align: center"><input type="button" onclick="houseSelected('" + cell.id + "')" value="选择(Enter)" /><input type="button" onclick="removeSelectDiv()" value="取消(Esc)" /><div>";
selectDivObj.innerHTML = selectItem;
$(houses[maxIndex][0] + "_select").checked = true;
selectedHouse = houses[maxIndex][0];
}
}
//确认选择
function houseSelected(cellID)
...{
if (selectedHouse)
...{
cloneHouse = $(selectedHouse).cloneNode(true);
joinSpan($(cellID), true);
}
if (selectDivObj)
...{
selectDivObj.parentNode.removeChild(selectDivObj);
selectDivObj = null;
}
}
//移除选择列表
function removeSelect()
...{
if (selectDivObj)
...{
selectDivObj.parentNode.removeChild(selectDivObj);
selectDivObj = null;
selectedHouse = null;
}
if (selectCell)
...{
$(selectCell).style.backgroundColor = "";
selectCell = null;
}
}
//鼠标在房子上按下复制
function mouseDown(obj)
...{
if (event.button == 1)
...{
cloneHouse = obj.cloneNode(true);
oLeft = parseInt(cloneHouse.style.left);
oTop = parseInt(cloneHouse.style.top);
oX = event.clientX;
oY = event.clientY;
cloneHouse.style.filter = "alpha(opacity=50)";
cloneHouse.style.zIndex = "-100";
obj.parentNode.appendChild(cloneHouse);
cloneHouse.style.cursor = "move";
cloneHouse.setCapture();
cloneHouse.onmousemove = function() ...{ mouseMove() };
cloneHouse.onmouseup = function() ...{ mouseUp() };
}
}
//鼠标拉动房子在table上选择格子
function mouseMove()
...{
if (event.button == 1)
...{
var nX = event.clientX;
var nY = event.clientY;
cloneHouse.style.left = (nX - oX + oLeft) + "px";
cloneHouse.style.top = (nY - oY + oTop) + "px";
var element = document.elementFromPoint(nX, nY);
var re1 = /^(cell)...{1}(_[1-5])...{2}(_value)...{1}$/; //TD内容
var re2 = /^(cell)...{1}(_[1-5])...{2}$/; //TD
var cellType = re1.test(element.id.toString()) ? 1 : re2.test(element.id.toString()) ? 2 : 0;
switch(cellType)
...{
case 1:
element.parentNode.style.border = "1px solid " + cloneHouse.className.split(" ")[1];
previousCell && previousCell != element.parentNode.id ? $(previousCell).style.cssText = "" : null;
previousCell = element.parentNode.id;
break;
case 2:
element.style.border = "1px solid " + cloneHouse.className.split(" ")[1];
previousCell && previousCell != element.id ? $(previousCell).style.cssText = "" : null;
previousCell = element.id;
break;
case 0:
previousCell ? $(previousCell).style.cssText = "" : null;
previousCell = null;
break;
}
}
}
//鼠标弹起
function mouseUp()
...{
if (cloneHouse)
...{
cloneHouse.releaseCapture();
//未选中表格,不加入
if (!previousCell)
...{
cloneHouse.parentNode.removeChild(cloneHouse);
return;
}
//邻居符合颜色要求加入,不符合不加入
var isExist = getNeighborExist(previousCell, cloneHouse.exist);
if (isExist)
...{
joinSpan($(previousCell), true);
}
else
...{
cloneHouse.releaseCapture();
cloneHouse.parentNode.removeChild(cloneHouse);
}
}
}
//判断触发事件的表格内的上下左右邻居是否有符合颜色要求
function getNeighborExist(cellID, allExist)
...{
//事件的框内已存在房子,不加入
if($(cellID).hasChildNodes())
...{
return false;
}
//拉动的房子不要求上下左右必须存在的颜色
if (allExist == "")
...{
return true;
}
var cellSplit = cellID.split("_");
var existSplit = allExist.split("_");
var existSplitLen = existSplit.length;
var neighborCell = new Array();
var rowIndex = parseInt(cellSplit[1]);
var cellIndex = parseInt(cellSplit[2]);
//邻居进栈
rowIndex > 1 ? neighborCell.push(cellSplit[0] + "_" + (rowIndex - 1) + "_" + cellSplit[2]) : null;
rowIndex < rowCount ? neighborCell.push(cellSplit[0] + "_" + (rowIndex + 1) + "_" + cellSplit[2]) : null;
cellIndex > 1 ? neighborCell.push(cellSplit[0] + "_" + cellSplit[1] + "_" + (cellIndex - 1)) : null;
cellIndex < cellCount ? neighborCell.push(cellSplit[0] + "_"+ cellSplit[1] + "_" + (cellIndex + 1)) : null;
//要求邻居个数超过所有邻居数,不加入
var neighborCount = neighborCell.length;
if (existSplitLen > neighborCount)
...{
return false;
}
var exist;
for (var existIndex = 0; existIndex < existSplitLen; existIndex++)
...{
exist = false;
for (var neighborIndex = 0; neighborIndex < neighborCount; neighborIndex++)
...{
if ($(neighborCell[neighborIndex]).hasChildNodes() && existSplit[existIndex] == $(neighborCell[neighborIndex]).childNodes[0].group)
...{
exist = true;
break;
}
}
//邻居没有要求的颜色,不加入
if (!exist)
...{
return false;
}
}
return true;
}
//加入/去除 单元
function joinSpan(cell, isJoin)
...{
if (isJoin)
...{
if (!cell.hasChildNodes())
...{
cell.innerHTML = "<span id="" + cell.id + "_value" title="双击拆房子" people="" + cloneHouse.people + "" ondblclick="joinSpan(this.parentNode, false)" group="" + cloneHouse.id + "" exist="" + cloneHouse.exist + "" class="" + cloneHouse.className + "">" + cloneHouse.innerHTML + "</span>";
$("people").innerHTML = parseInt($("people").innerHTML) + parseInt(cloneHouse.people);
cloneHouse.parentNode.removeChild(cloneHouse);
var step = new Array("in", cell.id, cell.innerHTML);
steps[thisStep] = step;
steps.length = ++thisStep;
}
}
else
...{
if (cell.hasChildNodes())
...{
var cellSplit = cell.id.split("_");
var neighborCell = new Array();
var rowIndex = parseInt(cellSplit[1]);
var cellIndex = parseInt(cellSplit[2]);
//邻居进栈
rowIndex > 1 ? neighborCell.push(cellSplit[0] + "_" + (rowIndex - 1) + "_" + cellSplit[2]) : null;
rowIndex < rowCount ? neighborCell.push(cellSplit[0] + "_" + (rowIndex + 1) + "_" + cellSplit[2]) : null;
cellIndex > 1 ? neighborCell.push(cellSplit[0] + "_" + cellSplit[1] + "_" + (cellIndex - 1)) : null;
cellIndex < cellCount ? neighborCell.push(cellSplit[0] + "_"+ cellSplit[1] + "_" + (cellIndex + 1)) : null;
//遍历邻居身边需求是否包括本房子
var neighborCount = neighborCell.length;
for (var neighborIndex = 0; neighborIndex < neighborCount; neighborIndex++)
...{
if ($(neighborCell[neighborIndex]).hasChildNodes())
...{
exist = $(neighborCell[neighborIndex]).childNodes[0].exist.split("_");
for (existIndex = 0; existIndex < exist.length; existIndex++)
...{
if (exist[existIndex] == cell.childNodes[0].group)
...{
return;
}
}
}
}
$("people").innerHTML = parseInt($("people").innerHTML) - parseInt(cell.childNodes[0].people);
var step = new Array("out", cell.id, cell.innerHTML);
steps[thisStep] = step;
steps.length = ++thisStep;
cell.innerHTML = "";
}
}
}
function arrowMove(eKeyCode)
...{
if (selectDivObj)
...{
switch(eKeyCode)
...{
case 37: //left
case 38: //up
if (selectedHouse)
...{
var previous = $(selectedHouse + "_select").parentNode.previousSibling;
if (previous && previous.tagName.toUpperCase() == "SPAN")
...{
previous.childNodes[0].checked = true;
selectedHouse = previous.childNodes[0].id.split("_")[0];
}
}
break;
case 39: //right
case 40: //down
if (selectedHouse)
...{
var next = $(selectedHouse + "_select").parentNode.nextSibling;
if (next && next.tagName.toUpperCase() == "SPAN")
...{
next.childNodes[0].checked = true;
selectedHouse = next.childNodes[0].id.split("_")[0];
}
}
break;
}
return;
}
if(selectCell)
...{
var cellSplit = selectCell.split("_");
var newSelectCell;
switch(eKeyCode)
...{
case 37: //left
if (parseInt(cellSplit[2]) == 1)
...{
return;
}
newSelectCell = cellSplit[0] + "_" + cellSplit[1] + "_" + (parseInt(cellSplit[2]) - 1);
break;
case 38: //up
if (parseInt(cellSplit[1]) == 1)
...{
return;
}
newSelectCell = cellSplit[0] + "_" + (parseInt(cellSplit[1]) - 1) + "_" + cellSplit[2];
break;
case 39: //right
if (parseInt(cellSplit[2]) == rowCount)
...{
return;
}
newSelectCell = cellSplit[0] + "_" + cellSplit[1] + "_" + (parseInt(cellSplit[2]) + 1);
break;
case 40: //down
if (parseInt(cellSplit[1]) == cellCount)
...{
return;
}
newSelectCell = cellSplit[0] + "_" + (parseInt(cellSplit[1]) + 1) + "_" + cellSplit[2];
break;
}
$(selectCell).style.backgroundColor = "";
selectCell = newSelectCell;
$(selectCell).style.backgroundColor = "#606066";
return;
}
selectCell = "cell_1_1";
$(selectCell).style.backgroundColor = "#606066";
}
//帮助
function getHelp()
...{
if (help)
...{
return;
}
help = document.createElement("<div>");
help.id = "help";
help.style.cssText = "position: absolute; padding: 5px; width: 0px; height: 0px; border: #606066 1px solid; overflow: hidden; left: " + event.x + "px; top: " + event.y + "px";
var helpText = "<p style="font-weight: bold; font-size: 15px">游戏规则(源于一思考题):</p>";
helpText += "<ol><li>一个场地里(默认5*5,可选择大小)的方格 打算往每个格子里放房子,有4种颜色的房子</li>";
helpText += "<li>蓝色的房子 占10人口 随便放在哪里都行</li>";
helpText += "<li>红色的房子 占20人口 要求和蓝色的房子相邻</li>";
helpText += "<li>绿色的房子 占30人口 要求和蓝色,红色的房子相邻行</li>";
helpText += "<li>黄色的房子 占40人口 要求和蓝色,红色,绿色的房子相邻</li>";
helpText += "<li>如何放置 才能使5*5的格子占用的人口数量最大? </li></ol>";
helpText += "<p style="font-weight: bold; font-size: 15px">操作说明:</p>";
helpText += "<ol><li>拉动各颜色的房子到欲放置的格子处释放鼠标,如果格子符合该颜色房子的需求则房子成功放入,否则房子不放入,如:欲放黄色房子,则本格子上下左右需存在蓝绿红三种房子。</li>";
helpText += "<li>单击任何一个格子弹出该格子当前可放入的房子选项,双击房子即可放入,或者选中其中一个后按回车或点选择亦可放入。</li>";
helpText += "<li>双击有房子的格子或房子即可拆掉此房子。</li>";
helpText += "<li>键盘操作:";
helpText += "<ul><li>按上下左右箭头可在表格内移动,当前格子背景色为黑色,如无选中则从第一行第一列开始,按回车后选择房子,按Delete或"."为拆掉房子。</li>";
helpText += "<li>如果弹出选择房子时,上下左右箭头为选择当前格子可用的房子(如:向放黄色房子需先在需要放置的格子上下左右格放好蓝绿红房子,方可选择),按下回车后此房子加入格子内,Esc键为不做选择并关掉选择房子。</li>";
helpText += "<li>如果拆除房子的邻居有对本房子要求时本房子不可拆除,需先拆除对于本房子做要求的房子,如:想拆掉蓝色房子,但上下左右有红色房子则需先拆掉红色房子方可拆掉蓝色房子。</li></ul></li>";
helpText += "<li>按Ctrl+Z可后退一步,如果后退后未再做操作按Ctrl+Y可前进一步,可多次后退或前进(在房子总数足够或后退步数足够的情况下),反之后退前进无效。</li>";
helpText += "<li>coding by pippe <a href="mailto:pippe@163.com">pippe@163.com</a>。</li></ol>";
helpText += "<span style="width: 100%; text-align: center"><a href="javascript:" onclick="setHelp(false)" style="text-align: center">关闭(Esc)</a></span>";
help.innerHTML = helpText;
document.body.appendChild(help);
setHelp(true);
}
function setHelp(isOpen)
...{
var nowLeft = parseInt(help.style.left);
var nowTop = parseInt(help.style.top);
var nowWidth = parseInt(help.style.width);
var nowHeight = parseInt(help.style.height);
var space = 50;
if (isOpen)
...{
help.style.width = nowWidth + space < 500 ? (nowWidth + space) + "px" : "500px";
help.style.height = nowHeight + space < 600 ? (nowHeight + space) + "px" : "600px";
help.style.left = nowLeft > (document.body.clientWidth - nowWidth) / 2 + space ? (nowLeft - space) + "px" : nowLeft < (document.body.clientWidth - nowWidth) / 2 - space ? (nowLeft + space) + "px" : (document.body.clientWidth - nowWidth) / 2 + "px";
help.style.top = nowTop > (document.body.clientHeight - nowHeight) / 2 + space ? (nowTop - space) + "px" : nowTop < (document.body.clientHeight - nowHeight) / 2 - space ? (nowTop + space) + "px" : (document.body.clientHeight - nowHeight) / 2 + "px";
nowWidth + space < 500 || nowHeight + space < 600 || nowLeft < (document.body.clientWidth - nowWidth) / 2 - space || nowTop > (document.body.clientHeight - nowHeight) / 2 + space || nowTop < (document.body.clientHeight - nowHeight) / 2 - space ? setTimeout("setHelp(" + isOpen + ")", 10) : null;
}
else
...{
help.style.width = nowWidth - space > 0 ? (nowWidth - space) + "px" : "0px";
help.style.height = nowHeight - space > 0 ? (nowHeight - space) + "px" : "0px";
help.style.left = nowLeft - space > 0 ? (nowLeft - space) + "px" : "0px";
help.style.top = nowTop - space > 0 ? (nowTop - space) + "px" : "0px";
nowWidth - space > 0 || nowHeight - space > 0 || nowLeft - space > 0 || nowTop - space > 0 ? setTimeout("setHelp(" + isOpen + ")", 10) : help = null;
}
}
//后退前进
function goOn(status)
...{
switch (status)
...{
case -1:
if (thisStep > 0)
...{
thisStep--;
var cell = $(steps[thisStep][1]);
if (steps[thisStep][0] == "in")
...{
$("people").innerHTML = parseInt($("people").innerHTML) - parseInt(cell.childNodes[0].people);
cell.innerHTML = "";
}
else
...{
cell.innerHTML = steps[thisStep][2];
$("people").innerHTML = parseInt($("people").innerHTML) + parseInt(cell.childNodes[0].people);
}
}
break;
case 1:
if (thisStep < steps.length)
...{
var cell = $(steps[thisStep][1]);
if (steps[thisStep][0] == "in")
...{
cell.innerHTML = steps[thisStep][2];
$("people").innerHTML = parseInt($("people").innerHTML) + parseInt(cell.childNodes[0].people);
}
else
...{
$("people").innerHTML = parseInt($("people").innerHTML) - parseInt(cell.childNodes[0].people);
cell.innerHTML = "";
}
thisStep++;
}
break;
}
}
//重新开始
function reStart()
...{
location.reload();
}
//取消选择框
function removeSelectDiv()
...{
if (selectDivObj)
...{
selectDivObj.parentNode.removeChild(selectDivObj);
selectDivObj = null;
}
help ? setHelp(false) : null;
}
createTable(5, 5);
createHouse("blue", 10, ",", ""); //房子颜色,占用人口数,标识图标,上下左右必须有存在的颜色(多个以_分割)
createHouse("red", 20, "/", "blue");
createHouse("green", 30, "-", "blue_red");
createHouse("yellow", 40, ".", "blue_red_green");
document.onselectstart = function() ...{return false;};
window.onhelp = function() ...{ return false; };
document.body.onclick = function()
...{
if (selectDivObj)
...{
var element = document.elementFromPoint(event.x, event.y);
while(element.tagName != "undefined" && element.tagName.toUpperCase() != "BODY")
...{
if (element.id == "selectDiv" || element.id == selectCell)
...{
return;
}
element = element.parentNode;
}
removeSelect();
}
}
document.onkeydown = function()
...{
event.keyCode == 37 || event.keyCode == 38 || event.keyCode == 39 || event.keyCode == 40 ? arrowMove(event.keyCode) : null; //左上右下箭头
if (event.keyCode == 13)
...{
//回车
if (selectDivObj)
...{
houseSelected(selectCell);
}
else if(selectCell)
...{
selectHouse($(selectCell));
}
}
(event.keyCode == 46 || event.keyCode == 110) && !selectDivObj && selectCell ? joinSpan($(selectCell), false) : null; //DELETE删除
event.ctrlKey && event.keyCode == 71 ? reStart() : null; //CTRL+G重新开始
event.ctrlKey && event.keyCode == 89 ? goOn(1) : null; //CTRL+Y前进一步
event.ctrlKey && event.keyCode == 90 ? goOn(-1) : null; //CTRL+Z后退一步
event.keyCode == 27 ? removeSelectDiv() : null; //ESC取消选择框
if (event.keyCode == 112)
...{
getHelp();
event.keyCode = 0;
event.returnValue = false;
}
}
</script>
</body>
</html>
<head>
<title>JS小游戏 - 盖房子</title>
<style type="text/css">
body
...{
font-size: 12px;
cursor: default;
}
#tb
...{
text-align: center;
vertical-align: middle;
border: #606066 5px double;
border-collapse: collapse;
}
td
...{
border: #F5F5F5 1px solid;
width: 100px;
height: 100px;
}
#selectDiv
...{
position: absolute;
border: #606066 1px solid;
background-color: #F5F5F5;
z-index: 100;
}
#msg
...{
width: 300px;
top: 15px;
}
#msg #all
...{
width: 100%;
height: 30px;
line-height: 30px;
text-align: left;
vercital-align: middle;
padding-left: 10px;
background-color: #606066;
font-weight: bold;
color: #F5F5F5;
}
.houseList
...{
position: absolute;
cursor: default;
}
.house
...{
width: 50px;
height: 50px;
line-height: 50px;
margin: 5px;
font-family: Wingdings;
font-size: 36px;
text-align: center;
}
.fontDiv
...{
position: absolute;
width: 50px;
height: 20px;
line-height: 20px;
margin: 5px;
float: left;
font-size: 15px;
text-align: center;
cursor: default;
}
.blue
...{
background-color: blue;
}
.red
...{
background-color: red;
}
.green
...{
background-color: green;
}
.yellow
...{
background-color: yellow;
}
</style>
</head>
<body>
<div style="height: 30px; font-weight: bold">场地大小:
<input id="small" name="size" type="radio" checked onclick="reSize(5, 5)" /><label for="small">小(5 * 5)</label>
<input id="middle" name="size" type="radio" onclick="reSize(8, 8)" /><label for="middle">中(8 * 8)</label>
<input id="large" name="size" type="radio" onclick="reSize(10, 10)" /><label for="large">大(10 * 10)</label>
<a href="javascript:" onclick="getHelp()">帮助 / 操作说明 (F1)</a>
<a href="javascript:" onclick="reStart()">重新开始 (Ctrl+G)</a>
<a href="javascript:" onclick="goOn(-1)">←后退一步(Ctrl+Z)</a>
<a href="javascript:" onclick="goOn(1)">前进一步→(Ctrl+Y)</a>
</div>
<div id="houseDiv" style="position: relative; height: 60px; z-index: -10"></div>
<div id="msg">
<div id="all">总人口数: <span id="people">0</span></div>
</div>
<div id="tbDiv"></div>
<script>
//coding by pippe pippe@163.com
function $(objID)
...{
return document.getElementById(objID);
}
var rowCount, cellCount; //行数,列数
var cloneHouse;
var oLeft, oTop, oX, oY;
var previousCell; //存放上一个经过的TD
var houses = new Array(); //所有的房子
var selectCell; //双击选中的TD
var selectDivObj; //房子选择的DIV
var selectedHouse; //选中的房子
var help;
var steps = new Array();
var thisStep = 0;
//创建填充背景的表格
function createTable(rows, cells)
...{
rowCount = rows;
cellCount = cells;
var tb = document.createElement("table");
tb.id = "tb";
var row, cell;
for (var rowIndex = 1; rowIndex <= rowCount; rowIndex++)
...{
row = tb.insertRow(-1);
row.id = "row_" + rowIndex;
for (var cellIndex = 1; cellIndex <= cellCount; cellIndex++)
...{
cell = row.insertCell(-1);
cell.id = "cell_" + rowIndex + "_" + cellIndex;
cell.title = "单击盖房子(Enter),双击拆房子(Delete)";
cell.onclick = function() ...{ selectHouse(this); };
cell.ondblclick = function() ...{ joinSpan(this, false);};
}
}
$("tbDiv").appendChild(tb);
}
function reSize(rows, cells)
...{
$("tbDiv").removeChild($("tb"));
createTable(rows, cells);
}
//创建可供填充的房子
//房子颜色,占用人口数,标识图标,上下左右必须有存在的颜色(多个以_分割)
function createHouse()
...{
var len = arguments.length;
if (len == 4)
...{
var houseDivCount = $("houseDiv").childNodes.length;
var div = document.createElement("div");
div.id = arguments[0];
div.className = "house " + arguments[0];
div.style.left = (20 + (houseDivCount * 30)) + "px";
div.style.top = "0px";
div.style.position = "absolute";
div.style.cursor = "move";
div.onmousedown = function() ...{ mouseDown(this) };
div.people = arguments[1];
div.innerHTML = arguments[2];
div.exist = arguments[3];
$("houseDiv").appendChild(div);
houses.push(arguments);
var span = document.createElement("span");
span.id = arguments[0] + "_span";
span.className = "fontDiv";
span.style.left = (20 + (houseDivCount * 30)) + "px";
span.style.top = "0px";
span.innerHTML = arguments[1] + "人口";
$("houseDiv").appendChild(span);
}
}
//选择房子
function selectHouse(cell)
...{
removeSelect();
if (cell.hasChildNodes())
...{
return;
}
selectCell = cell.id;
cell.style.backgroundColor='#606066';
selectDivObj = document.createElement("div");
selectDivObj.id = "selectDiv";
document.body.appendChild(selectDivObj);
selectDivObj.style.left = (cell.offsetLeft + tbDiv.offsetLeft) + "px";
selectDivObj.style.top = (cell.offsetTop + tbDiv.offsetTop) + "px";
var selectItem = "";
var maxIndex = 0, maxExist = 0;
for(var houseIndex = 0; houseIndex < houses.length; houseIndex++)
...{
var isExist = getNeighborExist(cell.id, houses[houseIndex][3]);
if (isExist)
...{
if (houses[houseIndex][3].split("_").length >= maxExist)
...{
maxExist = houses[houseIndex][3].split("_").length;
maxIndex = houseIndex;
}
selectItem = "<span title="双击选择" ondblclick="houseSelected('" + cell.id + "')"><input type="radio" id="" + houses[houseIndex][0] + "_select" onclick="selectedHouse='" + houses[houseIndex][0] + "'" name="selectHouse" /><label for="" + houses[houseIndex][0] + "_select" class="house " + houses[houseIndex][0] + "">" + houses[houseIndex][2] + "</label></span>" + selectItem;
}
continue;
}
if (selectItem != "")
...{
selectItem += "<div style="text-align: center"><input type="button" onclick="houseSelected('" + cell.id + "')" value="选择(Enter)" /><input type="button" onclick="removeSelectDiv()" value="取消(Esc)" /><div>";
selectDivObj.innerHTML = selectItem;
$(houses[maxIndex][0] + "_select").checked = true;
selectedHouse = houses[maxIndex][0];
}
}
//确认选择
function houseSelected(cellID)
...{
if (selectedHouse)
...{
cloneHouse = $(selectedHouse).cloneNode(true);
joinSpan($(cellID), true);
}
if (selectDivObj)
...{
selectDivObj.parentNode.removeChild(selectDivObj);
selectDivObj = null;
}
}
//移除选择列表
function removeSelect()
...{
if (selectDivObj)
...{
selectDivObj.parentNode.removeChild(selectDivObj);
selectDivObj = null;
selectedHouse = null;
}
if (selectCell)
...{
$(selectCell).style.backgroundColor = "";
selectCell = null;
}
}
//鼠标在房子上按下复制
function mouseDown(obj)
...{
if (event.button == 1)
...{
cloneHouse = obj.cloneNode(true);
oLeft = parseInt(cloneHouse.style.left);
oTop = parseInt(cloneHouse.style.top);
oX = event.clientX;
oY = event.clientY;
cloneHouse.style.filter = "alpha(opacity=50)";
cloneHouse.style.zIndex = "-100";
obj.parentNode.appendChild(cloneHouse);
cloneHouse.style.cursor = "move";
cloneHouse.setCapture();
cloneHouse.onmousemove = function() ...{ mouseMove() };
cloneHouse.onmouseup = function() ...{ mouseUp() };
}
}
//鼠标拉动房子在table上选择格子
function mouseMove()
...{
if (event.button == 1)
...{
var nX = event.clientX;
var nY = event.clientY;
cloneHouse.style.left = (nX - oX + oLeft) + "px";
cloneHouse.style.top = (nY - oY + oTop) + "px";
var element = document.elementFromPoint(nX, nY);
var re1 = /^(cell)...{1}(_[1-5])...{2}(_value)...{1}$/; //TD内容
var re2 = /^(cell)...{1}(_[1-5])...{2}$/; //TD
var cellType = re1.test(element.id.toString()) ? 1 : re2.test(element.id.toString()) ? 2 : 0;
switch(cellType)
...{
case 1:
element.parentNode.style.border = "1px solid " + cloneHouse.className.split(" ")[1];
previousCell && previousCell != element.parentNode.id ? $(previousCell).style.cssText = "" : null;
previousCell = element.parentNode.id;
break;
case 2:
element.style.border = "1px solid " + cloneHouse.className.split(" ")[1];
previousCell && previousCell != element.id ? $(previousCell).style.cssText = "" : null;
previousCell = element.id;
break;
case 0:
previousCell ? $(previousCell).style.cssText = "" : null;
previousCell = null;
break;
}
}
}
//鼠标弹起
function mouseUp()
...{
if (cloneHouse)
...{
cloneHouse.releaseCapture();
//未选中表格,不加入
if (!previousCell)
...{
cloneHouse.parentNode.removeChild(cloneHouse);
return;
}
//邻居符合颜色要求加入,不符合不加入
var isExist = getNeighborExist(previousCell, cloneHouse.exist);
if (isExist)
...{
joinSpan($(previousCell), true);
}
else
...{
cloneHouse.releaseCapture();
cloneHouse.parentNode.removeChild(cloneHouse);
}
}
}
//判断触发事件的表格内的上下左右邻居是否有符合颜色要求
function getNeighborExist(cellID, allExist)
...{
//事件的框内已存在房子,不加入
if($(cellID).hasChildNodes())
...{
return false;
}
//拉动的房子不要求上下左右必须存在的颜色
if (allExist == "")
...{
return true;
}
var cellSplit = cellID.split("_");
var existSplit = allExist.split("_");
var existSplitLen = existSplit.length;
var neighborCell = new Array();
var rowIndex = parseInt(cellSplit[1]);
var cellIndex = parseInt(cellSplit[2]);
//邻居进栈
rowIndex > 1 ? neighborCell.push(cellSplit[0] + "_" + (rowIndex - 1) + "_" + cellSplit[2]) : null;
rowIndex < rowCount ? neighborCell.push(cellSplit[0] + "_" + (rowIndex + 1) + "_" + cellSplit[2]) : null;
cellIndex > 1 ? neighborCell.push(cellSplit[0] + "_" + cellSplit[1] + "_" + (cellIndex - 1)) : null;
cellIndex < cellCount ? neighborCell.push(cellSplit[0] + "_"+ cellSplit[1] + "_" + (cellIndex + 1)) : null;
//要求邻居个数超过所有邻居数,不加入
var neighborCount = neighborCell.length;
if (existSplitLen > neighborCount)
...{
return false;
}
var exist;
for (var existIndex = 0; existIndex < existSplitLen; existIndex++)
...{
exist = false;
for (var neighborIndex = 0; neighborIndex < neighborCount; neighborIndex++)
...{
if ($(neighborCell[neighborIndex]).hasChildNodes() && existSplit[existIndex] == $(neighborCell[neighborIndex]).childNodes[0].group)
...{
exist = true;
break;
}
}
//邻居没有要求的颜色,不加入
if (!exist)
...{
return false;
}
}
return true;
}
//加入/去除 单元
function joinSpan(cell, isJoin)
...{
if (isJoin)
...{
if (!cell.hasChildNodes())
...{
cell.innerHTML = "<span id="" + cell.id + "_value" title="双击拆房子" people="" + cloneHouse.people + "" ondblclick="joinSpan(this.parentNode, false)" group="" + cloneHouse.id + "" exist="" + cloneHouse.exist + "" class="" + cloneHouse.className + "">" + cloneHouse.innerHTML + "</span>";
$("people").innerHTML = parseInt($("people").innerHTML) + parseInt(cloneHouse.people);
cloneHouse.parentNode.removeChild(cloneHouse);
var step = new Array("in", cell.id, cell.innerHTML);
steps[thisStep] = step;
steps.length = ++thisStep;
}
}
else
...{
if (cell.hasChildNodes())
...{
var cellSplit = cell.id.split("_");
var neighborCell = new Array();
var rowIndex = parseInt(cellSplit[1]);
var cellIndex = parseInt(cellSplit[2]);
//邻居进栈
rowIndex > 1 ? neighborCell.push(cellSplit[0] + "_" + (rowIndex - 1) + "_" + cellSplit[2]) : null;
rowIndex < rowCount ? neighborCell.push(cellSplit[0] + "_" + (rowIndex + 1) + "_" + cellSplit[2]) : null;
cellIndex > 1 ? neighborCell.push(cellSplit[0] + "_" + cellSplit[1] + "_" + (cellIndex - 1)) : null;
cellIndex < cellCount ? neighborCell.push(cellSplit[0] + "_"+ cellSplit[1] + "_" + (cellIndex + 1)) : null;
//遍历邻居身边需求是否包括本房子
var neighborCount = neighborCell.length;
for (var neighborIndex = 0; neighborIndex < neighborCount; neighborIndex++)
...{
if ($(neighborCell[neighborIndex]).hasChildNodes())
...{
exist = $(neighborCell[neighborIndex]).childNodes[0].exist.split("_");
for (existIndex = 0; existIndex < exist.length; existIndex++)
...{
if (exist[existIndex] == cell.childNodes[0].group)
...{
return;
}
}
}
}
$("people").innerHTML = parseInt($("people").innerHTML) - parseInt(cell.childNodes[0].people);
var step = new Array("out", cell.id, cell.innerHTML);
steps[thisStep] = step;
steps.length = ++thisStep;
cell.innerHTML = "";
}
}
}
function arrowMove(eKeyCode)
...{
if (selectDivObj)
...{
switch(eKeyCode)
...{
case 37: //left
case 38: //up
if (selectedHouse)
...{
var previous = $(selectedHouse + "_select").parentNode.previousSibling;
if (previous && previous.tagName.toUpperCase() == "SPAN")
...{
previous.childNodes[0].checked = true;
selectedHouse = previous.childNodes[0].id.split("_")[0];
}
}
break;
case 39: //right
case 40: //down
if (selectedHouse)
...{
var next = $(selectedHouse + "_select").parentNode.nextSibling;
if (next && next.tagName.toUpperCase() == "SPAN")
...{
next.childNodes[0].checked = true;
selectedHouse = next.childNodes[0].id.split("_")[0];
}
}
break;
}
return;
}
if(selectCell)
...{
var cellSplit = selectCell.split("_");
var newSelectCell;
switch(eKeyCode)
...{
case 37: //left
if (parseInt(cellSplit[2]) == 1)
...{
return;
}
newSelectCell = cellSplit[0] + "_" + cellSplit[1] + "_" + (parseInt(cellSplit[2]) - 1);
break;
case 38: //up
if (parseInt(cellSplit[1]) == 1)
...{
return;
}
newSelectCell = cellSplit[0] + "_" + (parseInt(cellSplit[1]) - 1) + "_" + cellSplit[2];
break;
case 39: //right
if (parseInt(cellSplit[2]) == rowCount)
...{
return;
}
newSelectCell = cellSplit[0] + "_" + cellSplit[1] + "_" + (parseInt(cellSplit[2]) + 1);
break;
case 40: //down
if (parseInt(cellSplit[1]) == cellCount)
...{
return;
}
newSelectCell = cellSplit[0] + "_" + (parseInt(cellSplit[1]) + 1) + "_" + cellSplit[2];
break;
}
$(selectCell).style.backgroundColor = "";
selectCell = newSelectCell;
$(selectCell).style.backgroundColor = "#606066";
return;
}
selectCell = "cell_1_1";
$(selectCell).style.backgroundColor = "#606066";
}
//帮助
function getHelp()
...{
if (help)
...{
return;
}
help = document.createElement("<div>");
help.id = "help";
help.style.cssText = "position: absolute; padding: 5px; width: 0px; height: 0px; border: #606066 1px solid; overflow: hidden; left: " + event.x + "px; top: " + event.y + "px";
var helpText = "<p style="font-weight: bold; font-size: 15px">游戏规则(源于一思考题):</p>";
helpText += "<ol><li>一个场地里(默认5*5,可选择大小)的方格 打算往每个格子里放房子,有4种颜色的房子</li>";
helpText += "<li>蓝色的房子 占10人口 随便放在哪里都行</li>";
helpText += "<li>红色的房子 占20人口 要求和蓝色的房子相邻</li>";
helpText += "<li>绿色的房子 占30人口 要求和蓝色,红色的房子相邻行</li>";
helpText += "<li>黄色的房子 占40人口 要求和蓝色,红色,绿色的房子相邻</li>";
helpText += "<li>如何放置 才能使5*5的格子占用的人口数量最大? </li></ol>";
helpText += "<p style="font-weight: bold; font-size: 15px">操作说明:</p>";
helpText += "<ol><li>拉动各颜色的房子到欲放置的格子处释放鼠标,如果格子符合该颜色房子的需求则房子成功放入,否则房子不放入,如:欲放黄色房子,则本格子上下左右需存在蓝绿红三种房子。</li>";
helpText += "<li>单击任何一个格子弹出该格子当前可放入的房子选项,双击房子即可放入,或者选中其中一个后按回车或点选择亦可放入。</li>";
helpText += "<li>双击有房子的格子或房子即可拆掉此房子。</li>";
helpText += "<li>键盘操作:";
helpText += "<ul><li>按上下左右箭头可在表格内移动,当前格子背景色为黑色,如无选中则从第一行第一列开始,按回车后选择房子,按Delete或"."为拆掉房子。</li>";
helpText += "<li>如果弹出选择房子时,上下左右箭头为选择当前格子可用的房子(如:向放黄色房子需先在需要放置的格子上下左右格放好蓝绿红房子,方可选择),按下回车后此房子加入格子内,Esc键为不做选择并关掉选择房子。</li>";
helpText += "<li>如果拆除房子的邻居有对本房子要求时本房子不可拆除,需先拆除对于本房子做要求的房子,如:想拆掉蓝色房子,但上下左右有红色房子则需先拆掉红色房子方可拆掉蓝色房子。</li></ul></li>";
helpText += "<li>按Ctrl+Z可后退一步,如果后退后未再做操作按Ctrl+Y可前进一步,可多次后退或前进(在房子总数足够或后退步数足够的情况下),反之后退前进无效。</li>";
helpText += "<li>coding by pippe <a href="mailto:pippe@163.com">pippe@163.com</a>。</li></ol>";
helpText += "<span style="width: 100%; text-align: center"><a href="javascript:" onclick="setHelp(false)" style="text-align: center">关闭(Esc)</a></span>";
help.innerHTML = helpText;
document.body.appendChild(help);
setHelp(true);
}
function setHelp(isOpen)
...{
var nowLeft = parseInt(help.style.left);
var nowTop = parseInt(help.style.top);
var nowWidth = parseInt(help.style.width);
var nowHeight = parseInt(help.style.height);
var space = 50;
if (isOpen)
...{
help.style.width = nowWidth + space < 500 ? (nowWidth + space) + "px" : "500px";
help.style.height = nowHeight + space < 600 ? (nowHeight + space) + "px" : "600px";
help.style.left = nowLeft > (document.body.clientWidth - nowWidth) / 2 + space ? (nowLeft - space) + "px" : nowLeft < (document.body.clientWidth - nowWidth) / 2 - space ? (nowLeft + space) + "px" : (document.body.clientWidth - nowWidth) / 2 + "px";
help.style.top = nowTop > (document.body.clientHeight - nowHeight) / 2 + space ? (nowTop - space) + "px" : nowTop < (document.body.clientHeight - nowHeight) / 2 - space ? (nowTop + space) + "px" : (document.body.clientHeight - nowHeight) / 2 + "px";
nowWidth + space < 500 || nowHeight + space < 600 || nowLeft < (document.body.clientWidth - nowWidth) / 2 - space || nowTop > (document.body.clientHeight - nowHeight) / 2 + space || nowTop < (document.body.clientHeight - nowHeight) / 2 - space ? setTimeout("setHelp(" + isOpen + ")", 10) : null;
}
else
...{
help.style.width = nowWidth - space > 0 ? (nowWidth - space) + "px" : "0px";
help.style.height = nowHeight - space > 0 ? (nowHeight - space) + "px" : "0px";
help.style.left = nowLeft - space > 0 ? (nowLeft - space) + "px" : "0px";
help.style.top = nowTop - space > 0 ? (nowTop - space) + "px" : "0px";
nowWidth - space > 0 || nowHeight - space > 0 || nowLeft - space > 0 || nowTop - space > 0 ? setTimeout("setHelp(" + isOpen + ")", 10) : help = null;
}
}
//后退前进
function goOn(status)
...{
switch (status)
...{
case -1:
if (thisStep > 0)
...{
thisStep--;
var cell = $(steps[thisStep][1]);
if (steps[thisStep][0] == "in")
...{
$("people").innerHTML = parseInt($("people").innerHTML) - parseInt(cell.childNodes[0].people);
cell.innerHTML = "";
}
else
...{
cell.innerHTML = steps[thisStep][2];
$("people").innerHTML = parseInt($("people").innerHTML) + parseInt(cell.childNodes[0].people);
}
}
break;
case 1:
if (thisStep < steps.length)
...{
var cell = $(steps[thisStep][1]);
if (steps[thisStep][0] == "in")
...{
cell.innerHTML = steps[thisStep][2];
$("people").innerHTML = parseInt($("people").innerHTML) + parseInt(cell.childNodes[0].people);
}
else
...{
$("people").innerHTML = parseInt($("people").innerHTML) - parseInt(cell.childNodes[0].people);
cell.innerHTML = "";
}
thisStep++;
}
break;
}
}
//重新开始
function reStart()
...{
location.reload();
}
//取消选择框
function removeSelectDiv()
...{
if (selectDivObj)
...{
selectDivObj.parentNode.removeChild(selectDivObj);
selectDivObj = null;
}
help ? setHelp(false) : null;
}
createTable(5, 5);
createHouse("blue", 10, ",", ""); //房子颜色,占用人口数,标识图标,上下左右必须有存在的颜色(多个以_分割)
createHouse("red", 20, "/", "blue");
createHouse("green", 30, "-", "blue_red");
createHouse("yellow", 40, ".", "blue_red_green");
document.onselectstart = function() ...{return false;};
window.onhelp = function() ...{ return false; };
document.body.onclick = function()
...{
if (selectDivObj)
...{
var element = document.elementFromPoint(event.x, event.y);
while(element.tagName != "undefined" && element.tagName.toUpperCase() != "BODY")
...{
if (element.id == "selectDiv" || element.id == selectCell)
...{
return;
}
element = element.parentNode;
}
removeSelect();
}
}
document.onkeydown = function()
...{
event.keyCode == 37 || event.keyCode == 38 || event.keyCode == 39 || event.keyCode == 40 ? arrowMove(event.keyCode) : null; //左上右下箭头
if (event.keyCode == 13)
...{
//回车
if (selectDivObj)
...{
houseSelected(selectCell);
}
else if(selectCell)
...{
selectHouse($(selectCell));
}
}
(event.keyCode == 46 || event.keyCode == 110) && !selectDivObj && selectCell ? joinSpan($(selectCell), false) : null; //DELETE删除
event.ctrlKey && event.keyCode == 71 ? reStart() : null; //CTRL+G重新开始
event.ctrlKey && event.keyCode == 89 ? goOn(1) : null; //CTRL+Y前进一步
event.ctrlKey && event.keyCode == 90 ? goOn(-1) : null; //CTRL+Z后退一步
event.keyCode == 27 ? removeSelectDiv() : null; //ESC取消选择框
if (event.keyCode == 112)
...{
getHelp();
event.keyCode = 0;
event.returnValue = false;
}
}
</script>
</body>
</html>
游戏说明:
- 一个5*5的方格 打算往每个格子里放房子,有4种颜色的房子
- 蓝色的房子 占10人口 随便放在哪里都行
- 红色的房子 占20人口 要求和蓝色的房子相邻
- 绿色的房子 占30人口 要求和蓝色,红色的房子相邻
- 黄色的房子 占40人口 要求和蓝色,红色,绿色的房子相邻
- 问 如何放置 才能使5*5的格子占用的人口数量最大?
操作说明:
- 拉动各颜色的房子到欲放置的格子处释放鼠标,如果格子符合该颜色房子的需求则房子成功放入,否则房子不放入,如:欲放黄色房子,则本格子上下左右需存在蓝绿红三种房子。
- 单击任何一个格子弹出该格子当前可放入的房子选项,双击房子即可放入,或者选中其中一个后按回车或点选择亦可放入。
- 双击有房子的格子或房子即可拆掉此房子。
- 键盘操作:
- 按上下左右箭头可在表格内移动,当前格子背景色为黑色,如无选中则从第一行第一列开始,按回车后选择房子,按Delete或“.”为拆掉房子。
- 如果弹出选择房子时,上下左右箭头为选择当前格子可用的房子(如:向放黄色房子需先在需要放置的格子上下左右格放好蓝绿红房子,方可选择),按下回车后此房子加入格子内,Esc键为不做选择并关掉选择房子。
- 如果拆除房子的邻居有对本房子要求时本房子不可拆除,需先拆除对于本房子做要求的房子,如:想拆掉蓝色房子,但上下左右有红色房子则需先拆掉红色房子方可拆掉蓝色房子。
- 按Ctrl+Z可后退一步,如果后退后未再做操作按Ctrl+Y可前进一步,可多次后退或前进(在房子总数足够或后退步数足够的情况下),反之后退前进无效。
- JS小游戏 - 盖房子
- 盖房子
- 盖房子
- 盖房子
- 盖房子_DP
- Vijos1057. 盖房子
- P1057 盖房子
- 盖房子优化1
- 盖房子优化2
- 盖房子优化3
- [Vijos1057] 盖房子
- CSU 1813 盖房子
- 1057.盖房子
- vijos 1057 盖房子
- CillyB盖房子
- [vijos1057]盖房子
- [BZOJ1515]盖房子
- CillyB盖房子 QDU
- ubuntu中的deb文件包介绍
- java也可以来做黑客:控制肉鸡
- Qtopia中文输入法移植
- 体验 DreamSpark
- IE8 部分汉化包
- JS小游戏 - 盖房子
- xp下VMWare安装linux系统
- SYN Flood攻击的基本原理及防御
- J2EE的13种核心技术
- 一些符号及颜色的英语写法总结
- asp.net2.0利用TreeView实现无限级树型菜单
- 缓冲区溢出攻击的分析与实时检测
- Linux分区方案
- nc命令详解