<commit_before>package com.diusrex.tictactoe.android;

import android.app.Activity;
import android.app.DialogFragment;
import android.os.Bundle;
import android.view.View;

import com.diusrex.tictactoe.R;
import com.diusrex.tictactoe.dialogs.WinDialogActivityListener;
import com.diusrex.tictactoe.dialogs.WinDialogFragment;
import com.diusrex.tictactoe.logic.BoardStatus;
import com.diusrex.tictactoe.logic.BoxPosition;
import com.diusrex.tictactoe.logic.Move;
import com.diusrex.tictactoe.logic.Player;
import com.diusrex.tictactoe.logic.SectionPosition;
import com.diusrex.tictactoe.logic.TicTacToeEngine;
import com.diusrex.tictactoe.logic.UndoAction;

import java.util.Calendar;

public class GameActivity extends Activity implements GameEventHandler, WinDialogActivityListener {
    static public final String IS_NEW_GAME = "IsNewGame";
    static private final long COOLDOWN = 250;

    BoardStatus board;
    Player currentPlayer;

    BoardStateSaverAndLoader saverAndLoader;

    GameGraphicsUpdater graphicsUpdater;

    long previousTime;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);

        saverAndLoader = new BoardStateSaverAndLoader(this);

        MainGridOwner mainGridOwner = new MainGridOwner(this, this, (MyGrid) findViewById(R.id.mainGrid));
        graphicsUpdater = new GameGraphicsUpdater(mainGridOwner);

        boolean newGame = getIntent().getBooleanExtra(IS_NEW_GAME, true);
        if (newGame) {
            saverAndLoader.resetBoardState();

            // Make sure it does not try this again
            getIntent().putExtra(IS_NEW_GAME, false);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        board = saverAndLoader.loadBoard();
        updateCurrentPlayer();

        graphicsUpdater.redrawBoard(this, board);

        SectionPosition selectedSection = saverAndLoader.loadSelectedSection(board);

        if (!winnerExists()) {
            prepareForNextMove(getCurrentTime(), selectedSection);
        } else {
            // Will now reshow the win dialog if there is a winner
            disablePerformingMove();
            sectionSelected(selectedSection);
        }
    }

    private void updateCurrentPlayer() {
        currentPlayer = TicTacToeEngine.getNextPlayer(board);
    }

    @Override
    protected void onPause() {
        super.onPause();

        saverAndLoader.saveGameState(board);
    }

    @Override
    public void boxSelected(BoxPosition position) {
        Move move = new Move(position, currentPlayer);

        long currentTime = getCurrentTime();
        if (TicTacToeEngine.isValidMove(board, move) && currentTime - previousTime > COOLDOWN) {
            TicTacToeEngine.applyMoveIfValid(board, move);
            graphicsUpdater.redrawBoard(this, board);

            handleWinOrPrepareForNextMove(position, currentTime);
        }
    }

    private void handleWinOrPrepareForNextMove(BoxPosition position, long currentTime) {
        if (winnerExists()) {
            handleWin(position);
        } else {
            prepareForNextMove(currentTime, board.getSectionToPlayIn());
        }
    }

    private boolean winnerExists() {
        return TicTacToeEngine.getWinner(board) != Player.Unowned;
    }

    private void prepareForNextMove(long currentTime, SectionPosition selectedSection) {
        updateCurrentPlayer();

        sectionSelected(selectedSection);

        graphicsUpdater.sectionToPlayInChanged(board.getSectionToPlayIn());

        previousTime = currentTime;
    }

    private void handleWin(BoxPosition position) {
        graphicsUpdater.updateWinLine(board);

        sectionSelected(position.getSectionIn());

        String winningPlayer = getPlayerAsString();
        disablePerformingMove();

        showWinDialog(winningPlayer);
    }

    private void disablePerformingMove() {
        // Will not allow the player unowned to play
        currentPlayer = Player.Unowned;

        // There is no section to play into
        graphicsUpdater.sectionToPlayInChanged(SectionPosition.make(-1, -1));
    }

    private void showWinDialog(String winningPlayer) {
        DialogFragment fragment = WinDialogFragment.newInstance(winningPlayer);
        fragment.show(getFragmentManager(), "dialog");
    }

    @Override
    public void sectionSelected(SectionPosition section) {
        saverAndLoader.selectedSectionChanged(section);
        updateGraphicalSelectedSection(section);
    }

    private void updateGraphicalSelectedSection(SectionPosition section) {
        SectionOwner mainSection = new SelectedSectionOwner(section, (MyGrid) findViewById(R.id.selectedSection), this);
        graphicsUpdater.selectedSectionChanged(this, board, mainSection, section);
    }

    private long getCurrentTime() {
        Calendar c = Calendar.getInstance();
        return c.getTimeInMillis();
    }

    public void undoMove(View v) {
        if (canUndoLastMove()) {
            Move lastMove = board.getAllMoves().peek();

            UndoAction.undoLastMove(board);

            graphicsUpdater.redrawBoard(this, board);
            prepareForNextMove(getCurrentTime(), board.getSectionToPlayIn());
        }
    }

    private String getPlayerAsString() {
        switch (currentPlayer) {
        case Player_1:
            return getString(R.string.player_1);

        case Player_2:
            return getString(R.string.player_2);

        default:
            return getString(R.string.no_player);
        }
    }
