I'm creating a fairly simple C# Monogame project using visual studios 2019. I am getting a stack overflow error but it breaks on random lines each time I debug. Sometimes it'll break just on a "{". I think I've had weird errors like this before that seem like something messed up in the lower level code I don't have access to. I've already tried clean code, rebuild project, closing solutions, unloading/reloading project, and restarting my pc. Can anyone help me out?
So I found which code block is breaking somehow.
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
namespace Project1
{
class Map
{
public Vector2 Player;
public Vector2 Destination;
public GameState gamestate = new GameState();
public int Rows { get; set; }
public int Cols { get; set; }
private SpriteBatch spriteBatch;
private Texture2D texture;
private Color[] colors;
private bool[,] state;
private bool[,] next_state;
private Random random = new Random();
public Map(GraphicsDevice graphicsDevice, SpriteBatch spriteBatch, int rows, int cols)
{
texture = new Texture2D(graphicsDevice, cols, rows);
this.spriteBatch = spriteBatch;
colors = new Color[rows * cols];
state = new bool[rows, cols];
next_state = new bool[rows, cols];
this.Rows = rows;
this.Cols = cols;
Player = new Vector2(random.Next(Cols), random.Next(Rows));
Destination = new Vector2(random.Next(Cols), random.Next(Rows));
gamestate.Reset();
}
public void Randomize()
{
Player = new Vector2(random.Next(Cols), random.Next(Rows));
Destination = new Vector2(random.Next(Cols), random.Next(Rows));
for (int r = 0; r < Rows; r )
{
for (int c = 0; c < Cols; c )
{
int ran = random.Next(3);
if (ran == 1) next_state[r, c] = true;
else next_state[r, c] = false;
}
}
next_state[(int)Player.Y, (int)Player.X] = true;
next_state[(int)Destination.Y, (int)Destination.X] = true;
Apply();
}
int neighbors;
public void Step()
{
for (int r = 0; r < Rows; r )
{
for (int c = 0; c < Cols; c )
{
neighbors = 0;
if (r < Rows - 1 && state[r 1, c]) neighbors ;
if (c < Cols - 1 && state[r, c 1]) neighbors ;
if (r > 0 && state[r - 1, c]) neighbors ;
if (c > 0 && state[r, c - 1]) neighbors ;
if (r < Rows - 1 && c < Cols - 1 && state[r 1, c
1]) neighbors ;
if (r > 0 && c > 0 && state[r - 1, c - 1]) neighbors ;
if (r < Rows - 1 && c > 0 && state[r 1, c - 1]) neighbors ;
if (r > 0 && c < Cols - 1 && state[r - 1, c 1]) neighbors ;
if (state[r, c] == true)
{
if (neighbors < 2 || neighbors > 3)
next_state[r, c] = false;
}
else
{
if (neighbors == 3) next_state[r, c] = true;
}
}
}
gamestate.Moves ;
Apply();
}
public void Apply()
{
int i = 0;
state = next_state;
for (int r = 0; r < Rows; r )
{
for (int c = 0; c < Cols; c )
{
if (state[r, c] == true) colors[i] = Color.Black;
else colors[i] = Color.White;
if (state[r, c] == true && Player == new Vector2(c, r)) colors[i] = Color.Red;
else if (state[r, c] == false && Player == new Vector2(c, r)) colors[i] = Color.Green;
if (Destination == new Vector2(c, r)) colors[i] = Color.Blue;
i ;
}
}
texture.SetData(colors);
if (Player == Destination)
{
gamestate.Level ;
gamestate.SaveState();
gamestate.Reset();
Randomize();
}
if (state[(int)Player.Y, (int)Player.X])
{
gamestate.Level = 0;
Randomize();
}
}
Vector2 size_to_draw;
Vector2 position_to_draw;
Rectangle rectangle_to_draw;
public void Draw()
{
size_to_draw = new Vector2(Cols * 15, Rows * 15);
position_to_draw = new Vector2((Game1.screen.X - size_to_draw.X) / 2, (Game1.screen.Y - size_to_draw.Y) / 2);
rectangle_to_draw = new Rectangle((int)position_to_draw.X, (int)position_to_draw.Y, (int)size_to_draw.X, (int)size_to_draw.Y);
spriteBatch.Draw(texture, rectangle_to_draw, Color.White);
gamestate.DrawData(spriteBatch);
}
}
}
When I take out
if (Player == Destination)
{
gamestate.Level ;
gamestate.SaveState();
gamestate.Reset();
Randomize();
}
if (state[(int)Player.Y, (int)Player.X])
{
gamestate.Level = 0;
Randomize();
}
from the Apply() method it lets me run the program. Here is the gamestate class:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
namespace Project1
{
class GameState
{
public float Clock { get; set; }
public int Level { get; set; }
public int Moves { get; set; }
public List<SaveState> saves = new List<SaveState>();
public void SaveState()
{
saves.Add(new SaveState(Level, Moves, Clock));
}
public void Reset()
{
Clock = 0;
Moves = 0;
}
public void DrawData(SpriteBatch spriteBatch)
{
for (int i = 0; i < saves.Count; i )
{
spriteBatch.DrawString(Game1.font, saves[(saves.Count - 1) - i].String, new Vector2(10, 10 (30 * i)), Color.White);
}
}
}
struct SaveState
{
public SaveState(int level, int moves, float time)
{
Level = level;
Moves = moves;
Timestamp = time;
String = " Level: " Level " Moves: " Moves " Time: " Timestamp;
}
int Level;
int Moves;
float Timestamp;
public string String;
}
}
CodePudding user response:
Randomize() calls Apply() and the code you removed from Apply() to make it work calls Randomize(). Since all those (infinite) method calls are pushed on the stack you will eventually get a stack overflow.