【生命遊戲】純前端web版,可在線體驗

前言

關於【生命遊戲】之前小編寫發過一篇Java版的,這裏就不再對其介紹了,不瞭解的讀者可以點下方鏈接前往瞭解:
https://blog.csdn.net/weixin_44155115/article/details/103884572

這一次小編做了一個web版的,並分享在我的碼雲上,感覺用js做確實是比Java的swing做起來方便很多,這也算是小編初學前端第一個練習吧。

效果圖

先看看效果圖吧!
有興趣的朋友也可以點擊下方鏈接試玩:
http://nonoas.gitee.io/webproj/LifeGame/
在這裏插入圖片描述

源碼

這裏小編把源碼附上,送給和我一樣初學前端的朋友,也希望路過的大佬不吝賜教,哈哈。
源碼也可以通過下方【碼雲】鏈接獲取:
https://gitee.com/nonoas/webProj/tree/master/LifeGame

HTML

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>生命遊戲網頁版</title>
		<link type="text/css" rel="stylesheet" href="css/index.css" />
		<link type="text/css" rel="stylesheet" href="css/style.css" />
		<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
		<script src="js/index.js"></script>
	</head>

	<body>
		<div class="center-content-box">
			<h1>生命遊戲</h1>
		</div>
		<div id="table-module" class="center-content-box">

			<!-- 遊戲簡介 -->
			<div id="game-intro">
				<h2>遊戲簡介</h2>
				<p>生命遊戲(game of life)爲1970年由英國數學家J. H. Conway所提出
					某細胞的鄰居包括上、下、左、右、左上、左下、右上與右下相鄰之細胞 遊戲規則如下:</p>
				<p><b>孤單死亡:</b>如果細胞的鄰居小於等於1個,則該細胞在下一次狀態將死亡;</p>
				<p><b>擁擠死亡:</b>如果細胞的鄰居在4個及以上,則該細胞在下一次狀態將死亡;</p>
				<p><b>穩定:</b>如果細胞的鄰居爲2個或3個,則下一次狀態爲穩定存活;</p>
				<p><b>復活:</b>如果某位置原無細胞存活,而該位置的鄰居爲2個或3個,則該位置將復活一個細胞。</p>
			</div>

			<div id="table-box">
				<table id="cell-table" border="1">
				</table>
			</div>

			<!-- 操作界面 -->
			<div id="game-operator">
				<div class="text-module">
					<p id="cur-period"><span class="Label">當前週期:</span><span id="period"></span></p>
					<p>
						<span class="Label">行列數量:</span>
						<input id="cell-count" type="text" placeholder="整數(0<n<=100)" />
					</p>
					<p><span class="Label">演化速度:</span><input id="speed" type="text" /></p>
					<p title="設置隨機分佈時的密度"><span class="Label">分佈密度:</span><input id="thickness" type="text" /></p>
					<p class="comment">提示:“行列數量” 和 “分佈密度” 在點擊 “重新佈置” 後生效。</p>
				</div>

				<div class="btn-module">
					<div class="btn-box">
						<p><input id="resetCell" type="button" value="重新佈置" /></p>
						<p><input id="btn-randomSet" type="button" value="隨機分佈" /></p>
						<p><input id="next-term" type="button" value="下一週期" /></p>
						<p><input id="btn-start" type="button" value="開始演化" /></p>
					</div>
				</div>

			</div>
		</div>
		<div id="copy-right">
			<nav class="center-content-box">
				<a href="">作者:Nonoas</a>
				<hr>
				<a href="https://blog.csdn.net/weixin_44155115/article/details/105129831">CSDN</a>
				<hr>
				<a href="https://gitee.com/nonoas/webProj/tree/master/LifeGame" target="_blank">Gitee</a>
			</nav>
		</div>
	</body>

</html>

CSS

@charset "utf-8";

* {
	margin: 0;
	box-sizing: border-box;
	color: white;
	font-family:"Microsoft YaHei UI";
	/* border: 1px solid #aaa; */
}

html {
	height: 100%;
	width: 100%;
}

body {
	width: 100%;
	height: 100%;
	padding: 2%;
	background: url(../img/home-bg.png);
	overflow: hidden;
}

h1{
	filter: drop-shadow(2px 5px 5px rgba(0, 0, 0, 0.3));
	-webkit-filter: drop-shadow(2px 5px 5px rgba(0, 0, 0, 0.3));
	-moz-filter: drop-shadow(2px 5px 5px rgba(0, 0, 0, 0.3));
}

#table-module {
	height: 90%;
}

