<commit_before>package com.castlefrog.agl.domains.connect4;

import java.util.ArrayList;
import java.util.List;

import com.castlefrog.agl.AbstractSimulator;
import com.castlefrog.agl.IllegalActionException;
import com.castlefrog.agl.TurnType;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;

public final class Connect4Simulator extends AbstractSimulator<Connect4State, Connect4Action> {
    private static final int N_AGENTS = 2;
    private static final long ALL_LOCATIONS = (1L << ((Connect4State.HEIGHT + 1) * Connect4State.WIDTH)) - 1;
    private static final long FIRST_COLUMN = (1L << Connect4State.HEIGHT + 1) - 1;
    private static final long BOTTOM_ROW = ALL_LOCATIONS / FIRST_COLUMN;
    private static final long ABOVE_TOP_ROW = BOTTOM_ROW << Connect4State.HEIGHT;

    private static final int[] REWARDS_BLACK_WINS = new int[] { 1, -1 };
    private static final int[] REWARDS_WHITE_WINS = new int[] { -1, 1 };
    private static final int[] REWARDS_NEUTRAL = new int[] { 0, 0 };

    private final int[] columnHeights_;
    private final TurnType turnType_;

    private Connect4Simulator(Connect4State state,
                              TurnType turnType) {
        legalActions_ = new ArrayList<>();
        legalActions_.add(new ArrayList<Connect4Action>());
        legalActions_.add(new ArrayList<Connect4Action>());
        columnHeights_ = new int[Connect4State.WIDTH];
        turnType_ = turnType;
        setState(state);
    }

    private Connect4Simulator(Connect4Simulator simulator,
                              int[] height) {
        super(simulator);
        turnType_ = simulator.getTurnType();
        columnHeights_ = new int[height.length];
        System.arraycopy(height, 0, columnHeights_, 0, height.length);
    }

    public Connect4Simulator copy() {
        return new Connect4Simulator(this, columnHeights_);
    }

    public static Connect4Simulator create(TurnType turnType) {
        return new Connect4Simulator(getInitialState(turnType), turnType);
    }

    public static Connect4Simulator create(Connect4State state,
                                           TurnType turnType) {
        return new Connect4Simulator(state, turnType);
    }

    public void setState(Connect4State state) {
        state_ = state;
        long[] bitBoards = state_.getBitBoards();
        computeRewards(bitBoards);
        computeLegalActions(bitBoards);
    }

    private void computeHeights(long[] bitBoards) {
        long bitBoard = bitBoards[0] | bitBoards[1];
        for (int i = 0; i < Connect4State.WIDTH; i += 1) {
            columnHeights_[i] = (Connect4State.HEIGHT + 1) * i;
            while ((bitBoard & (1L << columnHeights_[i])) != 0) {
                columnHeights_[i] += 1;
            }
        }
    }

    public void stateTransition(List<Connect4Action> actions) {
        Connect4Action action = actions.get(state_.getAgentTurn());
        if (!legalActions_.get(state_.getAgentTurn()).contains(action)) {
            throw new IllegalActionException(action, state_);
        }
        long[] bitBoards = state_.getBitBoards();
        bitBoards[state_.getAgentTurn()] ^= (1L << (columnHeights_[action.getLocation()]++));
        state_ = new Connect4State(bitBoards, getNextAgentTurn(state_.getAgentTurn()));
        computeRewards(bitBoards);
        computeLegalActions(action);
    }

    private void computeLegalActions(Connect4Action action) {
        if (legalActions_.get(state_.getAgentTurn()).isEmpty()) {
            List<Connect4Action> temp = legalActions_.get(0);
            legalActions_.set(0, legalActions_.get(1));
            legalActions_.set(1, temp);
        }
        if (rewards_ == REWARDS_NEUTRAL) {
            if (((1L << columnHeights_[action.getLocation()]) & ABOVE_TOP_ROW) != 0) {
                legalActions_.get(state_.getAgentTurn()).remove(action);
            }
        } else {
            clearLegalActions();
        }
    }

    private void computeLegalActions(long[] bitBoards) {
        clearLegalActions();
        computeHeights(bitBoards);
        if (rewards_ == REWARDS_NEUTRAL) {
            //long bitBoard = bitBoards[0] | bitBoards[1];
            for (int i = 0; i < Connect4State.WIDTH; i += 1) {
                if (((/*bitBoard |*/ (1L << columnHeights_[i])) & ABOVE_TOP_ROW) == 0) {
                    legalActions_.get(state_.getAgentTurn()).add(Connect4Action.valueOf(i));
                }
            }
        }
    }

