У меня есть следующая матрица:
0XXXX XXXXX XX @ XX XXXXX XXXXX
Это представление настольной игры. 0 - красная пешка. Х - нормальная пешка. @ - это пустое место на доске. Вы можете просто переместить пешку (красную или нормальную), перепрыгивая через другую пешку (не красную). Это можно сделать горизонтально, вертикально в любом направлении.
Игра заканчивается, когда у вас есть только красная пешка посередине и других пешек не осталось.
Есть так много решений, которые я получаюпереполнение ошибки, когда я просто запускаю синхронизацию. Мне нужен родитель и решения. Каждый ход у меня так много возможностей ...
Сначала я сделал состояние доски (свободный, занятый, красный) (перечисления)
Затем я сделал доску с матричным состоянием доски [,] у этого есть два конструктора ... Один с игрой в качестве параметра, другой с доской. Конечно, есть свойство родительской платы.
Итак ... когда игра является параметром, она только начинается, я генерирую матрицу. Когда доска является параметром, я просто пробегаю по матрице и копирую значения в новое.
У меня есть функция 'losOp' (MakeSolution). Я запускаю это с первой созданной доски.
Если эта доска не указана как 'nosolution' (позже), эта генерирует все возможные новые доски (делая каждый возможный шаг с каждой возможной пешкой). Тогда все эти решения отправляются в стек. Оттуда я снова и снова вызываю функцию «losOp», пока в стеке больше нет решений. Или в параметрических решениях в классе Board.
Когда Board не является решением, я звоню родителю, чтобы удалить меня из моих решений. Если у моего родителя больше не осталось решений, он вызывает своего родителя, чтобы удалить его тоже ...
Но каждое решение, которое не является решением, заносится в список игр noSolutions (в виде матрицы), поэтомумы можем проверить, нужно ли нам вычислять эту плату.
Но .... Это просто продолжает работать .... Или у меня переполнение памяти ...
Яautodidact, и впервые я работаю с потоками, пытаясь асинхронно, но это также дает мне переполнение ошибки ...
Я действительно даже не знаю, есть ли у этой вещи решение ...
Класс Bordvakjes - это просто объект с enum vrij, bezet, rood (свободный, занятый, красный)
Я бегу из формы, это просто начало новой игры
public class Game
{
public Form1 TheForm;
public Bord Start;
//Onoplosbaar = no solutions
public List<Bordvak[,]> Onoplosbaar = new List<Bordvak[,]>();
public Game(Form1 form)
{
Onoplosbaar = new List<Bordvak[,]>();
Start = new Bord(this, form);
}
}
public class Bord
{
//not needed
Form1 form;
//game running
Game theGame;
//current board setup
Bordvak[,] Vakjes;
//current round
int Beurt = 0;
//not needed
int formBeurt = 0;
//will list all possible solutions for this board
public List<Bord> MijnOplossingen;
//get txt with represent board easily instead of matrix
public string afbeelding;
//not needed
public int FormBeurt { get { return formBeurt; } set { formBeurt = value; if (MyParent != null) { MyParent.FormBeurt = value; MyParent.form.Beurt = value; } else { form.setValue(value); } } }
//board from where this board occurred
public Bord MyParent { get; set; }
/// <summary>
/// I'm a solution of a previous board
/// </summary>
/// <param name="parent"></param>
///
public Bord(Bord parent)
{
theGame = parent.theGame;
//form in fact is unessecary, is already in game
form = parent.form;
Vakjes = new Bordvak[5, 5];
for (int rij = 0; rij < 5; rij++)
{
for (int col = 0; col < 5; col++)
{
Vakjes[rij, col] = new Bordvak(parent.Vakjes[rij, col].MyStatus);
}
}
MyParent = parent;
Beurt = parent.Beurt + 1;
//tried for async but still got error overflow
//that's why now with stack
//code still ok i presume
Form1.setPointer pointer = parent.form.setValue;
pointer.Invoke(Beurt);
Application.DoEvents();
}
/// <summary>
/// Im the first board to start, put matrix
/// </summary>
public Bord(Game game, Form1 _form)
{
theGame = game;
form=_form;
form.Show();
Application.DoEvents();
Vakjes = new Bordvak[5,5];
for (int rij = 0; rij < 5; rij++)
{
for (int col = 0; col < 5; col++)
{
if (rij == 0 && col == 0)
Vakjes[0, 0] = new Bordvak(Bordvak.Status.rood);
if (rij == 2 && col == 2)
Vakjes[2, 2] = new Bordvak(Bordvak.Status.vrij);
//is this the best way ????
if (!(rij == 0 && col == 0) && !(rij == 2 && col == 2))
Vakjes[rij, col] = new Bordvak(Bordvak.Status.bezet);
}
}
LosOp();
}
/// <summary>
/// Returns true if this board is the end solution
/// it also generates the string to show the board
/// instead of checking the matrix
/// </summary>
/// <param name="afbeelding"></param>
/// <returns></returns>
public bool Done(ref string afbeelding)
{
bool done = true;
for (int rij = 0; rij < 5; rij++)
{
for (int col = 0; col < 5; col++)
{
if (Vakjes[rij, col].MyStatus == Bordvak.Status.bezet)
{
done = false;
afbeelding += "X";
}else
{
if (Vakjes[rij, col].MyStatus == Bordvak.Status.rood)
{
afbeelding += "O";
}
else
{
afbeelding += "@";
}
}
}
afbeelding += "\n";
}
if (done)
if (Vakjes[2, 2].MyStatus == Bordvak.Status.rood)
done = true;
else
done = false;
return done;
}
/// <summary>
/// Check if this is the end solution
/// if not, do all possible moves
///
/// </summary>
public void LosOp()
{
afbeelding = "";
if (Done(ref afbeelding))
{
MessageBox.Show(afbeelding);
return;
}
//do all possible moves
MijnOplossingen = Oplossingen();
//if i have solutions
if (MijnOplossingen.Count>0)
{
int start = MijnOplossingen.Count - 1;
//loop over every solution
for (int i = start; i > 0; i--)
{
//put solution in stack
Stack<Bord> stack = new Stack<Bord>();
stack.Push(MijnOplossingen[i]);
//loop all solutions in stack
while (stack.Count > 0)
{
Bord current = stack.Pop();
//if this board isn't handled yet,handle
if (!theGame.Onoplosbaar.Contains(current.Vakjes))
{
//check solutions (this fuction)
current.LosOp();
//put every solution back in stack
foreach (Bord bord in current.MijnOplossingen)
{
stack.Push(bord);
}
}
}
//async doesnt work... error overflow
// Task.Factory.StartNew(MijnOplossingen[i].LosOp);
//we made af move
form.Beurt = Beurt;
//update form
Application.DoEvents();
}//go back to stack
}
else //there are no solutions
{
//remove me from my parent's solutions
MyParent.RemoveMe(this);
}
}
public void RemoveMe(Bord me)
{
//i wasn't a solution, put me in memory "unsolved"
theGame.Onoplosbaar.Add(me.Vakjes);
//remove move from possible solutions
MijnOplossingen.Remove(me);
//if i don't have other solutions,
//remove me from my parent's parent too..
if (MijnOplossingen.Count == 0)
MyParent.RemoveMe(this);
}
public List<Bord> Oplossingen()
{
//get all solutions,
//check below, above, left and right
List<Bord> oplossingen = new List<Bord>();
for (int rij = 0; rij < 5; rij++)
{
for (int col = 0; col < 5; col++)
{
//spring naar beneden
if (rij <= 2)
{
//als ik pion of rood ben
if ((Vakjes[rij, col].MyStatus == Bordvak.Status.bezet || Vakjes[rij, col].MyStatus == Bordvak.Status.rood))
{
if (Vakjes[rij + 1, col].MyStatus == Bordvak.Status.bezet && Vakjes[rij + 2, col].MyStatus == Bordvak.Status.vrij)
{
Bord bord = new Bord(this);
bord.Vakjes[rij + 1, col].MyStatus = Bordvak.Status.vrij;
bord.Vakjes[rij + 2, col].MyStatus = Vakjes[rij, col].MyStatus;
bord.Vakjes[rij, col].MyStatus = Bordvak.Status.vrij;
oplossingen.Add(bord);
}
}
}
//spring naar boven
if (rij >= 2)
{
//als ik pion of rood ben
if ((Vakjes[rij, col].MyStatus == Bordvak.Status.bezet || Vakjes[rij, col].MyStatus == Bordvak.Status.rood))
{
if (Vakjes[rij - 1, col].MyStatus == Bordvak.Status.bezet && Vakjes[rij - 2, col].MyStatus == Bordvak.Status.vrij)
{
Bord bord = new Bord(this);
bord.Vakjes[rij - 1, col].MyStatus = Bordvak.Status.vrij;
bord.Vakjes[rij - 2, col].MyStatus = Vakjes[rij, col].MyStatus;
bord.Vakjes[rij, col].MyStatus = Bordvak.Status.vrij;
oplossingen.Add(bord);
}
}
}
//spring naar link
if (col >= 2)
{
//als ik pion of rood ben
if ((Vakjes[rij, col].MyStatus == Bordvak.Status.bezet || Vakjes[rij, col].MyStatus == Bordvak.Status.rood))
{
if (Vakjes[rij, col - 1].MyStatus == Bordvak.Status.bezet && Vakjes[rij, col - 2].MyStatus == Bordvak.Status.vrij)
{
Bord bord = new Bord(this);
bord.Vakjes[rij, col - 1].MyStatus = Bordvak.Status.vrij;
bord.Vakjes[rij, col - 2].MyStatus = Vakjes[rij, col].MyStatus;
bord.Vakjes[rij, col].MyStatus = Bordvak.Status.vrij;
oplossingen.Add(bord);
}
}
}
//spring naar rechts
if (col <= 2)
{
//als ik pion of rood ben
if ((Vakjes[rij, col].MyStatus == Bordvak.Status.bezet || Vakjes[rij, col].MyStatus == Bordvak.Status.rood))
{
if (Vakjes[rij, col + 1].MyStatus == Bordvak.Status.bezet && Vakjes[rij, col + 2].MyStatus == Bordvak.Status.vrij)
{
Bord bord = new Bord(this);
bord.Vakjes[rij, col + 1].MyStatus = Bordvak.Status.vrij;
bord.Vakjes[rij, col + 2].MyStatus = Vakjes[rij, col].MyStatus;
bord.Vakjes[rij, col].MyStatus = Bordvak.Status.vrij;
oplossingen.Add(bord);
}
}
}
}
}
return oplossingen;
}
}
Асинхронизация: ошибка переполнения Синхронизация: ошибка переполнения Стек: очень медленно
Это лучший способ решения моей проблемы ???