Denksport: Radialer Bestplatz-Algorithmus

Mik3e hat gesagt.:
Sieh dir mal das SWF von Datic an..
Das kann genau das, was ich brauche (Vorausgesetzt es ist kein Fake-Code dahinter :)

Nur ein paar Feinheiten müssten dann noch gemacht werden, aber sonst sieht das sehr brauchbar aus...

Ich hoffe er ist bald wieder mal online und kann mir den Source posten :))

Sorry, an dem PC geht das leider nicht.
Falls er nicht mehr online kommen sollte, oder das ein fake-code ist, kannst du dir ja nocheinmal meine Idee anschaun.
Ich vermute nämlich fast, dass das klappen könnte.
 
Das komplexe ist ja eigentlich das anordnen der Plätze hintereinander und nebeneinander... Zusammenhängende in einer Reihe oder eine Spalte finden ist ja easy..
Ich saug mir grad die Flash Trial und werd mir dann den source mal ansehen :) Bin schon sehr gespannt..
 
Hehe ;) So geht's auch.

Ähm meine 2 Funktionen, die ich beschrieben habe würden ja noch weitergehen.
Dann sucht er sich so viele es geht nebeneinander (und der Rest muss größer als 1 sein, sonst sitzt einer Alleine) und den Rest dahinter. Er sucht sich eben eine Stelle, wo das möglich ist ;)
Das lässt sich ja alles ausrechnen, welcher Platz wo ist, um dann abzufragen ob die Plätze frei sind.
 
Naja.. ist etwas viel .. ich les mir das durch, was brauchbar klingt.
Aber ich hab nun den Quellcode von Datic.. Mein Problem: Meine Actionskript-Zeit ist schon etwas in die Jahre gekommen. Aber ich werde das schon irgendwie entschlüsseln:

Code:
var places = new Array();
places[0] = new Array(true, true, false, false, false);
places[1] = new Array(false, false, false, true, true);
places[2] = new Array(false, true, true, true, false);
places[3] = new Array(true, true, false, false, false);

var resp = new Array();
var famt = 0;
var c = 0;

for (var y=0; y<places.length; y++) {
	for (var x=0; x<places[y].length; x++) {
		var clp = this.attachMovie("pad", "p" + c, c);
		clp._x = x * clp._width;
		clp._y = y * clp._height;
		var cl = new Color(clp);
		var d = (places[y][x])? 0x00FF00 : 0xFF0000;
		cl.setRGB(d);
		c ++;
	}
}

button.onPress = function() {
	doCheck(parseInt(etext.text, 10));
}

function doCheck(a) {
	checkPlaces(a);
	showPlaces();
}

function showPlaces() {
	for (var y=0; y<resp.length; y++) {
		for (var x=0; x<resp[y].length; x++) {
			var clp = this.attachMovie("pad", "p" + c, c);
			clp._x = x * clp._width;
			clp._y = y * clp._height + 100;
			var cl = new Color(clp);
			var d = (resp[y][x])? 0x00FF00 : 0xFF0000;
			cl.setRGB(d);
			c ++;
		}
	}
}


function clearResp() {
	resp = new Array();
	for (var y=0; y<places.length; y++) {
		resp[y] = new Array(places[y].length);
		for (var x=0; x<places[y].length; x++) {
			resp[y][x] = false;
			//trace(resp[y][x]);
		}
	}
	famt = 0;
}

function countResp() {
	var c = 0;
	for (var y=0; y<places.length; y++) {
		for (var x=0; x<places[y].length; x++) {
			if (resp[y][x] == true) c ++;
		}
	}
	return c;
}


function checkPlaces(amt) {
	for (var i=1; i<=3; i++) {
		for (var y=0; y<places.length; y++) {
			for (var x=0; x<places[0].length; x++) {
				clearResp();
				resp = flood(places, i, x, y, resp, amt);
				if (countResp() >= amt) return true;
			}
		}
	}
}

function flood(matrix, fmode, x, y, rmtx, amt) {
	if (famt >= amt) return rmtx;
	if (matrix[y][x] == true && rmtx[y][x] != true) {
		rmtx[y][x] = true;
		famt ++;
		switch(fmode) {
			case 1:
				rmtx = flood(matrix, fmode, x - 1, y, rmtx, amt);
				rmtx = flood(matrix, fmode, x + 1, y, rmtx, amt);
				break;
			case 2: 
				rmtx = flood(matrix, fmode, x - 1, y, rmtx, amt);
				rmtx = flood(matrix, fmode, x + 1, y, rmtx, amt);
				rmtx = flood(matrix, fmode, x, y - 1, rmtx, amt);
				rmtx = flood(matrix, fmode, x, y + 1, rmtx, amt);
				break;
			case 3:
				rmtx = flood(matrix, fmode, x - 1, y, rmtx, amt);
				rmtx = flood(matrix, fmode, x + 1, y, rmtx, amt);
				rmtx = flood(matrix, fmode, x, y - 1, rmtx, amt);
				rmtx = flood(matrix, fmode, x, y + 1, rmtx, amt);
				rmtx = flood(matrix, fmode, x - 1, y - 1, rmtx, amt);
				rmtx = flood(matrix, fmode, x + 1, y - 1, rmtx, amt);
				rmtx = flood(matrix, fmode, x - 1, y + 1, rmtx, amt);
				rmtx = flood(matrix, fmode, x + 1, y + 1, rmtx, amt);
				break;
		}
	}
	return rmtx;
}

Der Anfang ist klar: ein zweidimensioanles Array "Places" (4 Reihen, 5 Spalten). In den Spalten ist dann jeweils der boolsche Wert für "verfügbar" und "nicht verfügbar" gespeichert.

