Archiv

Archive for the ‘Code’ Category

LDAP Verbindung mit C#

2. Dezember 2011 Hinterlasse einen Kommentar

// Kompilieren mit
// C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /out:ldap.exe /reference:"C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.DirectoryServices.dll" LDAPReader.cs   // Benötigt:
// System.DirectoryServices.dll   using System;
using System.DirectoryServices;
using System.IO;   namespace LDAP {   public class Program {   private const string FILE_NAME = "Thiel Michael.txt";
        private const string LDAP_PATH = "LDAP://X500.bund.de/OU=BSIEXTERN,o=Bund,c=de";
        private const string FILTER = "(&(objectClass=person)(cn=Thiel Michael))";   public static void Main(string[] args) {   Console.WriteLine("Verbinde mit " + LDAP_PATH);
            using (var searcher = new DirectorySearcher(new DirectoryEntry { Path = LDAP_PATH, AuthenticationType = AuthenticationTypes.Anonymous }, FILTER)) {
                try {
                    string email = searcher.FindOne().GetDirectoryEntry().Properties["mail"].Value.ToString();
                    Console.WriteLine(email);
                    File.WriteAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), FILE_NAME), email);
                    Console.WriteLine("Die Datei \"" + FILE_NAME + "\" wurde auf dem Desktop geschrieben");
                } catch (Exception e) {
                    Console.WriteLine(e.Message);
                }
            }
            Console.Read();
        }
    }
}
Kategorien:.NET, C#, Code Schlagwörter: , ,

Global System Hooks in C#

16. November 2011 Hinterlasse einen Kommentar

Currently I am programing a shell replacement for Windows 7 with WPF and C#. Low Level hooking to the mouse and keyboard is very simple, but message and shell hooking does not work at all. I did some research (Google) and found out that it is not possible in C#.
Then I found this article:
Using Window Messages to Implement Global System Hooks in C# from ChrisP1118.
He is basically using the Desktop window handle (with the help of SetProp and GetProp) to store the hWnd that is shared between the instances of the callbacks. It works very well. But there is a big problem. It depends on the desktop availability. Which does not exists if I’m using an other shell.
In his article he mentioned that he originally wanted to solve the problem with sharing memory.
Well I took his code and with the big help from
Microsoft I was able to implement memory sharing.

image

OK… I know… even a six years old could have done that… Easy stuff…

Source Code

WilsonGlobalSystemHooksWithSharedMemory_src.zip

Kalaha in Java

26. Februar 2011 Hinterlasse einen Kommentar

Das Projekt habe ich jetzt abgegeben und mir wurde erlaubt den Code zu veröffentlichen… Aber zuerst die Anforderungen des Projekts…

image

image

 

Screenshots

Hauptmenü

image

Replay

image

Spiel Laden

image

Neues Spiel starten

image

Wird geladen… Bitte warten… sagt Boxxy…

image

Das Spiel…

image

Das Replay mit Bug… Die Angezeigte Runde ist nicht korrekt… Korrigiere ich nicht mehr… Smiley

image

Optionen

image

 

Damit das Programm auch als Applet funktioniert, muss das Applet signiert werden.

Dazu benutzt man keytool und jarsigner. Beide Programme befinden sich im Java bin Ordner…

Wie das Signieren funktioniert wird hier genau beschrieben.

 

Das Programm –> Skydrive

Der Code –> Skydrive

Viel Spaß damit… Anfragen auf Verbesserungen, bitte nicht an mich, da ich Java und Eclipse jetzt von meiner Platte schmeiße… Das heißt… Nimm den Code und verbessere selbst… Aber erwähne mich und die Seite in den Credits…

Kategorien:Code, Java Schlagwörter: , , ,

Java Events im Vergleich zu C# Events

18. Februar 2011 4 Kommentare

Ich mache hier mal ein Vergleich um zu zeigen, was ich mit unnötige Komplexität und Unübersichtlichkeit meine.

 


Erstellen von Custom Events

Java

Java
1
23
45
    public interface EventCustom extends EventListener
    {        public void fireEvent(EventObject e);
    } 
GeSHi 1.0.8.8
Java
1
23
45
67
89
1011
1213
1415
1617
18
    protected Vector<EventCustom> listenerList = new Vector<EventCustom>();
     public void addEventListener(EventCustom eventListener)
    {        listenerList.add(eventListener);
    }      public void removeEventListener(EventCustom eventListener)    {
        listenerList.remove(eventListener);    }
        private void fireEndOfGame(EventObject e)
    {        for(EventCustom listener: listenerList)
            listener.fireEvent(e);    }
 
GeSHi 1.0.8.8

C#

C#
1
    public delegate void EventCustomHandler(object sender);
GeSHi 1.0.8.8
C#
1
private EventCustomHandler CustomEvent;
GeSHi 1.0.8.8

 


Event aufrufen

Java

Java
1
fireEndOfGame(new EventObject(this));
GeSHi 1.0.8.8

C#

C#
1
if(CustomEvent!=null) CustomEvent(this);
GeSHi 1.0.8.8

 


Listener hinzufügen

Java

