Laden...

not all code path return a value Oo?

Erstellt von wurstpeter vor 17 Jahren Letzter Beitrag vor 17 Jahren 3.776 Views
W
wurstpeter Themenstarter:in
76 Beiträge seit 2006
vor 17 Jahren
not all code path return a value Oo?

Hallo 😉

ja ich weis ...eigentlich sollte das doch kein Problem sein...
aber irgendwiehäng ich grade... oder mir fehlt die konentration... wenn ich nich schon länger dran hängen würde würd ich auch nich posten ...

deshalb bitte kurz n blick drauf uns sagen was das problem ist

danke euch schonma 😁


   private int[] PixelSearchs(int startX,int startY,int rangeX,int rangeY, int step,int color,int shade)
        {
	    found=false;
 starts = DateTime.Now;
     while(starts.AddSeconds(35) < DateTime.Now)
    {
            for(int x=startX;x<startX+rangeX;x+=step)
            {
                for(int y=startY;y<startY+rangeY;y+=step)
                {
                    if(autoit.PixelGetColor(x,y)==color) // if(autoit.PixelGetColor(x,y)==color)
                        return new int[]{x,y}; 
                    found = true;
                }
            }
     }
     if(!found)
     {
     	throw new ApplicationException("PixelSearch: Failed to find the color ("+color.ToString()+")");
     }
        }


Er meint dazu: MainForm.Pixelsearch(int, int, int, int, int, int, int); not all code patch return a value.

Schon alles möglich probiert aber wie gesagt, komme nich drauf

1.271 Beiträge seit 2005
vor 17 Jahren

Wenn deine Methode einen Rückgabewert hat, muss sie auch etwas zurückgeben und zwar auch jeder Code-"Pfad" (also jede Abzweigung, die dein Code durch if...else...else if, switch, usw. macht). Wenn du die genaue FEhlernummer (CSxxxx) in die MSDN-/SDK-Doku eingibst, sollte auch eine ausführliche Erklärung kommen.

A wise man can learn more from a foolish question than a fool can learn from a wise answer!
Bruce Lee

Populanten von Domizilen mit fragiler, transparenter Außenstruktur sollten sich von der Translation von gegen Deformierung resistenter Materie distanzieren!
Wer im Glashaus sitzt, sollte nicht mit Steinen werfen.

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo wurstpeter,

siehe auch Syntaxfehler selbst lösen (Compilerfehlermeldungen)

herbivore

W
wurstpeter Themenstarter:in
76 Beiträge seit 2006
vor 17 Jahren

mhjah danke, aber das löst nich wirklich mein problem..
ich habe zwar den return error weg

indem ich einfach vor dem


return null;
  if(!found)
     {

eingebaut habe...

so folgendes problem aber:

Ich möchte ja das mein While loop für 35 sekunden durchläuft und checkt ob die farbe gefunden wurde... und ich möchte nur einen return bekommen, wenn die farbe gefunden wurde/innerhalb den 35 sek)... sonst möchte ich nach dem 35 sekunden eine execption kriegen.

Denn wenn ich einfach nen return null; einbaue

(das while loop mit den 35sek timeout müsste doch so funktionieren?)
bekomme ich probleme mit folgendem:

autoit.MouseClick("right", searchs[0], searchs[1], 1, 1);

Gibts dafürne lösung?

369 Beiträge seit 2006
vor 17 Jahren

Warum nicht einfach die Zeile "if (!found)" entfernen? Diese Verzweigung wird so oder so nur erreicht, wenn die Schleife ohne Ergebnis beendet wurde und deinen Schilderungen zu Folge soll in diesem Fall die Exception geschmissen werden...

/edit.. PS: ApplicationException sollte nicht verwendet werden. Siehe auch:
-> http://msdn2.microsoft.com/en-us/library/ms229007.aspx
-> http://blogs.msdn.com/brada/archive/2004/03/25/96251.aspx
-> http://msdnwiki.microsoft.com/en-us/mtpswiki/8446ee40-beb1-49fa-8733-4d8e813471c0.aspx

Auch solltest du weder Exeption, SystemException noch ApplicationException direkt werfen: http://msdnwiki.microsoft.com/en-us/mtpswiki/dd14ef5c-80e6-41a5-834e-eba8e2eae75e.aspx

W
wurstpeter Themenstarter:in
76 Beiträge seit 2006
vor 17 Jahren

gut werd ich mir merken 😉

aber wenn ich die if(found)
zeile lösche behebt das leider noch immer nicht mein problem...
denn wenn ich return null; entferne kommt wieder oben genanntes problem...

