ฉันไม่มีอะไรทำเลยเขียนจาวาสคริปต์ให้ Lianliankan ด้วย เพื่อนๆ ที่ต้องการเรียนรู้ควรอ่าน
ส่วนที่ยากที่สุดของ Lian Lian Kan น่าจะเป็นการค้นหาเส้นทาง ซึ่งก็คือดูว่ามีเส้นทางที่ผ่านได้ระหว่างจุดสองจุดที่คลิกด้วยเมาส์หรือไม่ ฉันเห็นวิธีการเขียนแบบวนซ้ำของใครบางคน และฉันรู้สึกคัน ดังนั้นฉันจึงคิดออกและพบว่ามันไม่ยากขนาดนั้นหากไม่มีการเรียกซ้ำ
การค้นหาเส้นทางจะวิเคราะห์จากง่ายไปหายาก ขั้นแรกให้วิเคราะห์ว่าสามารถเชื่อมต่อเส้นตรงเป็นเส้นตรงได้หรือไม่ จากนั้นวิเคราะห์ว่าสามารถเชื่อมต่อจุดสองจุดบนเส้นตรงด้วยการหมุนสองรอบได้หรือไม่ และสุดท้ายวิเคราะห์สถานการณ์เมื่อไม่เชื่อมต่อกัน บนเส้นตรง
ทดสอบภายใต้ IE6, IE8, firefox3.0.3
คัดลอกรหัสรหัสดังต่อไปนี้:
<html>
<หัว>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ซอร์สโค้ด JS Lianliankan เวอร์ชันที่มีคำอธิบายประกอบสมบูรณ์แบบ</title>
</หัว>
<สไตล์>
โต๊ะ{
ชายแดนยุบ: ยุบ;
-
ทีดี{
เส้นขอบ: ทึบ #ccc 1px;
ความสูง: 36px;
ความกว้าง: 36px;
เคอร์เซอร์: ตัวชี้;
-
td img{
ความสูง: 30px;
ความกว้าง: 30px;
เส้นขอบ: ทึบ #fff 3px;
-
ตัวกรอง: อัลฟ่า (ความทึบ = 80);
-ความทึบแสง: 0.8;
ความทึบ: 0.8;
-
-
</สไตล์>
<สคริปต์>
//ส่วนต่อไปนี้เป็นส่วนอัลกอริธึมการค้นหาเส้นทางและไม่เกี่ยวข้องกับเลเยอร์การนำเสนอ
//ตัวแปรทั่วโลก
var X = 16; // จำนวนแถวทั้งหมด
var Y = 14; // จำนวนคอลัมน์ทั้งหมด
ประเภท var = 15;//ประเภทกราฟิก
// เมทริกซ์เค้าโครง
//เพื่อความสะดวกของอัลกอริทึม แถวแรก คอลัมน์แรก แถวสุดท้าย และคอลัมน์สุดท้ายของเมทริกซ์จะถูกทำเครื่องหมายเป็น 0 ทั้งหมด ซึ่งเป็นเส้นทางธรรมชาติ
var arr = อาร์เรย์ใหม่ (Y);
var tbl;//แสดงองค์ประกอบตารางของเค้าโครง
var p1 = null;//พิกัดของจุดแรกที่ใช้ในเส้นทางการค้นหา
var p2 = null;//พิกัดของจุดที่สองที่ใช้ในเส้นทางการค้นหา
var e1 = null;//องค์ประกอบที่สอดคล้องกับจุดแรก
var e2 = null;//องค์ประกอบที่สอดคล้องกับจุดที่สอง
//การค้นหาเส้นทาง ให้สองจุด ค้นหาเส้นทาง
//เส้นทางแสดงด้วยจุดเชื่อมต่อ
ฟังก์ชั่น getPath (p1, p2) {
//จัดเรียง p1 และ p2 ก่อนเริ่มการค้นหา เพื่อให้ p2 อยู่ไกลจากมุมขวาล่างของ p1 มากที่สุดเท่าที่จะเป็นไปได้
// สิ่งนี้สามารถทำให้อัลกอริทึมง่ายขึ้น
ถ้า(p1.x>p2.x){
var t = p1;
พี1 = พี2;
p2 = เสื้อ;
-
อย่างอื่นถ้า(p1.x==p2.x){
ถ้า(p1.y>p2.y){
var t = p1;
พี1 = พี2;
p2 = เสื้อ;
-
-
//โดยการวิเคราะห์ความสัมพันธ์เชิงตำแหน่งระหว่างสองจุดใน Lianliankan เราจะค่อยๆ วิเคราะห์แต่ละประเภทจากง่ายไปหายาก
//ประเภทแรก ไม่ว่าจุดสองจุดจะอยู่บนเส้นตรงหรือไม่ และจุดสองจุดสามารถเชื่อมต่อกันด้วยเส้นตรงได้หรือไม่
if((ออนไลน์Y(p1, p2)||onlineX(p1, p2)) && hasLine(p1, p2)){
สถานะ = 'ประเภท 1';
กลับ [p1,p2];
-
//แบบที่ 2 ถ้าจุดใดจุดหนึ่งในสองจุดถูกล้อมไว้จนสุดก็จะใช้งานไม่ได้
ถ้า( !isEmpty({x:p1.x, y:p1.y+1}) && !isEmpty({x:p1.x, y:p1.y-1}) && !isEmpty({x:p1. x-1, y:p1.y}) && !isEmpty({x:p1.x+1, y:p1.y}) ){
สถานะ = 'ประเภท 2';
กลับเป็นโมฆะ;
-
ถ้า( !isEmpty({x:p2.x, y:p2.y+1}) && !isEmpty({x:p2.x, y:p2.y-1}) && !isEmpty({x:p2.y-1}) x-1, y:p2.y}) && !isEmpty({x:p2.x+1, y:p2.y}) ){
สถานะ = 'ประเภท 2';
กลับเป็นโมฆะ;
-
//แบบที่ 3 จุด 2 จุดอยู่บนเส้นตรง แต่ไม่สามารถต่อด้วยเส้นตรงได้
เป็น pt0, pt1, pt2, pt3;
//หากทั้งหมดอยู่บนแกน x ให้สแกนเส้นทางที่เป็นไปได้จากซ้ายไปขวา
//สร้างจุดยอด 4 จุด pt0, pt1, pt2, pt3 ในแต่ละครั้ง จากนั้นตรวจสอบว่าเชื่อมต่อระหว่างกันหรือไม่
ถ้า(ออนไลน์X(p1, p2)){
สำหรับ(var i=0; i<Y; i++){
ถ้า(i==p1.y){
ดำเนินการต่อ;
-
pt0 = p1;
pt1 = {x: p1.x, y: i};
pt2 = {x: p2.x, y: i};
pt3 = p2;
//ถ้าจุดยอดไม่ว่างเปล่าถนนจะถูกปิดกั้น
ถ้า(!isEmpty(pt1) || !isEmpty(pt2)){
ดำเนินการต่อ;
-
ถ้า( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){
สถานะ = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')' ;
กลับ [pt0, pt1, pt2, pt3];
-
-
-
//หากทั้งหมดอยู่บนแกน y ให้สแกนเส้นทางที่เป็นไปได้จากบนลงล่าง
//สร้างจุดยอด 4 จุด pt0, pt1, pt2, pt3 ในแต่ละครั้ง จากนั้นตรวจสอบว่าเชื่อมต่อระหว่างกันหรือไม่
ถ้า(ออนไลน์Y(p1, p2)){
สำหรับ (var j=0; j<X; j++){
ถ้า(j==p1.x){
ดำเนินการต่อ;
-
pt0 = p1;
pt1 = {x:j, y:p1.y};
pt2 = {x:j, y:p2.y};
pt3 = p2;
//หากจุดยอดไม่ว่างเปล่า ถนนจะถูกปิดกั้น
ถ้า(!isEmpty(pt1) || !isEmpty(pt2)){
ดำเนินการต่อ;
-
ถ้า( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){
สถานะ = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')' ;
กลับ [pt0, pt1, pt2, pt3];
-
-
-
//แบบที่สี่ จุดสองจุดไม่อยู่บนเส้นตรง
//สแกนเส้นทางที่เป็นไปได้ในแนวตั้งก่อน
//ในทำนองเดียวกัน สร้างจุดยอด 4 จุดในแต่ละครั้งเพื่อดูว่าผ่านได้หรือไม่
สำหรับ(var k=0; k<Y; k++){
pt0 = p1;
pt1 = {x:p1.x, y:k};
pt2 = {x:p2.x, y:k};
pt3 = p2;
สถานะ = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')' ;
//กรณีพิเศษ ถ้า pt0 และ pt1 ตรงกัน
ถ้า(เท่ากับ(pt0,pt1)){
//หาก pt2 ไม่ว่างเปล่า เส้นทางนี้จะถูกบล็อก
ถ้า(!isEmpty(pt2)){
ดำเนินการต่อ;
-
ถ้า( hasLine(pt1, pt2) && hasLine(pt2, pt3) ){
กลับ [pt1, pt2, pt3];
-
อื่น{
ดำเนินการต่อ;
-
-
//กรณีพิเศษ ถ้า pt2 และ pt3 ทับซ้อนกัน
อื่นถ้า (เท่ากับ (pt2, pt3)) {
//หาก pt1 ไม่ว่างเปล่า เส้นทางนี้จะถูกบล็อก
ถ้า(!isEmpty(pt1)){
ดำเนินการต่อ;
-
ถ้า( hasLine(pt0, pt1) && hasLine(pt1, pt2) ){
กลับ [pt0, pt1, pt2];
-
อื่น{
ดำเนินการต่อ;
-
-
//ถ้าทั้ง pt1 และ pt2 ไม่ว่างเปล่า มันจะไม่ทำงาน
ถ้า(!isEmpty(pt1) || !isEmpty(pt2)){
ดำเนินการต่อ;
-
ถ้า( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){
กลับ [pt0, pt1, pt2, pt3];
-
-
//สแกนเส้นทางที่เป็นไปได้ในแนวนอน
สำหรับ(var k=0; k<X; k++){
pt0 = p1;
pt1 = {x:k, y:p1.y};
pt2 = {x:k, y:p2.y};
pt3 = p2;
สถานะ = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')' ;
ถ้า(เท่ากับ(pt0,pt1)){
ถ้า(!isEmpty(pt2)){
ดำเนินการต่อ;
-
ถ้า( hasLine(pt1, pt2) && hasLine(pt2, pt3) ){
กลับ [pt1, pt2, pt3];
-
-
ถ้า (เท่ากับ (pt2,pt3)){
ถ้า(!isEmpty(pt1)){
ดำเนินการต่อ;
-
ถ้า( hasLine(pt0, pt1) && hasLine(pt1, pt2) ){
กลับ [pt0, pt1, pt2];
-
-
ถ้า(!isEmpty(pt1) || !isEmpty(pt2)){
ดำเนินการต่อ;
-
ถ้า( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){
กลับ [pt0, pt1, pt2, pt3];
-
-
//สถานะ='type4';
กลับเป็นโมฆะ;
/************ จบแบบที่ 4 **************/
-
ฟังก์ชั่นเท่ากับ (p1, p2) {
กลับ ((p1.x==p2.x)&&(p1.y==p2.y));
-
ฟังก์ชั่นออนไลน์X (p1, p2) {
กลับ p1.y==p2.y;
-
ฟังก์ชั่นออนไลน์ Y (p1, p2) {
กลับ p1.x==p2.x;
-
ฟังก์ชั่น isEmpty (p) {
กลับ (arr[py][px]==0);
-
ฟังก์ชั่น hasLine (p1, p2) {
ถ้า(p1.x==p2.x&&p1.y==p2.y){
กลับเป็นจริง;
-
ถ้า(ออนไลน์Y(p1, p2)){
var i = p1.y>p2.y?p2.y:p1.y;
ฉัน = ฉัน+1;
var สูงสุด = p1.y>p2.y?p1.y:p2.y;
สำหรับ(; i<สูงสุด; i++){
วาร์ p = {x: p1.x, y: i};
ถ้า(!isEmpty(p)){
หยุดพัก
-
-
ถ้า(i==สูงสุด){
กลับเป็นจริง;
-
กลับเท็จ;
-
อย่างอื่นถ้า (onlineX (p1, p2)) {
var j = p1.x>p2.x?p2.x:p1.x;
เจ = เจ+1;
สูงสุด = p1.x>p2.x?p1.x:p2.x;
สำหรับ(; j<สูงสุด; j++){
var p = {x: j, y: p1.y};
ถ้า(!isEmpty(p)){
หยุดพัก
-
-
ถ้า(j==สูงสุด){
กลับเป็นจริง;
-
กลับเท็จ;
-
-
//ส่วนต่อไปนี้เป็นส่วนของเลเยอร์การนำเสนอ รวมถึงการวาด การเริ่มต้นเมทริกซ์ การผูกเหตุการณ์เมาส์...
ฟังก์ชั่น $(id){return document.getElementById(id)}
var t1, t2;//สำหรับการทดสอบ
// เส้นทางฐานรูปภาพ
var IMG_PATH = '//www.VeVB.COm';
//การเริ่มต้น
ฟังก์ชั่น init(){
//สร้างไลบรารีรูปภาพ
var imgs = อาร์เรย์ใหม่ (30);
สำหรับ(var i=1; i<=30; i++){
imgs[i] = 'r_' + ฉัน + '.gif';
-
tbl = $('tbl');
//สร้างโต๊ะ
สำหรับ(var row=0;row<Y-2;row++){
var tr=tbl.insertRow(-1);
สำหรับ (var col=0;col<X-2;col++) {
var td=tr.insertCell(-1);
-
-
//สร้างเมทริกซ์
สำหรับ(var i=0; i<Y; i++){
arr[i] = อาร์เรย์ใหม่(X);
สำหรับ (var j=0; j<X; j++){
arr[i][เจ] = 0;
-
-
ผลรวม var = (X-2)*(Y-2);
var tmp = new Array(total);//ใช้เพื่อสร้างตำแหน่งแบบสุ่ม
สำหรับ (var i=0; i<total; i++){
ทีเอ็มพี[i] = 0;
-
สำหรับ (var i=0; i<total; i++){
ถ้า(tmp[i]==0){
var t = Math.floor(Math.random()*types) + 1;
ทีเอ็มพี[i] = ที;
ในขณะที่ (จริง) {
var c = Math.floor(Math.random()*(total-i)) + i;
ถ้า(tmp[c]==0){
ทีเอ็มพี[ค] = ที;
หยุดพัก;
-
-
-
-
วาร์ ค = 0;
สำหรับ(var i=1; i<Y-1; i++){
สำหรับ(var j=1; j<X-1; j++){
arr[i][j] = tmp[c++];
tbl.rows[i-1].cells[j-1].innerHTML = '<img src="' + IMG_PATH + imgs[arr[i][j]] + '" />';
-
-
//ผูกเหตุการณ์เมาส์
var img1, img2;
document.body.onclick = ฟังก์ชั่น (e) {
var el = document.all?event.srcElement:e.target;
ถ้า(el.parentNode.tagName!='TD'){
กลับ;
-
ถ้า(!img1){
img1 = เอล;
-
อื่น{
img2 = เอล;
-
el.style.border = 'ทึบ #3399FF 3px';
el = el.parentNode;
ถ้า(el.innerHTML==''){
p1 = p2 = e1 = e2 = โมฆะ;
-
var r = el.parentNode.rowIndex +1;
var c = el.cellIndex +1;
ถ้า(p1==null){
//el.childNodes[0].style.border = 'ทึบ #ccc 3px';
p1 = {x:c, y:r};
e1 = เอล;
-
อื่น{
p2 = {x:c, y:r};
e2 = เอล;
ถ้า(!เท่ากับ(p1, p2)&&e1.innerHTML==el.innerHTML){
เส้นทาง var = getPath (p1, p2);
ถ้า (เส้นทาง! = null) {
e1.innerHTML = e2.innerHTML = '';
arr[p1.y][p1.x] = arr[p2.y][p2.x] = 0;
-
-
ถ้า(t1){t1.style.พื้นหลังสี = '';}
t1 = e1;
ถ้า(t2){t2.style.พื้นหลังสี = '';}
ที2 = อี2;
img1.style.border = 'ทึบ #fff 3px';
img2.style.border = 'ทึบ #fff 3px';
p1 = p2 = e1 = e2 = img1 = img2 = โมฆะ;
t1.style.พื้นหลังสี = t2.style.พื้นหลังสี = 'สีชมพูอ่อน';
-
-
-
</สคริปต์>
<body onload="init();">
js Lianliankan เวอร์ชันคำอธิบายประกอบที่สมบูรณ์แบบ<br />
<table id="tbl" cellspacing="0" cellpadding="0">
</ตาราง>
</ร่างกาย>
</html>