Package minesweeper.ai.games

Source Code of minesweeper.ai.games.Windows7GameState

package minesweeper.ai.games;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import minesweeper.ai.utils.User32;

import com.sun.jna.platform.win32.WinDef.HWND;

import minesweeper.ai.utils.CellClassifier;

public class Windows7GameState implements GameState {
 
  private static final String PROGRAM_PATH = "C:/Program Files/Microsoft Games/Minesweeper/Minesweeper.exe";
 
  private Rectangle windowRect;
  private int rows, cols;
  private int bombs;
  private State state;
  private Set<Position> flagged = new HashSet<>();
 
  private Robot robot;
  private BufferedImage snapshot;
  private boolean upToDate;
  {
    try { robot = new Robot(); }
    catch(Exception e) { System.exit(0);}
  }
 
  public static GameState createEasyGame() {
    return new Windows7GameState(9, 9, 10);
  }
  public static GameState createIntermediateGame() {
    return new Windows7GameState(16,16,40);
  }
  public static GameState createAdvancedGame() {
    return new Windows7GameState(16,30,99);
  }
 
  public Windows7GameState(int rows, int cols, int bombs) {
    this.rows = rows;
    this.cols = cols;
    this.bombs = bombs;
    state = State.IN_PROGRESS;
    startGame();
  }
 
  private void startGame() {
        HWND hwnd = User32.INSTANCE.FindWindow(null, "Minesweeper");
        if(hwnd == null) {
          try {
        new ProcessBuilder(PROGRAM_PATH).start();
            sleep(2222);
            hwnd = User32.INSTANCE.FindWindow(null, "Minesweeper");
      } catch (IOException e) { e.printStackTrace(); }
        }
        User32.INSTANCE.SwitchToThisWindow(hwnd, false);
        takeNap();
        config();
        takeNap();
        int[] rect = { 0,0,0,0 };
        User32.INSTANCE.GetWindowRect(hwnd, rect);
        windowRect = new Rectangle(rect[0], rect[1], rect[2]-rect[0], rect[3]-rect[1]);
        Rectangle r = CellClassifier.reduceBoard(robot.createScreenCapture(windowRect));
        windowRect.width = r.width;
        windowRect.height = r.height;
        windowRect.x += r.x;
        windowRect.y += r.y;
  }
 
  private void config() {
        robot.keyPress(KeyEvent.VK_F5);
        takeNap();
        HWND options = User32.INSTANCE.FindWindow(null, "Options");
        int[] r = {0,0,0,0};
        User32.INSTANCE.GetWindowRect(options, r);
        mouseClick(r[0]+200,r[1]+75);
        robot.keyPress(KeyEvent.VK_TAB);
        type(rows);
        robot.keyPress(KeyEvent.VK_TAB);
        type(cols);   
        robot.keyPress(KeyEvent.VK_TAB);
        type(bombs);  
        robot.keyPress(KeyEvent.VK_ENTER);    
        takeNap(); takeNap();
  }

  @Override
  public int getCell(int row, int col) {
    if(! upToDate) update();
    if(flagged.contains(Position.valueOf(row,col)))
      return Cell.FLAG;
    return CellClassifier.classify(cellImg(row,col));
  }
 
  private void update() {
    snapshot = robot.createScreenCapture(windowRect);
    upToDate = true;
  }
 
  private BufferedImage cellImg(int row, int col) {
    Rectangle r = rectFromPosition(row,col);
    r.x -= windowRect.x; r.y -= windowRect.y;
    return snapshot.getSubimage(r.x, r.y, r.width, r.height);
  }

  @Override
  public int getCell(Position p) {
    return getCell(p.row, p.col);
  }

  @Override
  public int getRows() {
    return rows;
  }

  @Override
  public int getCols() {
    return cols;
  }

  @Override
  public int getBombs() {
    return bombs;
  }

  @Override
  public int getRemainingBombs() {
    return bombs - flagged.size();
  }

  @Override
  public void pick(int row, int col) {
    upToDate = false;
    if(checkStatus() != State.IN_PROGRESS) return;
    Point pt = pointFromPosition(row, col);
    mouseClick(pt.x,pt.y);
  }

  @Override
  public void pick(Position p) {
    pick(p.row, p.col);
  }

  @Override
  public void flag(int row, int col) {
    upToDate = false;
    if(checkStatus() != State.IN_PROGRESS) return;
    flagged.add(Position.valueOf(row,col));
    Point pt = pointFromPosition(row, col);
    mouseRightClick(pt.x,pt.y);
  }

  @Override
  public void flag(Position p) {
    flag(p.row, p.col);
  }

  @Override
  public State getState() {
    return state;
  }

  @Override
  public void restart() {
    // TODO Auto-generated method stub
   
  }
 
  public BufferedImage screenshot() {
    return robot.createScreenCapture(windowRect);
  }
 
  private Point pointFromPosition(int row, int col) {
    return new Point(windowRect.x+(col*windowRect.width+windowRect.width/2) / cols, windowRect.y+(row*windowRect.height+windowRect.height/2) / rows);
  }
 
  private Rectangle rectFromPosition(int row, int col) {
    Rectangle ans = new Rectangle(pointFromPosition(row,col));
    ans.x -= 10; ans.y -= 10; ans.width = 20; ans.height = 20;
    return ans;
  }
 
  private void takeNap() {
    sleep(78);
  }
  private void sleep(long millis) {
    try { Thread.sleep(millis); }
    catch(InterruptedException e) {}
  }
 
  private State checkStatus() {
    if(User32.INSTANCE.FindWindow("", "Game Lost") != null)
      state = State.LOSE;
    if(User32.INSTANCE.FindWindow("", "Game Won") != null)
      state = State.LOSE;
    return state;
  }
 
  private void mouseClick(int x, int y) {
    robot.mouseMove(x,y);
    robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
    robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
    takeNap();
  }
 
  private void mouseRightClick(int x, int y) {
    robot.mouseMove(x,y);
    robot.mousePress(InputEvent.BUTTON3_DOWN_MASK);
    robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK);
    takeNap();
  }
 
    private static final int[] KEYEVENTS = {
            KeyEvent.VK_0,KeyEvent.VK_1,KeyEvent.VK_2,
            KeyEvent.VK_3,KeyEvent.VK_4,KeyEvent.VK_5,
            KeyEvent.VK_6,KeyEvent.VK_7,KeyEvent.VK_8,
            KeyEvent.VK_9
        };
  private void type(int n) {
    if(n >= 100) robot.keyPress(KEYEVENTS[n/100 % 10]);
    if(n >= 10) robot.keyPress(KEYEVENTS[n/10 % 10]);
    robot.keyPress(KEYEVENTS[n%10]);
    takeNap();
  }

}
TOP

Related Classes of minesweeper.ai.games.Windows7GameState

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.