Java
1
23
45
67
89
anyObject.addEventListener(new EventCustom()
{    @Override
    public void fireEvent(EventObject e)    {
         // Bla bla bla    }
}); 
GeSHi 1.0.8.8

oder

Java
1
23
45
67
89
    private EventCustom eventCustom = new EventCustom()
    {        @Override
        public void fireEvent(EventObject e)        {
            // bla bla bla        }
    }; 
GeSHi 1.0.8.8
Java
1
anyObject.addEventListener(eventCustom);
GeSHi 1.0.8.8

oder

Java
1
23
45
67
89
1011
1213
1415
public class CustomEvent implements EventCustom
{    private Object sender;
            public CustomEvent(Object sender)
    {        this.sender = sender;
    }            @Override    public void fireEvent(EventObject e)
    {        // bla bla bla
    }}
GeSHi 1.0.8.8
Java
1
private CustomEvent customEvent = new CustomEvent(this);
GeSHi 1.0.8.8
Java
1
anyObject.addEventListener(eventCustom);
GeSHi 1.0.8.8

 

C#

C#
1
anyObject.CustomEvent += AnyObject_CustomEvent;
GeSHi 1.0.8.8
C#
1
23
4
private void AnyObject_CustomEvent(object sender) 
{     // bla bla bla
}
GeSHi 1.0.8.8

oder

C#
1
23
4
this.CustomEvent += delegate(object sender) 
{    // bla bla bla
};
GeSHi 1.0.8.8

 

So… Genug für heute….

Kategorien:.NET, C#, Java Schlagwörter: , , , ,

Java sucks…

17. Februar 2011 2 Kommentare

Ich bin mit mein Java Projekt jetzt fast fertig, wobei ich erst am 23. Januar angefangen habe… Es ist extrem OOP-lastig geworden… Ich habe über 50 Klassen; der längste ist 18 Seiten lang, ca. 1000 Zeilen. Die Hauptvoraussetzung war die strikte Trennung zwischen Grafik und Logik. So musste ich vieles über Events lösen… Und Java Events sind… Komplett fürn Arsch…

Aber bevor ich mich über Java auslasse… Ein Vorschau auf mein Projekt… Ich werde später den Code zum Download hier verlinken…

fap2000

fap2000_2

fap2000_3

Die KI hat noch ein paar Bugs… Und es ist auch selten dämlich… Noch!… Aber ich habe ja noch bis 25. Februar zeit. Für das Hauptmenü werde ich mir noch was künstlerisches einfallen lassen. Zur Zeit sieht es ziemlich karg aus.

Und hier die Klassen…

image

Nun zu Java…

Java sucks weil…

  • Keine unsigned Datentypen – Vor allem das umwandeln von Long in Hex machte es mir viele Probleme, wenn man die magische Grenze eines signed übertritt… Da wird der Wert nämlich negativ und Java behandelt den Wert auch als Negativwert…
  • Zwang zur Nutzung von Anonymen Klassen – Mein Code ist damit so was von “dreckig”… Ich habe dann immer das Bedürfnis duschen zu müssen, wenn ich den Code sehe. /* Edit */ Hauptsächlich im Zusammenhang mit Listener gemeint
  • @Override hat gar kein Nutzen – Ob ich es jetzt weglasse oder mit dranschreibe… Keinen Unterschied… Nichts…
  • Getter Setter vollkommen Käse – Das man Methoden nutzt um “Properties” Werte zuzuweisen, kann ich in C++ vorkommen verstehen… Aber in Java? WTF! Warum? Java möchte Modern sein, aber das ist absolut nicht modern. Meine Klassen ist gegen Ende vollkommen mit den Getter/Setter Methoden gepflastert… Vollkommen unübersichtlich… Tuet mir leid das sagen zu müssen… Visual Basic <= 6.0 ist eine “unfertige” unschöne (milde ausgedrückt) Sprache, aber VB hatte schon richtige Properties… Im Gegensatz zu Java… Ich konnte Property Zuweisungen in einer Zeile schreiben… Mein Code war übersichtlicher.
  • Das Threading ist lächerlich beschränkt – Ich wollte ein Thread für eine unbestimmte Zeit anhalten, aber sehe da: suspend() ist Deprecated. Ich konsultierte Google und nichts… Wenn man in Java ein Thread anhalten möchte, geht es nicht… Man muss den kompletten Thread beenden. Ist das nicht schön? Edit … Es funktioniert mit wait() und notify() – danke upeuker
  • abstract methods in Nicht-Abstrakte Klassen – Geht nicht
  • Extension von Klassen – geht nicht… Ich muss eine Klassen immer erben um es erweitern zu können…
  • Überladen von Operatoren – geht nicht … und ich wollte so gern Child-Nodes durch den plus Operator hinzufügen
  • Indexer – gibt es nicht… Ok… Das ist vielleicht zu viel verlangt…
  • Mehrere Klassen in einer Datei – geht nicht
  • Primitive Datentypen – Ein schlimmes übel. Folgendes ist absolut nicht möglich: intData.toString() … Man muss entweder so: Integer.toString(intData) oder es so: Integer intData2 = intData; intData2.toString(); … Das ist gar nicht OOP… Mich wundert es aber wieso ich Primitive zu einem Object zuweisen kann oder warum der ++ Operator beim int Überladen ist… Compiler-trick vielleicht?
  • Trennung zwischen Code und GUI – Nicht gelungen… bzw. nicht vorhanden…
  • Events/Listeners – Die schlimmste Ausgeburt der Hölle… So etwas dumm komplexes und unübersichtliches habe ich echt noch nie gesehen. Frage: Warum ist dieser Dreck nur mit Interfaces gelöst worden? Ich muss deswegen Methoden implementieren, dass ich absolut nicht benötige. Wenn ich nur den Mausklick auswerten will, warum muss ich zum Teufel mousePressed() implementieren? Warum muss ich das als anonyme Klasse implementieren? Warum muss ich mein Code komplett mit dem Mist zukleistern? Schlimmer ist ja noch, wenn man Benutzerdefinierte Events hat. Ich habe 30 Zeilen Code geschrieben um nur ein (1) Event auslösen zu können… Warum? Weil… Man benötigt eine Collection für die Listeners, man benötigt Methoden für den Collection (add, remove, size), man benötigt ein Interface, man benötigt eine Methode als Auslöser… und und und… OMG… In C# sind das ganze 3 Zeilen Code… 2 wenn man den DefaultEvent nutzt…
  • /*Edit*/ Parameterübergabe mit by Reference – geht nicht … Man muss den Umweg über Klassen gehen.

Und warum ist das so? Weil… Java sucks!

Kategorien:Java Schlagwörter: , ,

Game of Life mit J#

23. Januar 2011 Hinterlasse einen Kommentar

Ich hab einen dummen Fehler gefunden. Der Fehler ist im Grunde ein Denkfehler von mir. Ich habe den “Flag”, ob die Zelle lebt oder stirbt direkt im selben Array geschrieben weswegen das Ergebnis dann verfälscht wurde. Wenn z.B. Zelle 1 genau 3 Nachbarn hat und deswegen wiederbelebt wird, wird im selben Moment Zelle 2 sterben, da in diesem Fall Regel 4 greift.

image

Um das Problem zu umgehen bzw. zu Lösen, schreibt man einfach die Ergebnisse der “Nachbarprüfung” in einem Buffer. Danach schreibt man den Buffer in das eigentliche Zellenarray zurück.

Dieses J# Programm funktioniert zum Beispiel genauso wie es sein sollte. Ich werde die anderen Game of Life Versionen nach und nach korrigieren.

image

J#
1
23
45
67
89
1011
1213
1415
1617
1819
2021
2223
2425
2627
2829
3031
3233
3435
3637
3839
4041
4243
4445
4647
4849
5051
5253
5455
5657
5859
6061
6263
6465
6667
6869
7071
7273
7475
7677
7879
8081
8283
8485
8687
8889
9091
9293
9495
9697
9899
100101
102103
104105
106107
108109
110111
112113
114115
116117
118119
120121
122123
124125
126127
128129
130131
132133
134135
136137
138139
140141
142143
144145
146147
148149
150151
152153
154155
package GameOfLifeJSharp;
 import java.util.Random;
import System.*;  public class Program{
    final static int WORLD_WIDTH = 30;    final static int WORLD_HEIGHT = 20;
    final static double LIFE_ABUNDANCY = 31.5;    final static int STABLE_GENERATIONS = 10;
    final static char CELL_PRESENTATION = 'O';      public static void main(String[] args)    {
        int[,] cell = new int[WORLD_WIDTH,WORLD_HEIGHT];        // In my older Game of Life code I used to
        // check directly, but this seems to lead to        // faulty results...
        int[,] cellBuffer = new int[WORLD_WIDTH,WORLD_HEIGHT];          int stableGenerations = 0;        int startingCell = (int)(LIFE_ABUNDANCY * 
            (WORLD_WIDTH * WORLD_HEIGHT) / 100);        int oldPopulation = 0; // How many cells do we have last gen?
        int population = startingCell;        int generation = 0;
        // This avoids the "if"        char[] cellPresentation = new char[] {' ', 
            CELL_PRESENTATION};          // assign a value to the cells ... zero!        for(int y=0; y < WORLD_HEIGHT; y++) {
            for(int x=0; x< WORLD_WIDTH; x++) {                cell[x,y] = 0;
                cellBuffer[x,y] =0;            }
        }          // randomize cell        Random random = new Random(
            System.currentTimeMillis()); // create a randomizer        // java... makes my life harder ^^
        int randX;        int randY;
        while (startingCell > 0) {            randX=random.nextInt(WORLD_WIDTH - 2) + 1;
            randY=random.nextInt(WORLD_HEIGHT - 2) + 1;            cell[randX, randY] = randomCell(
                cell[randX, randY], random);            startingCell -= cell[randX, randY];
        }          while (stableGenerations < STABLE_GENERATIONS)        {
            // show the cells            // but clear the screen first
            Console.Clear();            for (int y = 0; y < WORLD_HEIGHT; y++)
            {                for (int x = 0; x < WORLD_WIDTH; x++)
                {                    Console.Write(cellPresentation[cell[x, y]]);
                }                Console.Write("\n");
            }            Console.Write("Generation: " + generation + 
                " Population: " + population);            generation++;
             // check if this generation is stable
            if (population == oldPopulation)                stableGenerations++;
            else                stableGenerations = 0;
             oldPopulation = population;
            population = 0;              // check the cells            for (int y = 1; y < WORLD_HEIGHT - 2; y++)
            {                for (int x = 1; x < WORLD_WIDTH - 2; x++)
                {                    // count my neighbors
                    int neighbors = 0;                    neighbors += cell[x - 1, y - 1];
                    neighbors += cell[x - 1, y];                    neighbors += cell[x - 1, y + 1];
                    neighbors += cell[x, y - 1];                    neighbors += cell[x, y + 1];
                    neighbors += cell[x + 1, y - 1];                    neighbors += cell[x + 1, y];
                    neighbors += cell[x + 1, y + 1];                      // apply rules, but change thier                    // status in the buffer
                    // Birth                    if (cell[x, y] == 0 && neighbors == 3)
                        cellBuffer[x, y] = 1;                    else if (cell[x, y] == 0)
                        // we copy dead cells too;                        cellBuffer[x, y] = 0;
                     // Death due to loneliness
                    if (cell[x, y] == 1 && neighbors < 2)                        cellBuffer[x, y] = 0;
                     // live longer
                    if (cell[x, y] == 1 && neighbors > 1 &&                        neighbors < 4)
                        cellBuffer[x, y] = 1;                      // Death due to overpopulation                    if (cell[x, y] == 1 && neighbors > 3)
                        cellBuffer[x, y] = 0;                      population += cellBuffer[x, y];                }
            }              // now copy the buffer to cells            // clone doesnt seem to work :-/
            copyBufferToCell(cell, cellBuffer);            try
            {                Thread.sleep(100);
            }            catch (Exception e) { }
        }          Console.Read();    }
     // Java is such a sad language... no pass by reference
    // Even the shitty VB6 has pass by reference    public static int randomCell(int cell, Random rand)
    {        if (cell == 0 && rand.nextInt(1000) > 500)
            return 1;        else
            return 0;    }
     public static void copyBufferToCell(int[,] cell, 
        int[,] buffer)    {
        for (int x = 0; x < WORLD_WIDTH; x++) {            for (int y = 0; y < WORLD_HEIGHT; y++) {
                cell[x, y] = buffer[x, y];            }
        }    }
} 
GeSHi 1.0.8.8
Kategorien:.NET, Code, J# Schlagwörter: , ,

