[C#] Turn The Lights On

    • Release

    Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von faxe1008.

      [C#] Turn The Lights On

      Name des Spiels:
      Turn The Lights On

      Beschreibung:
      Dies ist mein erstes kleines C# Spiel, das in einer Freistunde aufgrund von Langeweile entstanden ist (Danke hierbei an @BjöNi: s OnlineIDE). Durch das Klicken auf ein Feld wird das Feld rechts, links, unterhalb, oberhalb und das Feld selbst umgeschaltet. Ziel des Spiels ist es das gesamte Raster zu beleuchten.

      Screenshot(s):


      Verwendete Programmiersprache und IDE:
      Visual C# IDE: Visual Studio 2013

      Systemanforderungen:
      .NET Framework 3.0

      Lizenz/Weitergabe:
      Freeware
      Dateien

      8-) faxe1008 8-)

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „faxe1008“ ()

      Hey,

      nette Spiel.

      Fehler: Wählt man Feldgröße 50, so stürzt das Programm mit einer IndexOutOfRange-Exception ab. Minimiert man das Spiel und holt das Fenster wieder zurück, so ist das Spielfeld nur noch grau. Aktualisiert sich erst wieder, nachdem geklickt wurde. Mit zunehmender Größe des Feldes tritt dieser unschöne Effekt auf:



      Insgesamt ist die Optik => naja :whistling: Könnte man bestimmt noch dran arbeiten. Online-Highscore wäre noch ne Ergänzung. Ansonsten, wie gesagt, nette Idee.
      Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
      Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

      SpaceyX schrieb:

      Wählt man Feldgröße 50, so stürzt das Programm mit einer IndexOutOfRange-Exception ab.

      Ja das Problem ist, dass ich ein 50,50 Boolean Array verwende und dass das anscheinend diesen Überlauf produziert. Ich wollte das Array zwar Resizen aber zweidimensionale Array stellen die Function nicht bereit. Dafür muss ich mir noch was überlegen.

      Was den nächsten Bug betrifft habe ich keine Ahnung woran das liegt ich zeichne im Paint Event ?(

      SpaceyX schrieb:

      Insgesamt ist die Optik => naja :whistling:


      Vorschläge? :D

      SpaceyX schrieb:

      nette Idee.

      Danke :)

      8-) faxe1008 8-)
      Nein, fürs Design habe ich keine Vorschläge, da ich wohl derjenige bin, der von so etwas am wenigsten Ahnung hat 8o

      Ein Tipp aber: Arbeite objektorientiert. Ein weiterer Hinweis. Ein Rectangle hat eine .Contains()-Funktion, welche einen Point entgegen nimmt.
      Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
      Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
      Ok das Minimize Problem hab ich gelöst.

      SpaceyX schrieb:

      Ein Tipp aber: Arbeite objektorientiert.

      Wo hab ich hier nicht objektorientiert gearbeitet? Das mit dem Rectangle.Contains ist mir durchaus bekannt, aber ich prüfe nicht ob die Mauskoordinate in einem der Rasterfelder liegt.

      Für alle, die sonst noch ne Idee haben(Das Projekt ist damit OpenSource):


      Spoiler anzeigen

      VB.NET-Quellcode

      1. using System;
      2. using System.Collections.Generic;
      3. using System.ComponentModel;
      4. using System.Data;
      5. using System.Drawing;
      6. using System.Text;
      7. using System.Drawing.Drawing2D;
      8. using System.Windows.Forms;
      9. namespace Turn_The_Lights_On
      10. {
      11. public partial class Form1 : Form
      12. {
      13. public Form1()
      14. {
      15. InitializeComponent();
      16. }
      17. Boolean[,] field = new Boolean[50,50];
      18. Boolean invalidated_btn = false;
      19. int cell_height = 0;
      20. int cell_width = 0;
      21. int numbs = 0;
      22. decimal val;
      23. private void btn_new_Click(object sender, EventArgs e)
      24. {
      25. btn_new.Enabled = false;
      26. numericSize.Enabled = false;
      27. val = numericSize.Value;
      28. for (int x = 0; x <= val; x++)
      29. {
      30. for (int y = 0; y <= val; y++)
      31. {
      32. field[x, y] = false;
      33. }
      34. }
      35. numbs = 0;
      36. draws.Text = "Züge: " + numbs.ToString();
      37. invalidated_btn = true;
      38. pbshow.Invalidate();
      39. }
      40. public void prepare_field(Graphics gr) {
      41. cell_height = int.Parse((pbshow.Height / val).ToString());
      42. cell_width = int.Parse((pbshow.Width / val).ToString());
      43. for (int zähler = 0; zähler <= val; zähler++)
      44. {
      45. gr.DrawLine(Pens.Black, new Point(0, cell_height * zähler), new Point(pbshow.Width, cell_height * zähler));
      46. }
      47. for (int zähler = 0; zähler <= val; zähler++)
      48. {
      49. gr.DrawLine(Pens.Black, new Point(cell_width * zähler, 0), new Point(cell_width * zähler, pbshow.Height));
      50. }
      51. }
      52. public void DrawField(Graphics gr) {
      53. for (int x = 0; x <= val; x++) {
      54. for (int y = 0; y <= val; y++)
      55. {
      56. if (field[x,y] == true){
      57. int cordinate_x = x * cell_width;
      58. int cordinate_y = y * cell_height;
      59. Rectangle rect = new Rectangle(cordinate_x +1,cordinate_y +1,cell_width -2,cell_height-2);
      60. using (LinearGradientBrush lgb = new LinearGradientBrush(rect, Color.Red, Color.DarkRed , LinearGradientMode.ForwardDiagonal))
      61. {
      62. gr.FillEllipse(lgb, rect);
      63. }
      64. }
      65. }
      66. }
      67. }
      68. public Boolean CheckVictoy() {
      69. Boolean won = true;
      70. for (int x = 0; x <= val - 1; x++)
      71. {
      72. for (int y = 0; y <= val - 1; y++)
      73. {
      74. if (field[x, y] == false) {
      75. won = false;
      76. }
      77. }
      78. }
      79. return won;
      80. }
      81. private void pictureBox1_Paint(object sender, PaintEventArgs e)
      82. {
      83. e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
      84. e.Graphics.InterpolationMode = InterpolationMode.Bilinear;
      85. Rectangle rect = new Rectangle(0,0,pbshow.Width,pbshow .Height);
      86. using (LinearGradientBrush lgb = new LinearGradientBrush(rect, Color.White, Color.LightGray , LinearGradientMode.ForwardDiagonal))
      87. {
      88. e.Graphics.FillRectangle(lgb, rect);
      89. }
      90. if (invalidated_btn==true){
      91. prepare_field(e.Graphics);
      92. DrawField(e.Graphics);
      93. invalidated_btn = false;
      94. }
      95. }
      96. Point pt;
      97. private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
      98. {
      99. pt = e.Location;
      100. }
      101. private void pictureBox1_Click(object sender, EventArgs e)
      102. {
      103. numbs = numbs + 1;
      104. draws.Text = "Züge: " + numbs.ToString();
      105. int x = int.Parse((pt.X / cell_width).ToString());
      106. int y = int.Parse((pt.Y / cell_height).ToString());
      107. field[x, y] = !field[x, y];
      108. if (x > 0) { field[x - 1, y] = !field[x - 1, y]; }
      109. if (x + 1 < val) { field[x + 1, y] = !field[x + 1, y]; }
      110. if (y > 0) { field[x, y - 1] = !field[x, y - 1]; }
      111. if (y + 1 < val) { field[x, y + 1] = !field[x, y + 1]; }
      112. invalidated_btn = true;
      113. pbshow.Invalidate();
      114. if (CheckVictoy() == true) {
      115. MessageBox.Show("Glückwunsch, sie haben gewonnen.", "Gewonnen");
      116. btn_new.Enabled = true;
      117. numericSize.Enabled = true;
      118. }
      119. }
      120. private void btn_cancel_Click(object sender, EventArgs e)
      121. {
      122. for (int x = 0; x <= val; x++)
      123. {
      124. for (int y = 0; y <= val; y++)
      125. {
      126. field[x, y] = false;
      127. }
      128. }
      129. btn_new.Enabled = true;
      130. numericSize.Enabled = true;
      131. }
      132. private void Form1_Resize(object sender, EventArgs e)
      133. {
      134. invalidated_btn = true;
      135. pbshow.Invalidate();
      136. }
      137. }
      138. }


      Offtopic: Irgendwie buggt der Downloadzähler 570 Downloads in einer Stunde?

      8-) faxe1008 8-)
      Läuft unter Linux :)
      Ich muss mich auch ma dransetzen und das 6x6 Feld meistern.. ^^

      // Edit
      Jetzt ma noch ne Frage..
      Warum Invalidaten eigentlich immer alle?
      Ist nicht eigentlich Refresh() die richtige funktion?

      Meines Wissens nach erklärt Invalidate() nur bestimmte bereiche für ungültig, ohne sie neu zu zeichnen.
      Das Invalidaten und neuzeichnen sollte doch eigentlich durch Refresh() passiere, oder nicht?
      571 mal heruntergeladen - zuletzt: Heute, 21:10)

      Respekt. Was das Spiel angeht: Das Design ist für mich nen bisschen gewöhnungsbedürftig, aber die Idee is nice ;)
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      @Artentus: Entschuldige habe deinen Post überlesen :S . Wie kann ich in der Routine eine Variable erstellen, die auch in anderen Subs verfügbar ist?

      Trade schrieb:

      571 mal heruntergeladen - zuletzt: Heute, 21:10) Respekt


      Wie oben erwähnt, das Ding buggt gerade anscheinend.

      Trade schrieb:

      Das Design ist für mich nen bisschen gewöhnungsbedürftig,

      Wie gesagt es steht euch allen frei Vorschläge zu machen... ;)

      EDIT:// Problem gelöst:
      Spoiler anzeigen

      VB.NET-Quellcode

      1. using System;
      2. using System.Collections.Generic;
      3. using System.ComponentModel;
      4. using System.Data;
      5. using System.Drawing;
      6. using System.Text;
      7. using System.Drawing.Drawing2D;
      8. using System.Windows.Forms;
      9. namespace Turn_The_Lights_On
      10. {
      11. public partial class Form1 : Form
      12. {
      13. public Form1()
      14. {
      15. InitializeComponent();
      16. }
      17. Boolean[,] field = new Boolean[1,1];
      18. Boolean invalidated_btn = false;
      19. int cell_height = 0;
      20. int cell_width = 0;
      21. int numbs = 0;
      22. decimal val;
      23. private void btn_new_Click(object sender, EventArgs e)
      24. {
      25. btn_new.Enabled = false;
      26. numericSize.Enabled = false;
      27. val = numericSize.Value;
      28. field = new Boolean[int.Parse((val + 1).ToString()), int.Parse((val + 1).ToString())];
      29. for (int x = 0; x <= val; x++)
      30. {
      31. for (int y = 0; y <= val; y++)
      32. {
      33. field[x, y] = false;
      34. }
      35. }
      36. numbs = 0;
      37. draws.Text = "Züge: " + numbs.ToString();
      38. invalidated_btn = true;
      39. pbshow.Invalidate();
      40. }
      41. public void prepare_field(Graphics gr) {
      42. cell_height = int.Parse((pbshow.Height / val).ToString());
      43. cell_width = int.Parse((pbshow.Width / val).ToString());
      44. for (int zähler = 0; zähler <= val; zähler++)
      45. {
      46. gr.DrawLine(Pens.Black, new Point(0, cell_height * zähler), new Point(pbshow.Width, cell_height * zähler));
      47. }
      48. for (int zähler = 0; zähler <= val; zähler++)
      49. {
      50. gr.DrawLine(Pens.Black, new Point(cell_width * zähler, 0), new Point(cell_width * zähler, pbshow.Height));
      51. }
      52. }
      53. public void DrawField(Graphics gr) {
      54. for (int x = 0; x <= val; x++) {
      55. for (int y = 0; y <= val; y++)
      56. {
      57. if (field[x,y] == true){
      58. int cordinate_x = x * cell_width;
      59. int cordinate_y = y * cell_height;
      60. Rectangle rect = new Rectangle(cordinate_x +1,cordinate_y +1,cell_width -2,cell_height-2);
      61. using (LinearGradientBrush lgb = new LinearGradientBrush(rect, Color.Red, Color.DarkRed , LinearGradientMode.ForwardDiagonal))
      62. {
      63. gr.FillEllipse(lgb, rect);
      64. }
      65. }
      66. }
      67. }
      68. }
      69. public Boolean CheckVictoy() {
      70. Boolean won = true;
      71. for (int x = 0; x <= val - 1; x++)
      72. {
      73. for (int y = 0; y <= val - 1; y++)
      74. {
      75. if (field[x, y] == false) {
      76. won = false;
      77. }
      78. }
      79. }
      80. return won;
      81. }
      82. private void pictureBox1_Paint(object sender, PaintEventArgs e)
      83. {
      84. e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
      85. e.Graphics.InterpolationMode = InterpolationMode.Bilinear;
      86. Rectangle rect = new Rectangle(0,0,pbshow.Width,pbshow .Height);
      87. using (LinearGradientBrush lgb = new LinearGradientBrush(rect, Color.White, Color.LightGray , LinearGradientMode.ForwardDiagonal))
      88. {
      89. e.Graphics.FillRectangle(lgb, rect);
      90. }
      91. if (invalidated_btn==true){
      92. prepare_field(e.Graphics);
      93. DrawField(e.Graphics);
      94. invalidated_btn = false;
      95. }
      96. }
      97. Point pt;
      98. private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
      99. {
      100. pt = e.Location;
      101. }
      102. private void pictureBox1_Click(object sender, EventArgs e)
      103. {
      104. numbs = numbs + 1;
      105. draws.Text = "Züge: " + numbs.ToString();
      106. int x = int.Parse((pt.X / cell_width).ToString());
      107. int y = int.Parse((pt.Y / cell_height).ToString());
      108. field[x, y] = !field[x, y];
      109. if (x > 0) { field[x - 1, y] = !field[x - 1, y]; }
      110. if (x + 1 < val) { field[x + 1, y] = !field[x + 1, y]; }
      111. if (y > 0) { field[x, y - 1] = !field[x, y - 1]; }
      112. if (y + 1 < val) { field[x, y + 1] = !field[x, y + 1]; }
      113. invalidated_btn = true;
      114. pbshow.Invalidate();
      115. if (CheckVictoy() == true) {
      116. MessageBox.Show("Glückwunsch, sie haben gewonnen.", "Gewonnen");
      117. btn_new.Enabled = true;
      118. numericSize.Enabled = true;
      119. }
      120. }
      121. private void btn_cancel_Click(object sender, EventArgs e)
      122. {
      123. for (int x = 0; x <= val; x++)
      124. {
      125. for (int y = 0; y <= val; y++)
      126. {
      127. field[x, y] = false;
      128. }
      129. }
      130. btn_new.Enabled = true;
      131. numericSize.Enabled = true;
      132. }
      133. private void Form1_Resize(object sender, EventArgs e)
      134. {
      135. invalidated_btn = true;
      136. pbshow.Invalidate();
      137. }
      138. }
      139. }

      8-) faxe1008 8-)

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „faxe1008“ ()

      So hätte ich z.B. das Spielfeld implementiert. Dann einfach jedes mal eine neue Instanz erzeugen.

      C-Quellcode

      1. public class Field
      2. {
      3. readonly bool[,] lights;
      4. public bool this[int x, int y]
      5. {
      6. get { return lights[x, y]; }
      7. }
      8. public Field(int width, int height)
      9. {
      10. lights = new bool[width, height];
      11. }
      12. public void SwitchLights(int x, int y)
      13. {
      14. lights[x, y] = !lights[x, y];
      15. if (x > lights.GetLowerBound(0)) lights[x - 1, y] = !lights[x - 1, y];
      16. if (y > lights.GetLowerBound(1)) lights[x, y - 1] = !lights[x, y - 1];
      17. if (x < lights.GetUpperBound(0)) lights[x + 1, y] = !lights[x + 1, y];
      18. if (y < lights.GetUpperBound(1)) lights[x, y + 1] = !lights[x, y + 1];
      19. }
      20. }
      Was ich noch als zusätzlichen Schwierigkeitsaspekt gut fände, wäre, wenn schon von vornherein bestimmte Felder an wären (das Programm fängt mit einem vollen Feld an und macht ein paar zufällige Züge), ansonsten passt alles :). Für das mit der Grafik wüde ich es so machen: Lampe aus: grauer Kreis; Lampe an: gelber Kreis.
      Gar nicht so einfach, auch wenn ich kurzzeitig aus Frust, nur noch geklickt habe ^^


      Die Farbe rot ist irgendwie doch sehr agressiv.
      Man solte zu beginn einen Colordialog bestätigen oder ähnliches.

      1.000 Downloads in unter 3 stunden, nice one.