<commit_before>package com.github.apixandru.games.rummikub.model;

import com.github.apixandru.games.rummikub.model.listeners.CardLocationListener;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

import static com.github.apixandru.games.rummikub.model.Constants.NUM_COLS;
import static com.github.apixandru.games.rummikub.model.Constants.NUM_ROWS;

/**
 * @author <NAME>
 * @since December 22, 2015
 */
public abstract class Grid {

    private final List<CardLocationListener> listeners = new ArrayList<>();

    final Card[][] cards;

    Grid(final int rows, final int cols) {
        this.cards = new Card[rows][cols];
    }


    /**
     * @param card
     * @param x
     * @param y
     * @return
     */
    public boolean placeCard(Card card, int x, int y) {
        if (inBounds(x, y) && isFree(x, y)) {
            cards[y][x] = card;
            informListeners(lstnr -> lstnr.onCardPlaced(card, x, y));
            return true;
        }
        return false;
    }

    /**
     * @param card
     * @param x
     * @param y
     * @return
     */
    public boolean removeCard(final Card card, int x, int y) {
        if (null == card || !inBounds(x, y) || cards[y][x] != card) {
            return false;
        }
        cards[y][x] = null;
        return true;
    }

    /**
     * @param x
     * @param y
     * @return
     */
    private boolean inBounds(final int x, final int y) {
        return y < NUM_ROWS && x < NUM_COLS;
    }

    /**
     * @param signal
     */
    private void informListeners(final Consumer<CardLocationListener> signal) {
        listeners.stream().forEach(signal);
    }

    /**
     * @param x
     * @param y
     * @return
     */
    public boolean isFree(int x, int y) {
        return null == cards[y][x];
    }

    /**
     * @param listener
     */
    public void addListener(final CardLocationListener listener) {
        this.listeners.add(listener);
    }

}
<commit_msg>allow replacing the same card in the same place<commit_after>package com.github.apixandru.games.rummikub.model;

import com.github.apixandru.games.rummikub.model.listeners.CardLocationListener;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

import static com.github.apixandru.games.rummikub.model.Constants.NUM_COLS;
import static com.github.apixandru.games.rummikub.model.Constants.NUM_ROWS;

/**
 * @author <NAME>
 * @since December 22, 2015
 */
public abstract class Grid {

    private final List<CardLocationListener> listeners = new ArrayList<>();

    final Card[][] cards;

    Grid(final int rows, final int cols) {
        this.cards = new Card[rows][cols];
    }


    /**
     * @param card
     * @param x
     * @param y
     * @return
     */
    public boolean placeCard(Card card, int x, int y) {
        if (!inBounds(x, y)) {
            return false;
        }
        // TODO maybe something more IntelliJ-ent
        if (isFree(x, y) || card == cards[y][x]) {
            cards[y][x] = card;
            informListeners(lstnr -> lstnr.onCardPlaced(card, x, y));
            return true;
        }
        return false;
    }

    /**
     * @param card
     * @param x
     * @param y
     * @return
     */
    public boolean removeCard(final Card card, int x, int y) {
        if (null == card || !inBounds(x, y) || cards[y][x] != card) {
            return false;
        }
        cards[y][x] = null;
        return true;
    }

    /**
     * @param x
     * @param y
     * @return
     */
    private boolean inBounds(final int x, final int y) {
        return y < NUM_ROWS && x < NUM_COLS;
    }

    /**
     * @param signal
     */
    private void informListeners(final Consumer<CardLocationListener> signal) {
        listeners.stream().forEach(signal);
    }

    /**
     * @param x
     * @param y
     * @return
     */
    public boolean isFree(int x, int y) {
        return null == cards[y][x];
    }

    /**
     * @param listener
     */
    public void addListener(final CardLocationListener listener) {
        this.listeners.add(listener);
    }

}

{'fraction_non_alphanumeric': 0.12888349514563108, 'fraction_numerical': 0.002912621359223301, 'mean_word_length': 2.1125377643504533, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1372695', 'n_tokens_mistral': 1350, 'n_tokens_neox': 1309, 'n_words': 320}