- What language is this for?
C# - Which rule?
S2583 C# static code analysis - Why do you believe it’s a false-positive/false-negative?
The code is reachable and works fine. I appended a program that proves this - Are you using
- SonarLint
Visual studio 2022, SonarLint version 7.3.0.77872
- SonarLint
- How can we reproduce the problem? Give us a self-contained snippet of code (formatted text, no screenshots)
This is a connect 4 code that I was working with. The IsWinningMove() Method gives me the false positive in the if statement checking the amount of tokens when checking if there are 4 tokens in a row.
I understand the code is quite tricky to follow so I thought the linter probably had issues with it, I made an alternative version with cleaner syntax to see if it would help but it doesn’t.
The main function creates a board and then executes the test so you can see that it indeed passes and it can evaluate to true unlike what the linter suggest.
If you need more information I would be happy to provide it
public class Program
{
public static void Main(string[] args)
{
Board board = new Board();
board.CreatePosition();
bool result = board.IsWinningMove(0);
Console.WriteLine(result); // prints true, so the check succeeds even though sonarlint says it won't
bool resultAlt = board.IsWinningMoveAlternative(0);
Console.WriteLine(resultAlt);
}
class Board
{
public Board()
{
_currentPlayerIndex = 0;
_board = new int[10, 10];
_highestRowIndex = new int[10];
for (int i = 0; i < BoardWidth; i++)
_highestRowIndex[i] = 9;
}
public void CreatePosition()
{
_board[1, 9] = 1;
_board[2, 9] = 1;
_board[3, 9] = 1;
_highestRowIndex[1] = 8;
_highestRowIndex[2] = 8;
_highestRowIndex[3] = 8;
}
private readonly int[,] _board;
private int BoardWidth => _board.GetLength(0);
private int BoardHeight => _board.GetLength(1);
private int CurrentTurnToken => _currentPlayerIndex == 0 ? 1 : 2;
private int _currentPlayerIndex;
private readonly int[] _highestRowIndex;
public bool IsWinningMove(int col)
{
// vertical check goes here but omitted for brevity
for (int dy = -1; dy <= 1; dy++)
{ // Iterate on horizontal (dy = 0) or two diagonal directions (dy = -1 or dy = 1).
int numberOfTokens = 0; // counter of the number of tokens of current player surrounding the played token in tested direction.
for (int dx = -1; dx <= 1; dx += 2) // count continuous tokens of current player on the left, then right of the played column.
for (int x = col + dx, y = _highestRowIndex[col] + dx * dy;
x >= 0 && x < BoardWidth && y >= 0 && y < BoardHeight && _board[x, y] == CurrentTurnToken;
numberOfTokens++)
{
x += dx;
y += dx * dy;
}
// false positive in this if statement
if (numberOfTokens >= 3) // there is an alignment if at least 3 other tokens of the current user
return true; // are surrounding the played token in the tested direction.
} // honestly I don't really know how this works but it does lmao
return false;
}
public bool IsWinningMoveAlternative(int col)
{
// vertical check goes here but omitted for brevity
for (int dy = -1; dy <= 1; dy++)
{ // Iterate on horizontal (dy = 0) or two diagonal directions (dy = -1 or dy = 1).
int numberOfTokens = 0; // counter of the number of tokens of current player surrounding the played token in tested direction.
for (int dx = -1; dx <= 1; dx += 2) // count continuous tokens of current player on the left, then right of the played column.
{
int x = col + dx;
int y = _highestRowIndex[col] + dx * dy;
while (x >= 0 && x < BoardWidth && y >= 0 && y < BoardHeight && _board[x, y] == CurrentTurnToken)
{
numberOfTokens++;
x += dx;
y += dx * dy;
}
}
// changing the stuff above to something more readable still results in the error
if (numberOfTokens >= 3) // there is an alignment if at least 3 other tokens of the current user
return true; // are surrounding the played token in the tested direction.
} // honestly I don't really know how this works but it does lmao
return false;
}
}
}