<commit_msg>Changed GameActivity to be able to handle draws.<commit_after>package com.diusrex.tictactoe.android;

import android.app.Activity;
import android.app.DialogFragment;
import android.os.Bundle;
import android.view.View;

import com.diusrex.tictactoe.R;
import com.diusrex.tictactoe.android.dialogs.DrawDialogFragment;
import com.diusrex.tictactoe.android.dialogs.GameEndActivityListener;
import com.diusrex.tictactoe.android.dialogs.WinDialogFragment;
import com.diusrex.tictactoe.logic.BoardStatus;
import com.diusrex.tictactoe.logic.BoxPosition;
import com.diusrex.tictactoe.logic.Move;
import com.diusrex.tictactoe.logic.Player;
import com.diusrex.tictactoe.logic.SectionPosition;
import com.diusrex.tictactoe.logic.TicTacToeEngine;
import com.diusrex.tictactoe.logic.UndoAction;

import java.util.Calendar;

public class GameActivity extends Activity implements GameEventHandler, GameEndActivityListener {
    static public final String IS_NEW_GAME = "IsNewGame";
    static private final long COOLDOWN = 250;

    BoardStatus board;
    Player currentPlayer;

    BoardStateSaverAndLoader saverAndLoader;

    GameGraphicsUpdater graphicsUpdater;

