Вы считаете правильно. Вам просто нужно использовать окно row_number, чтобы выбрать 3 верхних и правильно упорядочить результаты. Посмотрите на код ниже.
df.groupBy("estado","producto").count()
.withColumn("row_num",row_number().over(Window.partitionBy("estado","producto").orderBy(col("count").desc)))
.filter(col("row_num") <= 3)
.drop("row_num")
.orderBy(col("estado"), col("producto"), col("count").desc)
Проверьте эту ссылку для правильного использования row_number в Pyspark. Spark SQL Row_number () PartitionBy Sort Desc
Что-то стоит:
rowSum == 3 || columnSum == 3 || diagnolSum == 3
..?
Другим простым выходом будет сохранение выигрышных позиций в виде данных в массиве и использование цикла для проверки всех возможные условия выигрыша вместо нескольких операторов ifs
// winnable positions
var winnables = new[] {
"012",
"345",
"678",
"036",
"147",
"258",
"048",
"246"
};
// extracted from btnOne Two Three....
var gameState = new[] { "X", "O", "X", "whatever" };
string winner = null;
// check each winnable positions
foreach (var position in winnables) {
var pos1 = int.Parse(position[0].ToString());
var pos2 = int.Parse(position[1].ToString());
var pos3 = int.Parse(position[2].ToString());
if (gameState[pos1] == gameState[pos2] &&
gameState[pos2] == gameState[pos3])
winner = gameState[pos1];
}
// do we have a winner?
if (!string.IsNullOrEmpty(winner))
/* we've got a winner */
По сути, не используйте btnOne btnTwo btnThree, используйте правильный массив кнопок или массив, который сохраняет состояние игры в более доступном формате, и его будет легче вычислить.
Если вы храните свои кнопки в многомерном массиве, вы можете написать несколько методов расширения для получения строк, столбцов и диагоналей .
public static class MultiDimensionalArrayExtensions
{
public static IEnumerable<T> Row<T>(this T[,] array, int row)
{
var columnLower = array.GetLowerBound(1);
var columnUpper = array.GetUpperBound(1);
for (int i = columnLower; i <= columnUpper; i++)
{
yield return array[row, i];
}
}
public static IEnumerable<T> Column<T>(this T[,] array, int column)
{
var rowLower = array.GetLowerBound(0);
var rowUpper = array.GetUpperBound(0);
for (int i = rowLower; i <= rowUpper; i++)
{
yield return array[i, column];
}
}
public static IEnumerable<T> Diagonal<T>(this T[,] array,
DiagonalDirection direction)
{
var rowLower = array.GetLowerBound(0);
var rowUpper = array.GetUpperBound(0);
var columnLower = array.GetLowerBound(1);
var columnUpper = array.GetUpperBound(1);
for (int row = rowLower, column = columnLower;
row <= rowUpper && column <= columnUpper;
row++, column++)
{
int realColumn = column;
if (direction == DiagonalDirection.DownLeft)
realColumn = columnUpper - columnLower - column;
yield return array[row, realColumn];
}
}
public enum DiagonalDirection
{
DownRight,
DownLeft
}
}
И если вы используете TableLayoutPanel
с 3 строками и 3 столбцами, вы можете легко создавать свои кнопки программно и сохранять их в массиве Button [3, 3]
.
Button[,] gameButtons = new Button[3, 3];
for (int row = 0; column <= 3; row++)
for (int column = 0; column <= 3; column++)
{
Button button = new Button();
// button...
gameLayoutPanel.Items.Add(button);
gameButtons[row, column] = button;
}
И проверить победителя:
string player = "X";
Func<Button, bool> playerWin = b => b.Value == player;
gameButtons.Row(0).All(playerWin) ||
// ...
gameButtons.Column(0).All(playerWin) ||
// ...
gameButtons.Diagonal(DiagonalDirection.DownRight).All(playerWin) ||
// ...