und wenn ich's drinnelasse krieg ich mit meiner mousemove funktion probleme...
da die n "gültigen" x,y return braucht...
welcher in den 35 sekunden auch garantiert auftritt...

B
1.529 Beiträge seit 2006
vor 17 Jahren
private int[] PixelSearch(int startX,int startY,int rangeX,int rangeY, int step,int color,int shade)
{
   DateTime start = DateTime.Now.AddSeconds(35);
   while(start > DateTime.Now)
   {
      for(int x=startX;x<startX+rangeX;x+=step)
      {
         for(int y=startY;y<startY+rangeY;y+=step)
         {
            if(autoit.PixelGetColor(x,y)==color)
               return new int[]{x,y};
         }
      }
   }
   throw new ApplicationException("PixelSearch: Failed to find the color ("+color.ToString()+")");
}
U
239 Beiträge seit 2006
vor 17 Jahren

Wie wär's denn hiermit?
Setze den return an das Ende der Methode und hinter found=true setzt du ein break;
damit die Schleife verlassen wird.

B
1.529 Beiträge seit 2006
vor 17 Jahren

Ich verstehe trotzdem nicht, was das mit den 35 Sekunden soll.
Wieso darf die Schleife nur 35 Sekunden durchlaufen werden?

Vor allem: wieso soll sie eine Exception werfen, falls in dieser Zeit kein passendes Pixel gefunden wurde (noch dazu: auf was für einem Rechner soll die Suche denn länger als 35 Sekunden dauern)?

Und wieso wird nicht jedes Pixel sondern nur jedes "step-te" geprüft?

Kurz gesagt: Häh? Was willst du erreichen?

W
wurstpeter Themenstarter:in
76 Beiträge seit 2006
vor 17 Jahren

xD sry sorgt vielleicht für verwirrung aber ich erklär das ganze mal.-..

der pixelsearch wird in einem Spiel durchgeführt

Und innerhalb von 35 Sekunden erscheint im Spiel ein Objekt, welches ich finden möchte, da die farbe im Spiel einzigartig ist...

So das Objekt hat die eigenschaft zufällig aufzutreten, an irgendeiner stelle, und das auch nur für 1 sekunde...

Wenn ich jetzt jeden Pixel prüfen würde... dann würde mein pc z.b. das objekt nur durch "glück" finden, da es einfach zu langsam is inenrhalb 1 sekunden einmal den bildschirm abzuscannen

Und da das objekt innerhalb von 35 sekunden auftritt nach start... eben die 35sekunden schleife...

Wenn jemand ne bessre methode... oder auf jedenfall ne "schnellere" pixelsearch methode kennt , höre ich mir dieses gerne an, da ich von meine auch nich begeistert bin 😉

/edit/
achja... und Borg, deine function geht zwar ... aber ich brauch die variable found = true;
und am besten wäre noch dass ganze ohne execption zu lösen 😉... aber wenn ich die exception entferne.. kommt wieder die "not all code path..." fehler

Danke auf jedenfalöl für die schnelle antworten

369 Beiträge seit 2006
vor 17 Jahren

Du brauchst dein found in keinster Weise da sich dies implizit durch das return-statement ergibt.

/edit: Muss mich korrigieren, found ist keine lokale Variable sondern klassen-global.

/edit2: Wahrscheinlich entspricht dann aber eher das hier deinen Vorstellungen:


if(autoit.PixelGetColor(x,y)==color)
{
    found =true;
    return new int[]{x,y};
}

T
512 Beiträge seit 2006
vor 17 Jahren

Die Fehlermeldung ist doch ganz eindeutig.

Nicht überall wo die Methode verlassen wird, wird ein Wert zurückgegeben.
Lösung: überall wo die Methode verlassen wird, einen Wert zurückgeben.

e.f.q.

Aus Falschem folgt Beliebiges

W
wurstpeter Themenstarter:in
76 Beiträge seit 2006
vor 17 Jahren

achja gut 😉
habe es gelöst bis hier hin...

369 Beiträge seit 2006
vor 17 Jahren

Oder du schiebst ein Application.DoEvents() dazwischen...

W
wurstpeter Themenstarter:in
76 Beiträge seit 2006
vor 17 Jahren

ja besser wäre das ganze doch in nen background worker zu verschieben oder?

da meine form nach 2-3 durchläufen sich aufhängt (also keine rückmeldung)

das script aber weiterläuft...

hab ich auch schon gemacht... wobei ich folgendes verwendet habe:

