gpt4 book ai didi

c# - AI在垂直井字棋c#中发挥不佳

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:36:15 25 4
gpt4 key购买 nike

我正在用 AI 玩井字棋游戏。 AI 表现良好,除非必须以垂直方式取胜。所有其他方式(水平和对角线)都有效

我已经做了很多调试和一步一步,但还没有找到解决方案。我以为你们可以帮助我找到问题并帮助我解决问题!

  int findTwoPions(Boolean?[,] jeu)
{

// La méthode qui selon moi est à modifier car c'est celle ci qui décide la position que doit prendre l'IA quand elle peu gagner

int somme = 0;
int compteurX = 0;
int compteur0 = 0;

//Diagonale descendante
for (int i = 0; i < 3; i++)
{
if ((jeu[0, 0] == false || jeu[1, 1] == false || jeu[2, 2] == false) && (jeu[0, 0] == true || jeu[1, 1] == true || jeu[2, 2] == true))
{
somme += 0;
}
else
{
if (jeu[i, i] == false)
{
compteur0++;
compteurX = 0;
if (compteur0 == 2)
{
somme += 1500;
}
}
else if (jeu[i, i] == true)
{
compteur0 = 0;
compteurX++;
if (compteurX == 2)
{
somme -= 1600;
}
}
}
}

compteurX = 0;
compteur0 = 0;

//Diagonale montante
for (int i = 0; i < 3; i++)
{
if ((jeu[0, 2] == false || jeu[1, 1] == false || jeu[2, 0] == false) && (jeu[0, 2] == true || jeu[1, 1] == true || jeu[2, 0] == true))
{
}
else
{
if (jeu[i, 2 - i] == false)
{
compteur0++;
compteurX = 0;
if (compteur0 == 2)
{
somme += 1500;
}
}
else if (jeu[i, 2 - i] == true)
{
compteurX++;
compteur0 = 0;
if (compteurX == 2)
{
somme -= 1600;
}
}
}
}

//En ligne
for (int i = 0; i < 3; i++)
{
compteurX = 0;
compteur0 = 0;

if ((jeu[0, i] == false || jeu[1, i] == false || jeu[2, i] == false) && (jeu[0, i] == true || jeu[1, i] == true || jeu[2, i] == true))
{
somme += 0;
}
else
{
//Verticale
for (int j = 0; j < 3; j++)
{

if (jeu[j, i] == false)
{
compteur0++;
compteurX = 0;
if (compteur0 == 2)
{
somme += 1500;
}
}
else if (jeu[j, i] == true)
{
compteurX++;
compteur0 = 0;
if (compteurX == 2)
{
somme -= 1600;

}
}

}
}

compteurX = 0;
compteur0 = 0;

if ((jeu[i, 0] == false || jeu[i, 1] == false || jeu[i, 2] == false) && (jeu[i, 0] == true || jeu[i, 1] == true || jeu[i, 2] == true))
{
return somme += 0;
} // Voir les valeurs i j pcque c'est faux
else
{
//Horizontale
for (int j = 0; j < 3; j++)
{

if (jeu[i, j] == false)
{
compteur0++;
compteurX = 0;
if (compteur0 == 2)
{
somme += 1500;
}
}
else if (jeu[i, j] == true)
{
compteurX++;
compteur0 = 0;
if (compteurX == 2)
{
somme -= 1600;
}
}

}
}
}

return somme;
}

}

我认为问题出在我为“somme”添加值时或我在井字游戏中的运行方式。如果您需要更多代码,请告诉我,谢谢!

更新:

我的AIRoutine.cs