#table-box {
	width: 30rem;
	height: 30rem;
	padding: 1.5%;
	background-color: #23b8af;
	filter: drop-shadow(2px 5px 5px rgba(0, 0, 0, 0.2));
	-webkit-filter: drop-shadow(2px 5px 5px rgba(0, 0, 0, 0.2));
	-moz-filter: drop-shadow(2px 5px 5px rgba(0, 0, 0, 0.2));
	border-radius: 1rem;
}

#table-box td:hover {
	animation: tdHover 1s;
	background-color: rgba(255, 255, 255, 0.7);
}

table {
	width: 100%;
	height: 100%;
	text-align: center;
	border-collapse: collapse;
	border: 1px solid white;
}

#game-intro {
	width: 20%;
	height: 30rem;
	margin-right: 2%;
	padding: 2%;
	background-color: #23b8af;
	border-radius: 1rem;
	filter: drop-shadow(2px 5px 5px rgba(0, 0, 0, 0.2));
	-webkit-filter: drop-shadow(2px 5px 5px rgba(0, 0, 0, 0.2));
	-moz-filter: drop-shadow(2px 5px 5px rgba(0, 0, 0, 0.2));
	overflow: auto;
}

#game-intro::-webkit-scrollbar {
	display: none;
}

#game-intro h2 {
	margin-bottom: 1.5rem;
	text-align: center;
}

#game-intro p {
	font-size: 0.9rem;
	margin: 5% 0 5% 0;
}

#game-operator {
	width: 20%;
	height: 30rem;
	margin-left: 2%;
	padding: 1%;
	background-color: #23b8af;
	border-radius: 1rem;
	filter: drop-shadow(2px 5px 5px rgba(0, 0, 0, 0.2));
	-webkit-filter: drop-shadow(2px 5px 5px rgba(0, 0, 0, 0.2));
	-moz-filter: drop-shadow(2px 5px 5px rgba(0, 0, 0, 0.2));
	overflow: auto;
}

#game-operator p {
	margin: 5%;
}

#game-operator::-webkit-scrollbar {
	display: none;
}

.text-module {
	height: 45%;
}

.text-module input[type="text"] {
	width: calc(100%);
	padding: 2%;
	border: 1.5px solid #fff;
	outline: none;
	background-color: rgba(0, 0, 0, 0);
}

input::-webkit-input-placeholder {
	color: #ddd;
}

input::-moz-placeholder {
	/* Mozilla Firefox 19+ */
	color: #ddd;
}

input:-moz-placeholder {
	/* Mozilla Firefox 4 to 18 */
	color: #ddd;
}

input:-ms-input-placeholder {
	/* Internet Explorer 10-11 */
	color: #ddd;
}


.text-module p {
	display: flex;
	align-items: center;
}

#cur-period {
	display: flex;
	justify-content: flex-start;
}

.text-module .Label {
	font-weight: bold;
	white-space: nowrap;
}

.text-module .comment{
	font-size: 0.7rem;
}

#cell-count {
	width: calc(100%-10px);
}

.btn-module {
	height: 50%;
	display: flex;
	align-items: flex-end;
}

.btn-box {
	width: 100%;
}

.btn-module input[type="button"] {
	width: 100%;
	padding: 0.5rem;
	font-size: 1.1rem;
	color: #19867d;
	border: none;
	border-radius: 1rem;
	background-color: #b8faff;
	transition: all 0.4s;
	outline: none;
}

.btn-module input[type="button"]:hover{
	background-color: #fff;
}

.btn-module input[type="button"]:active{
	background-color: #b8faff;
}

#copy-right a {
	margin: 0 1% 0 1%;
	font-size: 0.8rem;
}

#copy-right hr{
	height: 1rem;
	border: none;
	border-right: 1px solid #fff;
}

JS

var row = 15; //全局設置網格的數量
var speed = 200;
var period;
var thickness = 3;

var r = "rgba(255, 255, 255, 0.9)";
var n = "rgba(255, 255, 255, 0)";

// 狀態數組
var lifeRule = new Array();

//細胞皿數組
var cell = new Array();

var tr; //表格行

var suspand; //演化標記,用於停止演化


//文檔初始化代碼塊
$(function() {

	initAll()

});

