C#.NET を使用して戦艦ゲームを構築しています。かなり単純なスコアリング メカニズムを使用することになっています。プレイヤーまたはコンピュータのいずれかが 17 ヒットを記録した場合、沈没船はありません。ヒットを記録すると、別のターンを取得できます。AI は、ヒットを記録するまでランダムに攻撃します。ヒットした時点で、傾向が見つかるまで各方向のタイルを攻撃し、その後、行き止まり (空いているスペースまたはエッジのいずれか) が見つかるまで直線で攻撃を続けます。ボード. コンピューターが攻撃していたのとは反対の方向にヒットされていないスペースがあった場合, その後、それらのスペースを攻撃します. すでにヒットしたスペースをターゲットにしたり、すでにたどられたパターンに従いません.
これまでの私のAIは次のとおりです。
int shipCounter = 0, trend = 0;
static Random rnd = new Random();
bool gameOver = false, playerTurn = false;
int[] score = { 0, 0 };
struct gameData
{
public bool occupied, hit, marked;
}
gameData[,,] data;
public void computerMove()
{
Point target = seekTarget();
try
{
if (data[1, target.X, target.Y].hit)
computerMove();
else
{
data[1, target.X, target.Y].hit = true;
if (data[1, target.X, target.Y].occupied)
{
attacking = true;
score[0]++;
computerMove();
}
}
playerTurn = true;
}
catch (IndexOutOfRangeException)
{ computerMove(); }
}
public Point seekTarget()
{
Point origin = new Point(-1, -1);
//find a point that's been hit.
int x = 0, y = 0;
while (x < gridSize && y < gridSize)
{
if (data[1, x, y].hit && data[1, x, y].occupied && !data[1, x, y].marked)
{
origin = new Point(x, y);
break;
}
x++;
if (x == gridSize && y != gridSize)
{
x = 0;
y++;
}
}
return findTargets(origin);
}
public Point findTargets(Point origin)
{
Point[] lim = { origin, origin, origin, origin };
Point[] possibleTargets = { origin, origin, origin, origin };
//Find the edges.
while (lim[0].X >= -1 && ((!data[1, lim[0].X, lim[0].Y].hit && !data[1, lim[0].X, lim[0].Y].occupied) || (data[1, lim[0].X, lim[0].Y].hit && data[1, lim[0].X, lim[0].Y].occupied)))
{
lim[0].X--;
if (lim[0].X == -1)
break;
}
while (lim[1].Y >= -1 && ((!data[1, lim[0].X, lim[0].Y].hit && !data[1, lim[0].X, lim[0].Y].occupied) || (data[1, lim[0].X, lim[0].Y].hit && data[1, lim[0].X, lim[0].Y].occupied)))
{
lim[1].Y--;
if (lim[1].Y == -1)
break;
}
while (lim[2].X <= gridSize && ((!data[1, lim[0].X, lim[0].Y].hit && !data[1, lim[0].X, lim[0].Y].occupied) || (data[1, lim[0].X, lim[0].Y].hit && data[1, lim[0].X, lim[0].Y].occupied)))
{
lim[2].X++;
if (lim[2].X == gridSize)
break;
}
while (lim[3].Y <= gridSize && ((!data[1, lim[0].X, lim[0].Y].hit && !data[1, lim[0].X, lim[0].Y].occupied) || (data[1, lim[0].X, lim[0].Y].hit && data[1, lim[0].X, lim[0].Y].occupied)))
{
lim[3].Y++;
if (lim[3].Y == gridSize)
break;
}
//Cell targeting AI
}
return new Point(rnd.Next(10), rnd.Next(10));
}
何がうまくいかないのか理解できないため、非常に面倒です。関数を引用しfindTargets
て、コンピューターをランダムに攻撃させるだけでも、問題なく動作します。コンピューターとプレイヤーはターンを交換し、コンピューターはレジスターに当たります。
ただし、有効にfindTargets
すると、プレイヤーは 1 回の攻撃を行うことができ、コンピューターはそのターンを取りません。その後、プレイヤーの攻撃十字線がまだ表示されていても、プレイヤーのターンに戻りません。誰かが助けてくれれば、それは大歓迎です。Paint
またはmouseDown
メソッドが含まれていないことをお詫びします。文字制限を超えています。
UIなしfindTargets
(プレイヤーとコンピューターのトレードターン)。
UI ありfindTargets
(コンピューターはターンを実行できず、プレイヤーは 1 ターンしか実行できません)。
助けてくれてありがとう。
編集:私は問題を分離しました.whileループから抜け出せないようですfindTargets
. origin
のときにループしないようにして問題に対処しても(-1, -1)
、最初のヒットでループに巻き込まれます。
編集 2:最初のループにヒットし、無限にループします。なぜか全然伸びませんlim[0].X
。メッセージボックスをループに挿入してデータを表示すると、2 回表示され、まだループしているにもかかわらず再表示されません。これがなぜなのか誰か知っていますか?