    private void computeRewards(long[] bitBoards) {
        int height = Connect4State.HEIGHT;
        for (int i = 0; i < bitBoards.length; i += 1) {
            long bitBoard = bitBoards[i];
            long diagonal1 = bitBoard & (bitBoard >> height);
            long horizontal = bitBoard & (bitBoard >> (height + 1));
            long diagonal2 = bitBoard & (bitBoard >> (height + 2));
            long vertical = bitBoard & (bitBoard >> 1);
            if (((diagonal1 & (diagonal1 >> 2 * height)) |
                    (horizontal & (horizontal >> 2 * (height + 1))) |
                    (diagonal2 & (diagonal2 >> 2 * (height + 2))) |
                    (vertical & (vertical >> 2))) != 0) {
                if (i == 0) {
                    rewards_ = REWARDS_BLACK_WINS;
                    return;
                } else {
                    rewards_ = REWARDS_WHITE_WINS;
                    return;
                }
            }
        }
        rewards_ = REWARDS_NEUTRAL;
    }

    private int getNextAgentTurn(int agentTurn) {
        switch (turnType_) {
            case RANDOM:
                return (int)(Math.random() * N_AGENTS);
            case SEQUENTIAL:
                return (agentTurn + 1) % N_AGENTS;
            case RANDOM_ORDER:
                if (agentTurn >= 0) {
                    return ((agentTurn + 1) % N_AGENTS) * -1 - 1;
                } else {
                    return (int)(Math.random() * N_AGENTS);
                }
            case BIDDING:
                throw new NotImplementedException();
        }
        throw new IllegalArgumentException("Invalid TurnType " + turnType_);
    }

    public static Connect4State getInitialState(TurnType turnType) {
        switch (turnType) {
            case RANDOM:
                return new Connect4State(new long[N_AGENTS], (int)(Math.random() * N_AGENTS));
            case SEQUENTIAL:
                return new Connect4State(new long[N_AGENTS], 0);
            case RANDOM_ORDER:
                return new Connect4State(new long[N_AGENTS], (int)(Math.random() * N_AGENTS));
            case BIDDING:
                throw new NotImplementedException();
        }
        throw new IllegalArgumentException("Invalid TurnType " + turnType);
    }

    public int getNAgents() {
        return N_AGENTS;
    }

    public TurnType getTurnType() {
        return turnType_;
    }
}<commit_msg>indicate other turn types have not been implemented<commit_after>package com.castlefrog.agl.domains.connect4;

import java.util.ArrayList;
import java.util.List;

import com.castlefrog.agl.AbstractSimulator;
import com.castlefrog.agl.IllegalActionException;
import com.castlefrog.agl.TurnType;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;

public final class Connect4Simulator extends AbstractSimulator<Connect4State, Connect4Action> {
    private static final int N_AGENTS = 2;
    private static final long ALL_LOCATIONS = (1L << ((Connect4State.HEIGHT + 1) * Connect4State.WIDTH)) - 1;
    private static final long FIRST_COLUMN = (1L << Connect4State.HEIGHT + 1) - 1;
    private static final long BOTTOM_ROW = ALL_LOCATIONS / FIRST_COLUMN;
    private static final long ABOVE_TOP_ROW = BOTTOM_ROW << Connect4State.HEIGHT;

    private static final int[] REWARDS_BLACK_WINS = new int[] { 1, -1 };
    private static final int[] REWARDS_WHITE_WINS = new int[] { -1, 1 };
    private static final int[] REWARDS_NEUTRAL = new int[] { 0, 0 };

    private final int[] columnHeights_;
    private final TurnType turnType_;

    private Connect4Simulator(Connect4State state,
                              TurnType turnType) {
        legalActions_ = new ArrayList<>();
        legalActions_.add(new ArrayList<Connect4Action>());
        legalActions_.add(new ArrayList<Connect4Action>());
        columnHeights_ = new int[Connect4State.WIDTH];
        turnType_ = turnType;
        setState(state);
    }

    private Connect4Simulator(Connect4Simulator simulator,
                              int[] height) {
        super(simulator);
        turnType_ = simulator.getTurnType();
        columnHeights_ = new int[height.length];
        System.arraycopy(height, 0, columnHeights_, 0, height.length);
    }

    public Connect4Simulator copy() {
        return new Connect4Simulator(this, columnHeights_);
    }

    public static Connect4Simulator create(TurnType turnType) {
        return new Connect4Simulator(getInitialState(turnType), turnType);
    }

    public static Connect4Simulator create(Connect4State state,
                                           TurnType turnType) {
        return new Connect4Simulator(state, turnType);
    }

