prispôsobujem si pre potreby môjho matematického webu kód na hru
"Človeče, nehnevaj sa!" a neviem si poradiť s nasledovným:
keď hráč nevyrieši daný príklad správne (napr. kvadratickú rovnicu),
tak stráca nárok na hod kockou a nasleduje ďalši hráč, preto potrebujem
tlačidlo "Ďalši hráč", ktoré to umožní, ale akosi sa mi nedarí správne
kód upraviť
a ešte by som potreboval zrušiť pravidlo, že na štartovaciu pozíciu sa
môže postaviť s panáčikom až keď hodí 6, čiže na štartovaciu by sa
mal umiestniť po padnutí hociakého čísla, aby som to mohol používať
efektívne na hodinách matematiky
Vopred ďakujem!
/* "Človeče, nehnevaj sa!" in einer Umsetzung als Browser-Game
*
* V 0.2 (2011-03-12)
*
* SOFTWARE LICENSE: LGPL
* (C) 2011 Felix Riesterer
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Felix Riesterer ([email protected])
*/
MAEDN = {
variants : ["Classic", "Crazy India"],
mode : "Classic",
colors : ["blue", "yellow", "green", "red"],
pieces : [],
players : [],
baseURL : false,
dice : {
// Würfel-Objekt
roll : function (animated, override) {
var t = MAEDN;
this.value = Math.floor(Math.random() *6) +1;
if (override) this.value = override;
this.busy = 1;
if (animated) {
if (t.game.currentPlayer.isHumanPlayer) {
this.element.className = this.element.className.replace(
/(value\d|rolling)/i, "rolling"
);
this.busy = 1 + t.game.animationSpeed * 37;
} else {
this.element.className = this.element.className.replace(
/(value\d|rolling)/i, "value" + this.value
);
this.busy = 1 + t.game.animationSpeed * 20;
}
}
returnthis.value;
},
animate : function () {
this.busy --;
if (!this.busy) {
this.element.className = this.element.className.replace(
/(value\d|rolling)/i, "value" + this.value
);
MAEDN.game.nextStep();
}
},
makeUsable : function () {
this.isUsable = true;
this.element.className += " usable";
},
unmakeUsable : function () {
this.isUsable = false;
this.element.className = this.element.className.replace(/ usable/i, "");
},
value : 0, // Anfangswert
busy : 0, // Würfel nicht animiert
isUsable : false, // Würfel zunächst unbenutzbar machen
element : false// wird ersetzt durch <span>-Element
},
field : {
// Objekt für das Spielfeld
waypoints : [
{ name:"wp_000", x:36, y:191, nextWP: "wp_001" },
{ name:"wp_001", x:75, y:191, nextWP: "wp_002" },
{ name:"wp_002", x:113, y:191, nextWP: "wp_003" },
{ name:"wp_003", x:152, y:191, nextWP: "wp_004" },
{ name:"wp_004", x:191, y:191, nextWP: "wp_005" },
{ name:"wp_005", x:191, y:152, nextWP: "wp_006" },
{ name:"wp_006", x:191, y:113, nextWP: "wp_007" },
{ name:"wp_007", x:191, y:75, nextWP: "wp_008" },
{ name:"wp_008", x:191, y:36, nextWP: "wp_009" },
{ name:"wp_009", x:230, y:36, nextWP: "wp_010" },
{ name:"wp_010", x:268, y:36, nextWP: "wp_011" },
{ name:"wp_011", x:268, y:74, nextWP: "wp_012" },
{ name:"wp_012", x:268, y:113, nextWP: "wp_013" },
{ name:"wp_013", x:268, y:152, nextWP: "wp_014" },
{ name:"wp_014", x:268, y:191, nextWP: "wp_015" },
{ name:"wp_015", x:307, y:191, nextWP: "wp_016" },
{ name:"wp_016", x:346, y:191, nextWP: "wp_017" },
{ name:"wp_017", x:385, y:191, nextWP: "wp_018" },
{ name:"wp_018", x:423, y:191, nextWP: "wp_019" },
{ name:"wp_019", x:423, y:230, nextWP: "wp_020" },
{ name:"wp_020", x:423, y:268, nextWP: "wp_021" },
{ name:"wp_021", x:385, y:268, nextWP: "wp_022" },
{ name:"wp_022", x:346, y:268, nextWP: "wp_023" },
{ name:"wp_023", x:307, y:268, nextWP: "wp_024" },
{ name:"wp_024", x:268, y:268, nextWP: "wp_025" },
{ name:"wp_025", x:268, y:307, nextWP: "wp_026" },
{ name:"wp_026", x:268, y:346, nextWP: "wp_027" },
{ name:"wp_027", x:268, y:385, nextWP: "wp_028" },
{ name:"wp_028", x:268, y:423, nextWP: "wp_029" },
{ name:"wp_029", x:230, y:423, nextWP: "wp_030" },
{ name:"wp_030", x:191, y:423, nextWP: "wp_031" },
{ name:"wp_031", x:191, y:385, nextWP: "wp_032" },
{ name:"wp_032", x:191, y:346, nextWP: "wp_033" },
{ name:"wp_033", x:191, y:307, nextWP: "wp_034" },
{ name:"wp_034", x:191, y:268, nextWP: "wp_035" },
{ name:"wp_035", x:152, y:268, nextWP: "wp_036" },
{ name:"wp_036", x:113, y:268, nextWP: "wp_037" },
{ name:"wp_037", x:75, y:268, nextWP: "wp_038" },
{ name:"wp_038", x:36, y:268, nextWP: "wp_039" },
{ name:"wp_039", x:36, y:230, nextWP: "wp_000" }
],
homes : {
blue : {
seats : [
{ name:"wp_040", x:84, y:423 },
{ name:"wp_041", x:36, y:423 },
{ name:"wp_042", x:84, y:375 },
{ name:"wp_043", x:36, y:375 }
],
startingPoint : "wp_030",
goals : [
{ name:"wp_056", x:231, y:382 },
{ name:"wp_057", x:231, y:353 },
{ name:"wp_058", x:231, y:324 },
{ name:"wp_059", x:231, y:295 }
],
exit : "wp_029",
highlighter : {
element : false
}
},
yellow : {
seats : [
{ name:"wp_044", x:36, y:84 },
{ name:"wp_045", x:36, y:35 },
{ name:"wp_046", x:84, y:84 },
{ name:"wp_047", x:84, y:35 }
],
startingPoint : "wp_000",
goals : [
{ name:"wp_060", x:74, y:229 },
{ name:"wp_061", x:103, y:229 },
{ name:"wp_062", x:132, y:229 },
{ name:"wp_063", x:161, y:229 }
],
exit : "wp_039",
highlighter : {
element : false
}
},
green : {
seats : [
{ name:"wp_048", x:375, y:35 },
{ name:"wp_049", x:423, y:35 },
{ name:"wp_050", x:375, y:84 },
{ name:"wp_051", x:423, y:84 }
],
startingPoint : "wp_010",
goals : [
{ name:"wp_064", x:231, y:73 },
{ name:"wp_065", x:231, y:103 },
{ name:"wp_066", x:231, y:132 },
{ name:"wp_067", x:231, y:162 }
],
exit : "wp_009",
highlighter : {
element : false
}
},
red : {
seats : [
{ name:"wp_052", x:424, y:375 },
{ name:"wp_053", x:424, y:423 },
{ name:"wp_054", x:375, y:375 },
{ name:"wp_055", x:375, y:423 }
],
startingPoint : "wp_020",
goals : [
{ name:"wp_068", x:386, y:229 },
{ name:"wp_069", x:357, y:229 },
{ name:"wp_070", x:328, y:229 },
{ name:"wp_071", x:299, y:229 }
],
exit : "wp_019",
highlighter : {
element : false
}
}
},
winnerIcons : [],
endDisplay : false,
settings : false,
connectWaypoints : function () {
// String-Wert der "next"-Eigenschaft der Wegpunkte durch passende Objekte ersetzenvar colors = MAEDN.colors,
i, w, s;
// Wegpunkte des Parcoursfor (w = 0; w < this.waypoints.length; w++) {
for (i = 0; i < this.waypoints.length; i++) {
if (this.waypoints[w].nextWP == this.waypoints[i].name) {
this.waypoints[w].nextWP = this.waypoints[i];
}
}
// Wegpunkte der Startfelder der Spieler mit "Einstiegs-Waypoint" verknüpfenfor (i = 0; i < 4; i++) {
if (this.homes[colors[i]].startingPoint == this.waypoints[w].name) {
// Namen durch Referenz auf objekt ersetzenthis.homes[colors[i]].startingPoint = this.waypoints[w];
for (s = 0; s < 4; s++) {
this.homes[colors[i]].seats[s].nextWP = this.waypoints[w];
}
}
// "Ausstieg" mit Referenz verknüpfenif (this.homes[colors[i]].exit == this.waypoints[w].name) {
this.homes[colors[i]].exit = this.waypoints[w];
}
}
}
// Zielfelder verknüpfenfor (i = 0; i < 4; i++) {
for (w = 0; w < 3; w++) {
this.homes[colors[i]].goals[w].nextWP = this.homes[colors[i]].goals[w+1];
}
}
},
element : false// hier steht später ein <p>-Element
},
init : function () {
// Code, der noch vor dem vollständigen Laden ausgeführt wirdvar oldwinonload = window.onload,
s = document.getElementsByTagName("script"),
i;
for (i = 0; i < s.length; i++) {
if (s[i].src && s[i].src.match(/\/maedn\.js/i)) {
this.baseURL = s[i].src.replace(/\/maedn\.js.*/i, "");
}
}
window.onload = function () {
if (typeof oldwinonload == "function") {
oldwinonload();
}
MAEDN.onLoad(); // onLoad-Methode des MAEDN-Objektes ausführen
};
},
onLoad : function () {
// Code, der nach dem vollständigen Laden ausgeführt wirdvar t = this, // für Closure benötigt
colors = ["modrý","žltý","zelený","červený"],
s, i;
// "contains"-Methode für Arrays nachrüsten, falls diese im Browser fehltif (!Array.contains) {
Array.prototype.contains = function (o) {
var i;
for (i inthis) {
if (this[i] == o) {
returntrue;
}
}
returnfalse;
}
}
// "getLast"-Methode für Arrays nachrüstenif (!Array.getLastElement) {
Array.prototype.getLastElement = function () {
returnthis[this.length -1];
}
}
// CSS-Datei nachladen:document.getElementsByTagName("head")[0].appendChild(
t.createHTMLElement({
// <link rel="stylesheet" type="text/css" href="nehnevajsa.css" />
tagName : "link",
rel : "stylesheet",
type : "text/css",
href : "nehnevajsa.css"
})
);
// Hinweise auf benötigtes JavaScript entfernen
s = t.getElementsByClassName("javascript.*");
for (i = 0; i < s.length; i++) {
if (s[i].parentNode) {
s[i].parentNode.removeChild(s[i]);
}
}
// Spielfeld
t.field.element = t.createHTMLElement({
tagName : "p",
id : "field"
});
document.body.appendChild(t.field.element);
t.field.connectWaypoints(); // Wegpunkte verketten// Schriftzug "Človeče, nehnevaj sa!" (<span>)
t.field.element.appendChild(
t.createHTMLElement({
tagName : "span",
id : "name",
textNode : "Človeče, nehnevaj sa!"
})
);
// Würfel
t.dice.element = t.createHTMLElement({
tagName : "span",
id : "dice",
className : "value0",
onclick : function () {
if (t.dice.isUsable) {
t.dice.unmakeUsable();
t.dice.roll(true); // true = "mit Animation"
}
}
});
t.field.element.appendChild(t.dice.element);
// Einstellungen (<span>)
t.field.settings = t.createHTMLElement({
tagName : "span",
id : "settings"
});
t.field.element.appendChild(t.field.settings);
// Einstellungen Mensch oder Computer als Spieler
t.field.settings.appendChild(
t.createHTMLElement({
tagName : "span",
id : "players"
})
);
for (i = 0; i < 4; i++) {
t.field.settings.lastChild.appendChild(
t.createHTMLElement({
tagName : "span",
className : t.colors[i],
text : colors[i] + " "
})
);
t.field.settings.lastChild.lastChild.appendChild(
t.createHTMLElement({
tagName : "select"
})
);
t.field.settings.lastChild.lastChild.lastChild.appendChild(
t.createHTMLElement({
tagName : "option",
value : "computer",
text : "Počítač"
})
);
t.field.settings.lastChild.lastChild.lastChild.appendChild(
t.createHTMLElement({
tagName : "option",
value : "human",
text : "Človek",
selected : (i == 0 || i==1 || i==2 || i==3 ? "selected" : "")
})
);
t.field.settings.lastChild.lastChild.lastChild.appendChild(
t.createHTMLElement({
tagName : "option",
value : "-- N/A --",
text : "-- nikto --"
})
);
}
// Einstellung für den Schlagzwang
t.field.settings.appendChild(t.createHTMLElement({
tagName : "span",
id : "force-removal"
}));
t.field.settings.lastChild.appendChild(t.createHTMLElement({
tagName : "input",
id : "force-removal-checkbox",
type : "checkbox",
checked : "checked"
}));
t.field.settings.lastChild.appendChild(t.createHTMLElement({
tagName : "label",
htmlFor : "force-removal-checkbox",
text : " Schlagzwang"
}));
// Auswahl der Spieltypen
t.field.settings.appendChild(
t.createHTMLElement({
tagName : "span",
id : "game-type",
text : "Typ hry: "
})
);
s = t.createHTMLElement({ tagName : "select" });
for (i = 0; i < t.variants.length; i++) {
s.appendChild(
t.createHTMLElement({
tagName : "option",
value : t.variants[i],
text : t.variants[i]
})
);
}
t.field.settings.lastChild.appendChild(s);
t.field.settings.lastChild.appendChild(
t.createHTMLElement({
tagName : "button",
text : "Nová hra!",
onclick : function () { t.game.setup(); }
})
);
t.field.settings.lastChild.appendChild(
t.createHTMLElement({
tagName : "button",
text : "Ďalší hráč!",
onclick : function () { }
})
);
// Einstellung für die Animationsgeschwindigkeit
t.field.settings.appendChild(t.createHTMLElement({
tagName : "span",
id : "animations",
text : "Animácie: "
}));
s = t.createHTMLElement({
tagName : "select",
onchange : function () { MAEDN.game.animationSpeed = Math.floor(this.value); }
});
for (i = 0; i < 3; i++) {
s.appendChild(
t.createHTMLElement({
tagName : "option",
value : 2 - i,
text : ["normálne","rýchle","žiadne"][i]
})
);
}
t.field.settings.lastChild.appendChild(s);
for (i = 0; i < 4; i++) {
// Player
t.players[i] = new t.Player(i);
}
for (i = 0; i < 16; i++) {
// Spielsteine anlegen
t.pieces.push(new t.Piece());
}
for (i = 0; i < 3; i++) {
// Icons für Gewinner anlegen
t.field.winnerIcons.push(
t.createHTMLElement({
tagName : "span",
className : "winner-icon " + ["first","second","third"][i]
})
);
t.field.element.appendChild(t.field.winnerIcons.getLastElement());
}
t.field.endDisplay = t.createHTMLElement({
tagName : "span",
id : "end-display"
});
t.field.element.appendChild(t.field.endDisplay);
// Grafiken nachladen
t.preloader.prepare();
// "Herzschlag" für Animationen einrichten
window.setInterval(function () { t.heartbeat(); }, 10);
},
preloader : {
xhr : false,
images : [],
element : false,
bar : false,
count: 0,
prepare : function () {
var t = MAEDN,
_t = this,
i, s;
//natives XMLHttpRequest objectif (window.XMLHttpRequest) {
try {
this.xhr = new XMLHttpRequest();
} catch (e) {}
//für IE/Windows
} elseif (window.ActiveXObject) {
try {
this.xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
this.xhr = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (this.xhr) {
this.xhr.onreadystatechange = function () {
if (_t.xhr.readyState == 4 && _t.xhr.responseText.length > 50) {
_t.load();
}
};
this.xhr.open("get", t.baseURL + "/nehnevajsa.css", true);
this.xhr.send();
}
},
load : function () {
var t = MAEDN,
_t = this,
buttons = document.getElementsByTagName("button"),
images = this.xhr.responseText.match(/url\(([^})])+\)/ig),
i, images, g;
if (images.length) {
for (i = 0; i < buttons.length; i++) {
buttons[i].disabled = "disabled";
}
this.element = t.createHTMLElement({
tagName : "span",
id : "preloader",
text : "Grafiken werden geladen..."
});
t.field.element.appendChild(this.element);
this.bar = t.createHTMLElement({
className : "bar",
tagName : "span",
text : "0%"
});
this.element.appendChild(this.bar);
this.bar.insertBefore(t.createHTMLElement({ tagName : "span" }), this.bar.firstChild);
for (i = 0; i < images.length; i++) {
g = images[i].replace(/[^\(]+\(([^\)]+)\).*/, "$1");
this.images.push(this.url + g.replace(/^\.\//, ""));
}
g = function () { _t.count++; _t.loadNext(); };
for (i = 0; i < this.images.length; i++) {
this.images[i] = t.createHTMLElement({
tagName : "img",
src : this.images[i],
onload : g,
onerror : g
});
if (this.images[i].width) {
g();
}
}
}
},
loadNext : function () {
var p = Math.floor(100 * this.count / (this.images.length -1));
this.bar.firstChild.style.width = Math.floor(p) + "%";
this.bar.lastChild.data = p + "%";
if (this.count == this.images.length -1) {
this.finish();
}
},
finish : function () {
var buttons = document.getElementsByTagName("button"),
i;
for (i = 0; i < buttons.length; i++) {
buttons[i].disabled = "";
}
this.element.style.display = "none";
}
},
game : {
steps : ["determineMaxDiceRolls", "rollDice", "movePiece", "removeOpponentPiece"],
currentStep : 0,
initialNumberOfPlayers : 0,
currentPlayer : false,
isRunning : false,
isWaiting : false,
animationSpeed : 2,
forceRemoval : true,
lastMovedPiece : false,
removedPiece : false,
setup : function () {
var t = MAEDN,
sel = document.getElementById("players").getElementsByTagName("select"),
i, p;
// Winner-Icons zurücksetzenfor (i = 0; i < t.field.winnerIcons.length; i++) {
t.field.winnerIcons[i].className = t.field.winnerIcons[i].className.replace(
new RegExp(" (" + t.colors.join("|") + ")", "gi"), ""
);
}
// Spieltyp einstellen
t.mode = document.getElementById("game-type").getElementsByTagName("select")[0].value;
// schlagzwang einstellenthis.forceRemoval = document.getElementById("force-removal-checkbox").checked;
// Für jeden Player einstellen ...for (p = 0; p < 4; p++) {
// ... ob er mitspielt
t.players[p].isParticipating = (sel[p].value.match(/^[a-z]/i) ? true: false);
// ... ob er ein menschlicher Spieler ist
t.players[p].isHumanPlayer = (sel[p].value.match(/^human/i) ? true: false);
// ... wie seine vier Spielsteine gefärbt sindfor (i = 0; i < 4; i++) {
t.pieces[p*4 +i].hide();
// ... wenn er mitspieltif (t.players[p].isParticipating) {
// Spielstein einfärbenif (t.mode.match(/^crazy india$/i)) {
t.pieces[p*4 + i].color = t.colors[i];
t.pieces[p*4 + i].element.className = "piece " + t.colors[i];
}
if (t.mode.match(/^classic$/i)) {
t.pieces[p*4 + i].color = t.colors[p];
t.pieces[p*4 + i].element.className = "piece " + t.colors[p];
}
// Spielstein auf Startposition schicken
t.pieces[p*4 + i].positionElement({
x : Math.floor(t.field.element.offsetWidth /2),
y : Math.floor(t.field.element.offsetHeight /2)
});
t.pieces[p*4 + i].waypoints.push(
t.field.homes[t.colors[p]].seats[i]
);
t.pieces[p*4 + i].setMoving();
} else {
// ... wenn er nicht mitspielt: Spielsteine unsichtbar machen
t.pieces[p*4 + i].color = "none";
t.pieces[p*4 + i].element.className = "piece none";
}
}
}
p = 0; // Anzahl teilnehmender Spielerfor (i = 0; i < t.players.length; i++) {
if (t.players[i].isParticipating) {
p++;
}
}
if (p > 1) {
// Jetzt kann das Spiel losgehen!
t.game.isWaiting = false;
t.game.currentStep = 0;
t.game.currentPlayer = false;
t.game.isRunning = true;
t.dice.value = 0;
t.dice.element.className = "value0";
t.game.initialNumberOfPlayers = p;
t.field.endDisplay.className = "";
} else {
// zu wenig Mitspieler!for (i = 0; i < t.pieces.length; i++) {
t.pieces[i].hide();
}
alert("Zuwenig Mitspieler!");
}
},
nextStep : function () {
var t = MAEDN,
receivingPlayers = [],
i, p, movablePieces, rest, maxPossible, goalsPieces;
this.isRunning = true;
if (!this.currentPlayer || !this.currentPlayer.isParticipating) {
// gültigen Spieler sicherstellenthis.currentPlayer = this.getNextPlayer();
}
switch (this.currentStep) {
// maximale Würfelanzahl des Spielers ermittelncase0:
this.currentPlayer.maxDiceRolls = 1;
t.dice.value = 0;
t.dice.element.className = "value0 " + this.currentPlayer.color;
if (this.currentPlayer.getGoalsPieces().length
+ this.currentPlayer.getHomePieces().length
== 4
) {
// Player hat keine Spielsteine "unterwegs"!
maxPossible = true;
rest = 4 - this.currentPlayer.getGoalsPieces().length;
for (i = 0; i < rest; i++) {
// Hat er alle Spielsteine im Ziel in lückenloser Aufstellung "von oben"?for (p = 0; p < t.pieces.length; p++) {
if (t.field.homes[this.currentPlayer.color].goals[i]
== t.pieces[p].lastWaypoint
) {
maxPossible = false;
}
}
}
if (maxPossible) {
this.currentPlayer.maxDiceRolls = 3;
}
}
this.currentStep++;
break;
// Player beginnt seine Runde -> würfeln lassencase1:
if (this.currentPlayer.isHumanPlayer) {
t.dice.makeUsable();
this.isWaiting = true;
} else {
t.dice.roll(true);
}
this.currentStep++;
break;
// Player hat gewürfelt -> auswertencase2:
// kann der Player eine Figur spielen?
movablePieces = this.currentPlayer.getMovablePieces();
if (!movablePieces.length) {
// neinif (t.dice.value > 6) {// zrebny povodne tu bolo != 6if (this.currentPlayer.isHumanPlayer && this.currentPlayer.maxDiceRolls == 1) {
// menschlichem Spieler die Chance geben, seine letzte Würfelzahl zu sehenthis.currentPlayer.maxDiceRolls--;
this.isWaiting = true;
setTimeout(
function () {
MAEDN.game.isWaiting = false;
}, 1 + this.animationSpeed * 500
);
return;
} else {
this.currentPlayer.maxDiceRolls--;
this.currentStep = 1;
this.isWaiting = false;
if (this.currentPlayer.maxDiceRolls < 1) {
this.currentPlayer = this.getNextPlayer();
this.currentStep = 0;
}
}
} else {
/* Spieler kann zwar die gewürfelte sechs nicht umsetzen,
darf aber nochmal würfeln */this.currentStep = 1;
this.isWaiting = false;
}
} else {
// ja, kann erif (!this.currentPlayer.isHumanPlayer) {
// automatisch spielen
p = Math.floor(Math.random() * movablePieces.length);
movablePieces[p].makeMove();
} else {
this.isWaiting = true;
for (p = 0; p < movablePieces.length; p++) {
// spielbare Steine markieren
movablePieces[p].makeUsable();
}
}
this.currentStep++;
}
break;
// Player hat gezogen -> wie weiter verfahren?case3:
for (i = 0; i < t.pieces.length; i++) {
if (t.game.lastMovedPiece != t.pieces[i]
&& t.game.lastMovedPiece.lastWaypoint == t.pieces[i].lastWaypoint
) {
this.removedPiece = t.pieces[i];
}
}
if (this.removedPiece) {
// Spieler ermitteln, der den Spielstein entgegennehmen mussfor (p = 0; p < t.players.length; p++) {
if (t.players[p] != t.game.currentPlayer
&& t.players[p].isParticipating
&& t.players[p].canTakeBackPiece(this.removedPiece)
) {
receivingPlayers.push(t.players[p]);
}
}
if (receivingPlayers.length < 2 || !this.currentPlayer.isHumanPlayer) {
receivingPlayers[
Math.floor(Math.random() * receivingPlayers.length)
].receivePiece();
} else {
/* menschlichen Spieler auswählen lassen, an welchen
Mitspieler der Spielstein zurück gehen soll */for (p = 0; p < receivingPlayers.length; p++) {
receivingPlayers[p].activateHoverElement();
this.isWaiting = true;
}
}
}
goalsPieces = this.currentPlayer.getGoalsPieces();
if (goalsPieces.length > 3) {
// Gewinner markieren
i = 0;
while (i < 3
&& i < this.initialNumberOfPlayers -1
&& t.field.winnerIcons[i].className.match(
new RegExp(" ("+t.colors.join("|")+")", "ig")
)
) {
i++;
}
if (i < 3 && i < this.initialNumberOfPlayers -1) {
t.field.winnerIcons[i].className += " " + this.currentPlayer.color;
}
this.currentPlayer.isParticipating = false;
}
if (this.getParticipatingPlayers().length < 2) {
// Spielendethis.isRunning = false;
t.field.endDisplay.className = "active";
}
if (t.dice.value == 6) {
// Spieler darf nochmal!this.maxDiceRolls = 1;
this.currentStep = 1;
} else {
this.currentPlayer = this.getNextPlayer();
this.currentStep = 0;
}
break;
}
},
getNextPlayer : function () {
var t = MAEDN,
nextPlayer = this.currentPlayer || t.players[0],
i = 0;
if (this.currentPlayer) {
while (t.players[i] != this.currentPlayer) {
i++;
}
while (nextPlayer == this.currentPlayer || !nextPlayer.isParticipating) {
i++;
if (i == t.players.length) {
i = 0;
}
nextPlayer = t.players[i];
}
}
return nextPlayer;
},
getParticipatingPlayers : function () {
var t = MAEDN,
participating = [],
i;
for (i = 0; i < t.players.length; i++) {
if (t.players[i].isParticipating) {
participating.push(t.players[i]);
}
}
return participating;
}
},
heartbeat : function () {
// Herzschlag für Animationen (prüft, wer bewegt werden muss)var t = this,
passive = true,
i;
if (t.game.isRunning) {
for (i = 0; i < t.pieces.length; i++) {
// Spielsteine animierenif (t.pieces[i].isMoving) {
t.pieces[i].move();
t.game.lastMovedPiece = t.pieces[i];
passive = false;
}
}
if (t.dice.busy) {
// Würfel animieren
t.dice.animate();
passive = false;
}
if (passive && !t.game.isWaiting) {
t.game.nextStep();
}
}
},
Piece : function () {
// Konstruktor-Funktion zum Bauen eines Spielstein-Objektesvar t = MAEDN,
_t = this;
this.color = "none";
// HTML-Element (<span>) erzeugen und gleich ins Spielfeld einhängenthis.element = t.createHTMLElement({
tagName : "span",
className : "piece none",
onclick : function (e) {
var p;
if (_t.isUsable) {
t.game.isWaiting = false;
_t.makeMove();
for (p = 0; p < t.pieces.length; p++) {
t.pieces[p].unmakeUsable();
}
}
}
});
t.field.element.appendChild(this.element);
// Koordinaten innerhalb des Spielfeldsthis.x = 1;
this.y = 1;
this.waypoints = []; // hier stehen später waypoint-Objektethis.lastWaypoint = false;
this.steps = []; // {x:n, y:n} (Zwischensschritte bis zum nächsten Wegpunkt)this.isMoving = false; // steuert, ob die heartbeat-Funktion den Spielstein bewegen darfthis.willRemove = false; // Referenz auf einen Spielstein der geschlagen wirdthis.plotCourse = function () {
// Pfad für Spielstein zusammenstellenvar course = [], // Liste der Wegpunkte für diesen Spielstein
currentWP = this.lastWaypoint,
stepsLeft = t.dice.value,
player = t.game.currentPlayer,
mayMove, i, p;
while (stepsLeft) {
// Waypoints kennen ihre jeweiligen nächsten Nachbarnif (currentWP.nextWP) {
// es gibt also einen erreichbaren Nachbarn -> nutzen!if (currentWP == t.field.homes[player.color].exit) {
// Abzweigung zu den Zielplätzen? -> ersten Zielplatz statt Nachbarn benutzen
currentWP = t.field.homes[player.color].goals[0];
} else {
currentWP = currentWP.nextWP;
}
course.push(currentWP);
} else {
// keine erreichbaren Nachbarn, Würfelzahl kann nicht ausgenutzt werden!
stepsLeft = 1;
course = [];
}
if (stepsLeft == 1 && t.field.homes[player.color].goals.contains(currentWP)) {
// In den Zielfeldern kann man keine belegten Felder besetzen!for (p = 0; p < t.pieces.length; p++) {
if (t.pieces[p].lastWaypoinbt == currentWP) {
course = [];
}
}
}
stepsLeft--;
}
return course;
};
this.positionElement = function (pos) {
// Spielstein auf gegebenen Koordinaten im Spielfeld anzeigenvar x, y;
if (pos) {
// Sind der Funktion Koordinaten übergeben worden?this.x = pos.x;
this.y = pos.y;
}
x = this.x || this.steps[0].x;
y = this.y || this.steps[0].y;
this.element.style.left = Math.floor(x - this.element.offsetWidth / 2) + "px";
this.element.style.top = Math.floor(y - this.element.offsetHeight / 2) + "px";
};
this.move = function () {
// Funktion für einen Schrittvar piece = this,
steps = [],
dx, dy, x, y, end, test, i;
if (t.game.animationSpeed) {
if (this.steps.length > 0) {
// Schritt ausführenthis.x = this.steps[0].x;
this.y = this.steps[0].y;
this.positionElement();
this.steps.shift(); // ersten Schritt entfernen, denn er wurde gerade gegangen
} else {
// keine Schritte mehr übrig! -> neue Schritte zum nächsten Wegpunkt erstellenif (this.waypoints.length > 0) {
// es gibt noch zu erreichende Wegpunktethis.lastWaypoint = this.waypoints.shift();
if (t.game.animationSpeed > 1) {
// neue Schritte erstellen
x = this.lastWaypoint.x - this.x;
y = this.lastWaypoint.y - this.y;
end = Math.abs(x);
test = Math.abs(y);
end = end > test ? end : test;
i = 0;
while (i <= end) {
dx = this.x + Math.floor(
i * (this.lastWaypoint.x - this.x) / end
);
dy = this.y + Math.floor(
i * (this.lastWaypoint.y - this.y) / end
);
this.steps.push({x:dx, y:dy});
if (end > 80) {
i = (!i ? 1 : i+4);
} else {
i++;
}
}
this.steps.push(this.lastWaypoint);
} else {
for (x = 0; x < 10; x++) {
this.steps.push(this.lastWaypoint);
}
}
} else {
// Keine Wegpunkte mehr zu erreichen und keine Schritte mehr auszuführenthis.unsetMoving();
}
}
} else {
if (this.waypoints.length) {
this.lastWaypoint = this.waypoints.getLastElement();
this.steps = [];
}
if (this.steps.length) {
this.lastWaypoint = this.steps.getLastElement();
}
this.steps = [];
this.waypoints = [];
this.positionElement(this.lastWaypoint);
this.unsetMoving();
}
};
this.makeMove = function () {
var i, p;
// mit dieser Spielfigur einen Zug ausführenif (t.field.homes[t.game.currentPlayer.color].seats.contains(this.lastWaypoint)) {
// Figur von Home auf Startposition bringenthis.waypoints.push(t.field.homes[t.game.currentPlayer.color].startingPoint);
} else {
// Figur im Parcours oder auf den Zielfeldern bewegenthis.waypoints = this.plotCourse();
}
for (i = 0; i < t.pieces.length; i++) {
// falls ein anderer Spielstein geschlagen werden soll, diesen als ängstlich markierenif (this.waypoints.getLastElement() == t.pieces[i].lastWaypoint) {
t.pieces[i].element.className += " afraid";
}
}
this.setMoving();
};
this.setMoving = function () {
// Spielstein für Animationen beweglich machenthis.isMoving = true;
this.element.className += " moving";
};
this.unsetMoving = function () {
var i;
this.isMoving = false;
this.element.className = this.element.className.replace(/ (moving|afraid)/ig, "");
if (t.game.currentPlayer) {
for (i = 0; i < t.field.homes[t.game.currentPlayer.color].goals.length; i++) {
if (t.field.homes[t.game.currentPlayer.color].goals.contains(this.lastWaypoint)
&& !this.element.className.match(/ home/i)
) {
this.element.className += " home";
}
}
}
if (this.willRemove) {
t.game.removedPiece = this.willRemove;
this.willRemove = false;
}
};
this.makeUsable = function () {
// Spielstein für menschlichen Spieler anklickbar machenthis.isUsable = true;
this.element.className += " usable";
};
this.unmakeUsable = function () {
this.isUsable = false;
this.element.className = this.element.className.replace(/ usable/gi, "");
};
this.hide = function () {
// Spielstein unsichtbar machen (hat danach keine Farbe mehr!)this.isMoving = false;
this.color = "none";
this.element.className = "piece none";
this.waypoints = [];
this.steps = [];
this.lastWaypoint = false;
};
// Element positionierenthis.positionElement();
},
Player : function (params) {
// Konstruktor-Funktion zum Bauen eines Player-Objektesvar t = MAEDN,
_t = this;
this.color = t.colors[params];
this.isHumanPlayer = false; // von einem Computerspieler ausgehenthis.isParticipating = false; // spielt mit?this.maxDiceRolls = 3; // Anzahl Würfelversuchethis.isActive = false; // zeigt an, ob Spieler "am Zug" istthis.hoverElement = t.createHTMLElement({
tagName : "span",
className : "home-hover " + t.colors[params],
onclick : function () {
var i;
_t.receivePiece(t.game.removedPiece);
t.game.removedPiece = false;
for (i = 0; i < t.players.length; i++) {
t.players[i].deactivateHoverElement();
}
}
});
t.field.element.appendChild(this.hoverElement);
this.getHomePieces = function () {
// Liste der eigenen noch nicht ins Spiel gebrachten Spielsteine ermittelnvar pieces = [],
i, wp;
// alle Spielsteine prüfenfor (i = 0; i < t.pieces.length; i++) {
// die home-Positionen des Spielers prüfenfor (wp = 0; wp < t.field.homes[this.color].seats.length; wp++) {
// Spielstein sitzt zuhause?if (t.pieces[i].lastWaypoint == t.field.homes[this.color].seats[wp]) {
pieces.push(t.pieces[i]);
}
}
}
return pieces;
};
this.getGoalsPieces = function () {
// Liste der bereits erfolgreich in die Zielfelder gebrachten Spielsteine ermittelnvar pieces = [],
i, wp;
// alle Spielsteine prüfenfor (i = 0; i < t.pieces.length; i++) {
// die home-Positionen des Spielers prüfenfor (wp = 0; wp < t.field.homes[this.color].goals.length; wp++) {
// Spielstein sitzt im Ziel?if (t.pieces[i].lastWaypoint == t.field.homes[this.color].goals[wp]) {
pieces.push(t.pieces[i]);
}
}
}
return pieces;
};
this.getMovablePieces = function () {
// "t" ist von weiter oben her noch bekannt! ("Closure")var piecesAtHome = this.getHomePieces(),
piecesInGoals = this.getGoalsPieces(),
runningPieces = [],
activeColors = this.getColorsOfActivePieces(),
otherPlayersActiveColors = [],
movablePieces = [],
i, p, pl, occupied, possible, canRemove;
for (p = 0; p < t.players.length; p++) {
// aktive Farben der anderen Spieler ermittelnif (t.players[p] != this && t.players[p].isParticipating) {
otherPlayersActiveColors = otherPlayersActiveColors.concat(
t.players[p].getColorsOfActivePieces()
);
}
}
for (i = 0; i < t.pieces.length; i++) {
// für den Spieler verfügbare Spielsteine im Parcours und den Zielfeldern ermittelnif (
(t.field.waypoints.contains(t.pieces[i].lastWaypoint)
&& activeColors.contains(t.pieces[i].color)
) || (
t.field.homes[this.color].goals.contains(t.pieces[i].lastWaypoint)
)) {
runningPieces.push({
piece : t.pieces[i], // Referenz auf Spielstein
course : t.pieces[i].plotCourse(), // Liste an Waypoints
canRemovePiece : false// kann anderen Spielstein schlagen
});
}
}
for (i = runningPieces.length - 1; i >= 0; i--) {
// prüfen, ob die verfügbaren Spielsteine gültige Züge ausführen können
possible = true;
if (runningPieces[i].course.length < 1) {
// kein Feld mit allen Würfelaugen erreichbar
possible = false;
} else {
// gültiger Spielzug möglichfor (p = 0; p < t.pieces.length; p++) {
// welcher Spielstein kann einen anderen schlagen?if (runningPieces[i].course.getLastElement() == t.pieces[p].lastWaypoint) {
runningPieces[i].canRemovePiece = t.pieces[p];
}
}
if (runningPieces[i].canRemovePiece) {
// der schlagbare Spielstein darf kein eigener sein!if (!otherPlayersActiveColors.contains(runningPieces[i].canRemovePiece.color)
|| t.field.homes[this.color].goals.contains(
runningPieces[i].canRemovePiece.lastWaypoint
)
) {
possible = false;
}
}
}
if (!possible) {
runningPieces.splice(i, 1);
}
}
// Würfelergebnis umsetzenif (t.dice.value == 6) {
/* auf den Start wartende Spielsteine benutzen wenn
Startpunkt von keinem eigenen Stein besetzt wird */
occupied = false;
for (i = 0; i < t.pieces.length; i++) {
if (t.pieces[i].lastWaypoint == t.field.homes[this.color].startingPoint) {
occupied = t.pieces[i];
}
}
if (!occupied
||
(occupied && otherPlayersActiveColors.contains(occupied.color))
) {
for (i = 0; i < piecesAtHome.length; i++) {
movablePieces[i] = piecesAtHome[i]; // Array umkopieren!
}
}
}
if (!movablePieces.length) {
// keine 6 gewürfelt, oder keine Spielsteine zum Einsteigen übrigfor (i = 0; i < runningPieces.length; i++) {
/* nur Spielsteine in Erwägung ziehen, die entweder aus dem Parcours
heraus auf ein Zielfeld gelangen können, oder die einen anderen
Spielstein schlagen können */if (runningPieces[i].canRemovePiece
||
(t.field.waypoints.contains(runningPieces[i].piece.lastWaypoint)
&& t.field.homes[this.color].goals.contains(
runningPieces[i].course.getLastElement()
)
)
) {
movablePieces.push(runningPieces[i].piece);
if (runningPieces[i].canRemovePiece) {
canRemove = true;
}
}
}
if (!canRemove || !movablePieces.length || !t.game.forceRemoval) {
/* Wenn kein Spielstein ins Ziel kann und auch kein anderer Spielstein
geschlagen werden kann, dann darf irgendein Spielstein verwendet werden,
der die gewürfelte Zahl Schritte zurücklegen kann.
Bei fehlendem Schlagzwang darf sowieso jeder mögliche Stein gespielt werden. */for (i = 0; i < runningPieces.length; i++) {
movablePieces.push(runningPieces[i].piece);
}
}
}
if (movablePieces.length) {
/* Wenn ein "eigener" Spielstein auf dem Startfeld steht während noch andere
"in den Startlöchern" stehen, und wenn kein anderer Mitspieler diesen
Stein als seinen eigenen benutzen kann, dann muss dieser Stein wegbewegt
werden, anstatt dass ein neuer Stein ins Spiel gebracht werden kann. */for (i = 0; i < runningPieces.length; i++) {
if (runningPieces[i].piece.lastWaypoint == t.field.homes[this.color].startingPoint
&& !otherPlayersActiveColors.contains(runningPieces[i].piece.color)
&& piecesAtHome.length
) {
movablePieces = [runningPieces[i].piece];
}
}
}
return movablePieces;
};
this.getColorsOfActivePieces = function () {
var pieces = [],
activeColors = [],
i, c;
if (t.mode.match(/^classic/i)) {
activeColors.push(this.color);
}
if (t.mode.match(/^crazy india/i)) {
pieces = this.getHomePieces().concat(this.getGoalsPieces());
for (i = 0; i < t.colors.length; i++) {
// Farb-Array kopieren!
activeColors[i] = t.colors[i];
}
for (i = 0; i < pieces.length; i++) {
for (c = activeColors.length -1; c >= 0; c--) {
// Farbe aus den aktiven Farben löschenif (activeColors[c] == pieces[i].color) {
activeColors.splice(c, 1);
}
}
}
}
return activeColors;
};
this.canTakeBackPiece = function (piece) {
returnthis.getColorsOfActivePieces().contains(piece.color);
};
this.receivePiece = function () {
var free = [],
homePieces = this.getHomePieces(),
i, p;
for (i = 0; i < t.field.homes[this.color].seats.length; i++) {
// Array umkopieren
free.push(t.field.homes[this.color].seats[i]);
}
for (p = 0; p < homePieces.length; p++) {
for (i = free.length -1; i >= 0; i--) {
// besetzte Wartefelder aussortierenif (homePieces[p].lastWaypoint == free[i]) {
free.splice(i, 1);
}
}
}
t.game.removedPiece.waypoints.push(free[Math.floor(Math.random() * free.length)]);
t.game.removedPiece.setMoving();
t.game.removedPiece.element.className += " afraid";
t.game.removedPiece = false;
t.game.isWaiting = false;
};
this.activateHoverElement = function () {
this.hoverElement.className += " active";
};
this.deactivateHoverElement = function () {
this.hoverElement.className = this.hoverElement.className.replace(/ active/i, "");
};
},
getElementsByClassName : function (className, element) {
element = element ? element : document;
var muster = new RegExp("(^|\\s)" + className + "(\\s|$)");
var alles = element.getElementsByTagName("*");
var gefunden = new Array();
var i;
for (i = 0; i < alles.length; i++) {
if (alles[i] && alles[i].className && alles[i].className != "") {
if (alles[i].className.match(muster))
gefunden.push(alles[i]);
}
}
return gefunden;
},
createHTMLElement : function (params) {
var el, p;
/* "params" ist ein Objekt, das folgende Eigenschaften haben kann:
{ tagName : "p", // z.B. für <p>
text : "Textinhalt" // als Text-ChildNode des Elements
... // weitere (native) Eigenschaften des HTML-Elementobjekts (z.B. id, className etc.)
} */if (params.tagName && params.tagName.match(/[a-z]/)) {
el = document.createElement(params.tagName);
for (p in params) {
if (p.match(/^text/i)) {
el.appendChild(document.createTextNode(params[p]));
} else {
if (!p.match(/^tagname$/i)) {
el[p] = params[p];
}
}
}
}
return el;
}
}
MAEDN.init();
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.