// 全局初始化
function initAll() {

	period = 0;

	$("#cell-count").attr("value", row);
	$("#speed").attr("value", speed);
	$("#period").text(period);
	$("#thickness").attr("value", thickness);

	//初始化細胞皿數組
	for (var i = 0; i < row; i++) {
		cell[i] = new Array();
		for (var j = 0; j < row; j++) {
			cell[i][j] = 0;
		}
	}

	//初始化狀態數組
	for (var i = 0; i < row; i++) {
		lifeRule[i] = new Array();
		for (var j = 0; j < row; j++) {
			lifeRule[i][j] = 0;
		}
	}

	// 初始化表格
	for (var i = 0; i < row; i++) {
		var tr = $("<tr>");
		for (var j = 0; j < row; j++) {
			tr.append($("<td>"));
		}
		tr.appendTo($("#cell-table"));
	}

	// 單元格點擊事件
	$("td").click(function() {

		var color = $(this).css("background-color");

		var rowIndex = $(this).parent().index();
		var cellIndex = $(this).index()

		// 改變顏色和cell真值數組
		if (color == r) {
			cell[rowIndex][cellIndex] = 0;
			$(this).css("background-color", n);
		} else {
			cell[rowIndex][cellIndex] = 1;
			$(this).css("background-color", r);
		}
	});

	tr = $("#cell-table").find("tr");

	// 隨機佈置細胞皿
	$("#btn-randomSet").click(function() {

		for (var i = 0; i < row; i++)
			for (var j = 0; j < row; j++) {
				var flag = getRandomNum(0, 10);
				if (flag < thickness) {
					cell[i][j] = 1;
					tr.eq(i).find("td").eq(j).css("background-color", r);
				} else {
					cell[i][j] = 0;
					tr.eq(i).find("td").eq(j).css("background-color", n);
				}
			}
	});
}

$(function() {

	$("#cell-count").change(function() {
		var rows = $(this).val();
		if (rows <= 0 || rows > 100){
			alert("行列數量取值範圍爲:(0,100]");
			$(this).val(row);
		}
			
		
	});

	$("#speed").change(function() {
		var s = $(this).val();
		if (s < 0 || s> 5000) {
			alert("演化速度取值範圍爲:[0,5000]");
			$(this).val(speed);
		} else {
			speed=$(this).val();
		}
	});

	// 開始演化
	$("#btn-start").click(function() {
		var text = $(this).val();
		console.log(text);
		if (text == "開始演化") {
			$(this).val("暫停");
			suspand = setInterval(evolution, speed);
		} else {
			$(this).val("開始演化");
			clearInterval(suspand);
		}
	});

	// 下一週期
	$("#next-term").click(function() {
		evolution();
	});

	//重置
	$("#resetCell").click(function() {

		clearInterval(suspand);

		$("#btn-start").val("開始演化");

		row = $("#cell-count").val();
		speed = $("#speed").val();
		period = $("#period").text();
		thickness = $("#thickness").val();


		$("#cell-table").empty();

		initAll();
	});
})




// 獲取最小值到最大值之前的整數隨機數
function getRandomNum(Min, Max) {
	var Range = Max - Min;
	var Rand = Math.random();
	return (Min + Math.round(Rand * Range));
}

function evolution() {
	var tr = $("#cell-table").find("tr");
	setCellBool();
	for (var i = 0; i < lifeRule.length; i++)
		for (var j = 0; j < lifeRule[0].length; j++) {
			if (lifeRule[i][j] == 1) {
				cell[i][j] = 1;
				tr.eq(i).find("td").eq(j).css("background-color", r);
			} else {
				cell[i][j] = 0;
				tr.eq(i).find("td").eq(j).css("background-color", n);
			}
		}
	$("#period").text(++period);
}


//設置下一週期的細胞狀態
function setCellBool() {
	for (var i = 0; i < lifeRule.length; i++)
		for (var j = 0; j < lifeRule[0].length; j++) {
			switch (countAround(i, j)) {
				case 0:
				case 1:
				case 4:
				case 5:
				case 6:
				case 7:
				case 8:
					lifeRule[i][j] = 0;
					break;
				case 2:
				case 3:
					lifeRule[i][j] = 1;
					break;
			}
		}
}

// 統計某單元格周圍的細胞數量
function countAround(r, c) {
	var count = 0;
	//上一行
	count += countCell(r - 1, c - 1);
	count += countCell(r - 1, c);
	count += countCell(r - 1, c + 1);
	//同行
	count += countCell(r, c - 1);
	count += countCell(r, c + 1);
	// 下一行
	count += countCell(r + 1, c - 1);
	count += countCell(r + 1, c);
	count += countCell(r + 1, c + 1);

	return count;
}

//統計一個單元格內的細胞數量
function countCell(r, c) {
	if (r < 0 || r >= row || c < 0 || c >= row || cell[r][c] == 0)
		return 0;
	return 1;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章