    public void setState(Connect4State state) {
        state_ = state;
        long[] bitBoards = state_.getBitBoards();
        computeRewards(bitBoards);
        computeLegalActions(bitBoards);
    }

    private void computeHeights(long[] bitBoards) {
        long bitBoard = bitBoards[0] | bitBoards[1];
        for (int i = 0; i < Connect4State.WIDTH; i += 1) {
            columnHeights_[i] = (Connect4State.HEIGHT + 1) * i;
            while ((bitBoard & (1L << columnHeights_[i])) != 0) {
                columnHeights_[i] += 1;
            }
        }
    }

    public void stateTransition(List<Connect4Action> actions) {
        Connect4Action action = actions.get(state_.getAgentTurn());
        if (!legalActions_.get(state_.getAgentTurn()).contains(action)) {
            throw new IllegalActionException(action, state_);
        }
        long[] bitBoards = state_.getBitBoards();
        bitBoards[state_.getAgentTurn()] ^= (1L << (columnHeights_[action.getLocation()]++));
        state_ = new Connect4State(bitBoards, getNextAgentTurn(state_.getAgentTurn()));
        computeRewards(bitBoards);
        computeLegalActions(action);
    }

    private void computeLegalActions(Connect4Action action) {
        if (legalActions_.get(state_.getAgentTurn()).isEmpty()) {
            List<Connect4Action> temp = legalActions_.get(0);
            legalActions_.set(0, legalActions_.get(1));
            legalActions_.set(1, temp);
        }
        if (rewards_ == REWARDS_NEUTRAL) {
            if (((1L << columnHeights_[action.getLocation()]) & ABOVE_TOP_ROW) != 0) {
                legalActions_.get(state_.getAgentTurn()).remove(action);
            }
        } else {
            clearLegalActions();
        }
    }

    private void computeLegalActions(long[] bitBoards) {
        clearLegalActions();
        computeHeights(bitBoards);
        if (rewards_ == REWARDS_NEUTRAL) {
            for (int i = 0; i < Connect4State.WIDTH; i += 1) {
                if (((1L << columnHeights_[i]) & ABOVE_TOP_ROW) == 0) {
                    legalActions_.get(state_.getAgentTurn()).add(Connect4Action.valueOf(i));
                }
            }
        }
    }

    private void computeRewards(long[] bitBoards) {
        int height = Connect4State.HEIGHT;
        for (int i = 0; i < bitBoards.length; i += 1) {
            long bitBoard = bitBoards[i];
            long diagonal1 = bitBoard & (bitBoard >> height);
            long horizontal = bitBoard & (bitBoard >> (height + 1));
            long diagonal2 = bitBoard & (bitBoard >> (height + 2));
            long vertical = bitBoard & (bitBoard >> 1);
            if (((diagonal1 & (diagonal1 >> 2 * height)) |
                    (horizontal & (horizontal >> 2 * (height + 1))) |
                    (diagonal2 & (diagonal2 >> 2 * (height + 2))) |
                    (vertical & (vertical >> 2))) != 0) {
                if (i == 0) {
                    rewards_ = REWARDS_BLACK_WINS;
                    return;
                } else {
                    rewards_ = REWARDS_WHITE_WINS;
                    return;
                }
            }
        }
        rewards_ = REWARDS_NEUTRAL;
    }

    private int getNextAgentTurn(int agentTurn) {
        switch (turnType_) {
            case RANDOM:
                return (int)(Math.random() * N_AGENTS);
            case SEQUENTIAL:
                return (agentTurn + 1) % N_AGENTS;
            case RANDOM_ORDER:
                throw new NotImplementedException();
            case BIDDING:
                throw new NotImplementedException();
        }
        throw new IllegalArgumentException("Invalid TurnType " + turnType_);
    }

    public static Connect4State getInitialState(TurnType turnType) {
        switch (turnType) {
            case RANDOM:
                return new Connect4State(new long[N_AGENTS], (int)(Math.random() * N_AGENTS));
            case SEQUENTIAL:
                return new Connect4State(new long[N_AGENTS], 0);
            case RANDOM_ORDER:
                throw new NotImplementedException();
            case BIDDING:
                throw new NotImplementedException();
        }
        throw new IllegalArgumentException("Invalid TurnType " + turnType);
    }

    public int getNAgents() {
        return N_AGENTS;
    }

    public TurnType getTurnType() {
        return turnType_;
    }
}
{'fraction_non_alphanumeric': 0.10588148367075513, 'fraction_numerical': 0.01396482931875277, 'mean_word_length': 2.1922169811320753, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7486506', 'n_tokens_mistral': 3988, 'n_tokens_neox': 3779, 'n_words': 857}