Ich habe nichts zu tun, also habe ich auch ein Javascript für Lianliankan geschrieben. Die Kommentare sind relativ vollständig. Freunde, die es lernen möchten.
Der schwierigste Teil von Lian Lian Kan ist wahrscheinlich die Pfadsuche, bei der es darum geht, herauszufinden, ob es zwischen den beiden mit der Maus angeklickten Punkten einen passierbaren Pfad gibt. Ich habe die rekursive Schreibmethode von jemandem gesehen und es juckte mich, also habe ich es herausgefunden und festgestellt, dass es ohne Rekursion nicht so schwierig ist.
Die Pfadsuche wird von einfach bis schwierig analysiert. Analysieren Sie zunächst, ob eine gerade Linie in einer geraden Linie verbunden werden kann, analysieren Sie dann, ob zwei Punkte auf einer geraden Linie durch Drehen von zwei Kurven verbunden werden können, und analysieren Sie schließlich die Situation, in der dies nicht der Fall ist auf einer geraden Linie.
Getestet unter IE6, IE8, Firefox3.0.3.
Kopieren Sie den Codecode wie folgt:
<html>
<Kopf>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>JS Lianliankan Quellcode perfekt kommentierte Version</title>
</head>
<Stil>
Tisch{
border-collapse: Zusammenbruch;
}
td{
Rand: fest #ccc 1px;
Höhe: 36px;
Breite: 36px;
Cursor: Zeiger;
}
td img{
Höhe: 30px;
Breite: 30px;
Rand: fest #fff 3px;
/*
Filter: Alpha(Deckkraft=80);
-moz-Opazität: 0,8;
Deckkraft: 0,8;
*/
}
</style>
<Skript>
// Der folgende Teil ist der Teil des Pfadsuchalgorithmus und hat nichts mit der Präsentationsebene zu tun
//globale Variablen
var X = 16; //Gesamtzahl der Zeilen
var Y = 14; //Gesamtzahl der Spalten
vartypes = 15;//Grafiktypen
//Layoutmatrix
// Zur Vereinfachung des Algorithmus werden die erste Zeile, die erste Spalte, die letzte Zeile und die letzte Spalte der Matrix alle als 0 markiert, was einem natürlichen Pfad entspricht.
var arr = neues Array(Y);
var tbl;// Zeigt das Tabellenelement des Layouts an
var p1 = null;//Die Koordinaten des ersten im Suchpfad verwendeten Punkts
var p2 = null;//Die Koordinaten des zweiten im Suchpfad verwendeten Punkts
var e1 = null;//Das Element, das dem ersten Punkt entspricht
var e2 = null;//Das Element, das dem zweiten Punkt entspricht
//Pfadsuche, bei gegebenen zwei Punkten nach einem Pfad suchen
//Der Pfad wird durch verbindbare Punkte dargestellt
Funktion getPath(p1, p2){
//Sortieren Sie p1 und p2, bevor Sie mit der Suche beginnen, sodass p2 möglichst weit unten rechts von p1 liegt.
//Dies kann den Algorithmus vereinfachen
if(p1.x>p2.x){
var t = p1;
p1 = p2;
p2 = t;
}
sonst if(p1.x==p2.x){
if(p1.y>p2.y){
var t = p1;
p1 = p2;
p2 = t;
}
}
// Durch die Analyse der Positionsbeziehung zwischen den beiden Punkten in Lianliankan analysieren wir schrittweise jeden Typ von einfach bis schwierig.
// Der erste Typ, ob zwei Punkte auf einer geraden Linie liegen und ob die beiden Punkte durch eine gerade Linie verbunden werden können
if((onlineY(p1, p2)||onlineX(p1, p2)) && hasLine(p1, p2)){
status = 'Typ 1';
return [p1,p2];
}
// Der zweite Typ funktioniert nicht, wenn einer der beiden Punkte vollständig umgeben ist.
if( !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}) ){
status = 'Typ 2';
null zurückgeben;
}
if( !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}) ){
status = 'Typ 2';
null zurückgeben;
}
// Beim dritten Typ liegen zwei Punkte auf einer geraden Linie, können aber nicht durch eine gerade Linie verbunden werden
var pt0, pt1, pt2, pt3;
//Wenn sie alle auf der x-Achse liegen, scanne mögliche Pfade von links nach rechts,
// Konstruieren Sie jedes Mal 4 Eckpunkte pt0, pt1, pt2, pt3 und prüfen Sie dann, ob sie miteinander verbunden sind
if(onlineX(p1, p2)){
for(var i=0; i<Y; i++){
if(i==p1.y){
weitermachen;
}
pt0 = p1;
pt1 = {x: p1.x, y: i};
pt2 = {x: p2.x, y: i};
pt3 = p2;
//Wenn der Scheitelpunkt nicht leer ist, ist die Straße blockiert.
if(!isEmpty(pt1) || !isEmpty(pt2)){
weitermachen;
}
if( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){
status = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')' ;
return [pt0, pt1, pt2, pt3];
}
}
}
//Wenn sie alle auf der y-Achse liegen, scannen Sie mögliche Pfade von oben nach unten,
// Konstruieren Sie jedes Mal 4 Eckpunkte pt0, pt1, pt2, pt3 und prüfen Sie dann, ob sie miteinander verbunden sind
if(onlineY(p1, p2)){
for(var j=0; j<X; j++){
if(j==p1.x){
weitermachen;
}
pt0 = p1;
pt1 = {x:j, y:p1.y};
pt2 = {x:j, y:p2.y};
pt3 = p2;
//Wenn der Scheitelpunkt nicht leer ist, ist die Straße blockiert.
if(!isEmpty(pt1) || !isEmpty(pt2)){
weitermachen;
}
if( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){
status = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')' ;
return [pt0, pt1, pt2, pt3];
}
}
}
// Beim vierten Typ liegen die beiden Punkte nicht auf einer geraden Linie.
//Mögliche Pfade zuerst vertikal scannen
//Konstruieren Sie auf ähnliche Weise jedes Mal 4 Scheitelpunkte, um zu sehen, ob sie passierbar sind
for(var k=0; k<Y; k++){
pt0 = p1;
pt1 = {x:p1.x, y:k};
pt2 = {x:p2.x, y:k};
pt3 = p2;
status = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')' ;
//Sonderfall, wenn pt0 und pt1 übereinstimmen
if(equal(pt0,pt1)){
//Wenn pt2 nicht leer ist, ist dieser Pfad blockiert
if(!isEmpty(pt2)){
weitermachen;
}
if( hasLine(pt1, pt2) && hasLine(pt2, pt3) ){
return [pt1, pt2, pt3];
}
anders{
weitermachen;
}
}
//Sonderfall, wenn pt2 und pt3 überlappen
sonst if(equal(pt2,pt3)){
//Wenn pt1 nicht leer ist, ist dieser Pfad blockiert
if(!isEmpty(pt1)){
weitermachen;
}
if( hasLine(pt0, pt1) && hasLine(pt1, pt2) ){
return [pt0, pt1, pt2];
}
anders{
weitermachen;
}
}
//Wenn weder pt1 noch pt2 leer sind, funktioniert es nicht.
if(!isEmpty(pt1) || !isEmpty(pt2)){
weitermachen;
}
if( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){
return [pt0, pt1, pt2, pt3];
}
}
//Mögliche Pfade horizontal scannen
for(var k=0; k<X; k++){
pt0 = p1;
pt1 = {x:k, y:p1.y};
pt2 = {x:k, y:p2.y};
pt3 = p2;
status = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')' ;
if(equal(pt0,pt1)){
if(!isEmpty(pt2)){
weitermachen;
}
if( hasLine(pt1, pt2) && hasLine(pt2, pt3) ){
return [pt1, pt2, pt3];
}
}
if(equal(pt2,pt3)){
if(!isEmpty(pt1)){
weitermachen;
}
if( hasLine(pt0, pt1) && hasLine(pt1, pt2) ){
return [pt0, pt1, pt2];
}
}
if(!isEmpty(pt1) || !isEmpty(pt2)){
weitermachen;
}
if( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){
return [pt0, pt1, pt2, pt3];
}
}
//status='type4';
null zurückgeben;
/*************** Endtyp 4 **************/
}
Funktion equal(p1, p2){
return ((p1.x==p2.x)&&(p1.y==p2.y));
}
Funktion onlineX(p1, p2){
return p1.y==p2.y;
}
Funktion onlineY(p1, p2){
return p1.x==p2.x;
}
Funktion isEmpty(p){
return (arr[py][px]==0);
}
Funktion hasLine(p1, p2){
if(p1.x==p2.x&&p1.y==p2.y){
return true;
}
if(onlineY(p1, p2)){
var i = p1.y>p2.y?p2.y:p1.y;
i = i+1;
var max = p1.y>p2.y?p1.y:p2.y;
for(; i<max; i++){
var p = {x: p1.x, y: i};
if(!isEmpty(p)){
brechen
}
}
if(i==max){
return true;
}
return false;
}
sonst if(onlineX(p1, p2)){
var j = p1.x>p2.x?p2.x:p1.x;
j = j+1;
var max = p1.x>p2.x?p1.x:p2.x;
for(; j<max; j++){
var p = {x: j, y: p1.y};
if(!isEmpty(p)){
brechen
}
}
if(j==max){
return true;
}
return false;
}
}
//Der folgende Teil ist der Teil der Präsentationsebene, einschließlich Zeichnen, Initialisieren der Matrix, Binden von Mausereignissen ...
Funktion $(id){return document.getElementById(id)}
var t1, t2;//zum Testen
//Bildbasispfad
var IMG_PATH = '//www.VeVB.COm';
//Initialisierung
Funktion init(){
//Bildbibliothek erstellen
var imgs = neues Array(30);
for(var i=1; i<=30; i++){
imgs[i] = 'r_' + i + '.gif';
}
tbl = $('tbl');
//Tabelle erstellen
for(var row=0;row<Y-2;row++){
var tr=tbl.insertRow(-1);
for(var col=0;col<X-2;col++) {
var td=tr.insertCell(-1);
}
}
//Matrix konstruieren
for(var i=0; i<Y; i++){
arr[i] = neues Array(X);
for(var j=0; j<X; j++){
arr[i][j] = 0;
}
}
var total = (X-2)*(Y-2);
var tmp = new Array(total);//Wird zum Generieren zufälliger Positionen verwendet
for(var i=0; i<total; i++){
tmp[i] = 0;
}
for(var i=0; i<total; i++){
if(tmp[i]==0){
var t = Math.floor(Math.random()*types) + 1;
tmp[i] = t;
while(true){
var c = Math.floor(Math.random()*(total-i)) + i;
if(tmp[c]==0){
tmp[c] = t;
brechen;
}
}
}
}
var c = 0;
for(var i=1; i<Y-1; i++){
for(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]] + '" />';
}
}
//Mausereignisse binden
var img1, img2;
document.body.onclick = function(e){
var el = document.all?event.srcElement:e.target;
if(el.parentNode.tagName!='TD'){
zurückkehren;
}
if(!img1){
img1 = el;
}
anders{
img2 = el;
}
el.style.border = 'solid #3399FF 3px';
el = el.parentNode;
if(el.innerHTML==''){
p1 = p2 = e1 = e2 = null;
}
var r = el.parentNode.rowIndex +1;
var c = el.cellIndex +1;
if(p1==null){
//el.childNodes[0].style.border = 'solid #ccc 3px';
p1 = {x:c, y:r};
e1 = el;
}
anders{
p2 = {x:c, y:r};
e2 = el;
if(!equal(p1, p2)&&e1.innerHTML==el.innerHTML){
var path = getPath(p1, p2);
if(path!=null){
e1.innerHTML = e2.innerHTML = '';
arr[p1.y][p1.x] = arr[p2.y][p2.x] = 0;
}
}
if(t1){t1.style.backgroundColor = '';}
t1 = e1;
if(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 perfekt kommentierte Version<br />
<table id="tbl" cellpacing="0" cellpadding="0">
</table>
</body>
</html>