    long previousTime;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);

        saverAndLoader = new BoardStateSaverAndLoader(this);

        MainGridOwner mainGridOwner = new MainGridOwner(this, this, (MyGrid) findViewById(R.id.mainGrid));
        graphicsUpdater = new GameGraphicsUpdater(mainGridOwner);

        boolean newGame = getIntent().getBooleanExtra(IS_NEW_GAME, true);
        if (newGame) {
            saverAndLoader.resetBoardState();

            // Make sure it does not try this again
            getIntent().putExtra(IS_NEW_GAME, false);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        board = saverAndLoader.loadBoard();
        updateCurrentPlayer();

        graphicsUpdater.redrawBoard(this, board);

        SectionPosition selectedSection = saverAndLoader.loadSelectedSection(board);

        // ToDo: Refactor this if else into a function
        if (gameStillRunning()) {
            prepareForNextMove(getCurrentTime(), selectedSection);
        } else {
            // Make it so no player can make a move
            disablePerformingMove();
            sectionSelected(selectedSection);
        }
    }

    private boolean gameStillRunning() {
        return !winnerExists() && !isADraw();
    }

    private void updateCurrentPlayer() {
        currentPlayer = TicTacToeEngine.getNextPlayer(board);
    }

    @Override
    protected void onPause() {
        super.onPause();

        saverAndLoader.saveGameState(board);
    }

    @Override
    public void boxSelected(BoxPosition position) {
        Move move = new Move(position, currentPlayer);

        long currentTime = getCurrentTime();
        if (TicTacToeEngine.isValidMove(board, move) && currentTime - previousTime > COOLDOWN) {
            TicTacToeEngine.applyMoveIfValid(board, move);
            graphicsUpdater.redrawBoard(this, board);

            handleWinOrPrepareForNextMove(position, currentTime);
        }
    }

    private void handleWinOrPrepareForNextMove(BoxPosition position, long currentTime) {
        if (winnerExists()) {
            handleWin(position);
        } else if (isADraw()) {
            handleDraw(position);
        } else {
            prepareForNextMove(currentTime, board.getSectionToPlayIn());
        }
    }

    private boolean isADraw() {
        return TicTacToeEngine.boardIsFull(board);
    }

    private boolean winnerExists() {
        return TicTacToeEngine.getWinner(board) != Player.Unowned;
    }

    private void prepareForNextMove(long currentTime, SectionPosition selectedSection) {
        updateCurrentPlayer();

        sectionSelected(selectedSection);

        graphicsUpdater.sectionToPlayInChanged(board.getSectionToPlayIn());

        previousTime = currentTime;
    }

    private void handleWin(BoxPosition position) {
        graphicsUpdater.updateWinLine(board);

        sectionSelected(position.getSectionIn());

        String winningPlayer = getPlayerAsString();
        disablePerformingMove();

        showWinDialog(winningPlayer);
    }

    private void handleDraw(BoxPosition position) {
        sectionSelected(position.getSectionIn());
        disablePerformingMove();

        showDrawDialog();
    }

    private void disablePerformingMove() {
        // Will not allow the player unowned to play
        currentPlayer = Player.Unowned;

        // There is no section to play into
        graphicsUpdater.sectionToPlayInChanged(SectionPosition.make(-1, -1));
    }

    private void showWinDialog(String winningPlayer) {
        DialogFragment fragment = WinDialogFragment.newInstance(winningPlayer);
        fragment.show(getFragmentManager(), "dialog");
    }

    private void showDrawDialog() {
        DialogFragment fragment = DrawDialogFragment.newInstance();
        fragment.show(getFragmentManager(), "dialog");
    }

    @Override
    public void sectionSelected(SectionPosition section) {
        saverAndLoader.selectedSectionChanged(section);
        updateGraphicalSelectedSection(section);
    }

    private void updateGraphicalSelectedSection(SectionPosition section) {
        SectionOwner mainSection = new SelectedSectionOwner(section, (MyGrid) findViewById(R.id.selectedSection), this);
        graphicsUpdater.selectedSectionChanged(this, board, mainSection, section);
    }

    private long getCurrentTime() {
        Calendar c = Calendar.getInstance();
        return c.getTimeInMillis();
    }

    public void undoMove(View v) {
        if (canUndoLastMove()) {
            UndoAction.undoLastMove(board);

            graphicsUpdater.redrawBoard(this, board);
            prepareForNextMove(getCurrentTime(), board.getSectionToPlayIn());
        }
    }

    private String getPlayerAsString() {
        switch (currentPlayer) {
        case Player_1:
            return getString(R.string.player_1);

        case Player_2:
            return getString(R.string.player_2);

        default:
            return getString(R.string.no_player);
        }
    }

{'fraction_non_alphanumeric': 0.0866896493735811, 'fraction_numerical': 0.0015134953333893887, 'mean_word_length': 3.0774768597874527, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '374586', 'n_tokens_mistral': 3327, 'n_tokens_neox': 3209, 'n_words': 636}