package com.tos_bot.puzzleslove; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Random; import java.util.Stack; import android.R.integer; import android.annotation.SuppressLint; public class puzzleSolver { private int _maxMove; private int _minMove; private int _eightDSupport; private int[][] _board; private int _ComboNumber; private boolean _maxFind; private int _perferOrb; private solution _bestS; private int _move; public puzzleSolver(int min, int maxMove, int eightDSupport, int cm) { _minMove = min; _maxMove = maxMove; _eightDSupport = eightDSupport; _ComboNumber = cm; _maxFind = false; _bestS = null; } public ArrayList<solution> solveBoard() { ArrayList<solution> ret = new ArrayList<solution>(); return ret; } public solution solve_board(int[][] board) { _board = board; ArrayList<solution> solutions = new ArrayList<solution>(); solution seed_solution = null; seed_solution = make_solution(board, 0, 0); inPlaceSolution(seed_solution); for (int i = 0, s = 0; i < 5; ++i) { for (int j = 0; j < 6; ++j, ++s) { if (i == 0 || i == 4 || j == 0 || j == 5) { solutions.add(copySolutionCursor(seed_solution, i, j)); // solutions.add(copySolutionCursor(seed_solution, 0, 0)); // solutions.add(copySolutionCursor(seed_solution, 4, 0)); // solutions.add(copySolutionCursor(seed_solution, 0, 5)); // solutions.add(copySolutionCursor(seed_solution, 4, 5)); } } } solveState solve_state = new solveState(_maxMove, _eightDSupport, 0, solutions); solve_board_step(solve_state); int bs=0; if(_bestS != null){ return _bestS; } for(int i =0;i<solve_state.solutions.size();i++){ if(solve_state.solutions.get(i).matches.size()>bs){ bs = solve_state.solutions.get(i).matches.size(); _bestS = solve_state.solutions.get(i); } } return _bestS; } public ArrayList<matchPair> findComboMatch(int[][] board, solution s) { int[][] matchBoard = new int[5][6]; for (int i = 0; i < 5; i++) { for (int k = 0; k < 6; k++) matchBoard[i][k] = -1; } // find horizontals for 3x for (int i = 0; i < 5; ++i) { // ROW int prev_1_orb = -5; int prev_2_orb = -5; for (int j = 0; j < 6; ++j) { // COLS int cur_orb = board[i][j]; if (prev_1_orb == prev_2_orb && prev_2_orb == cur_orb && cur_orb != -1) { matchBoard[i][j] = cur_orb; matchBoard[i][j - 1] = cur_orb; matchBoard[i][j - 2] = cur_orb; } prev_1_orb = prev_2_orb; prev_2_orb = cur_orb; } } // find verticals for 3x for (int j = 0; j < 6; ++j) { // cols int prev_1_orb = -5; int prev_2_orb = -5; for (int i = 0; i < 5; ++i) { // rows int cur_orb = board[i][j]; if (prev_1_orb == prev_2_orb && prev_2_orb == cur_orb && cur_orb != -1) { matchBoard[i][j] = cur_orb; matchBoard[i - 1][j] = cur_orb; matchBoard[i - 2][j] = cur_orb; } prev_1_orb = prev_2_orb; prev_2_orb = cur_orb; } } int[][] scratchBoard = new int[5][6]; for (int i = 0; i < 5; i++) for (int j = 0; j < 6; j++) scratchBoard[i][j] = matchBoard[i][j]; s.setCB(matchBoard); ArrayList<matchPair> ret = new ArrayList<matchPair>(); int ROWS = 5; int COLS = 6; for (int i = 0; i < 5; ++i) { for (int j = 0; j < 6; ++j) { int cur_orb = scratchBoard[i][j]; if (cur_orb == -1) { continue; } Stack<pos> stack = new Stack<pos>(); stack.add(new pos(i, j)); int count = 0; while (stack.size() > 0) { pos n = stack.pop(); if (scratchBoard[n.h][n.w] != cur_orb) { continue; } ++count; scratchBoard[n.h][n.w] = -1; if (n.h > 0) { stack.add(new pos(n.h - 1, n.w)); } if (n.h < ROWS - 1) { stack.add(new pos(n.h + 1, n.w)); } if (n.w > 0) { stack.add(new pos(n.h, n.w - 1)); } if (n.w < COLS - 1) { stack.add(new pos(n.h, n.w + 1)); } } ret.add(new matchPair(cur_orb, count)); } } return ret; } public solution make_solution(int[][] board, int h, int w) { solution ret; ret = new solution(board, new pos(0, 0), new pos(0, 0), new ArrayList<Integer>(), false, new ArrayList<matchPair>()); return ret; } public solution copySolutionCursor(solution s, int i, int j) { return new solution(s.board, new pos(i, j), new pos(i, j), s.path, s.is_done, new ArrayList<matchPair>()); } public solution copySolutionCursorWithI(solution s, int i, int j, pos ini) { return new solution(s.board, new pos(i, j), new pos(i, j), s.path, s.is_done, new ArrayList<matchPair>()); } public void inPlaceSolution(solution s) { } public void solve_board_step(solveState s) { if (_maxFind && s.p > _minMove) { return; } if (s.p >= _maxMove) { return; } ++s.p; s.solutions = evolve_solutions(s.solutions, s.dir_step,0); // solve_board_step(s); } public ArrayList<solution> evolve_solutions(ArrayList<solution> solutions, int dir_step,int deep) { ArrayList<solution> new_solutions = new ArrayList<solution>(); if(deep>= _maxMove){ int i =0; i=i; return new_solutions; } if (_maxFind && deep > _minMove) { int i =0; i=i; return new_solutions; } //if(_move > 2000){ // return new_solutions; //} deep ++; for (solution s : solutions) { if (s.is_done) { continue; } if(s.path.size()>4 && s.matches.size()<2){ s.is_done = true; continue; } if(s.path.size()>8 && s.matches.size()<3){ s.is_done = true; continue; } for (int dir = 0; dir < 8; dir += dir_step) { if (!can_move_orb_in_solution(s, dir)) { continue; } solution _solution = new solution(s.board, new pos(s.cursor.h, s.cursor.w), new pos(s.initcursor.h, s.initcursor.w), s.path, s.is_done, s.matches); in_place_swap_orb_in_solution(_solution, dir); _move++; in_place_evaluate_solution(_solution); new_solutions.add(_solution); } s.is_done = true; } solutions.addAll(evolve_solutions(new_solutions, dir_step,deep)); return solutions; } public boolean can_move_orb_in_solution(solution s, int dir) { if (s.path.size() == 0) { return can_move_orb(s.cursor, dir); } else if (s.path.get(s.path.size() - 1).intValue() == ((dir + 4) % 8)) { return false; } return can_move_orb(s.cursor, dir); } public boolean can_move_orb(pos rc, int d) { int COLS = 6; int ROWS = 5; Boolean flag = false; switch (d) { case 0: flag = rc.w < (COLS - 1); break; case 1: flag = (rc.h < (ROWS - 1)) && (rc.w < (COLS - 1)); break; case 2: flag = rc.h < (ROWS - 1); break; case 3: flag = (rc.h < (ROWS - 1)) && (rc.w > 0); break; case 4: flag = rc.w > 0; break; case 5: flag = (rc.h > 0) && (rc.w > 0); break; case 6: flag = rc.h > 0; break; case 7: flag = (rc.h > 0) && (rc.w < (COLS - 1)); break; } return flag; } public void in_place_swap_orb_in_solution(solution s, Integer dir) { in_place_swap_orb(s.board, s.cursor, dir); s.path.add(dir); } public void in_place_swap_orb(int[][] board, pos rc, Integer dir) { pos old_rc = new pos(rc.h, rc.w); in_place_move_rc(rc, dir); int orig_type = board[old_rc.h][old_rc.w]; board[old_rc.h][old_rc.w] = board[rc.h][rc.w]; board[rc.h][rc.w] = orig_type; } public void in_place_move_rc(pos rc, Integer dir) { switch (dir.intValue()) { case 0: rc.w += 1; break; case 1: rc.h += 1; rc.w += 1; break; case 2: rc.h += 1; break; case 3: rc.h += 1; rc.w -= 1; break; case 4: rc.w -= 1; break; case 5: rc.h -= 1; rc.w -= 1; break; case 6: rc.h -= 1; break; case 7: rc.h -= 1; rc.w += 1; break; } } @SuppressLint("NewApi") public void in_place_evaluate_solution(solution s) { int[][] current_board = new int[5][6]; for (int i = 0; i < 5; i++) for (int j = 0; j < 6; j++) current_board[i][j] = s.board[i][j]; ArrayList<matchPair> all_matches = new ArrayList<matchPair>(); while (true) { ArrayList<matchPair> matches = findComboMatch(current_board, s); if (matches.size() == 0) { break; } in_place_remove_matches(current_board, s.currentboard); in_place_drop_empty_spaces(current_board); all_matches.addAll(matches); break; } if (all_matches.size() >= _ComboNumber) { _bestS = s; _maxFind = true; } s.matches = all_matches; } public void in_place_remove_matches(int[][] cb, int[][] mb) { for (int i = 0; i < 5; ++i) { for (int j = 0; j < 6; ++j) { if (mb[i][j] != -1) { cb[i][j] = -8; } } } } public void in_place_drop_empty_spaces(int[][] board) { for (int j = 0; j < 6; ++j) { int dest_i = 5 - 1; for (int src_i = 5 - 1; src_i >= 0; --src_i) { if (board[src_i][j] != -1) { board[dest_i][j] = board[src_i][j]; --dest_i; } } for (; dest_i >= 0; --dest_i) { board[dest_i][j] = 'X'; } } } }