Android Open Source - android-tic-tac-toe Board






From Project

Back to project page android-tic-tac-toe.

License

The source code is released under:

MIT License

If you think the Android project android-tic-tac-toe listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.shaon.android.tictactoe.board;
//w  w w . j  a v  a2 s.c  o m
import static org.shaon.android.tictactoe.model.State.COLUMNS;
import static org.shaon.android.tictactoe.model.State.ROWS;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

import org.shaon.android.tictactoe.R;
import org.shaon.android.tictactoe.TicTacToeApplication;
import org.shaon.android.tictactoe.exception.InvalidTurn;
import org.shaon.android.tictactoe.model.ActionState;
import org.shaon.android.tictactoe.model.AlphaBetaSearch;
import org.shaon.android.tictactoe.model.PlayerConfig;
import org.shaon.android.tictactoe.model.SearchAlgorithm;
import org.shaon.android.tictactoe.model.State;
import org.shaon.android.tictactoe.model.TerminatingCondition;
import org.shaon.android.tictactoe.model.State.Combination;
import org.shaon.android.tictactoe.model.State.Player;

import android.app.Activity;
import android.view.View;
import android.widget.ImageView;

public class Board {

  private int cellId[][] = {
      { R.id.cell_top_left, R.id.cell_top, R.id.cell_top_right },
      { R.id.cell_left, R.id.cell_center, R.id.cell_right },
      { R.id.cell_bottom_left, R.id.cell_bottom, R.id.cell_bottom_right } };

  private Cell board[][];
  private Activity context;
  private State state;
  private Player currentPlayer;

  private ImageView turnImage;
  private View gameOverWinView;
  private View humanVsGreenBotView;
  private View turnView;
  private View gameOverTieView;
  private ImageView gameOverWinImage;
  
  private GameMode gameMode;
  private boolean gameOverFlag;
  private PlayerConfig playerConfig;
  private SearchAlgorithm searchAlgorithm;

  private boolean greenRobotThinking;

  private static HashMap<Combination, Integer[][]> combinationCellMapping;
  
  static {
    combinationCellMapping = new HashMap<State.Combination, Integer[][]>();
    
    combinationCellMapping.put(Combination.COLUMN_1, new Integer[][] {{0,0}, {1,0}, {2,0}});
    combinationCellMapping.put(Combination.COLUMN_2, new Integer[][] {{0,1}, {1,1}, {2,1}});
    combinationCellMapping.put(Combination.COLUMN_3, new Integer[][] {{0,2}, {1,2}, {2,2}});
    combinationCellMapping.put(Combination.ROW_1, new Integer[][] {{0,0}, {0,1}, {0,2}});
    combinationCellMapping.put(Combination.ROW_2, new Integer[][] {{1,0}, {1,1}, {1,2}});
    combinationCellMapping.put(Combination.ROW_3, new Integer[][] {{2,0}, {2,1}, {2,2}});
    combinationCellMapping.put(Combination.DIAGONAL_1, new Integer[][] {{0,0}, {1,1}, {2,2}});
    combinationCellMapping.put(Combination.DIAGONAL_2, new Integer[][] {{0,2}, {1,1}, {2,0}});
  }
  
  public enum GameMode {
    VS_HUMAN,
    VS_GREEN_ROBOT
  }
  
  public Board(Activity context) {
    this.context = context;
    setUpViews();
    initializeBoard();
    initialize();
  }

  private void setUpViews() {
    
    turnImage = (ImageView) context.findViewById(R.id.main_turn_image);
    gameOverWinImage = (ImageView) context.findViewById(R.id.main_game_over_win_image);
    
    gameOverWinView = context.findViewById(R.id.main_game_over_win);
    gameOverTieView = context.findViewById(R.id.main_game_over_tie);    
    humanVsGreenBotView = context.findViewById(R.id.main_human_green_robot);
    turnView = context.findViewById(R.id.main_turn);    
  }

  private void initializeBoard() {
    board = new Cell[ROWS][COLUMNS];
    for (int i = 0; i < ROWS; i++) {
      for (int j = 0; j < COLUMNS; j++) {
        board[i][j] = new Cell(i, j, cellId[i][j], this, this.context);
      }
    }
  }

  public Cell getCell(int row, int column) {
    return board[row][column];
  }

  /**
   * Toggles the player
   */
  public void togglePlayer() {
    currentPlayer = PlayerConfig.opposite(currentPlayer);
  }

  public void clickCell(int row, int column) throws InvalidTurn {
    
    if(gameOverFlag) {
      throw new InvalidTurn("Game Over!");
    }
    
    if(greenRobotThinking) {      
      throw new InvalidTurn("I am thinking, give me a sec.!");
    }
    
    if (state.isEmpty(row, column)) {
      
      assignCurrentPlayer(row, column);
      updateTurnDisplay();

    } else {
      throw new InvalidTurn("Cell is not empty.");
    }
  }
  
  
  private void assignCurrentPlayer(int row, int column){
    
    state.assign(currentPlayer, row, column);
    board[row][column].setPlayer(currentPlayer);
    
    TerminatingCondition tc = state.checkFinished();
    if(tc != null) {
      gameOver(tc);
    }else{
      togglePlayer();
      
      if(gameMode.equals(GameMode.VS_GREEN_ROBOT) && 
          currentPlayer.equals(playerConfig.getAiPlayer())){
        greenRobotMove();        
      }
    }
  }
  