public Boolean?[][] IAPlay(Boolean?[][] jeu, int profondeur)
{

int max = -10000;
int tmp, tmp2 = 0, tmpSomme = -10000; // -10000
int tmpBefore = 0;
int maxi = 0, maxj = 0;
int somme = 0;
int biggestSomme = 0;

setTab(jeu); // convertit le tableau[][] en tableau[,]

for (int i = 0; i < 3; i++) // parcours toutes les cases vides du tableau
{
for (int j = 0; j < 3; j++)
{
//Si une case est vide, on joue le coup de l'IA sur cette case et on simule le jeu complet
if (tab[i, j] == null)
{
tab[i, j] = false; // On simule le coup de l'IA
somme = findTwoPions(tab);
tmp = Max(tab, profondeur - 1);



if (tmpBefore < tmp && biggestSomme > somme)
{
tmpSomme = somme + tmpBefore;
}
else if (tmpBefore > tmp && biggestSomme < somme)
{
tmpSomme = somme + tmpBefore;
}
else
{
tmpSomme = tmp + somme;
}

if (somme > biggestSomme)
{
biggestSomme = somme;
tmpBefore = tmp;
}

//|| ((tmp == max) && (r.Next(1, 100) % 2 == 0))
if (tmpSomme >= max)
{
max = tmpSomme;
tmp2 = somme;
maxi = i;
maxj = j;
}
tab[i, j] = null;
}
}
}

tab[maxi, maxj] = false;
return getTab(jeu);
}

最佳答案

让我们以可读可维护的方式来放置它:让我们提取一个方法 WinningLines 我们枚举所有获胜组合(我假设 jue 是二维数组 - bool?[3, 3]):

    using System.Linq;

...

private static IEnumerable<bool?[]> WinningLines(bool?[,] field) {
// Verticals
for (int column = 0; column < 3; ++column)
yield return new bool?[] {field[0, column], field[1, column], field[2, column]};

// Horizontals
for (int row = 0; row < 3; ++row)
yield return new bool?[] {field[row, 0], field[row, 1], field[row, 2]};

// Diagonals
yield return new bool?[] {field[0, 0], field[1, 1], field[2, 2]};
yield return new bool?[] {field[0, 2], field[1, 1], field[2, 0]};
}

现在让我们查询(借助Linq):

  // Do we have any winning combinations for the 1st Player (all 3 true in WinningLines):
bool hasFirstWon = WinningLines(jeu).Any(line => line.All(cell => cell == true));

// Do we have any winning combinations for the 2nd Player (all 3 false in WinningLines):
bool hasSecondWon = WinningLines(jeu).Any(line => line.All(cell => cell == false));

或者,如果您使用 somme 进行操作:

  int somme = 
WinningLines(jeu).Any(line => line.All(cell => cell == true)) ?
1500 // 1st wins
: WinningLines(jeu).Any(line => line.All(cell => cell == false)) ?
-1600 // 2nd wins
: 0; // no-one wins

编辑:现在让我们实现int findTwoPions(Boolean?[,] jeu) 方法的(简单)版本。首先让我们有

private static bool FirstIsOnMove(bool?[,] field) {
int count = 0;

foreach (var item in field)
if (item == true)
count += 1;
else if (item == true)
count -= 1;

return count == 0;
}

方法本身就是

 // This method rates the position in a [-1600..1500] range 
// [1st player has lost..1st player has won]
int findTwoPions(Boolean?[,] jeu) {
// Edge cases: win or lose
if (WinningLines(jeu).Any(line => line.All(cell => cell == true)))
return 1500; // 1st has won
else if (WinningLines(jeu).Any(line => line.All(cell => cell == false)))
return -1600; // 1st has lost

//TODO: add more heuristics (depending who is on move)

// Example: if palayer is on move and can win by its next move?
// Say, we have positions like
// X.. XXO
// OX. Or X.O
// .O. ...
if (FirstIsOnMove(jeu)) {
if (WinningLines(jeu)
.Any(line => line.Sum(item => item == true ? 1 : item == false ? -1 : 0) == 2))
return 1200; // 1st is going to win (unless it makes a blind)
}
else {
if (WinningLines(jeu)
.Any(line => line.Sum(item => item == true ? 1 : item == false ? -1 : 0) == -2))
return -1200; // 2st is going to win (unless it makes a blind)
}

// Neutral position - neither 1st not 2nd have any advantages
return 0;
}

关于c# - AI在垂直井字棋c#中发挥不佳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52182131/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com