Package minesweeper.ai.players

Source Code of minesweeper.ai.players.BruteForceAI

package minesweeper.ai.players;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import minesweeper.ai.games.BoardInfoHelper;
import minesweeper.ai.games.GameState;
import minesweeper.ai.games.BoardConfiguration.Cell;
import minesweeper.ai.games.BoardConfiguration.Position;
import minesweeper.ai.games.GameState.State;
import minesweeper.ai.games.MutableBoard;
import minesweeper.ai.utils.Combinations;
import minesweeper.ai.utils.Node;

public class BruteForceAI implements AIPlayer {
 
  private static final int SEARCH_SPACE_LIMIT = 50000;
 
  private DebugMode debug;
 
  public BruteForceAI() {
    this(DebugMode.OFF);
  }
  public BruteForceAI(DebugMode debug) {
    this.debug = debug;
    toFlag = new HashSet<>();
    toPick = new HashSet<>();
  }
 
    private Set<Position> toFlag, toPick;

  @Override
  public void solve(GameState game) {
    BoardInfoHelper helper = new BoardInfoHelper(game);
    game.pick(game.getRows()/2, game.getCols()/2);
    while(game.getState() == State.IN_PROGRESS) {
          if(! deduce(helper.getBoard()))
            if(! bruteForceSearch(helper.getBoard()))
              if(! pickRandom(helper.getBoard()))
                break;
          pickAndFlag(game);
    }
    if(debug == DebugMode.ON) System.out.println(game);
  }
 
  private void pickAndFlag(GameState game) {
      for(Position p : toPick)
        game.pick(p);
      for(Position p : toFlag)
        game.flag(p);
  }
 
  private boolean pickRandom(MutableBoard board) {
    BoardInfoHelper helper = new BoardInfoHelper(board);
      List<Position> unknown = helper.getUnknownBorderCells();
      toPick.clear(); toFlag.clear();
      if(unknown.size() == 0)
        unknown = helper.getCellsByValue(Cell.UNKNOWN);
      if(unknown.size() >= 1)
        toPick.add(unknown.get((int) (unknown.size() * Math.random())));
      return toPick.size() == 1;
  }
 
  private boolean deduce(MutableBoard board) {
    BoardInfoHelper helper = new BoardInfoHelper(board);
    toPick.clear(); toFlag.clear();
    for(Position cell : helper.getCellsWithAdjacentBombs()) {
            List<Position> unknown = helper.getAdjacentCellsByValue(cell, Cell.UNKNOWN);
            List<Position> flagged = helper.getAdjacentCellsByValue(cell, Cell.FLAG);
            if(board.getCell(cell) == unknown.size() + flagged.size())
                for(Position p : unknown)
                    toFlag.add(p);
            if(board.getCell(cell) == flagged.size())
                for(Position p : unknown)
                  toPick.add(p);
        }
    return toPick.size() > 0 || toFlag.size() > 0;
  }
 
    private boolean bruteForceSearch(MutableBoard board) {
      BoardInfoHelper helper = new BoardInfoHelper(board);
        List<Position> unknown = helper.getCellsByValue(Cell.UNKNOWN);
        int bombsToPlace = board.getRemainingBombs();
        toFlag.clear(); toPick.clear();
        if(Combinations.nCr(unknown.size(), bombsToPlace) < SEARCH_SPACE_LIMIT) {
          toFlag.addAll(unknown); toPick.addAll(unknown);
          enumerateBombLocations(helper, board, unknown, new Node(null,null), new Node(null,null), bombsToPlace);
          return toPick.size() > 0 || toFlag.size() > 0;
        } else return false;

    }
  
    private void enumerateBombLocations(BoardInfoHelper helper, MutableBoard board, List<Position> unknown, Node flagLocs, Node pickLocs, int bombsToPlace) {
        if(unknown.size() == 0) {
          if(bombsToPlace==0) {
            for(Position pick : pickLocs)
              board.setCell(pick, Cell.NO_BOMB);
            for(Position flag : flagLocs)
              board.setCell(flag, Cell.FLAG);
            if(helper.validateAll()) {
                toPick.retainAll(pickLocs.asSet());
                toFlag.retainAll(flagLocs.asSet());
            }
          }
            return;
        } else if(bombsToPlace < 0 || bombsToPlace > unknown.size()) return;
        Position p = unknown.remove(0);
        enumerateBombLocations(helper,board,new ArrayList<>(unknown),new Node(p,flagLocs), pickLocs, bombsToPlace-1);
        enumerateBombLocations(helper,board,new ArrayList<>(unknown),flagLocs, new Node(p,pickLocs), bombsToPlace);
    }
 
  @Override
  public String toString() {
    return "Basic Deductive AI with Brute Force End Game Strategy";
  }

}
TOP

Related Classes of minesweeper.ai.players.BruteForceAI

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.