  private void gameOver(TerminatingCondition tc) {
    
    turnView.setVisibility(View.GONE);
    humanVsGreenBotView.setVisibility(View.GONE);
    
    if(tc.isTie()) {
      gameOverTieView.setVisibility(View.VISIBLE);
    }else{
      gameOverWinView.setVisibility(View.VISIBLE);
      Integer[][] affectedCells = combinationCellMapping.get(tc.getCombination());
      
      for(int i = 0; i < affectedCells.length; i++){
        board[affectedCells[i][0]][affectedCells[i][1]].setAsWinningCell();
      }
      
      updatePlayerView(gameOverWinImage, tc.getPlayer());
    }
    gameOverFlag = true;
  }
  
  /**
   * Initializes the board. Resets all cells
   */
  public void initialize(){
    
    currentPlayer = PlayerConfig.randomPlayer();
    state = new State();
    
    for (int i = 0; i < ROWS; i++) {
      for (int j = 0; j < COLUMNS; j++) {
        board[i][j].setPlayer(null);
      }
    }

    TicTacToeApplication ticTacToeApplication = (TicTacToeApplication) context.getApplication();
    
    gameMode = ticTacToeApplication.getGameMode();
    gameOverFlag = false;
    
    updateModeDisplay();
    
    if(gameMode.equals(GameMode.VS_GREEN_ROBOT)) {
      initializeAlgorithm();
      updateGreenRobotDisplay();
    }else if(gameMode.equals(GameMode.VS_HUMAN)) {
      updateTurnDisplay();
    }
  }
  
  private void initializeAlgorithm() {
    
    playerConfig = new PlayerConfig(PlayerConfig.randomPlayer());
    searchAlgorithm = new AlphaBetaSearch();
    searchAlgorithm.setAiPlayer(playerConfig.getAiPlayer());
    
    greenRobotMove();
  }
  
  private void updateGreenRobotDisplay() {
    ImageView greenRobotImage = (ImageView) context.findViewById(R.id.green_robot_image);
    updatePlayerView(greenRobotImage, playerConfig.getAiPlayer());
    ImageView humanImage = (ImageView) context.findViewById(R.id.human_image);
    updatePlayerView(humanImage, playerConfig.getHumanPlayer());
  }

  private void greenRobotMove() {
    
    if(currentPlayer.equals(playerConfig.getAiPlayer())){
      
      greenRobotThinking = true;
      
      List<ActionState> possibleMoves = searchAlgorithm.search(state);
      //need to pick one randomly .. 
      if(possibleMoves.isEmpty()) {
        System.out.println("Out of suggestion!!");
        System.exit(0);
      }
      
      Date date = new Date();
      
      Random random = new Random(date.getTime());
      int randMove = random.nextInt(possibleMoves.size());
      
      ActionState as = possibleMoves.get(randMove);
      assignCurrentPlayer(as.getAction().getRow(), as.getAction().getColumn());

      greenRobotThinking = false;
    }
  }

  public void updateModeDisplay(){
    
    if(gameMode.equals(GameMode.VS_GREEN_ROBOT)) {
      
      turnView.setVisibility(View.GONE);
      humanVsGreenBotView.setVisibility(View.VISIBLE);
      gameOverWinView.setVisibility(View.GONE);
      gameOverTieView.setVisibility(View.GONE);
      
    }else if(gameMode.equals(GameMode.VS_HUMAN)) {
      
      turnView.setVisibility(View.VISIBLE);
      humanVsGreenBotView.setVisibility(View.GONE);
      gameOverWinView.setVisibility(View.GONE);
      gameOverTieView.setVisibility(View.GONE);
    }
  }
  
  public void updateTurnDisplay(){
    updatePlayerView(turnImage, currentPlayer);
  }
  
  public static void updatePlayerView(ImageView imageView, Player player){
    updatePlayerView(imageView, player, false);
  }

  public static void updatePlayerView(ImageView imageView, Player player, boolean winning) {

    if(player == null) {
      imageView.setImageResource(R.drawable.player_empty);
    }else if(player.equals(Player.X) && !winning) {
      imageView.setImageResource(R.drawable.player_x);
    }else if(player.equals(Player.X) && winning) {
      imageView.setImageResource(R.drawable.player_x_finished);
    }else if (player.equals(Player.O) && !winning) {
      imageView.setImageResource(R.drawable.player_o);
    }else if (player.equals(Player.O) && winning) {
      imageView.setImageResource(R.drawable.player_o_finished);
    }  
  }
}




Java Source Code List

org.shaon.android.tictactoe.TicTacToeApplication.java
org.shaon.android.tictactoe.activity.SettingsActivity.java
org.shaon.android.tictactoe.activity.TicTacToeActivity.java
org.shaon.android.tictactoe.board.Board.java
org.shaon.android.tictactoe.board.Cell.java
org.shaon.android.tictactoe.exception.InvalidTurn.java
org.shaon.android.tictactoe.model.ActionState.java
org.shaon.android.tictactoe.model.Action.java
org.shaon.android.tictactoe.model.AlphaBetaSearch.java
org.shaon.android.tictactoe.model.MinMax.java
org.shaon.android.tictactoe.model.PlayerConfig.java
org.shaon.android.tictactoe.model.SearchAlgorithm.java
org.shaon.android.tictactoe.model.State.java
org.shaon.android.tictactoe.model.TerminatingCondition.java
org.shaon.android.tictactoe.model.WinningCombination.java