public void ReadConfig() { string config = Console.ReadLine(); _game = new Game(); // NOTE: training currently set up to only work with standard (6 7 4 ...) connect 4 config -- // file format would have to change (rather than concat directly, columns would need to be delimited, etc.) }
public GameStates EvaluateGame(Game game) { GameStates result = EvaluateHorizontal(game); if (result == GameStates.InProgress) result = EvaluateVertical(game); if (result == GameStates.InProgress) result = EvaluateSouthEastDiagonal(game); if (result == GameStates.InProgress) result = EvaluateSouthWestDiagonal(game); if (result == GameStates.InProgress && IsGameADraw(game)) result = GameStates.Draw; return result; }
public GameStates EvaluateHorizontal(Game game) { int myCount; int opponentCount; // iterate over the rows, counting pieces by state for (int r = 0; r < Game.ROWS; r++) { // reset counters for each row myCount = 0; opponentCount = 0; // iterate over the columns for (int c = 0; c < Game.COLUMNS; c++) { // count pieces until an opposing player's piece or blank is encountered, // then reset the appropriate counter(s), and start a new count; // if the required number for a win is reached -- return a win switch (game.Board[r, c]) { case Game.ME: if (++myCount >= Game.PIECES_TO_WIN) return GameStates.WinMe; opponentCount = 0; break; case Game.OPPONENT: if (++opponentCount >= Game.PIECES_TO_WIN) return GameStates.WinOpponent; myCount = 0; break; default: myCount = opponentCount = 0; break; } } } return GameStates.InProgress; }
private int GetRandomValidColumn(Game game, List<int> options) { int result = -1; bool isValid = false; int temp; while (!isValid && options.Count > 0) { temp = options[_rnd.Next(options.Count)]; isValid = _game.IsMoveValid(temp); if (isValid) result = temp; } return result; }
private static void RunGame() { Process p = StartAiPlayer(); string line = p.StandardOutput.ReadLine(); DisplayMessageGreen(string.Format("running player: {0}", line)); string config = string.Format("{0} {1} {2} 0 {3}", Game.ROWS, Game.COLUMNS, Game.PIECES_TO_WIN, Game.TIME_LIMIT); DisplayMessageGreen(string.Format("game config: {0}", config)); p.StandardInput.WriteLine(config); Game game = new Game(); GameEvaluator evaluator = new GameEvaluator(); RandomPlayer player2 = new RandomPlayer(); GameStates gameState = GameStates.InProgress; while (gameState == GameStates.InProgress) { // read the move from player line = p.StandardOutput.ReadLine(); DisplayMessageGreen(string.Format("move from player: {0}", line)); // tie the move to the game state and evaluate game.AcceptMove(Game.ME, int.Parse(line.Trim())); gameState = evaluator.EvaluateGame(game); if (gameState != GameStates.InProgress) { HandleEndGame(gameState, p); break; } // get random player's move int move2 = player2.GetMove(game); game.AcceptMove(Game.OPPONENT, move2); gameState = evaluator.EvaluateGame(game); if (gameState != GameStates.InProgress) { HandleEndGame(gameState, p); break; } DisplayMessageGreen(string.Format("sending move: {0}", move2)); p.StandardInput.WriteLine(move2); } p.WaitForExit(); }
private bool IsGameADraw(Game game) { // if the top row is full, return a Draw bool fullTopRow = true; for (int c = 0; c < Game.COLUMNS; c++) { if (game.Board[0, c] == Game.EMPTY) { fullTopRow = false; break; } } if (fullTopRow) return true; return false; }
private GameStates EvaluateSouthWestDiagonal(Game game) { int myCount = 0; int opponentCount = 0; int row = 0; int column = 0; // check NE diagonal (starting from BOTTOM row) for (int c = 0; c <= (Game.COLUMNS - Game.PIECES_TO_WIN); c++) { // reset the counters myCount = 0; opponentCount = 0; row = Game.ROWS - 1; column = c; while (row >= 0 && column < Game.COLUMNS) { // count pieces until an opposing player's piece or blank is encountered, // then reset the appropriate counter(s), and start a new count; // if the required number for a win is reached -- return a win switch (game.Board[row, column]) { case Game.ME: if (++myCount >= Game.PIECES_TO_WIN) return GameStates.WinMe; opponentCount = 0; break; case Game.OPPONENT: if (++opponentCount >= Game.PIECES_TO_WIN) return GameStates.WinOpponent; myCount = 0; break; default: myCount = opponentCount = 0; break; } row--; column++; } } // check NE diagonal (starting from LEFT column) for (int r = Game.ROWS - 2; r >= Game.PIECES_TO_WIN - 1; r--) { // reset the counters myCount = 0; opponentCount = 0; row = r; column = 0; while (row >= 0 && column < Game.COLUMNS) { // count pieces until an opposing player's piece or blank is encountered, // then reset the appropriate counter(s), and start a new count; // if the required number for a win is reached -- return a win switch (game.Board[row, column]) { case Game.ME: if (++myCount >= Game.PIECES_TO_WIN) return GameStates.WinMe; opponentCount = 0; break; case Game.OPPONENT: if (++opponentCount >= Game.PIECES_TO_WIN) return GameStates.WinOpponent; myCount = 0; break; default: myCount = opponentCount = 0; break; } row--; column++; } } return GameStates.InProgress; }