ليس لدي ما أفعله، لذلك كتبت أيضًا تعليقات جافا سكريبت لـ Lianliankan، ويجب على الأصدقاء الذين يرغبون في التعلم قراءتها.
ربما يكون الجزء الأكثر صعوبة في Lian Lian Kan هو البحث عن المسار، وهو معرفة ما إذا كان هناك مسار مقبول بين النقطتين اللتين تم النقر عليهما بالماوس. لقد رأيت طريقة الكتابة العودية لشخص ما، وشعرت بالحكة، لذلك اكتشفت ذلك ووجدت أن الأمر ليس بهذه الصعوبة بدون التكرار.
يتم تحليل البحث عن المسار من البسيط إلى الصعب أولاً، قم بتحليل ما إذا كان من الممكن توصيل خط مستقيم بخط مستقيم، ثم قم بتحليل ما إذا كان من الممكن توصيل نقطتين على خط مستقيم عن طريق تحويل دورتين، وأخيرًا قم بتحليل الموقف عندما لا يكونا كذلك. على خط مستقيم.
تم اختباره تحت IE6، IE8، Firefox3.0.3.
انسخ رمز الكود كما يلي:
<أتش تي أم أل>
<الرأس>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>نسخة مشروحة مثالية من كود مصدر JS Lianliankan</title>
</الرأس>
<نمط>
طاولة{
انهيار الحدود: انهيار؛
}
الدفتيريا {
الحدود: الصلبة #ccc 1px؛
الارتفاع: 36 بكسل؛
العرض: 36 بكسل؛
المؤشر: المؤشر؛
}
صورة TD {
الارتفاع: 30 بكسل؛
العرض: 30 بكسل؛
الحدود: الصلبة #fff 3px؛
/*
عامل التصفية: ألفا (التعتيم = 80)؛
-عتامة moz: 0.8؛
العتامة: 0.8؛
*/
}
</نمط>
<النص البرمجي>
// الجزء التالي هو جزء خوارزمية البحث عن المسار وليس له علاقة بطبقة العرض التقديمي
// المتغيرات العالمية
var X = 16; // إجمالي عدد الصفوف
var Y = 14; // إجمالي عدد الأعمدة
أنواع var = 15;//أنواع الرسوم البيانية
// مصفوفة التخطيط
// لتسهيل الخوارزمية، تم وضع علامة 0 على الصف الأول والعمود الأول والصف الأخير والعمود الأخير من المصفوفة، وهو مسار طبيعي.
var arr = new Array(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){
فار تي = p1;
ص1 = ص2؛
ص2 = ر؛
}
وإلا إذا (p1.x==p2.x){
إذا(p1.y>p2.y){
فار تي = p1;
ص1 = ص2؛
ص2 = ر؛
}
}
// من خلال تحليل العلاقة الموضعية بين النقطتين في Lianliankan، نقوم بتحليل كل نوع تدريجيًا من البسيط إلى الصعب.
// النوع الأول، ما إذا كانت النقطتان على خط مستقيم، وما إذا كان من الممكن توصيل النقطتين بخط مستقيم
إذا((onlineY(p1, p2)||onlineX(p1, p2)) && hasLine(p1, p2)){
الحالة = 'النوع 1'؛
العودة [ص1، ص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. x-1, y:p2.y}) && !isEmpty({x:p2.x+1, y:p2.y})) ){
الحالة = 'النوع 2'؛
عودة فارغة؛
}
// النوع الثالث، نقطتان على خط مستقيم، لكن لا يمكن توصيلهما بخط مستقيم
فار pt0، pt1، pt2، pt3؛
// إذا كانت جميعها على المحور السيني، فافحص المسارات المحتملة من اليسار إلى اليمين،
// أنشئ 4 رؤوس pt0 وpt1 وpt2 وpt3 في كل مرة، ثم تحقق مما إذا كانت متصلة ببعضها البعض
إذا (أون لاين إكس (ص 1، ص 2)) {
ل(فار ط=0;أنا<Y;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]؛
}
}
}
// إذا كانت جميعها على المحور الصادي، فافحص المسارات المحتملة من الأعلى إلى الأسفل،
// أنشئ 4 رؤوس pt0 وpt1 وpt2 وpt3 في كل مرة، ثم تحقق مما إذا كانت متصلة ببعضها البعض
إذا (أون لاين (ص 1، ص 2)) {
ل(فار ي=0; ي<X; ي++){
إذا (ي==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 رؤوس في كل مرة لمعرفة ما إذا كان مقبولاً
ل(فار ك=0; ك<Y; ك++){
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]؛
}
}
// مسح المسارات المحتملة أفقيًا
ل(فار ك=0; ك<X; ك++){
pt0 = p1;
pt1 = {س:ك، ص:p1.y}؛
pt2 = {س:ك، ص: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 **************/
}
وظيفة متساوية (ص1، ص2) {
return ((p1.x==p2.x)&&(p1.y==p2.y));
}
وظيفة على الانترنتX(p1, p2){
إرجاع p1.y==p2.y;
}
وظيفة على الانترنتY(p1, p2){
إرجاع p1.x==p2.x;
}
الدالة فارغة (ع) {
return (arr[py][px]==0);
}
الدالة hasLine(p1, p2){
إذا(p1.x==p2.x&&p1.y==p2.y){
عودة صحيحة؛
}
إذا (أون لاين (ص 1، ص 2)) {
فار i = p1.y>p2.y?p2.y:p1.y;
أنا = أنا+1;
فار ماكس = p1.y>p2.y?p1.y:p2.y;
ل(; أنا<ماكس; أنا++){
فار ع = {س: p1.x، ص: أنا}؛
إذا (! إفراغ (ع)) {
استراحة
}
}
إذا (ط == الحد الأقصى) {
عودة صحيحة؛
}
عودة كاذبة.
}
وإلا إذا(onlineX(p1, p2)){
var j = p1.x>p2.x?p2.x:p1.x;
ي = ي+1;
فار ماكس = p1.x>p2.x?p1.x:p2.x;
ل(; ي<ماكس; ي++){
فار ع = {س: ي، ص: p1.y}؛
إذا (! إفراغ (ع)) {
استراحة
}
}
إذا (ي == ماكس) {
عودة صحيحة؛
}
عودة كاذبة.
}
}
// الجزء التالي هو جزء طبقة العرض التقديمي، بما في ذلك الرسم وتهيئة المصفوفة وربط أحداث الماوس...
الدالة $(id){return document.getElementById(id)}
var t1, t2;// للاختبار
// مسار قاعدة الصورة
var IMG_PATH = '//www.VeVB.COm';
//التهيئة
وظيفة الحرف الأول () {
// إنشاء مكتبة الصور
var imgs = new Array(30);
for(var i=1;i<=30;i++){
imgs[i] = 'r_' + i + '.gif';
}
tbl = $('tbl');
// بناء الجدول
for(varrow=0;row<Y-2;row++){
var tr=tbl.insertRow(-1);
for(var col=0;col<X-2;col++) {
var td=tr.insertCell(-1);
}
}
// بناء المصفوفة
ل(فار ط=0;أنا<Y;i++){
arr[i] = new Array(X);
ل(فار ي=0; ي<X; ي++){
arr[i][j] = 0;
}
}
فار الإجمالي = (X-2)*(Y-2);
var tmp = new Array(total);// يستخدم لإنشاء مواضع عشوائية
for(var i=0; i<total; i++){
تمب[i] = 0;
}
for(var i=0; i<total; i++){
إذا(تمب[i]==0){
var t = Math.floor(Math.random()*types) + 1;
tmp[i] = t;
بينما (صحيح) {
var c = Math.floor(Math.random()*(total-i)) + i;
إذا(تمب[ج]==0){
tmp[c] = t;
استراحة؛
}
}
}
}
فار ج = 0;
for(var i=1; i<Y-1; i++){
ل(فار ي=1; ي<X-1; ي++){
arr[i][j] = tmp[c++];
tbl.rows[i-1].cells[j-1].innerHTML = '<img src="' + IMG_PATH + imgs[arr[i][j]] + '" />';
}
}
// ربط أحداث الماوس
فار img1, img2;
document.body.onclick = الوظيفة(ه){
var el = document.all?event.srcElement:e.target;
إذا(el.parentNode.tagName!='TD'){
يعود؛
}
إذا (!img1){
img1 = el;
}
آخر{
img2 = el;
}
el.style.border = 'solid #3399FF 3px';
el = el.parentNode;
إذا(el.innerHTML==''){
p1 = p2 = e1 = e2 = null;
}
var r = el.parentNode.rowIndex +1;
فار ج = el.cellIndex +1;
إذا (ص1==خالية){
//el.childNodes[0].style.border = 'solid #ccc 3px';
ص1 = {س:ج، ص:ص}؛
e1 = ش;
}
آخر{
ص2 = {س:ج، ص:ص}؛
e2 = ش;
إذا(!equal(p1, p2)&&e1.innerHTML==el.innerHTML){
مسار فار = getPath(p1, p2);
إذا (المسار!=فارغ){
e1.innerHTML = e2.innerHTML = '';
arr[p1.y][p1.x] = arr[p2.y][p2.x] = 0;
}
}
إذا(t1){t1.style.backgroundColor = '';}
t1 = e1;
إذا(t2){t2.style.backgroundColor = '';}
t2 = e2;
img1.style.border = 'solid #fff 3px';
img2.style.border = 'solid #fff 3px';
p1 = p2 = e1 = e2 = img1 = img2 = null;
t1.style.backgroundColor = t2.style.backgroundColor = 'lightpink';
}
}
}
</script>
<body onload="init();">
js Lianliankan نسخة مشروحة مثالية<br />
<معرف الجدول = "tbl" تباعد الخلايا = "0" خلية الحشو = "0">
</الجدول>
</الجسم>
</html>