Changes between Version 2 and Version 3 of codekata/mastermind


Ignore:
Timestamp:
08/14/2013 05:57:15 PM (13 years ago)
Author:
chenyang
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • codekata/mastermind

    v2 v3  
    2626                3,活动一开始时,大家没有形成统一思想,就开始各顾各的编码,后继同事,难于续接。[[BR]] 
    2727 
    28  
     28''' 大家最终讨论的方案实现代码如下 ''' 
     29[[BR]] 
     30''' 猜测结果类 Result.java ''' 
     31{{{ 
     32/** 
     33 * 猜测结果类,若结果是4A0B,则猜中 
     34 * @author chenyang 
     35 * @version 7.0 
     36 * date : 2013-7-29 
     37 *  
     38 */ 
     39public class Result { 
     40         
     41        private int numA; 
     42         
     43        private int numB; 
     44 
     45        public int getNumA() { 
     46                return numA; 
     47        } 
     48 
     49        public void setNumA(int numA) { 
     50                this.numA = numA; 
     51        } 
     52 
     53        public int getNumB() { 
     54                return numB; 
     55        } 
     56 
     57        public void setNumB(int numB) { 
     58                this.numB = numB; 
     59        } 
     60         
     61        public Result() { 
     62                 
     63        } 
     64 
     65        public Result(int numA, int numB) { 
     66                super(); 
     67                this.numA = numA; 
     68                this.numB = numB; 
     69        } 
     70 
     71        public int sum(){ 
     72                return numA + numB; 
     73        } 
     74         
     75        /** 
     76         * 是否猜中所有数字 
     77         * @return 
     78         */ 
     79        public boolean isRight(){ 
     80                return this.numA == 4; 
     81        } 
     82 
     83        @Override 
     84        public String toString() { 
     85                return numA+"A"+numB+"B";  
     86        } 
     87         
     88} 
     89         
     90}}} 
     91 
     92''' 猜测结果测试类 ResultTest.java ''' 
     93{{{ 
     94import static org.junit.Assert.*; 
     95 
     96import org.junit.Test; 
     97 
     98/** 
     99 * @author chenyang 
     100 * @version 7.0 
     101 *  
     102 */ 
     103public class ResultTest { 
     104        @Test 
     105        public void isRight() throws Exception { 
     106                Result r = new Result(1,1); 
     107                assertFalse(r.isRight()); 
     108                 
     109                r = new Result(4,0); 
     110                assertTrue(r.isRight()); 
     111        } 
     112} 
     113}}} 
     114''' 谜底类 Puzzle.java ''' 
     115{{{ 
     116import java.util.Arrays; 
     117import java.util.LinkedList; 
     118import java.util.Random; 
     119 
     120/** 
     121 * @author chenyang 
     122 * @version 7.0 
     123 * date : 2013-7-29 
     124 *  
     125 */ 
     126public class Puzzle { 
     127         
     128        //谜底 
     129        private int[] numbers; 
     130 
     131        public int[] getNumbers() { 
     132                return numbers; 
     133        } 
     134 
     135        public void setNumbers(int[] numbers) { 
     136                this.numbers = numbers; 
     137        } 
     138         
     139        public Puzzle(){ 
     140                this.numbers = new int[4]; 
     141                LinkedList<String> list = new LinkedList<String>(); 
     142                for(int i=0; i<10; i++){ 
     143                        list.add(String.valueOf(i)); 
     144                } 
     145                Random random = new Random(); 
     146                //随机产生谜底 
     147                for(int i=0; i<4; i++){ 
     148                        int posi = random.nextInt(list.size());  
     149                        String value = list.remove(posi); 
     150                        this.numbers[i] = Integer.valueOf(value); 
     151                } 
     152        } 
     153         
     154        /** 
     155         * 用指定数组猜结果 
     156         * @param guess 
     157         * @return 猜测结果 
     158         */ 
     159        public Result match(int[] guess) { 
     160        int a=0; 
     161        int b=0; 
     162        for(int i =0; i<guess.length;i++){ 
     163                for(int j =0;j<numbers.length;j++){ 
     164                    if(guess[i] == numbers[j] && i == j){ 
     165                        a++; 
     166                    } else if(guess[i] == numbers[j]){ 
     167                        b++; 
     168                    } 
     169                } 
     170        } 
     171        return new Result(a,b);  
     172                 
     173        } 
     174 
     175        @Override 
     176        public String toString() { 
     177                return "Puzzle [numbers=" + Arrays.toString(numbers) + "]"; 
     178        } 
     179         
     180         
     181         
     182} 
     183         
     184}}} 
     185 
     186''' 谜底测试类 PuzzleTest.java ''' 
     187{{{ 
     188import static org.junit.Assert.*; 
     189 
     190import org.junit.Test; 
     191 
     192/** 
     193 * @author chenyang 
     194 * @version 7.0 
     195 *  
     196 */ 
     197public class PuzzleTest { 
     198        @Test 
     199        public void testPuzzle() throws Exception { 
     200                Puzzle puzzle = new Puzzle(); 
     201                int[] numbers = puzzle.getNumbers(); 
     202                assertNotNull(numbers); 
     203                 
     204                for(int i=0; i<numbers.length; i++){ 
     205                        assertTrue(numbers[i] >=0 && numbers[i] < 10); 
     206                } 
     207                 
     208        } 
     209         
     210        @Test 
     211        public void match() throws Exception { 
     212                Puzzle puzzle = new Puzzle(); 
     213                puzzle.setNumbers(new int[]{1,8,2,6}); 
     214                 
     215                Result result = puzzle.match(new int[]{2,0,3,5}); 
     216                assertTrue(result.getNumA() == 0); 
     217                assertTrue(result.getNumB() == 1); 
     218                 
     219                result = puzzle.match(new int[]{1,0,2,5}); 
     220                assertTrue(result.getNumA() == 2); 
     221                assertTrue(result.getNumB() == 0); 
     222                 
     223                result = puzzle.match(new int[]{1,8,2,6}); 
     224                assertTrue(result.getNumA() == 4); 
     225                assertTrue(result.getNumB() == 0); 
     226        } 
     227} 
     228         
     229}}} 
     230''' 猜测过程实现类 GuessHandler.java ''' 
     231{{{ 
     232import java.util.ArrayList; 
     233import java.util.Arrays; 
     234import java.util.LinkedList; 
     235import java.util.List; 
     236 
     237/** 
     238 * @author chenyang 
     239 * @version 7.0 
     240 * date : 2013-7-29 
     241 *  
     242 */ 
     243public class GuessHandler { 
     244 
     245        /** 
     246         * @param args 
     247         */ 
     248        public static void main(String[] args) { 
     249                // TODO Auto-generated method st 
     250                 
     251                Puzzle puzzle = new Puzzle(); 
     252                System.out.println(puzzle); 
     253                guessNumbers(puzzle, null); 
     254 
     255        } 
     256         
     257        /** 
     258         * 猜谜 
     259         * @param puzzle 谜语 
     260         * @param guess 试猜的谜语 
     261         * @return 谜底 
     262         */ 
     263        public static int[] guessNumbers(Puzzle puzzle, int[] guess){ 
     264                 
     265                if(guess == null){ 
     266                        //默认给一个答案 
     267                        guess = new int[]{1,2,3,4}; 
     268                } 
     269                System.out.println(Arrays.toString(guess)); 
     270                Result r = puzzle.match(guess); 
     271                 
     272                //运气好,一次就猜中 
     273                if(r.isRight()){ 
     274                        return guess; 
     275                } 
     276                 
     277                int[] result = new int[4]; 
     278                 
     279                LinkedList<String> list = new LinkedList<String>(); 
     280                for(int i=0; i<10; i++){ 
     281                        list.add(String.valueOf(i)); 
     282                } 
     283                for(int i=0; i<guess.length; i++){ 
     284                        int index = list.indexOf(String.valueOf(guess[i])); 
     285                        list.remove(index); 
     286                } 
     287                 
     288                //答案以外其它数字 
     289                int[] remain = new int[list.size()]; 
     290                for(int i=0; i<list.size(); i++){ 
     291                        int num = Integer.valueOf(list.get(i)); 
     292                        remain[i] = num; 
     293                } 
     294                 
     295                //当前答案数字匹配个数 
     296                int sum = r.sum(); 
     297                 
     298                //用答案以外的每一个数字去替换答案中的每一个数,如果匹配的个数增加,说明,替换的数是匹配数字 
     299                out : for(int i=0; i<remain.length; i++){ 
     300                        int temp = remain[i]; 
     301                        for(int j=0; j<guess.length; j++){ 
     302                                int init = guess[j]; //保留初始状态 
     303                                guess[j] = temp; 
     304                                System.out.println(Arrays.toString(guess)); 
     305                                r = puzzle.match(guess); 
     306                                //猜中结果 
     307                                if(r.isRight()){ 
     308                                        return guess; 
     309                                } 
     310                                if(r.sum() > sum){ 
     311                                        //替换的数字是匹配数 
     312                                        result = guess; 
     313                                        sum = r.sum(); 
     314                                        continue out; 
     315                                }else{ 
     316                                        //替换的数字不匹配,恢复到初始状态 
     317                                        guess[j] = init; 
     318                                } 
     319                                 
     320                                if(sum == 4){ 
     321                                        //数字全部匹配 
     322                                        break out; 
     323                                } 
     324                        } 
     325                } 
     326                 
     327                //将匹配的数字全排列 
     328                List<int[]> items = pl(result); 
     329                for(int i=0; i<items.size(); i++){ 
     330                        int[] curr = items.get(i); 
     331                        System.out.println(Arrays.toString(curr)); 
     332                        //每种组合都猜下 
     333                        r = puzzle.match(curr); 
     334                         
     335                        if(r.isRight()){ 
     336                                //数字,位置都正确 
     337                                return curr; 
     338                        } 
     339                } 
     340                return result; 
     341        } 
     342         
     343 
     344        /** 
     345         *  全排列 
     346         * @param data 
     347         * @return 
     348         */ 
     349        public static List<int[]> pl(int[] data){ 
     350                List<int[]> list = new ArrayList<int[]>(); 
     351                if(data.length == 1){ 
     352                        list.add(data); 
     353                        return list; 
     354                } 
     355                for(int i=0; i<data.length; i++){ 
     356                        int c = data[i]; 
     357                        int[] subdata = new int[data.length-1]; 
     358                        if(i == 0){ 
     359                                System.arraycopy(data, 1, subdata, 0, data.length-1); 
     360                        }else if(i == data.length - 1){ 
     361                                System.arraycopy(data, 0, subdata, 0, data.length-1); 
     362                        }else{ 
     363                                System.arraycopy(data, 0, subdata, 0, i); 
     364                                System.arraycopy(data, i+1, subdata, i, data.length-(i+1)); 
     365                        } 
     366                        List<int[]> sublist = pl(subdata); 
     367                        for(int j=0; j<sublist.size(); j++){ 
     368                                int[] subarr = sublist.get(j); 
     369                                int[] item = new int[subarr.length + 1]; 
     370                                item[0] = c; 
     371                                System.arraycopy(subarr, 0, item, 1, subarr.length); 
     372                                list.add(item); 
     373                        } 
     374                         
     375                } 
     376                return list; 
     377        } 
     378} 
     379         
     380}}} 
     381''' 猜测过程实现类测试 GuessHandlerTest.java ''' 
     382{{{ 
     383import java.util.Arrays; 
     384import java.util.List; 
     385import static org.junit.Assert.*; 
     386 
     387import org.junit.Test; 
     388 
     389/** 
     390 * @author chenyang 
     391 * @version 7.0 
     392 *  
     393 */ 
     394public class GuessHandlerTest { 
     395        @Test 
     396        public void pl() throws Exception { 
     397                List<int[]> list = GuessHandler.pl(new int[]{1,2,3}); 
     398                assertTrue(list.size() == 6); 
     399                for(int i=0; i<list.size(); i++){ 
     400                        int[] item = list.get(i); 
     401                        if(i == 0) assertEquals("[1, 2, 3]",Arrays.toString(item)); 
     402                        if(i == 1) assertEquals("[1, 3, 2]",Arrays.toString(item)); 
     403                        if(i == 2) assertEquals("[2, 1, 3]",Arrays.toString(item)); 
     404                        if(i == 3) assertEquals("[2, 3, 1]",Arrays.toString(item)); 
     405                        if(i == 4) assertEquals("[3, 1, 2]",Arrays.toString(item)); 
     406                        if(i == 5) assertEquals("[3, 2, 1]",Arrays.toString(item)); 
     407                } 
     408        } 
     409         
     410        @Test 
     411        public void guessNumbers() throws Exception { 
     412                 
     413                Puzzle puzzle = new Puzzle(); 
     414                 
     415                int[] result = GuessHandler.guessNumbers(puzzle, null); 
     416                for(int i=0; i<4; i++){ 
     417                        assertEquals(puzzle.getNumbers()[i],result[i]);  
     418                } 
     419                 
     420        } 
     421} 
     422         
     423}}}