this.backgroundWorker1.RunWorkerAsync(); // beim pixelsearch anfang

und nachdem der farbcode gefunden wurde
this.backgroundWorker2.CancelAsync();
und wieder main function mit start() aufrufen

der bw sieht bei mir so aus, und cancellation is auch auf true


		void BackgroundWorker2DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
		{
		if (this.backgroundWorker2.CancellationPending) {
		textBox3.Text = textBox3.Text+"\n\n"+"cancel worker";
        e.Cancel = true;
        return;
			}
		// pixelsearch....

start(); // start ist die main function
		}

schön und gut... aber wenn er wieder in die mainform switched hat er ca 2 sekunden zeit sich zu beenden... was er aber nicht macht.. und beim neuen bw aufruf komtm dann eben die execption dass er noch busy is

B
1.529 Beiträge seit 2006
vor 17 Jahren

Du wirst das Pixel trotzdem nicht finden.

Wenn ich dich jetzt richtig verstanden habe, taucht das farbige Pixel irgendwann an beliebiger Stelle innerhalb eines Zeitfensters von 35 Sekunden für genau eine Sekunde auf.
Da du davon ausgehst, dass die Schleife sogar länger als 35 Sekunden sucht, ist es relativ unwahrscheinlich, dass das Pixel genau in dem Teil der Fläche auftaucht, der innerhalb der nächsten Sekunde durchsucht wird (frag mich jetzt bitte aber nicht nach der genauen Wahrscheinlichkeit, diese hängt vor allem vom Zeitbedarf der Suchschleife ab).

W
wurstpeter Themenstarter:in
76 Beiträge seit 2006
vor 17 Jahren

ja etwa...

es ist ein splash... und ein spülash (z.b. wasserspritzer) ist leider sehr schnell wieder weg 😉
naja mein script in AutoIt schafft es jedenfalls den splash zu finden
was mein c# programm nicht schafft

Vergessn dazu zu sagen, dass der splash in einer fläche von etwa ´50x50 pixeln auftritt also durchaus möglich dass er gefunden werden sollte

naja trotzdem krieg ichs irgendwie nich gebackn,.,.. wäre schon sehr nett mit nem background worker

369 Beiträge seit 2006
vor 17 Jahren

Dein Programm kann nur funktionieren, wenn das Durchlaufen der beiden Vorschleifen weniger als eine Sekunde dauert - und ob das hinhaut hängt hauptsächlich von autoit.PixelGetColor ab. So ganz verstehe ich die Sache aber auch nicht. Mir erscheint das ganze als ein sehr eigentümlicher Ansatz... irgendwie muss das Pixel ja auch "dort" hinkommen. Dieses - ich will es mal Ereignis nennen - solltest du doch abfangen können und am Besten gleich die Koordinaten mit dazu. In diesem Fall kannst du dir die ganze Schleiferei sparen.

W
wurstpeter Themenstarter:in
76 Beiträge seit 2006
vor 17 Jahren

Da es noch immer für verwirrung sorgt werde ich das mal aufklären inklusive screenshot 😉

Ich geh doch schwer davon aus das bei einer fläche von 50x50 die for schleifen weniger als 1 sekunden brauchen werden

Abfangen kann ich das event nich, da es in einem Spiel passiert... und ich dazu memory reading anwenden müsste was ich 1. nicht kann, und 2. nich will ^^

Das Programm existiert schon "fertig" und funktionstüchtig, als AutoIt code...
nur wollte ich das in ein c# Programm umsetzten, wegen besserer gui und xml reading etc...
-------------------------------------------------------------------------------------------
Der erste pixelsearch (habe ich hier nicht aufgeführt) sucht nach dem schwarzen Schwimmer (im ganzen blauen bereich) welchen er auch wunderbar nach 1-2 Sekunden findet.

So nach dem er gefunden wurde wird der 2. Pixelsearch (die hier aufgeführte funktion) auf 50x50 pixel um den Schwimmer eingegrenzt....(siehe gelber bereich)

Jetzt soll der 2. pixelsearch 35 Sekunden lang in dem kleinen Bereich nach dem Splash suchen welcher "zufällig" auftaucht.

Splash ist rosa gekennzeichnet (die fast weissen tröpfchen)

Hoffe is nun klar 😉

369 Beiträge seit 2006
vor 17 Jahren