Game of Life mit C# und WinForms

22. Januar 2011 Hinterlasse einen Kommentar

Diesmal habe ich in C# mit Klassen so gearbeitet wie es im OOP angedacht ist. Die Zellen als Klasse, eine Gruppe der Zellen als Klasse, die Welt als Klasse, der Renderer als Klasse u.s.w…

Es ist lang geworden, da ich noch ein paar Gimmicks eingebaut habe; Zum Beispiel Mutanten und Zombies!

Das Hauptprogramm ist eigentlich schön kurz

C#
1
23
45
67
89
1011
1213
1415
1617
1819
2021
2223
2425
2627
2829
3031
3233
3435
3637
3839
4041
4243
4445
4647
4849
5051
5253
5455
    static class Program
    {        /// <summary>
        /// Der Haupteinstiegspunkt für die Anwendung.        /// </summary>
        [STAThread]        static void Main()
        {            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);              // Create world            World SimWorld = new World();
            SimWorld.GridSize = 18;            SimWorld.Height = 30;
            SimWorld.Width = 40;            SimWorld.LifeAbundancy = 30;
            SimWorld.Zombies = true;            SimWorld.Mutants = true;
            SimWorld.Initialize();              FormWorld mainWindow = new FormWorld(SimWorld);              // Initialize form            mainWindow.FormBorderStyle = FormBorderStyle.FixedSingle;
            mainWindow.MaximizeBox = false;            mainWindow.Height = 600;
            mainWindow.Width = 800;            mainWindow.UseHexagon = false;
            mainWindow.CellBornedColor = Color.GreenYellow;            mainWindow.CellDyingColor = Color.Gray;
            mainWindow.CellLiveColor = Color.LimeGreen;            mainWindow.CellZombieColor = Color.DarkSlateBlue;
            mainWindow.CellMutantColor = Color.Red;            mainWindow.BackgroundColor = Color.PaleGreen;
            mainWindow.RefreshTime = 50;              // Create and init Button            Button btnGo = new Button();
            mainWindow.Controls.Add(btnGo);            btnGo.AutoSize = true;
            btnGo.Text = "Simulation starten";            btnGo.Top = (mainWindow.Height >> 1) - (btnGo.Height >> 1);
            btnGo.Left = (mainWindow.Width >> 1) - (btnGo.Width >> 1);            // Assign Click event
            btnGo.Click += delegate(object sender, EventArgs e)            // I know this is bad... 
            {                btnGo.Visible = false;
                mainWindow.StartSimulation();            };
                        Application.Run(mainWindow);
        }    }
