using OECS; namespace TicTacToe; /// /// After each move, checks whether the game has been won or drawn. /// Updates the GameState singleton accordingly. /// public class WinCheckSystem : ISystem { public void Run(World world) { ref var state = ref world.GetSingleton(); if (state.Status != GameStatus.Playing) return; // Build a 3×3 grid of marks using the iterator API. var grid = new Player[3, 3]; var query = world.Query().With().With().Build(); using var iter = world.Select(query); while (iter.MoveNext()) { grid[iter.Current1.Row, iter.Current1.Col] = iter.Current2.Player; } // Check rows. for (int r = 0; r < 3; r++) { if (TryGetWinner(grid[r, 0], grid[r, 1], grid[r, 2], out var winner)) { SetWinner(world, ref state, winner); return; } } // Check columns. for (int c = 0; c < 3; c++) { if (TryGetWinner(grid[0, c], grid[1, c], grid[2, c], out var winner)) { SetWinner(world, ref state, winner); return; } } // Check diagonals. if (TryGetWinner(grid[0, 0], grid[1, 1], grid[2, 2], out var diag1)) { SetWinner(world, ref state, diag1); return; } if (TryGetWinner(grid[0, 2], grid[1, 1], grid[2, 0], out var diag2)) { SetWinner(world, ref state, diag2); return; } // Check draw. if (state.MoveCount >= 9) { state.Status = GameStatus.Draw; world.MarkModified(World.SingletonEntity); } } private static bool TryGetWinner(Player a, Player b, Player c, out Player winner) { if (a != Player.None && a == b && b == c) { winner = a; return true; } winner = Player.None; return false; } private static void SetWinner(World world, ref GameState state, Player winner) { state.Status = winner == Player.X ? GameStatus.XWon : GameStatus.OWon; world.MarkModified(World.SingletonEntity); } }