zoukankan      html  css  js  c++  java
  • 空当接龙求解:java版广度优先

    说是广度优先,其实一搜到底还是不可能的,通过多少步(比如30万的节点)扩展后,选取一个最合适的节点(倒数第四层节点的第4层孙节点数量最多的那个),重新进行同样步骤,直到扩展节点出现终局节点为止,system.out.print输出解局过程

    图片是解局过程片段

    package kdjl3;
    import java.util.ArrayList;
    import java.util.HashMap;

    public class Kdjl {

        public static void main(String[] args){
            Kdjl kdjl=new Kdjl();
            CurData curDataRoot = kdjl.getNewGame();
            //kdjl.exchangeCol(curDataRoot, 3, 7);
            kdjl.freecell(curDataRoot);
            /*
            System.out.println("DEBUG FOR MEMORY RELEASE CHECK.");
            kdjl=null;
            kdjl=new Kdjl();
            kdjl.freecell();
            System.out.println("DEBUG FOR MEMORY RELEASE CHECK.");
            kdjl.freecell();
            kdjl.freecell();
            kdjl.freecell();
            kdjl.freecell();
            kdjl.freecell();
            kdjl.freecell();
            kdjl.freecell();
            */
        }
        
        void exchangeCol(CurData cData,int c1,int c2) {
            int[] iTmp = new int[8];
            int backupCol,ppCol,iTmpBp;
            if(cData.bp[c1]>cData.bp[c2]) { backupCol = c1; ppCol = c2;}
            else { backupCol = c2; ppCol=c1;}
            for(int i=0;i<cData.bp[backupCol];i++) iTmp[i] = cData.board[backupCol][i];
            for(int i=0;i<cData.bp[ppCol];i++) cData.board[backupCol][i] = cData.board[ppCol][i];
            for(int i=0;i<cData.bp[backupCol];i++) cData.board[ppCol][i] = iTmp[i];
            iTmpBp=cData.bp[backupCol];
            cData.bp[backupCol]=cData.bp[ppCol];
            cData.bp[ppCol]=iTmpBp;
        }
        
        public CurData getNewGame() {
            CurData curDataRoot= new CurData();
            curDataRoot.bp[0] = 7;
            curDataRoot.bp[1] = 7;
            curDataRoot.bp[2] = 7;
            curDataRoot.bp[3] = 7;
            curDataRoot.bp[4] = 6;
            curDataRoot.bp[5] = 6;
            curDataRoot.bp[6] = 6;
            curDataRoot.bp[7] = 6;
            //int[] board_data={2,35,40,39,37,16,29,14,43,4,27,13,38,41,1,26,28,32,17,11,33,51,21,8,6,34,24,42,20,49,45,50,44,0,33,12,19,31,5,3,23,25,22,47,7,36,30,10,18,48,9,15};
            //int[] board_data={14,48,30,29,35,11,3,25,31,28,47,0,9,49,37,39,34,6,23,17,42,1,15,41,33,10,45,51,21,22,46,2,44,36,26,13,32,43,24,7,38,4,20,16,12,40,19,27,5,18,8,50};
            //int[] board_data={13,33,19,4,36,38,25,21,26,22,9,6,12,46,43,44,23,50,2,35,20,31,32,15,34,1,11,40,49,27,39,10,5,16,41,8,45,29,17,18,47,48,51,42,28,24,0,30,3,7,37,14};
            //freecell #278
            //int[] board_data={41,10,17,3,7,15,43,4,16,26,32,29,19,33,49,20,30,11,38,18,40,51,34,22,37,0,28,12,39,42,44,45,27,47,36,1,9,35,50,8,48,25,13,21,2,5,46,23,6,24,14,31};
            //freecell #617
            //int[] board_data={32,35,48,38,3,16,36,26,19,11,43,24,22,25,4,37,41,21,8,40,12,15,0,34,2,47,30,42,17,31,18,20,6,10,7,46,33,45,44,5,27,13,28,29,1,49,39,51,9,23,14,50};
            //freecell #669
            //int[] board_data={22,7,44,18,31,34,50,45,41,39,28,4,25,51,38,0,8,14,40,10,42,11,9,5,24,19,6,30,36,47,33,26,15,16,23,2,1,17,46,29,35,49,43,37,20,48,27,32,21,13,12,3};
            //freecell #1025
            //int[] board_data={27,41,8,21,28,6,35,38,13,34,12,16,20,15,39,37,3,36,51,7,17,18,1,44,24,22,10,30,50,47,11,0,26,2,19,31,32,23,14,46,33,45,49,42,25,5,9,29,40,48,4,43};
            //freecell #1381
            //int[] board_data={6,1,29,31,26,34,17,5,48,35,20,14,33,10,27,30,22,40,25,8,28,4,11,37,43,12,0,24,39,45,7,42,19,15,51,47,9,2,49,41,44,13,36,8,46,23,18,16,50,3,38,32};
            //freecell #3701
            //int[] board_data={2,39,22,28,36,16,15,7,43,27,5,1,51,34,3,41,19,21,24,45,10,17,50,32,49,8,4,46,18,11,0,25,9,42,38,35,30,37,33,14,47,44,48,6,12,13,26,20,31,40,23,29};
            //freecell #1941
            //int[] board_data={34,18,29,39,4,42,51,49,10,23,19,31,0,16,26,33,13,40,12,38,45,25,22,21,46,36,37,41,9,3,14,30,15,44,2,11,17,24,50,32,47,43,6,5,28,35,1,7,20,48,27,8};
            //freecell #7303
            //int[] board_data={17,48,1,35,34,43,3,26,36,7,51,38,42,47,40,12,46,9,25,0,19,6,21,30,8,45,29,28,4,22,32,13,27,41,5,50,18,49,16,24,15,33,31,20,11,39,2,44,14,10,37,23};
            //freecell #9123
            //int[] board_data={47,4,7,8,38,30,20,29,3,31,27,1,42,22,49,50,34,6,23,35,24,2,43,41,37,11,5,0,51,36,25,17,15,28,26,21,19,12,46,48,10,14,39,32,18,33,40,44,16,13,45,9};
            //freecell #10962
            int[] board_data={25,19,33,18,51,7,43,35,28,40,8,12,32,48,30,4,24,9,42,37,36,6,23,26,17,2,50,0,5,41,11,29,34,3,20,49,39,22,31,46,38,47,27,13,21,15,16,10,45,1,44,14};
            //freecell #13304
            //int[] board_data={13,16,28,10,5,4,24,17,51,33,29,2,45,19,31,20,44,7,15,12,21,9,26,50,43,32,35,22,34,0,8,25,40,27,37,47,14,46,11,6,18,39,23,42,48,3,1,36,49,30,41,38};
            //freecell #20003
            //int[] board_data={10,17,29,38,27,0,35,40,51,44,2,22,7,30,5,45,24,23,41,11,1,48,21,16,13,33,4,43,14,26,3,46,36,18,6,50,19,28,15,25,32,9,31,42,49,34,47,20,8,39,12,37};
            //freecell #20095
            //int[] board_data={5,31,24,40,2,39,44,27,10,36,16,1,45,6,18,19,13,21,42,17,43,8,7,48,12,28,3,22,25,26,37,32,0,49,35,29,50,14,51,9,46,33,11,23,41,4,20,15,34,47,38,30};
            //freecell #31945
            //int[] board_data={31,43,20,4,38,39,19,30,41,50,13,8,37,22,14,49,29,35,2,48,21,36,46,42,32,23,9,6,16,10,40,15,28,27,1,18,25,45,7,0,5,47,17,24,11,26,34,33,51,12,3,44};
            //freecell #838856
            //int[] board_data={36,17,4,45,16,8,38,19,41,44,30,9,0,42,37,48,24,23,14,32,25,49,21,18,34,28,47,12,1,33,43,2,7,11,6,26,35,40,15,20,29,39,13,51,46,50,22,3,10,31,27,5};
            //freecell win10 0912
            //int[] board_data={16,51,23,50,36,33,41,49,37,34,32,20,2,11,47,45,8,42,21,12,9,18,10,5,35,4,29,24,27,40,6,31,28,1,13,0,25,46,22,15,3,39,38,14,26,48,43,17,7,30,44,19};
            //freecell win10 1104
            //int[] board_data={4,34,6,20,27,15,42,9,35,24,11,39,40,12,16,46,0,48,51,1,7,29,10,43,36,19,17,8,23,25,33,31,26,22,41,49,47,18,44,13,32,50,37,30,28,21,14,45,3,5,38,2};
            //freecell
            //int[] board_data={10,0,17,44,41,27,14,22,51,46,28,49,35,23,7,19,6,36,21,31,24,18,42,13,38,8,15,47,25,5,43,33,9,3,45,1,39,11,40,16,29,12,48,32,4,34,20,26,50,37,2,30};
            //freecell #
            //int[] board_data={13,17,42,19,4,6,5,18,37,2,15,51,31,20,44,9,8,39,21,32,14,11,46,26,22,12,33,0,24,29,38,27,41,7,1,30,48,36,28,3,34,47,23,40,16,49,10,50,35,45,43,25};
            int cur_col = 0,cur_col_no=0,random_int;
            ArrayList<Integer> random_card=new ArrayList<Integer>();
            /*
            for(int i=0;i<52;i++) random_card.add(i);
            for(int i=0;i<52;i++) {
                random_int= (int) (Math.random() * (52-i));
                curDataRoot.board[cur_col][cur_col_no] = random_card.get(random_int);
                random_card.remove(random_int);
                cur_col_no++;
                if(cur_col_no == curDataRoot.bp[cur_col]) {
                    cur_col++;
                    cur_col_no = 0;
                }
            }
            //*/
            ///*
            for(int i=0;i<52;i++) {
                curDataRoot.board[cur_col][cur_col_no] = board_data[i];
                cur_col_no++;
                if(cur_col_no == curDataRoot.bp[cur_col]) {
                    cur_col++;
                    cur_col_no = 0;
                }
            }
            //*/
            
            return curDataRoot;
            
        }
        
        public void freecell(CurData curDataRoot){
            ArrayList<ArrayList<Move3>> srh=new ArrayList<ArrayList<Move3>>();
            ArrayList<Move3> floor;
            ArrayList<Integer> answer=new ArrayList<Integer>();
            HashMap<Long,Integer> srhMap=new HashMap<Long,Integer>();
            CurData curDataRootCopy= new CurData();
            CurData curData0= new CurData();
            CurData curData1= new CurData();
            Move3 root0=new Move3();
            //Significance sign = new Significance();
            
            for(int i=0;i<8;i++) for(int j=0;j<25;j++) curDataRootCopy.board[i][j]=curDataRoot.board[i][j];
            for(int i=0;i<8;i++) curDataRootCopy.bp[i]=curDataRoot.bp[i];
            for(int i=0;i<4;i++) curDataRootCopy.freePos[i]=curDataRoot.freePos[i];
            for(int i=0;i<4;i++) curDataRootCopy.finish[i]=curDataRoot.finish[i];
            
            
            
            root0.curData=curDataRoot;
            
            root0.curData.printCards();
            
            floor = new ArrayList<Move3>();
            floor.add(root0);
            srh.add(floor);
            int xCnt = 0;

            do {
                xCnt++;
                
                if(getNextRoot(xCnt,srhMap,srh,root0,curData0,curData1,answer)==1) break;
                
                srhMap.clear();;
                for(int i=1;i<srh.size();i++) {
                    srh.get(i).clear();
                }
                srh.clear();
                floor = new ArrayList<Move3>();
                //floor.add(maxLishun_move);
                floor.add(root0);
                srh.add(floor);    
                //cur_floor = 0;
                //mapHit=0;
                
            }while(true);
            
            System.out.println("################################# ANSWER #################################");
            root0.printAnswer(curDataRootCopy, answer);
            
            //
            srhMap.clear();;
            for(int i=1;i<srh.size();i++) {
                srh.get(i).clear();
            }
            srh.clear();
        }

        /**
         *
         * @param xCnt
         * @param srhMap
         * @param srh
         * @param root0
         * @param curData0
         * @param curData1
         * @param answer
         * @return
         */
        int getNextRoot(int xCnt,HashMap<Long,Integer> srhMap
                ,ArrayList<ArrayList<Move3>> srh
                ,Move3 root0
                ,CurData curData0
                ,CurData curData1
                ,ArrayList<Integer> answer) {
            
            ArrayList<Move3> floor;
            ArrayList<Move3> submoves;
            ArrayList<Move3> floor_current;
            int cur_floor = 0;
            Move3 root = null;
            int returnVal=0;
            
            exitDo:do {
                floor_current = srh.get(cur_floor);
                floor = new ArrayList<Move3>();
                for(int r=0;r<floor_current.size();r++) {
                    root = floor_current.get(r);
                    //if(count % 10000 ==0 ) {
                    //    root.printCards();
                    //}
                    if(cur_floor>0) root.genData(root0,curData0);
                    if(root.curData.finish[0]==13 && root.curData.finish[1]==13 && root.curData.finish[2]==13 && root.curData.finish[3]==13) {
                        returnVal = 1;
                        break exitDo;
                    }
                    if(root.pressedCards()==0) {
                        root.curData.printCards();
                        returnVal = 1;
                        break exitDo;
                    }
                    
                    //########################### check move, add child
                    submoves = this.getAllMoves(srhMap, root, curData1);
                    floor.addAll(submoves);
                }
                //########################### child=0
                if(floor.size()>0) {
                    cur_floor++;
                    srh.add(floor);
                    /*
                    System.out.println("xCnt="+xCnt + "  floor["+cur_floor+"]="+floor.size());
                    if(xCnt==1 && cur_floor<=2) {
                        for(int i=0;i<floor.size();i++)    System.out.println("floor["+ i+ "]=" +floor.get(i).move_from_to_cnt+"    mapstr="+floor.get(i).mapstr);
                    }
                    */
                }else break;
                
            }while((cur_floor<65-xCnt*15 || xCnt>2 && cur_floor<8)&& srhMap.size()<300000);
            System.out.println("COUNT:"+srhMap.size()+"    CUR_FLOOR:"+cur_floor);
            
            //################################## Select the node with the most child nodes on the fourth floor
            Move3 mp;
            int maxPosterity = 0;
            Move3 maxPosterity_move=null;
            if(returnVal ==0) {
                int loopCnt;
                if(xCnt > 2) loopCnt=8;
                else loopCnt =49-xCnt*19;
                if(loopCnt >= srh.size()) loopCnt= srh.size() -1;
                
                floor = srh.get(loopCnt);
                for(int j=0;j<floor.size();j++) {
                    floor.get(j).parent.parent.parent.parent.posteritys++;
                }
                floor= srh.get(loopCnt-4);
                for(int j=0;j<floor.size();j++) {
                    if(floor.get(j).posteritys > maxPosterity) {
                        maxPosterity = floor.get(j).posteritys;
                        maxPosterity_move = floor.get(j);
                    }
                }
                System.out.println(maxPosterity);
                mp=maxPosterity_move;
            }else {
                mp = root;
                maxPosterity_move = root;
            }
            //############################ Add the solution steps to ArrayList
            int answerStart=answer.size();
            while(mp.parent!=null) {
                answer.add(answerStart,mp.move_from_to_cnt);
                mp=mp.parent;
            }
            
            root0.genRoot(maxPosterity_move);
            root0.curData.printCards();
            
            return returnVal;
        }
        
        ArrayList<Move3> getAllMoves(HashMap<Long,Integer> srhMap,Move3 root,CurData cData) {
            int iTmp,iTmp3,iTmp11,iTmp13;
            ArrayList<Move3> moves= new ArrayList<Move3>();
            ArrayList<Move3> subMoves= new ArrayList<Move3>();
            //=================================check move
            subMoves = check_move_free(srhMap,root,cData);
            moves.addAll(subMoves);

            //=================================check move
            subMoves = check_move_board(srhMap,root,cData);
            moves.addAll(subMoves);
            
            return moves;
        }
        
        ArrayList<Move3> check_move_free(HashMap<Long,Integer> srhMap,Move3 root,CurData cData) {
            int iTmp,iTmp3,iTmp11,iTmp13;
            ArrayList<Move3> moves= new ArrayList<Move3>();
            //free --> board; free-->finish
            for(int i=0;i<4;i++) {
                iTmp = root.curData.freePos[i];
                if(iTmp>-1) {
                    for(int j=0;j<8;j++) {
                        if(root.curData.bp[j] == 0) {
                            //search
                                //srhMap.put(mapStr, mx);
                            int cardchk= root.CARD_CHECK(iTmp);
                            if(cardchk == 0) continue;
                            Move3 mx=new Move3(root,cData,8+i,j,cardchk);
                            //mx.COL_MOVE(cardchk);
                            
                            long mapStr=mx.mapStr();
                            if(srhMap.get(mapStr)== null) {
                                srhMap.put(mapStr, 0);
                                mx.curData=null;
                                moves.add(mx);
                            }
                            break;
                        }
                    }
                    for(int j=0;j<8;j++) {
                        if(root.curData.bp[j] > 0) {
                            iTmp3 = root.curData.board[j][root.curData.bp[j]-1];
                            if(root.curData.bp[j]>0 && (iTmp%13 == iTmp3%13 -1) && (iTmp>25 && iTmp3<=25 ||iTmp<=25 && iTmp3>25)) {
                                //search
                                Move3 mx=new Move3(root,cData,8+i,j);
                                    //srhMap.put(mapStr, mx);
                                long mapStr=mx.mapStr();
                                if(srhMap.get(mapStr)== null) {
                                    srhMap.put(mapStr, 0);
                                    mx.curData=null;
                                    moves.add(mx);
                                }
                            }
                        }
                    }
                    
                    if(iTmp%13== root.curData.finish[iTmp/13]) {
                        //search
                        Move3 mx=new Move3(root,cData,8+i,12+iTmp/13);
                        long mapStr=mx.mapStr();
                        if(srhMap.get(mapStr)== null) {
                            srhMap.put(mapStr, 0);
                            mx.curData=null;
                            moves.add(mx);
                        }
                    }
                }
            }
            
            return moves;
            
        }

        ArrayList<Move3> check_move_board(HashMap<Long,Integer> srhMap,Move3 root,CurData cData) {
            int iTmp,iTmp3,iTmp11,iTmp13;
            ArrayList<Move3> moves= new ArrayList<Move3>();
            //board --> free; board-->finish; board -->board
            for(int i=0;i<8;i++) {
                if(root.curData.bp[i]==0) {
                    int maxcol=root.CARD_CHECK3_FREECOL();
                    if(maxcol > -1) {
                        Move3 mx=new Move3(root,cData,i,maxcol,true);
                        long mapStr=mx.mapStr();
                        if(srhMap.get(mapStr)== null) {
                            srhMap.put(mapStr, 0);
                            moves.add(mx);
                        }
                        mx.curData=null;
                    }
                    break;
                    
                }
            }
            
            for(int i=0;i<8;i++) {
                //if(sign.islockcol(i)) continue;
                if(root.curData.bp[i]>0) {
                    iTmp=root.curData.board[i][root.curData.bp[i]-1];
                    int cardchk= root.CARD_CHECK3(iTmp);
                    if(cardchk > 0) {
                        Move3 mx=new Move3(root,cData,i,cardchk,true);
                        long mapStr=mx.mapStr();
                        if(srhMap.get(mapStr)== null) {
                            srhMap.put(mapStr, 0);
                            moves.add(mx);
                        }
                        mx.curData=null;
                    }
                    

                    if(iTmp%13 == root.curData.finish[iTmp/13]) {
                        //search
                        Move3 mx=new Move3(root,cData,i,12+iTmp/13);
                        long mapStr=mx.mapStr();
                        if(srhMap.get(mapStr)== null) {
                            srhMap.put(mapStr, 0);
                            moves.add(mx);
                        }
                        mx.curData=null;
                    }
                    
                }
            }
            
            for(int i=0;i<8;i++) {
                //if(sign.islockcol(i)) continue;
                if(root.curData.bp[i]>0) {
                    iTmp=root.curData.board[i][root.curData.bp[i]-1];
                    
                    for(int j=0;j<4;j++) {
                        if(root.curData.freePos[j]==-1) {
                            //search
                            Move3 mx=new Move3(root,cData,i,8+j,"");
                            long mapStr=mx.mapStr();
                            if(srhMap.get(mapStr)== null) {
                                if(root.curData.bp[i]>1) {
                                    iTmp11 = root.curData.board[i][root.curData.bp[i]-1];
                                    iTmp13 = root.curData.board[i][root.curData.bp[i]-2];
                                    if(iTmp11 % 13== iTmp13 % 13 -1 && (iTmp11>25 && iTmp13<=25 || iTmp11<25 && iTmp13>=25)) {
                                        //floor_last.add(mx);
                                        if(root.curData.finish[iTmp13/13]== iTmp13%13) {
                                            srhMap.put(mapStr, 0);
                                            moves.add(mx);
                                        }
                                    }else {
                                        srhMap.put(mapStr, 0);
                                        moves.add(mx);
                                    }
                                }else {
                                    srhMap.put(mapStr, 0);
                                    moves.add(mx);
                                }
                            }
                            mx.curData=null;
                            break;
                        }
                    }
                }
            }
            
            return moves;
            
        }
        
    }


    class Move3{
        static String[] cellStr= {"1","2","3","4","5","6","7","8","a","b","c","d","h","h","h","h"};
        
        Move3 parent = null;
        int posteritys=0;
        int move_from_to_cnt = -1;
        CurData curData=null;
        

        long mapStr() {
            long l=0;
            
            /*
            for(int i=0;i<8;i++) for(int j=0;j<25;j++) curData.board[i][j]=parent.curData.board[i][j];
            for(int i=0;i<8;i++) this.curData.bp[i]=parent.curData.bp[i];
            for(int i=0;i<4;i++) this.curData.freePos[i]=parent.curData.freePos[i];
            for(int i=0;i<4;i++) this.curData.finish[i]=parent.curData.finish[i];
            recoverOneMove(this.move_from_to_cnt);
            */
            
            for(int i=0;i<4;i++) l+=l*25+curData.finish[i];
            for(int i=0;i<8;i++) l+=l*25+curData.bp[i];
            return l;        
        }
        
        /**
         *
         * @param col
         * @return
         */
        boolean isRegularCol(int col) {
            int iTmp,iTmp3;
            for(int j=curData.bp[col]-1;j>0;j--) {
                iTmp = curData.board[col][j];
                iTmp3 = curData.board[col][j-1];
                if((iTmp%13 == iTmp3%13 -1) && (iTmp>25 && iTmp3<=25 ||iTmp<=25 && iTmp3>25)) {
                }else {
                    return false;
                }
            }
            if(curData.bp[col]>1 && curData.board[col][0] % 13 ==12) return true;
            else return false;
        }
        
        int pressedCards() {
            int iTmp,iTmp3,pressed=0;
            for(int i=0;i<8;i++) {
                for(int j=curData.bp[i]-1;j>0;j--) {
                    iTmp = curData.board[i][j];
                    iTmp3 = curData.board[i][j-1];
                    if((iTmp%13 == iTmp3%13 -1) && (iTmp>25 && iTmp3<=25 ||iTmp<=25 && iTmp3>25)) {
                    }else {
                        pressed+=j;
                        break;
                    }
                }
            }
            return pressed;
            
        }
        
        void recoverOneMove(int moveCode) {
            int mf1,mf2,mt,cards,loop,mf;

            move_from_to_cnt = moveCode;
            mf1=move_from_to_cnt/1000000;
            mf2=(move_from_to_cnt%1000000)/10000;
            mt=(move_from_to_cnt%10000)/100;
            cards=move_from_to_cnt%100;
            if(mf2==0) {
                loop=1;
            }else {
                loop=2;
                mf2--;
            }
            for(int j=0;j<loop;j++) {
                if(j==0) mf=mf1;
                else mf=mf2;
                if(cards==1 || loop==2 && j==0) {
                    if(mf>7) {
                        if(mt>11) {
                            //=================== free-->curData.finish
                            this.curData.finish[this.curData.freePos[mf-8]/13]++;
                            this.curData.freePos[mf-8]=-1;
                        }else {
                            //=================== free --> board
                            curData.board[mt][this.curData.bp[mt]]=this.curData.freePos[mf-8];
                            this.curData.bp[mt]++;
                            this.curData.freePos[mf-8]=-1;
                        }
                    }else {
                        if(mt>11) {
                            //===================== board-->curData.finish
                            this.curData.finish[curData.board[mf][this.curData.bp[mf]-1]/13]++;
                            curData.board[mf][this.curData.bp[mf]-1]=-1;
                            this.curData.bp[mf]--;
                        }else if(mt>7) {
                            //===================== board-->free
                            this.curData.freePos[mt-8]=curData.board[mf][this.curData.bp[mf]-1];
                            curData.board[mf][this.curData.bp[mf]-1]=-1;
                            this.curData.bp[mf]--;
                        }else {
                            //===================== board-->board
                            curData.board[mt][this.curData.bp[mt]]=curData.board[mf][this.curData.bp[mf]-1];
                            this.curData.bp[mf]--;
                            this.curData.bp[mt]++;
                        }
                    }
                }else {
                    for(int k=0;k<cards;k++)
                        curData.board[mt][curData.bp[mt]+k] = curData.board[mf][curData.bp[mf]-cards+k];
                    curData.bp[mf]-=cards;
                    curData.bp[mt]+=cards;
                }
                
            }
            curData.checkFinishCell();
            
        }
        
        void genData(Move3 m0,CurData cData) {
            curData = cData;
            for(int i=0;i<8;i++) for(int j=0;j<25;j++) curData.board[i][j]=m0.curData.board[i][j];
            for(int i=0;i<8;i++) this.curData.bp[i]=m0.curData.bp[i];
            for(int i=0;i<4;i++) this.curData.freePos[i]=m0.curData.freePos[i];
            for(int i=0;i<4;i++) this.curData.finish[i]=m0.curData.finish[i];
            
            
            Move3 mp=this;
            ArrayList<Integer> moves=new ArrayList<Integer>();
            while(mp.parent!=null) {
                moves.add(0,mp.move_from_to_cnt);
                mp=mp.parent;
            }
            
            for(int i=0;i<moves.size();i++) {
                recoverOneMove(moves.get(i));
            }
        }
        
        void genRoot(Move3 m0) {
            
            Move3 mp=m0;
            ArrayList<Integer> moves=new ArrayList<Integer>();
            while(mp.parent!=null) {
                moves.add(0,mp.move_from_to_cnt);
                mp=mp.parent;
            }
            
            for(int i=0;i<moves.size();i++) {
                recoverOneMove(moves.get(i));
            }
        }

        void printAnswer(CurData cData,ArrayList<Integer> answer) {
            curData = cData;
            int move_f2t,mf1,mf2,mt,cards,loop,mf,locksum=0;
            
            for(int i=0;i<answer.size();i++) {
                recoverOneMove(answer.get(i));
                move_f2t=answer.get(i);
                mf1=move_f2t/1000000;
                mf2=(move_f2t%1000000)/10000;
                mt=(move_f2t%10000)/100;
                cards=move_f2t%100;
                if(mf2==0)    System.out.println("step:"+i +"    moving:    "+cellStr[mf1]+cellStr[mt]);
                else System.out.println("step:"+i +"    moving:    "+cellStr[mf1]+cellStr[mt]+"  "+cellStr[mf2-1]+cellStr[mt]);
                this.curData.printCards(move_from_to_cnt);
            }
            

            for(int i=0;i<answer.size();i++) {
                move_f2t=answer.get(i);
                mf1=move_f2t/1000000;
                mf2=(move_f2t%1000000)/10000;
                mt=(move_f2t%10000)/100;
                cards=move_f2t%100;
                if(i%10==0) System.out.println("");
                System.out.print(cellStr[mf1]+cellStr[mt]+"  ");
                if(mf2>0) System.out.print(cellStr[mf2-1]+cellStr[mt]+"  ");
            }
            System.out.println("");
            
            ArrayList<Lock> locks = new ArrayList<Lock>();
            Lock lock;
            int moveFFTC,lockmax=0;
            for(int i=0;i<answer.size();i++) {
                moveFFTC = answer.get(i);
                mf1=moveFFTC/1000000;
                mf2=(moveFFTC%1000000)/10000;
                mt=(moveFFTC%10000)/100;
                cards=moveFFTC%100;
                int j=locks.size()-1;
                while(j>=0) {
                    lock=locks.get(j);
                    if(lock.fromCol == mt && lock.toCol== mf1 && lock.cardCnt==cards) {
                        System.out.println("lock!!!! AT step:" +i+"   start step:"+lock.step);
                    }else {
                        if(lock.toCol == mf1 && lock.cardCnt == cards) {
                            System.out.println("needless move!!!! AT step:" +lock.step +"   cur step:"+i);
                        }else if(lock.fromCol==mf1 || lock.fromCol == mt || lock.toCol == mf1 || lock.toCol ==mt) {
                            locks.remove(j);
                        }
                    }
                    j--;
                }
                if(mf2==0) {
                    lock = new Lock();
                    lock.step = i;
                    lock.cardCnt = cards;
                    lock.fromCol = mf1;
                    lock.toCol = mt;
                    locks.add(lock);
                    if(locks.size()>lockmax) {
                        lockmax=locks.size();
                        System.out.println("lock max="+lockmax);
                    }
                    locksum += locks.size();
                }
                
            }
            System.out.println("lock average="+locksum*100/answer.size()/100.0);
            
        }
        
        
        public Move3() {
            
        }
        
        public Move3(Move3 m0,CurData cData,int mf,int mt,String str) {
            parent=m0;
            move_from_to_cnt = mf*1000000+mt*100+1;
            curData=cData;
            
            for(int i=0;i<8;i++) for(int j=0;j<25;j++) curData.board[i][j]=m0.curData.board[i][j];
            for(int i=0;i<8;i++) this.curData.bp[i]=m0.curData.bp[i];
            for(int i=0;i<4;i++) this.curData.freePos[i]=m0.curData.freePos[i];
            for(int i=0;i<4;i++) this.curData.finish[i]=m0.curData.finish[i];
            
            //free --> board; free-->curData.finish
            //board --> free; board-->curData.finish; board -->board
            if(mf>7) {
                if(mt>11) {
                    //=================== free-->curData.finish
                    this.curData.finish[this.curData.freePos[mf-8]/13]++;
                    this.curData.freePos[mf-8]=-1;
                }else {
                    //=================== free --> board
                    curData.board[mt][this.curData.bp[mt]]=this.curData.freePos[mf-8];
                    this.curData.bp[mt]++;
                    this.curData.freePos[mf-8]=-1;
                }
            }else {
                if(mt>11) {
                    //===================== board-->curData.finish
                    this.curData.finish[curData.board[mf][this.curData.bp[mf]-1]/13]++;
                    curData.board[mf][this.curData.bp[mf]-1]=-1;
                    this.curData.bp[mf]--;
                }else if(mt>7) {
                    //===================== board-->free
                    this.curData.freePos[mt-8]=curData.board[mf][this.curData.bp[mf]-1];
                    curData.board[mf][this.curData.bp[mf]-1]=-1;
                    this.curData.bp[mf]--;
                }else {
                    //===================== board-->board
                    curData.board[mt][this.curData.bp[mt]]=curData.board[mf][this.curData.bp[mf]-1];
                    this.curData.bp[mf]--;
                    this.curData.bp[mt]++;
                }
            }
        }
        
        public Move3(Move3 m0,CurData cData,int mf,int mt) {
            parent=m0;
            move_from_to_cnt = mf*1000000+mt*100+1;
            curData=cData;
            
            //for(int i=0;i<8;i++) for(int j=0;j<25;j++) curData.board[i][j]=m0.curData.board[i][j];
            for(int i=0;i<8;i++) this.curData.bp[i]=m0.curData.bp[i];
            //for(int i=0;i<4;i++) this.curData.freePos[i]=m0.curData.freePos[i];
            for(int i=0;i<4;i++) this.curData.finish[i]=m0.curData.finish[i];
            
            //free --> board; free-->curData.finish
            //board --> free; board-->curData.finish; board -->board
            if(mf>7) {
                if(mt>11) {
                    //=================== free-->curData.finish
                    this.curData.finish[m0.curData.freePos[mf-8]/13]++;
                    //this.curData.freePos[mf-8]=-1;
                }else {
                    //=================== free --> board
                    //curData.board[mt][this.curData.bp[mt]]=this.curData.freePos[mf-8];
                    this.curData.bp[mt]++;
                    //this.curData.freePos[mf-8]=-1;
                }
            }else {
                if(mt>11) {
                    //===================== board-->curData.finish
                    this.curData.finish[m0.curData.board[mf][m0.curData.bp[mf]-1]/13]++;
                    //curData.board[mf][this.curData.bp[mf]-1]=-1;
                    this.curData.bp[mf]--;
                }else if(mt>7) {
                    //===================== board-->free
                    //this.curData.freePos[mt-8]=curData.board[mf][this.curData.bp[mf]-1];
                    //curData.board[mf][this.curData.bp[mf]-1]=-1;
                    this.curData.bp[mf]--;
                }else {
                    //===================== board-->board
                    //curData.board[mt][this.curData.bp[mt]]=curData.board[mf][this.curData.bp[mf]-1];
                    this.curData.bp[mf]--;
                    this.curData.bp[mt]++;
                }
            }
        }
        
        /**
         * move one card from free to free col and move cards to this card
         * @param m0
         * @param cData
         * @param mf
         * @param mt
         * @param cardchk
         */
        public Move3(Move3 m0,CurData cData,int mf,int mt,int cardchk) {
            parent=m0;
            int moveFrom = cardchk/100;
            int cards = cardchk % 100;
            move_from_to_cnt = mf*1000000+(moveFrom+1)*10000+mt*100+cards;
            
            curData=cData;
            for(int i=0;i<8;i++) this.curData.bp[i]=m0.curData.bp[i];
            for(int i=0;i<4;i++) this.curData.finish[i]=m0.curData.finish[i];
            curData.bp[mt]++;
            curData.bp[moveFrom]-=cards;
            curData.bp[mt]+=cards;
        }
        

        public Move3(Move3 m0,CurData cData,int mt,int cardchk,boolean bt) {
            parent=m0;
            move_from_to_cnt = cardchk/100*1000000+mt*100+cardchk % 100;
            curData=cData;
            
            //for(int i=0;i<8;i++) for(int j=0;j<25;j++) this.curData.board[i][j]=m0.curData.board[i][j];
            for(int i=0;i<8;i++) this.curData.bp[i]=m0.curData.bp[i];
            //for(int i=0;i<4;i++) this.curData.freePos[i]=m0.curData.freePos[i];
            for(int i=0;i<4;i++) this.curData.finish[i]=m0.curData.finish[i];
            
            int moveFrom = cardchk/100;
            int cards = cardchk % 100;
            ///*
            for(int i=0;i<cards;i++)
                curData.board[mt][curData.bp[mt]+i] = curData.board[moveFrom][curData.bp[moveFrom]-cards+i];
            //*/
            curData.bp[moveFrom]-=cards;
            curData.bp[mt]+=cards;
        }

        int CARD_CHECK(int card) {
            int[] cardcol= {0,0,0,0};
            int cols=0;
            for(int i=0;i<8;i++) {
                if(isRegularCol(i)) continue;
                for(int j=0;j<curData.bp[i];j++) {
                    //root.curData.curData.bp[j] == 0 && root.curData.curData.bp[i]>1) || ((iTmp%13 == iTmp3%13 -1) && (iTmp>25 && iTmp3<=25 ||iTmp<=25 && iTmp3>25))) {
                    if(curData.board[i][j] % 13== card % 13 -1 && (curData.board[i][j]>25 && card<=25 || curData.board[i][j]<=25 && card>25)) {
                        boolean ck=true;
                        for(int k=j+1;k<curData.bp[i];k++) {
                            if(curData.board[i][k] % 13== curData.board[i][k-1] % 13 -1 && (curData.board[i][k]>25 && curData.board[i][k-1]<=25 || curData.board[i][k]<25 && curData.board[i][k-1]>=25)) {
                            }else {
                                ck = false;
                                break;
                            }
                        }
                        if(ck) {
                            cardcol[cols] = i;
                            cardcol[cols+2] = curData.bp[i] - j; //chang du
                            cols++;
                            break;
                        }
                    }
                }
            }
            
            int kongdang=0,konglie=0;
            for(int i=0;i<4;i++) if(curData.freePos[i] == -1) kongdang++;
            for(int i=0;i<8;i++) if(curData.bp[i] == 0) konglie++;
            kongdang = (kongdang+2)*konglie;
            if(cols == 2) {
                if(cardcol[3]>cardcol[2]) {
                    if(cardcol[3]<=kongdang) return cardcol[1]*100+cardcol[3];
                    else if(cardcol[2]<=kongdang) return cardcol[0]*100+cardcol[2];
                    else return 0;
                }else {
                    if(cardcol[2]<=kongdang) return cardcol[0]*100+cardcol[2];
                    else if(cardcol[2]<=kongdang) return cardcol[1]*100+cardcol[3];
                    else return 0;
                }
            }else if(cols == 1) {
                if(cardcol[2]<=kongdang) return cardcol[0]*100+cardcol[2];
                else return 0;
            }else {
                return 0;
            }
        }

        int CARD_CHECK3(int card) {
            int[] cardcol= {0,0,0,0};
            int cols=0;
            for(int i=0;i<8;i++) {
                if(isRegularCol(i)) continue;
                for(int j=0;j<curData.bp[i];j++) {
                    //root.curData.curData.bp[j] == 0 && root.curData.curData.bp[i]>1) || ((iTmp%13 == iTmp3%13 -1) && (iTmp>25 && iTmp3<=25 ||iTmp<=25 && iTmp3>25))) {
                    if(curData.board[i][j] % 13== card % 13 -1 && (curData.board[i][j]>25 && card<=25 || curData.board[i][j]<=25 && card>25)) {
                        boolean ck=true;
                        for(int k=j+1;k<curData.bp[i];k++) {
                            if(curData.board[i][k] % 13== curData.board[i][k-1] % 13 -1 && (curData.board[i][k]>25 && curData.board[i][k-1]<=25 || curData.board[i][k]<25 && curData.board[i][k-1]>=25)) {
                            }else {
                                ck = false;
                                break;
                            }
                        }
                        if(ck) {
                            cardcol[cols] = i;
                            cardcol[cols+2] = curData.bp[i] - j; //chang du
                            cols++;
                            if(cols>2) {
                                System.out.print("aa");
                            }
                            break;
                        }
                    }
                }
            }
            
            int kongdang=0,konglie=0;
            for(int i=0;i<4;i++) if(curData.freePos[i] == -1) kongdang++;
            for(int i=0;i<8;i++) if(curData.bp[i] == 0) konglie++;
            kongdang = (kongdang+1)*(konglie+1);
            if(cols == 2) {
                if(cardcol[3]>cardcol[2]) {
                    if(cardcol[3]<=kongdang) return cardcol[1]*100+cardcol[3];
                    else if(cardcol[2]<=kongdang) return cardcol[0]*100+cardcol[2];
                    else return 0;
                }else {
                    if(cardcol[2]<=kongdang) return cardcol[0]*100+cardcol[2];
                    else if(cardcol[2]<=kongdang) return cardcol[1]*100+cardcol[3];
                    else return 0;
                }
            }else if(cols == 1) {
                if(cardcol[2]<=kongdang) return cardcol[0]*100+cardcol[2];
                else return 0;
            }else {
                return 0;
            }
        }

        int CARD_CHECK3_FREECOL() {
            int[] cardcol= {1,1,1,1,1,1,1,1,0};
            int tmp1,tmp3;
            for(int i=0;i<8;i++) {
                if(curData.bp[i]==0) cardcol[i] = 0;
                else if(curData.bp[i]==1) cardcol[i] = 1;
                else {
                    for(int j=curData.bp[i]-1;j>0;j--) {
                        tmp1 = curData.board[i][j];
                        tmp3 = curData.board[i][j-1];
                        if(tmp1 % 13== tmp3 % 13 -1 && (tmp1>25 && tmp3<=25 || tmp1<=25 && tmp3>25)) {
                            cardcol[i]++;
                        }else break;
                    }
                }
            }
            
            int kongdang=0,konglie=0;
            for(int i=0;i<4;i++) if(curData.freePos[i] == -1) kongdang++;
            for(int i=0;i<8;i++) if(curData.bp[i] == 0) konglie++;
            kongdang = (kongdang+1)*konglie;
            int max=8;
            for(int i=0;i<8;i++) {
                if(cardcol[i] <= kongdang && cardcol[i] < curData.bp[i] && cardcol[i]>cardcol[max]) max=i;
            }
            if(max == 8) return -1;
            return max*100+cardcol[max];
            
        }
        
        /*
        void COL_MOVE(int cardchk) {
            int moveto=(move_from_to_cnt%10000)/100;
            int moveFrom = cardchk/100;
            int cards = cardchk % 100;
            move_from_to_cnt = move_from_to_cnt + (cardchk/100+1)*10000;
            move_from_to_cnt = move_from_to_cnt/100*100+cards;
            for(int i=0;i<cards;i++) curData.board[moveto][1+i] = curData.board[moveFrom][curData.bp[moveFrom]-cards+i];
            curData.bp[moveFrom]-=cards;
            curData.bp[moveto]+=cards;
        }
        */

    }

    class CurData{
        static String[] huase= {"♣","♠","◆","♥"};
        static String[] paidian= {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
        
        public int[][] board = new int[8][25];
        public int[] bp = new int[8];
        public int[] freePos = {-1,-1,-1,-1};
        public int[] finish = new int[4];

        String cardStr(int c) {
            if(c<0) return "-";
            return huase[c/13]+paidian[c%13];
        }
        String cardStr(int col,int val) {
            if(val==0) return "-";
            return huase[col]+paidian[val-1];
        }
        void printCards() {
            System.out.println("|===============================================================|");
            System.out.println("|        FREE:        |        REC:        |");
            System.out.println("|"+cardStr(freePos[0]) + "    "+ cardStr(freePos[1]) + "    "+cardStr(freePos[2]) + "    "+cardStr(freePos[3])+ "    |"+ cardStr(0,finish[0]) + "    "+ cardStr(1,finish[1]) + "    "+cardStr(2,finish[2]) + "    "+cardStr(3,finish[3])+"    |");
            System.out.println("|===============================================================|");
            int max=0;
            String str;
            for(int i=0;i<8;i++) if(max<bp[i]) max= bp[i];
            for(int i=0;i<max;i++) {
                str = "";
                for(int j=0;j<8;j++) {
                    if(i<bp[j]) str+=cardStr(board[j][i]);
                    str+="    ";
                }
                System.out.println(str);
            }
            
        }
        
        String repeatChar(String s,int repeat) {
            String str="";
            for(int i=0;i<repeat;i++) str+=s;
            return str;
        }

        void printCards(int movefromto) {
            System.out.println("|===============================================================|");
            System.out.println("|        FREE:        |        REC:        |");
            System.out.println("|"+cardStr(freePos[0]) + "    "+ cardStr(freePos[1]) + "    "+cardStr(freePos[2]) + "    "+cardStr(freePos[3])+ "    |"+ cardStr(0,finish[0]) + "    "+ cardStr(1,finish[1]) + "    "+cardStr(2,finish[2]) + "    "+cardStr(3,finish[3])+"    |");
            System.out.println("|===============================================================|");
            
            int mf=movefromto/1000000;
            int mt=(movefromto%10000)/100;
            String moveSign="";
            if(mf<8 && mf<mt && mt<8) moveSign = repeatChar("    ",mf)+"┌"+repeatChar("─",(mt-mf)*8)+"↓";
            else if(mf<8 && mt>8 && mt>mf+8) moveSign = repeatChar("    ",mf)+"┌"+repeatChar("─",(mt-mf-8)*8)+"↑";
            else if(mf>=8 && mt<8 && mt+8>mf) moveSign = repeatChar("    ",mf-8)+"└"+repeatChar("─",(mt+8-mf)*8)+"↓";
            else if(mf>=8 && mt>mf) moveSign = repeatChar("    ",mf-8)+"└"+repeatChar("─",(mt-mf)*8)+"↑";
            else if(mf<8 && mt<mf) moveSign = repeatChar("    ",mt)+"↓"+repeatChar("─",(mf-mt)*8)+"┐";
            else if(mf<8 && mt>=8 && mt<mf+8) moveSign = repeatChar("    ",mt-8)+"↑"+repeatChar("─",(mf+8-mt)*8)+"┐";
            else if(mf>=8 && mt<8 && mt<mf-8) moveSign = repeatChar("    ",mt)+"↓"+repeatChar("─",(mf-8-mt)*8)+"┘";
            else if(mf>=8 && mt>mf) {}
            else if(mt == mf+8)    moveSign = repeatChar("    ",mf)+"↑";
            else if(mt == mf-8)    moveSign = repeatChar("    ",mt)+"↓";
            System.out.println(moveSign);
            
            int max=0;
            String str;
            for(int i=0;i<8;i++) if(max<bp[i]) max= bp[i];
            for(int i=0;i<max;i++) {
                str = "";
                for(int j=0;j<8;j++) {
                    if(i<bp[j]) str+=cardStr(board[j][i]);
                    str+="    ";
                }
                System.out.println(str);
            }
            
        }
        
        void checkFinishCell() {
            int upCards=1;
            int card,cardPoint,corresponding1,corresponding2;
            while(upCards>0) {
                upCards=0;
                for(int i=0;i<8;i++) {
                    if(bp[i]>0) {
                        card=board[i][bp[i]-1];
                        cardPoint = card%13;
                        if(card<26) {
                            corresponding1=2;
                            corresponding2=3;
                        }else {
                            corresponding1=0;
                            corresponding2=1;
                        }
                        if(cardPoint == finish[card/13] && (cardPoint <2 || (finish[corresponding1]>=cardPoint && finish[corresponding2]>=cardPoint))) {
                            bp[i]--;
                            finish[card/13]++;
                            upCards++;
                        }
                    }
                }
                for(int i=0;i<4;i++) {
                    if(freePos[i]>=0) {
                        card=freePos[i];
                        cardPoint = card%13;
                        if(card<26) {
                            corresponding1=2;
                            corresponding2=3;
                        }else {
                            corresponding1=0;
                            corresponding2=1;
                        }
                        if(cardPoint == finish[card/13] && (cardPoint <2 || (finish[corresponding1]>=cardPoint && finish[corresponding2]>=cardPoint))) {
                            freePos[i]=-1;
                            finish[card/13]++;
                            upCards++;
                        }
                    }
                }
            }
        }
        
    }

    class Lock{
        int step;
        int type;
        int fromCol;
        int toCol;
        int card;
        int cardCnt;
    }


  • 相关阅读:
    STL源码剖析 真是一本好书
    消息映射与消息路由原理
    linux下无法正常打开pdf文件的解决方法
    [转载]Amazon's Dynamo 中文版
    [转载]NoSQL数据建模技术
    [转载]linuxkerneltuningfor500k
    YCSB初步介绍
    Lamport's Logical Clocks 和 Vector Clock
    googleperftools 试用
    [转载]Big List Of 20 Common Bottlenecks
  • 原文地址:https://www.cnblogs.com/nocomment/p/8282507.html
Copyright © 2011-2022 走看看