Geh mal mit dem Debugger durch die Methode und du wirst merken er kommt garnicht in die Schleife. Schau dir die Abbruchsbedingung nochmal genau an... effektiv steht dort nämlich "while (DateTime.Now.AddSeconds(35) < DateTime.Now)". Sollte wohl eher "while (starts.AddSeconds(35) > DateTime.Now)" heißen. Bei der Gelegenheit würde ich aber auch gleich auf DateTime.UtcNow umstellen. Macht in diesem Zusammenhang zwar keinen Unterschied (bloß lokal verwendet), dennoch ist es besser sich das für die interne Verwendung (in allen Bereichen mit denen der Benutzer nicht in den Kontakt kommt - abgesehen von Config-Dateien) anzugewöhnen. Kann einem viel Ärger sparen. Außerdem solltest du statt der Exception einen boolschen Wert zurückgeben - das Ausgeben der Koordinaten erfolgt dann als out-Parameter.

PS: Für Koordinaten gibt es die Point-Struktur.

W
wurstpeter Themenstarter:in
76 Beiträge seit 2006
vor 17 Jahren

also
das mit datetime.now hat mich Borg ja schon korrigiert.. habe, dass so auch eingebaut

und der debugger kommt schon in die schleife

was meinste mit ps für die koorinaten gibts die Point Struktur?
stimmt irgendwas damit nicht?

bis jetzt sieht pixelsearch 2. loop so aus:


private int[] PixelSearchs(int startX,int startY,int rangeX,int rangeY, int step,int color,int shade)
{
   
   while(starts > DateTime.Now)
   {
      for(int x=startX;x<startX+rangeX;x+=step)
      {
         for(int y=startY;y<startY+rangeY;y+=step)
         {
            if(autoit.PixelGetColor(x,y)==color)
            	
               return new int[]{x,y};
         }
      }
   }
   
   timeout = true;
   return null;
 } 


funktioniert auch... bis auf dass sich mein programm dabei so gut wie "aufhängt" wegen der großen last ... beim schleifen durchlauf

369 Beiträge seit 2006
vor 17 Jahren

Statt einem Int[] würde ich die Point-Struktur verwenden. Macht die ganze Sache übersichtlicher... und entspricht eher den OOP-Prinzipien.

W
wurstpeter Themenstarter:in
76 Beiträge seit 2006
vor 17 Jahren

naja 😉 ich hab das bis jetzt alles zufriedenstellen lösen können, dank eurer hilfe 😉

nun steh ich aber wieder vor nem neuen problem^^

Problembeschreibung:

Er findet den SChwimmer, dann sucht der nach dem Splash, welchen er auch findet... danach führt er wieder die Funktion start() aus (nach finden / oder timeout)
Das Problem ist beim 2. ausführen der Funktion start() findet er nur noch den Schwimmer aber er findet den splash nicht mehr, ich denke das liegt a Backgroundworker....(denn beim Schwimmersearch verwende ich dieses nicht und alles klappt)...

Naja leider schaff ich es auch nicht rauszufinden warum er beim 2. durchlauf des Programms... den splash nicht mehr findet.
Vielleicht seht ihr ja da Problem, wäre super nett.
Danke schonmal


void start()
{
this.backgroundWorker2.CancelAsync();
timeout = false;
// Pixelsearch 1 (nach dem schwarzen schwimmer)
search =PixelSearch (55, 150,665,403, 2, 0x000000, 2);
if(autoit.error != 1)
{autoit.MouseMove(search[0],search[1],0);	}
// funktioniert wunderbar... 

this.backgroundWorker2.RunWorkerAsync();	

}

void BackgroundWorker2DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
		{
			
 BackgroundWorker bw = sender as BackgroundWorker;

if (bw.CancellationPending) {
        e.Cancel = true;
        return;
}
searchs =PixelSearchs (s_left, s_top,s_right,s_bottom, 1, 0xFFFFFF, 3);

if(!timeout)
{
	if(autoit.error != 1) // splash wurde gefunden
	{
autoit.MouseClick("right", searchs[0], searchs[1], 1, 1);
start();
}
}

So sieht die funktion für den pixelsearch 2 (Pixesearchs) aus:


      private int[] PixelSearchs(int startX,int startY,int rangeX,int rangeY, int step,int color,int shade)
{
   
   while(starts > DateTime.Now)
   {
      for(int x=startX;x<startX+rangeX;x+=step)
      {
         for(int y=startY;y<startY+rangeY;y+=step)
         {
            if(autoit.PixelGetColor(x,y)==color)
            	return new int[]{x,y};
               break;
         }
      }
   }
   
   timeout = true;
   return null;

} 

Ich hab den code mal "gekürzt" damit ihr es besser überschaun könnt