GeSHi 1.0.8.8


Aber die Klassen sind arg lang…

Und so sieht es aus…

Normal

image

Normal in Hexagon Anordnung

image

Mit Zombies

image

Mit Zombies und Mutanten

image

Und der Source Code

C#
1
23
45
67
89
1011
1213
1415
1617
1819
2021
2223
2425
2627
2829
3031
3233
3435
3637
3839
4041
4243
4445
4647
4849
5051
5253
5455
5657
5859
6061
6263
6465
6667
6869
7071
7273
7475
7677
7879
8081
8283
8485
8687
8889
9091
9293
9495
9697
9899
100101
102103
104105
106107
108109
110111
112113
114115
116117
118119
120121
122123
124125
126127
128129
130131
132133
134135
136137
138139
140141
142143
144145
146147
148149
150151
152153
154155
156157
158159
160161
162163
164165
166167
168169
170171
172173
174175
176177
178179
180181
182183
184185
186187
188189
190191
192193
194195
196197
198199
200201
202203
204205
206207
208209
210211
212213
214215
216217
218219
220221
222223
224225
226227
228229
230231
232233
234235
236237
238239
240241
242243
244245
246247
248249
250251
252253
254255
256257
258259
260261
262263
264265
266267
268269
270271
272273
274275
276277
278279
280281
282283
284285
286287
288289
290291
292293
294295
296297
298299
300301
302303
304305
306307
308309
310311
312313
314315
316317
318319
320321
322323
324325
326327
328329
330331
332333
334335
336337
338339
340341
342343
344345
346347
348349
350351
352353
354355
356357
358359
360361
362363
364365
366367
368369
370371
372373
374375
376377
378379
380381
382383
384385
386387
388389
390391
392393
394395
396397
398399
400401
402403
404405
406407
408409
410411
412413
414415
416417
418419
420421
422423
424425
426427
428429
430431
432433
434435
436437
438439
440441
442443
444445
446447
448449
450451
452453
454455
456457
458459
460461
462463
464465
466467
468469
470471
472473
474475
476477
478479
480481
482483
484485
486487
488489
490491
492493
494495
496497
498499
500501
502503
504505
506507
508509
510511
512513
514515
516517
518519
520521
522523
524525
526527
528529
530531
532533
534535
536537
538539
540541
542543
544545
546547
548549
550551
552553
554555
556557
558559
560561
562563
564565
566567
568569
570571
572573
574575
576577
578579
580581
582583
584585
586587
588589
590591
592593
594595
596597
598599
600601
602603
604605
606607
608609
610611
612613
614615
616617
618619
620621
622623
624625
626627
628629
630631
632633
634635
636637
638639
640641
642643
644645
646647
648649
650651
652653
654655
656657
658659
660661
662663
664665
666667
668669
670671
672673
674675
676677
678679
680681
682683
684685
686687
688689
690691
692693
694695
696697
698699
700701
702703
704705
706707
708709
710711
712713
714715
using System;
using System.Drawing;using System.Threading;
using System.Windows.Forms;  namespace GameOfLifeCSharpWinForms{
    static class Program    {
        /// <summary>        /// Der Haupteinstiegspunkt für die Anwendung.
        /// </summary>        [STAThread]
        static void Main()        {
            Application.EnableVisualStyles();            Application.SetCompatibleTextRenderingDefault(false);
             // Create world
            World SimWorld = new World();            SimWorld.GridSize = 16;
            SimWorld.Height = 30;            SimWorld.Width = 60;
            SimWorld.LifeAbundancy = 30;            SimWorld.Zombies = true;
            SimWorld.Mutants = true;            SimWorld.Initialize();
             FormWorld mainWindow = new FormWorld(SimWorld);
             // Initialize form
            mainWindow.FormBorderStyle = FormBorderStyle.FixedSingle;            mainWindow.MaximizeBox = false;
            mainWindow.Height = 600;            mainWindow.Width = 800;
            mainWindow.UseHexagon = true;            mainWindow.CellBornedColor = Color.GreenYellow;
            mainWindow.CellDyingColor = Color.Gray;            mainWindow.CellLiveColor = Color.LimeGreen;
            mainWindow.CellZombieColor = Color.DarkSlateBlue;            mainWindow.CellMutantColor = Color.Red;
            mainWindow.BackgroundColor = Color.PaleGreen;            mainWindow.RefreshTime = 400;
             // Create and init Button
            Button btnGo = new Button();            mainWindow.Controls.Add(btnGo);
            btnGo.AutoSize = true;            btnGo.Text = "Simulation starten";
            btnGo.Top = (mainWindow.Height >> 1) - (btnGo.Height >> 1);            btnGo.Left = (mainWindow.Width >> 1) - (btnGo.Width >> 1);
            // Assign Click event            btnGo.Click += delegate(object sender, EventArgs e)
            // I know this is bad...             {
                btnGo.Visible = false;                mainWindow.StartSimulation();
            };                        Application.Run(mainWindow);        }
    }      public class FormWorld : Form     {
        private static World World;        public bool Simulate { get; set; }
        public Color BackgroundColor { set; get; }        public Color CellDyingColor { get; set; }
        public Color CellBornedColor { get; set; }        public Color CellLiveColor { get; set; }
        public Color CellZombieColor { get; set; }        public Color CellMutantColor { get; set; }
        public int RefreshTime { get; set; }          public bool UseHexagon         { 
            get{return World.Cells.HexagonGrid;}            set { World.Cells.HexagonGrid = value; } 
        }          public FormWorld(World world): base()        {
            World = world;        }
         public void StartSimulation()
        {            Simulate = true;
             Graphics g = Graphics.FromHwnd(this.Handle);
            int Generation = 0;              while (Simulate)            {
                this.Invalidate();                Application.DoEvents();
                DrawBuffer(g);                  this.Text = "Generation: " + Generation +                    " Population: " + World.Cells.Population +
                    " Stable Generation: " +                     World.StableGenerationCounter +
                    " Is Stable: " + World.IsStable.ToString();                  Generation++;                if (World.IsStable) Simulate = false;
                 Thread.Sleep(RefreshTime);
            }              g.Dispose();        }
         private void DrawBuffer(Graphics g)
        {            // Create Buffer
            Bitmap Buffer = new Bitmap(this.Width,this.Height);            Graphics BufferGraphics = Graphics.FromImage(Buffer);
             // Draw World Background
            SolidBrush brush = new SolidBrush(BackgroundColor);            BufferGraphics.FillRectangle(brush, 0, 0, 
                this.Width, this.Height);              // Net Pen            Pen pen = new Pen(CellLiveColor);
             // Get center
            float X = (this.Width >> 1) -                 (World.GridSize * World.Width >> 1);
            float Y = (this.Height >> 1) -                 (World.GridSize * World.Height >> 1);
             // Draw the cells
            int CellSize = World.GridSize - 2;              Cell.CellState status;            for (int x = 0; x < World.Width; x++)
            {                for (int y = 0; y < World.Height; y++)
                {                    status = World.Cells[x, y].Status;
                    switch (status)                    {
                        case Cell.CellState.Borned:                             brush.Color = CellBornedColor; 
                            break;                        case Cell.CellState.Dying: 
                            brush.Color = CellDyingColor;                             break;
                        case Cell.CellState.Live:                             brush.Color = CellLiveColor;
                            break;                        case Cell.CellState.Zombies:
                            brush.Color = CellZombieColor;                            break;
                        case Cell.CellState.Mutants:                            brush.Color = CellMutantColor;
                            break;                    }
                    if (status != Cell.CellState.Dead)                    {
                        BufferGraphics.FillEllipse(brush,                             (x * World.GridSize) + X + 
                            World.Cells[x, y].XOffset,                             (y * World.GridSize) + Y, 
                            CellSize, CellSize);                    }
                }            }
            try            {
                // Draw me                g.DrawImage(Buffer, 0, 0);
            }            catch { }
             World.Refresh();
                        pen.Dispose();
            brush.Dispose();            BufferGraphics.Dispose();
            Buffer.Dispose();        }
         protected override void OnPaint(PaintEventArgs e)
        {            if(!Simulate)  base.OnPaint(e);
        }          protected override void OnPaintBackground(PaintEventArgs e)        {
            if(!Simulate) base.OnPaintBackground(e);        }
         protected override void OnClosing(
            System.ComponentModel.CancelEventArgs e)        {
            Simulate = false;            base.OnClosing(e);
        }      }      public class Cell    {
        [Flags]        public enum CellState 
        {             Dead = 2, 
            Borned = 4,             Live = 8, 
            Dying = 16,             Zombies = 32, 
            Mutants = 64,            AllLiving = Borned | Live | Mutants,
            AllDead = Dead | Dying        };
         // Properties
        internal int IsZombie        {
            get            {
                return (Status | CellState.Zombies)                    == CellState.Zombies ?
                    1 : 0;            }
        }          internal int IsMutant        {
            get            {
                return (Status | CellState.Mutants)                    == CellState.Mutants ?
                    1 : 0;            }
        }          private bool IsAlwaysDead = true;          private CellState _status;        public CellState Status
        {             get{ return _status; }
        }          private Cells _parent;        public Cells Parent
        { get { return _parent; } }          private int _x;        public int X { get { return _x; } }
         private int _y;
        public int Y { get { return _y; } }          public float XOffset        { 
            get             {
                if (Parent.HexagonGrid)                    return Y % 2 == 1 ? 
                        Parent.Parent.GridSize >> 1 : 0;                else
                    return 0;            } 
        }          public Cell(Cells parent, int x, int y)        {
            _parent = parent;            _x = x;
            _y = y;              // All Cells are always dead in the beginning            _status = CellState.Dead;
             // All Cells along the sides are always dead...
            // This is just easier to check them for neighbors            // cause no Errors will occure in this case
            if ((X > 0 && X < Parent.Parent.Width-1) &&                (Y > 0 && Y < Parent.Parent.Height-1))
                IsAlwaysDead = false;            else
                IsAlwaysDead = true;        }
         ~Cell()
        {            _parent = null;
        }          internal bool HasAttribute(CellState cellState)        {
            if ((Status & cellState) == cellState)                return true;
            else if ((Status | cellState) == cellState)                return true;
            else                return false;
        }          public void Live()        {
            if (Status == CellState.Dead)            {
                Parent.PopulationInternal++;                _status = CellState.Borned;
            }            else if (Status == CellState.Dying)
            {                Parent.PopulationInternal++;
                _status = CellState.Live;            }
            else if (Status == CellState.Borned)                _status = CellState.Live;
        }          public void Die()        {
            if (Status == CellState.Live ||                Status == CellState.Mutants)
            {                Parent.PopulationInternal--;
                _status = CellState.Dying;            }
            else if (Status == CellState.Borned)            {
                Parent.PopulationInternal--;                _status = CellState.Dead;
            }            else if (Status == CellState.Dying || 
                Status == CellState.Zombies)                _status = CellState.Dead;
        }          public Cell RandomizeLife()        {
            if (Status != CellState.Live)            {
                if (Parent.Randomize.Next(1000) > 500)                {
                    Live();                    return this;
                }                else
                    return this;            }
            else                return this;
         }
         public void RefreshCellStatus()
        {            // skip this if we are "always dead"
            if(IsAlwaysDead) return;              #region Normal Cells            int Neighbors = CountNeighbors(CellState.AllLiving);
                        // Apply Rules
            // No 1. - Birth            if (HasAttribute(CellState.AllDead)
                 && Neighbors == 3)                Live();
             else if (HasAttribute(CellState.AllLiving))
            {                // No. 2 - Lonelyness
                if (Neighbors < 2)                    Die();
                // No. 3 - Live longer 🙂                else if (Neighbors > 1 && Neighbors < 4)
                    Live();                // No. 4 - Overpopulated
                // Mutants dont die on overpopulation                else if (Neighbors > 3 &&
                    Status != CellState.Mutants)                    Die();
            }            else if (Status == CellState.Dying)
                Die();              #endregion              #region Unusual Cells            if (Parent.Parent.Zombies || Parent.Parent.Mutants)
            {                  int ZombieNeighbor =                    CountNeighbors(CellState.Zombies);
                 int MutantNeighbor =
                    CountNeighbors(CellState.Mutants);                  #region Zombie Cells                // This is the Zombie special
                if (Parent.Parent.Zombies)                {
                     // The Zombie get beaten to death
                    // if enough cell are around it                    if (Status == CellState.Zombies &&
                        Neighbors > 3)                        Die();
                    // Dead Cell have a small chance                    // in turning to zombies
                    else if (Status == CellState.Dead)                    {
                        if (Parent.Randomize.Next(1, 1000) > 992)                            _status = CellState.Zombies;
                    }                    // if I am not a zombie and one
                    // of my neighbors is a zombie                    // I have a chance of getting
                    // bitten. The more zombies the higher                    // the chance
                    else if (Status != CellState.Zombies &&                        ZombieNeighbor > 0)
                    {                        if (Parent.Randomize.Next(1, 1000) >
                            (999 >> ZombieNeighbor))                            _status = CellState.Zombies;
                    }                    // if there are too many zombies neighbors
                    // My neighbor will eat me                    else if (Status == CellState.Zombies &&
                        ZombieNeighbor > 4)                        Die();
                     // A Zombie has a chance of dying
                    // if a mutant is one of his neighbors                    // The more mutants the higher the
                    // chance                    if (Status == CellState.Zombies &&
                        MutantNeighbor > 0)                    {
                        if (Parent.Randomize.Next(1, 1000) >                            (700 >> ZombieNeighbor))
                            Die();                    }
                 }
                #endregion                  #region Mutant Cells                // Mutant Cell Special
                if (Parent.Parent.Mutants)                {
                    // A living cell has a chance in                    // turning to a mutant
                    if (Status == CellState.Live &&                        Parent.Randomize.Next(1, 1000) > 800)
                        _status = CellState.Mutants;                    // A mutant cell will die if
                    // there are more than 4                    // zombies around him
                    else if (Status == CellState.Mutants &&                        ZombieNeighbor > 4)
                        Die();                    // A mutant will turn normal if
                    // there are too many Mutants around                    // him
                    else if (Status == CellState.Mutants &&                        MutantNeighbor > 3)
                        _status = CellState.Live;                    // Dead Cells will live if more than 2
                    // Mutants are around                    else if (HasAttribute(CellState.AllDead) &&
                        MutantNeighbor > 2)                    { Live(); Live(); }
                 }
                #endregion            }
            #endregion        }
         private int CountNeighbors(CellState cellStateToCount)
        {            int RetVal = 0;
            if(!IsAlwaysDead)            {
                RetVal += Parent[X + 1, Y].                    HasAttribute(cellStateToCount).ToInt();
                 RetVal += Parent[X, Y - 1].
                    HasAttribute(cellStateToCount).ToInt();                RetVal += Parent[X, Y + 1].
                    HasAttribute(cellStateToCount).ToInt();                  RetVal += Parent[X - 1, Y].                    HasAttribute(cellStateToCount).ToInt();
                 // We are arranging the cells in a hexagon
                // Thats why its less 2 neighbors to check                // But we have to swap neighbors every 2nd
                // line                if (!Parent.HexagonGrid)
                {                    RetVal += Parent[X - 1, Y - 1].
                        HasAttribute(cellStateToCount).ToInt();                    RetVal += Parent[X - 1, Y + 1].
                        HasAttribute(cellStateToCount).ToInt();                    RetVal += Parent[X + 1, Y - 1].
                        HasAttribute(cellStateToCount).ToInt();                    RetVal += Parent[X + 1, Y + 1].
                        HasAttribute(cellStateToCount).ToInt();                }
                else                {
                    if (XOffset > 0)                    {
                        RetVal += Parent[X + 1, Y - 1].                            HasAttribute(cellStateToCount).ToInt();
                        RetVal += Parent[X + 1, Y + 1].                            HasAttribute(cellStateToCount).ToInt();
                    }                    else
                    {                        RetVal += Parent[X - 1, Y - 1].
                            HasAttribute(cellStateToCount).ToInt();                        RetVal += Parent[X - 1, Y + 1].
                            HasAttribute(cellStateToCount).ToInt();                    }
                }            }
            return RetVal;        }
         // Overload the plus operator
        public static int operator +(int number, Cell cell)        {
            return (cell.Status == CellState.Live ||                cell.Status== CellState.Borned)? 
                number + 1 : number;        }
         // Overload the minus operator
        public static int operator -(int number, Cell cell)        {
            return (cell.Status == CellState.Live ||                cell.Status == CellState.Borned) ? 
                number - 1 : number;        }
         // Override ToString
        public override string ToString()        {
            return "Cell " + X + " " + Y + " " +                 Status.ToString();
        }    }
     public class Cells
    {        internal int PopulationInternal { get; set; }
        internal Random Randomize { get; set; }          public int Population { get { return PopulationInternal; } }        public bool HexagonGrid { get; set; }
         private Cell[,] Lifeforms;
        public Cell this[int x, int y]        {
            get { return Lifeforms[x, y]; }            set { Lifeforms[x, y] = value; }
        }          private World _parent;        public World Parent
        { get { return _parent; } }                public Cells(World world)        {
            _parent = world;            Lifeforms = new Cell[Parent.Width, Parent.Height];
            PopulationInternal = 0;              // Populate with cells            for (int x=0; x < Parent.Width; x++)
            {                for (int y=0; y < Parent.Height; y++)
                {                    Lifeforms[x, y] = new Cell(this, x, y);
                }            }
             // Initialize Randomizer
            int Seed;            if (!int.TryParse(
                DateTime.Now.ToString("ffffff"), out Seed))                Seed = DateTime.Now.Second;
            Randomize = new Random(Seed);        }
         // Make sure to kill the cells
        ~Cells()        {
            for (int x = 0; x < Parent.Width; x++)            {
                for (int y = 0; y < Parent.Height; y++)                {
                    Lifeforms[x, y] = null;                }
            }            _parent = null;
        }          // Randomly Populate        public void Populate()
        {            // Calculate abundancy of life
            int Abundancy = ((Parent.Width-2) *                (Parent.Height-2)) * 
                Parent.LifeAbundancy / 100;            // randomly scatter cells
            int RandomY;            while (Abundancy > 0)
            {                for (int x = 1; x < Parent.Width - 2; x++)
                {                    RandomY = Randomize.
                        Next(1, Parent.Height - 2);                    Abundancy -= 
                        this[x, RandomY].                        RandomizeLife();
                }            }
        }    }
     public class World
    {        public Cells Cells { get; set; }
        public int Width { get; set; }        public int Height { get; set; }
        public int GridSize { get; set; }        public int StableGenerations { get; set; }
        public bool Zombies { get; set; }        public bool Mutants { get; set; }
        public int StableGenerationCounter        { get { return StabilityCounter; } }
         private bool _isStable = false;
        public bool IsStable { get { return _isStable; } }          private int _lifeAbundancy = 10;        public int LifeAbundancy
        {            get { return _lifeAbundancy; }
            set            {
                if (value < 0)                    _lifeAbundancy = 0;
                else if (value > 100)                    _lifeAbundancy = 100;
                else                    _lifeAbundancy = value;
            }        }
         public World()
        {            StableGenerations = 10;
        }          public void Initialize()        {
            if (Width < 4) Width = 4;            if (Height < 4) Height = 4;
            if (GridSize < 4) GridSize = 4;            Cells = new Cells(this);
            Cells.Populate();        }
         private int StabilityCounter = 0;
        private int OldPopulation = 0;        public void Refresh()
        {            for(int y=1; y<Height-2;y++)
            {                for(int x =1;x<Width-2 ;x++)
                {                    Cells[x,y].RefreshCellStatus();
                }            }
             if (Cells.Population > OldPopulation - 3 && 
                Cells.Population < OldPopulation + 3)                StabilityCounter++;
            else                StabilityCounter = 0;
             if (StabilityCounter == StableGenerations)
                _isStable = true;              OldPopulation = Cells.Population;        }
    }      internal static class Extensions    {
        public static int ToInt(this bool value)        {
            if(value) return 1;            else return 0;
        }    }
} 
GeSHi 1.0.8.8
Kategorien:.NET, C# Schlagwörter: