// Path: src/main/java/pl/joegreen/sergeants/framework/Actions.java
// public interface Actions {
// 
//     void move(int indexFrom, int indexTo);
// 
//     /**
//      * Direct move between fields. Works only if both fields are neighbours (either horizontally or vertically, not diagonally) - otherwise does nothing and logs error.
//      */
//     void move(Field fieldFrom, Field fieldTo);
// 
//     void move(int indexFrom, int indexTo, boolean moveHalf);
// 
//     /**
//      * Direct move between fields. Works only if both fields are neighbours (either horizontally or vertically, not diagonally) - otherwise does nothing and logs error.
//      * @param moveHalf if true, only half of the army will be moved (equal to double click in browser)
//      */
//     void move(Field fieldFrom, Field fieldTo, boolean moveHalf);
// 
//     void sendChat(String message);
// 
//     void sendTeamChat(String message);
// 
//     void leaveGame();
// 
//     void ping(int index);
// 
//     void ping(Field field);
// 
//     /**
//      * Remove all moves from the move queue.
//      */
//     void clearMoves();
// 
//     /**
//      * Get lower level API that potentially can make it possible to do something that is not possible by this interface.
//      * Use with caution, as using it can potentially make the framework work unexpectedly.
//      */
//     GeneralsApi getBareApi();
// }
// 
// Path: src/main/java/pl/joegreen/sergeants/framework/Bot.java
// public interface Bot {
// 
//     /**
//      * Called on every game state update from server.
//      * @param newGameState Contains current state of the game.
//      */
//     default void onGameStateUpdate(GameState newGameState) {
//         getLogger(Bot.class).info("Received new game state: " + newGameState.toString());
//     }
// 
//     /**
//      * Called when game is won, lost or the connection to the server is lost.
//      * @param gameResult Result of the game.
//      */
//     default void onGameFinished(GameResult gameResult) {
//         getLogger(Bot.class).info("Game finished, result: " + gameResult);
//     }
// 
//     /**
//      * Called when the new game is started.
//      * @param gameStarted Contains basic info about the game (replay id, players in the game).
//      */
//     default void onGameStarted(GameStarted gameStarted) {
//         getLogger(Bot.class).info("Game started: " + gameStarted);
//     }
// 
//     /**
//      * Called on every chat message (game chat, team chat)
//      */
//     default void onChatMessage(ChatMessage chatMessage){
//         getLogger(Bot.class).info("Chat message: " + chatMessage);
//     }
// 
// }


import pl.joegreen.sergeants.framework.Actions;
import pl.joegreen.sergeants.framework.Bot;
import java.util.function.Function;
package pl.joegreen.sergeants.simulator;



class BotInstanceCatcher<T extends Bot> implements Function<Actions, Bot> {

    private final Function<Actions, T> botProvider;
    public T lastCreatedBot;

    public BotInstanceCatcher(Function<Actions, T> botProvider) {
        this.botProvider = botProvider;
    }

    @Override
// Path: src/main/java/pl/joegreen/sergeants/framework/Actions.java
// public interface Actions {
// 
//     void move(int indexFrom, int indexTo);
// 
//     /**
//      * Direct move between fields. Works only if both fields are neighbours (either horizontally or vertically, not diagonally) - otherwise does nothing and logs error.
//      */
//     void move(Field fieldFrom, Field fieldTo);
// 
//     void move(int indexFrom, int indexTo, boolean moveHalf);
// 
//     /**
//      * Direct move between fields. Works only if both fields are neighbours (either horizontally or vertically, not diagonally) - otherwise does nothing and logs error.
//      * @param moveHalf if true, only half of the army will be moved (equal to double click in browser)
//      */
//     void move(Field fieldFrom, Field fieldTo, boolean moveHalf);
// 
//     void sendChat(String message);
// 
//     void sendTeamChat(String message);
// 
//     void leaveGame();
// 
//     void ping(int index);
// 
//     void ping(Field field);
// 
//     /**
//      * Remove all moves from the move queue.
//      */
//     void clearMoves();
// 
//     /**
//      * Get lower level API that potentially can make it possible to do something that is not possible by this interface.
//      * Use with caution, as using it can potentially make the framework work unexpectedly.
//      */
//     GeneralsApi getBareApi();
// }
// 
// Path: src/main/java/pl/joegreen/sergeants/framework/Bot.java
// public interface Bot {
// 
//     /**
//      * Called on every game state update from server.
//      * @param newGameState Contains current state of the game.
//      */
//     default void onGameStateUpdate(GameState newGameState) {
//         getLogger(Bot.class).info("Received new game state: " + newGameState.toString());
//     }
// 
//     /**
//      * Called when game is won, lost or the connection to the server is lost.
//      * @param gameResult Result of the game.
//      */
//     default void onGameFinished(GameResult gameResult) {
//         getLogger(Bot.class).info("Game finished, result: " + gameResult);
//     }
// 
//     /**
//      * Called when the new game is started.
//      * @param gameStarted Contains basic info about the game (replay id, players in the game).
//      */
//     default void onGameStarted(GameStarted gameStarted) {
//         getLogger(Bot.class).info("Game started: " + gameStarted);
//     }
// 
//     /**
//      * Called on every chat message (game chat, team chat)
//      */
//     default void onChatMessage(ChatMessage chatMessage){
//         getLogger(Bot.class).info("Chat message: " + chatMessage);
//     }
// 
// }


// Path: src/test/java/pl/joegreen/sergeants/simulator/BotInstanceCatcher.java
import pl.joegreen.sergeants.framework.Actions;
import pl.joegreen.sergeants.framework.Bot;
import java.util.function.Function;

package pl.joegreen.sergeants.simulator;



class BotInstanceCatcher<T extends Bot> implements Function<Actions, Bot> {

    private final Function<Actions, T> botProvider;
    public T lastCreatedBot;

    public BotInstanceCatcher(Function<Actions, T> botProvider) {
        this.botProvider = botProvider;
    }

    @Override
    public Bot apply(Actions actions) {