Dann durchläuft er alle Plätze mit den beiden for-Schleifen (in PHP foreach) um den Grundplan auszugeben (können wir also vernachlässigen).

Die "button.OnPress" Funktion können wir auch vernachlässigen. Wichtig ist für uns nur der Aufruf der "doCheck()" Funktion.

Diese Funktion ruft zuerst die "CheckPlaces()" Funktion auf. Als Parameter wird die Anzahl der gesuchten Plätze übergeben.

Dort wird dann die "flood()" Funktion ausgeführt und an diesem Punkt ist es bei mir aus.. Dann durchblick ich die Variablenbezeichnungen nicht mehr :)

..................
 
Hm naja mit Actionscript kenn ich mich jetzt nicht aus ...
Auch wenn ich es wahrscheinlich verstehen würde, wenn ichs mir genauer anschaun würde, lassen wir das mal die Leute machen, die es können :D

Zur Nor musst du das dann doch nocht selbst machen ...
 
OMG - der Quellcode ist noch so grauslig, der sollte hier nicht gepostet werden. ^^

Jedenfalls: Mit Deinem Beispiel funktioniert er - wenn ein "Startplatz" manuell ausgewählt werden soll, muss aber einiges geändert werden (im Moment geht das Ding die Matrix einfach von links oben nach rechts unten durch; das müsste dann wohl eher "Ringförmig" geschehen.

Ich werd mal schauen, ob ich die Zeit finde, diese verbotene Mischung aus lokalen und globalen Arrays zu vereinfachen und das ganze in PHP umzusetzen.

Gruß

P.S.: Das, wo man dann nicht mehr durchblickt, ist vermutlich der Punkt, wo in "flood" das globale Array "rmtx" als Parameter übergeben, verändert und zurückgegeben wird (Zur Entschuldigung: Ich hab den Code in einer Mittagspause schnell runtergetippt).
.
 
Zuletzt bearbeitet:
Hi..
Kein Problem, war ja nur ein Testcode :)
Ja, du hast recht.. bei der Flood Rekursion bin ich dann ausgestiegen :)) (zu viele Variablennamen die nicht sonderlich viel aussagen)..

Ich versuch das gerade in PHP nachzubauen.. Bin aber noch nicht weit gekommen..
Kannst Du Dir hier ansehen:
http://www.powerticket.net/TESTbestplatzcalc.php

Im Moment hab ich noch ein kleines Array Problem :)
Wenn Du mir das irgendwie für PHP klar machen könntest, wäre ich dir echt dankbar...

Ciao,
Mike
 
Hi,

ich habe mir Deine Version noch nicht angesehen (mach ich gleich), aber ich habe mal versucht, das ganze in PHP umzuschreiben:
PHP:
<?php
// globale Variablen

// in $places stehen die freien Plätze
$places = array();
$places[0] = array(true, true, false, false, false);
$places[1] = array(false, false, false, true, true);
$places[2] = array(false, true, true, true, false);
$places[3] = array(true, true, false, false, false);

// In $response werden die gefundenen Plätze geschrieben
$response = Array();
$famt = 0;

function searchPlaces($amt) {
	checkPlaces($amt);
	showPlaces();
}

// Gefundene Plätze löschen
function clearResp() {
	global $places, $response, $famt;
	$response = array();
	for (var $y=0; y<count($places); $y++) {
		$response[$y] = array();
		for (var $x=0; $x<count($places[$y]); $x++) {
			$response[$y][$x] = false;
		}
	}
	$famt = 0;
}

// Gefundene Plätze zählen
function countResp() {
	global $places, $response;
	$c = 0;
	for (var $y=0; y<count($places); $y++) {
		for (var $x=0; $x<count($places[$y]); $x++) {
			if ($response[$y][$x] == true) $c ++;
		}
	}
	return $c;
}

// Plätze suchen:
function checkPlaces($amt) {
	global $places, $response, $famt;
	for ($i=1; $i<=3; $i++) {
		for ($y=0; $y<count($places); $y++) {
			for ($x=0; $x<count($places[0]); $x++) {
				clearResp();
				flood($i, $x, $y, $amt);
				if (countResp() >= $amt) return;
			}
		}
	}
}

// Weitersuchen
function flood($fmode, $x, $y, $amt) {
	global $places, $response, $famt;
	if ($famt >= $amt) return;
	if ($places[$y][$x] == true && $response[$y][$x] != true) {
		$response[$y][$x] = true;
		$famt ++;
		switch($fmode) {
			case 1:
				flood($fmode, $x - 1, $y, $amt);
				flood($fmode, $x + 1, $y, $amt);
				break;
			case 2: 
				flood($fmode, $x - 1, $y, $amt);
				flood($fmode, $x + 1, $y, $amt);
				flood($fmode, $x, $y - 1, $amt);
				flood($fmode, $x, $y + 1, $amt);
				break;
			case 3:
				flood($fmode, $x - 1, $y, $amt);
				flood($fmode, $x + 1, $y, $amt);
				flood($fmode, $x, $y - 1, $amt);
				flood($fmode, $x, $y + 1, $amt);
				flood($fmode, $x - 1, $y - 1, $amt);
				flood($fmode, $x + 1, $y - 1, $amt);
				flood($fmode, $x - 1, $y + 1, $amt);
				flood($fmode, $x + 1, $y + 1, $amt);
				break;
		}
	}
	return;
}

?>
Kann gut sein, dass sich da noch Fehler verbergen, denn ich habe es nicht getestet (kann es sein, dass es statt "break" in PHP "exit" heisst?).

Gruß
.
 
Zuletzt bearbeitet:
Zurück