Your SlideShare is downloading.
×

×

Saving this for later?
Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.

Text the download link to your phone

Standard text messaging rates apply

Like this presentation? Why not share!

- Real Groovy by adelaidtes 245 views
- Groovy Api Tutorial by guligala 1771 views
- Discovering functional treasure in ... by Naresha K 270 views
- Little words of wisdom for the deve... by jaxLondonConference 298 views
- GR8Conf 2009: Groovy Usage Patterns... by GR8Conf 4439 views
- Groovy Power Features by Paul King 6296 views
- Introduction to Groovy and Grails by Marco Pas 6967 views
- Seminario de DSLs con Groovy by Paradigma Tecnoló... 126 views
- Using Grails to Power your Electric... by GR8Conf 1065 views
- Grails from scratch by Gustavo Pinto 2143 views
- Introduction To Groovy by manishkp84 1380 views
- groovy & grails - lecture 11 by alexmass 408 views

Like this? Share it with your network
Share

736

views

views

Published on

Eclipse tips

8 queens on a chess board

Genetic algorithm

Abstract class (a little bit more about inheritance)

No Downloads

Total Views

736

On Slideshare

0

From Embeds

0

Number of Embeds

0

Shares

0

Downloads

17

Comments

0

Likes

1

No embeds

No notes for slide

- 1. Groovy: Efficiency Oriented ProgrammingLecture 8Master Proteomics & Bioinformatics - University of GenevaAlexandre Masselot - summer 2011
- 2. Contents‣ Eclipse tips‣ 8 queens on a chess board‣ Genetic algorithm‣ Abstract class (a little bit more about inheritance)
- 3. Eclipse tips‣ Outline view in the right column - get a list of your field and method of the current class
- 4. Eclipse tips‣ Outline view in the right column - get a list of your field and method of the current class‣ Help > Key assist - get a list of all the possible shortcuts
- 5. Eclipse tips‣ Outline view in the right column - get a list of your field and method of the current class‣ Help > Key assist - get a list of all the possible shortcuts
- 6. 8 queens puzzle‣ Problem - put 8 queens on a chess board, - none is able to capture another (columns, rows and diagonal)
- 7. 8 queens puzzle: history‣ Chess player Max Bezzel proposed the problem in 1848
- 8. 8 queens puzzle: history‣ Chess player Max Bezzel proposed the problem in 1848‣ Mathematicians (including Gauss) worked on the problem (and generalization to n-queens)
- 9. 8 queens puzzle: history‣ Chess player Max Bezzel proposed the problem in 1848‣ Mathematicians (including Gauss) worked on the problem (and generalization to n-queens)‣ Franz Nauck proposed the first solutions (1850)
- 10. 8 queens puzzle: history‣ Chess player Max Bezzel proposed the problem in 1848‣ Mathematicians (including Gauss) worked on the problem (and generalization to n-queens)‣ Franz Nauck proposed the first solutions (1850)‣ Computer scientists joined the party: Edsger Dijkstra (1972) used the problem to illustrate depth-first backtracking algorithm
- 11. As usually, sexy problems divergen-queens, n×n chessboard with kings, knights... 6
- 12. 8 queens on a 8×8 chessboard: how many solutions? 7
- 13. 8
- 14. 8
- 15. 8 queens: some combinatorial considerations‣ Number of possible positions of 8 queens on a 8x8 chess board (no constraints): - 64 choose 8= = 4,426,165,368
- 16. 8 queens: some combinatorial considerations‣ Number of possible positions of 8 queens on a 8x8 chess board (no constraints): - 64 choose 8= = 4,426,165,368‣ Number of solution to the 8 queens puzzle: - 92, and reducing symmetries: 12 distinct
- 17. 8 queens: some combinatorial considerations‣ Number of possible positions of 8 queens on a 8x8 chess board (no constraints): - 64 choose 8= = 4,426,165,368‣ Number of solution to the 8 queens puzzle: - 92, and reducing symmetries: 12 distinct‣ extend to any n queens, on a n x n board
- 18. 8 queens: some combinatorial considerations‣ Number of possible positions of 8 queens on a 8x8 chess board (no constraints): - 64 choose 8= = 4,426,165,368‣ Number of solution to the 8 queens puzzle: - 92, and reducing symmetries: 12 distinct‣ extend to any n queens, on a n x n board n 1 2 3 4 5 6 7 8 9 10 distinct 1 0 0 2 2 1 6 12 46 92 unique 1 0 0 1 10 4 40 92 352 724 http://en.wikipedia.org/wiki/Eight_queens_puzzle
- 19. Goals for today ‣ Write code to find solutions
- 20. Goals for today ‣ Write code to find solutions ‣ Brute force
- 21. Goals for today ‣ Write code to find solutions ‣ Brute force ‣ Genetic programming (evolving random approach)
- 22. Goals for today ‣ Write code to find solutions ‣ Brute force ‣ Genetic programming (evolving random approach) ‣ generalize the problem to kings
- 23. Goals for today ‣ Write code to find solutions ‣ Brute force ‣ Genetic programming (evolving random approach) ‣ generalize the problem to kings ‣ code in tp8-solutions @ dokeos
- 24. An algorithm for solutions
- 25. An algorithm for solutions
- 26. An algorithm for solutions
- 27. An algorithm for solutions
- 28. An algorithm for solutions
- 29. An algorithm for solutions
- 30. An algorithm for solutions
- 31. An algorithm for solutions
- 32. An algorithm for solutions
- 33. An algorithm for solutions
- 34. An algorithm for solutions
- 35. An algorithm for solutions
- 36. An algorithm for solutions
- 37. An algorithm for solutions
- 38. An algorithm for solutions
- 39. An algorithm for solutions
- 40. An algorithm for solutions
- 41. An algorithm for solutions
- 42. An algorithm for solutions
- 43. An algorithm for solutions
- 44. An algorithm for solutions
- 45. A solution finder code:‣ A chessboard structure: - size & max number of pieces - add/remove pieces - count how many pieces are on the board - check if two pieces are conflicting
- 46. A solution finder code:‣ A chessboard structure: - size & max number of pieces - add/remove pieces - count how many pieces are on the board - check if two pieces are conflicting‣ A mechanism to explore one by one all solutions - mimic the brute force previous example
- 47. A code synopsis: board fields
- 48. A code synopsis: board fields‣ ChessBoard.groovy/ChessBoardWithQueens.groovy /// number of rows and column for the board int size=8
- 49. A code synopsis: board fields‣ ChessBoard.groovy/ChessBoardWithQueens.groovy /// number of rows and column for the board int size=8 /// maximum number of pieces on the board int maxPieces=0
- 50. A code synopsis: board fields‣ ChessBoard.groovy/ChessBoardWithQueens.groovy /// number of rows and column for the board int size=8 /// maximum number of pieces on the board int maxPieces=0 /** list of list of 2 integers each of them representing a piece on the board (between 0 and (size-1)) */ List piecesPositions = []
- 51. A code synopsis: board fields‣ ChessBoard.groovy/ChessBoardWithQueens.groovy /// number of rows and column for the board int size=8 /// maximum number of pieces on the board int maxPieces=0 /** list of list of 2 integers each of them representing a piece on the board (between 0 and (size-1)) */ List piecesPositions = []
- 52. A code synopsis: board methods
- 53. A code synopsis: board methods /// how many pieces on the board int countPieces(){...}
- 54. A code synopsis: board methods /// how many pieces on the board int countPieces(){...} /// synopsis: board << [0, 3] void leftShift(List<Integer> pos){...}
- 55. A code synopsis: board methods /// how many pieces on the board int countPieces(){...} /// synopsis: board << [0, 3] void leftShift(List<Integer> pos){...} /// remove last introduced piece List<Integer> removeLastPiece(){...}
- 56. A code synopsis: board methods /// how many pieces on the board int countPieces(){...} /// synopsis: board << [0, 3] void leftShift(List<Integer> pos){...} /// remove last introduced piece List<Integer> removeLastPiece(){...} /// are two pieces positions in conflict? boolean isPieceConflict(List<Integer> pA, List<Integer> pB){...}
- 57. A code synopsis: a recursive algorithm
- 58. A code synopsis: a recursive algorithm‣ Exploring means - placing a new piece at the next non-conflicting position - if all pieces are on the board, flag as a solution - exploring deeper
- 59. A code synopsis: a recursive algorithm‣ Exploring means - placing a new piece at the next non-conflicting position - if all pieces are on the board, flag as a solution - exploring deeper‣ The recursion means calling the same explore method deeper until and end is reached (e.g. all pieces are on the board)
- 60. A code synopsis: a recursive algorithm‣ Implementing the displayed algorithm explore: if (all pieces are on the board){ !! one solution !! return } pos ← next position after last piece while (pos is on the board){ add a piece on the board at pos if (no conflict){ explore() } remove last piece pos ← next position }
- 61. A code synopsis: a recursive algorithm‣ Implementing the displayed algorithm explore: if (all pieces are on the board){ !! one solution !! return } pos ← next position after last piece while (pos is on the board){ add a piece on the board at pos if (no conflict){ explore() } remove last piece pos ← next position }
- 62. A code synopsis: a recursive algorithm‣ Implementing the displayed algorithm explore: if (all pieces are on the board){ !! one solution !! return } pos ← next position after last piece while (pos is on the board){ add a piece on the board at pos if (no conflict){ explore() } remove last piece pos ← next position }
- 63. A code synopsis: a recursive algorithm‣ Implementing the displayed algorithm Implementing the displayed algorithm explore: if (all pieces are on the board){ !! one solution !! return } pos ← next position after last piece while (pos is on the board){ add a piece on the board at pos if (no conflict){ explore() } remove last piece pos ← next position }
- 64. A code synopsis: a recursive algorithm‣ Implementing the displayed algorithm Implementing the displayed algorithm explore: if (all pieces are on the board){ !! one solution !! return } pos ← next position after last piece while (pos is on the board){ add a piece on the board at pos if (no conflict){ explore() } remove last piece pos ← next position }
- 65. A codesynopsis: a a recursive algorithmA code synopsis: recursive algorithm‣ Implementing the displayed algorithm Implementing the displayed algorithm explore: if (all pieces are on the board){ !! one solution !! return } pos ← next position after last piece while (pos is on the board){ add a piece on the board at pos if (no conflict){ explore() } remove last piece pos ← next position }
- 66. So we only need to code two functionalities a) increment position; b) explore 17
- 67. A code synopsis: incrementing a position‣ Incrementing a piece position means
- 68. A code synopsis: incrementing a position‣ Incrementing a piece position means - Incrementing the column
- 69. A code synopsis: incrementing a position‣ Incrementing a piece position means - Incrementing the column - If end of line is reached: increment row and goto first column
- 70. A code synopsis: incrementing a position‣ Incrementing a piece position means - Incrementing the column - If end of line is reached: increment row and goto first column - Return null is end of the board is reached
- 71. A code synopsis: incrementing a position‣ Incrementing a piece position means - Incrementing the column - If end of line is reached: increment row and goto first column - Return null is end of the board is reached - Return [0,0] if starting position is null
- 72. A code synopsis: incrementing a position
- 73. A code synopsis: incrementing a position‣ Groovy code:
- 74. A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[
- 75. A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible
- 76. A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible then the first (and second is set to 0)
- 77. A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible then the first (and second is set to 0) returns null if end of board is reached
- 78. A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible then the first (and second is set to 0) returns null if end of board is reached returns [0,0] if a null position is to be incremented */
- 79. A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible then the first (and second is set to 0) returns null if end of board is reached returns [0,0] if a null position is to be incremented */ List<Integer> incrementPiecePosition(int boardSize, List<Integer> p){ return [p[0], p[1]+1] }
- 80. A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible then the first (and second is set to 0) returns null if end of board is reached returns [0,0] if a null position is to be incremented */ List<Integer> incrementPiecePosition(int boardSize, List<Integer> p){ if(p[1] == (boardSize - 1) ){ return [p[0]+1, 0] } return [p[0], p[1]+1] }
- 81. A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible then the first (and second is set to 0) returns null if end of board is reached returns [0,0] if a null position is to be incremented */ List<Integer> incrementPiecePosition(int boardSize, List<Integer> p){ if(p[1] == (boardSize - 1) ){ if(p[0] == (boardSize -1) ) return null return [p[0]+1, 0] } return [p[0], p[1]+1] }
- 82. A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible then the first (and second is set to 0) returns null if end of board is reached returns [0,0] if a null position is to be incremented */ List<Integer> incrementPiecePosition(int boardSize, List<Integer> p){ if(p==null) return [0,0] if(p[1] == (boardSize - 1) ){ if(p[0] == (boardSize -1) ) return null return [p[0]+1, 0] } return [p[0], p[1]+1] }
- 83. 8 queens: a recursive algorithm (cont’d)def explore(board){ //walk through all possible position until it is not possible anymore toincrement while(p = incrementPiecePosition(board.size, p)){ //put the current piece on the board to give it a try board<<p //remove the piece before training another position board.removeLastPiece() }}
- 84. 8 queens: a recursive algorithm (cont’d)def explore(board){ //walk through all possible position until it is not possible anymore toincrement while(p = incrementPiecePosition(board.size, p)){ //put the current piece on the board to give it a try board<<p if(!board.countConflicts()){ // if it can be added without conflict try exploration deeper // (with one nore piece) explore(board) } //remove the piece before training another position board.removeLastPiece() }}
- 85. 8 queens: a recursive algorithm (cont’d)def explore(board){ //lets take the last piece as starting point or null if the board is empty def p=board.countPieces()?board.piecesPositions[-1]:null //walk through all possible position until it is not possible anymore toincrement while(p = incrementPiecePosition(board.size, p)){ //put the current piece on the board to give it a try board<<p if(!board.countConflicts()){ // if it can be added without conflict try exploration deeper // (with one nore piece) explore(board) } //remove the piece before training another position board.removeLastPiece() }}
- 86. 8 queens: a recursive algorithm (cont’d)def explore(board){ if((! board.countConflicts()) && (board.countPieces() == board.maxPieces)){ println "A working setup :n$board" return } //lets take the last piece as starting point or null if the board is empty def p=board.countPieces()?board.piecesPositions[-1]:null //walk through all possible position until it is not possible anymore toincrement while(p = incrementPiecePosition(board.size, p)){ //put the current piece on the board to give it a try board<<p if(!board.countConflicts()){ // if it can be added without conflict try exploration deeper // (with one nore piece) explore(board) } //remove the piece before training another position board.removeLastPiece() }}
- 87. A recursive function calls itself 21
- 88. 8 queens: a recursive algorithm (cont’d)‣ Initialization contains: - defining a empty board with correct size - launching the first call to the recursive explore functionChessBoard board=[size:8, maxPieces:8]explore(board)
- 89. 8 queens: a recursive algorithm (cont’d)‣ Initialization contains: - defining a empty board with correct size - launching the first call to the recursive explore functionChessBoard board=[size:8, maxPieces:8]explore(board)‣ See scripts/recursiveChessExploration.groovy
- 90. 8 queens: a recursive algorithm (cont’d)‣ Initialization contains: - defining a empty board with correct size - launching the first call to the recursive explore functionChessBoard board=[size:8, maxPieces:8]explore(board)‣ See scripts/recursiveChessExploration.groovy
- 91. 8 queens: a recursive algorithm (cont’d)‣ Initialization contains: - defining a empty board with correct size - launching the first call to the recursive explore functionChessBoard board=[size:8, maxPieces:8]explore(board)‣ See scripts/recursiveChessExploration.groovy
- 92. 8 queens: a recursive algorithm (cont’d)‣ Initialization contains: - defining a empty board with correct size - launching the first call to the recursive explore functionChessBoard board=[size:8, maxPieces:8]explore(board)‣ See scripts/recursiveChessExploration.groovy
- 93. Recursion: the limits
- 94. Recursion: the limits‣ Recursive method is concise
- 95. Recursion: the limits‣ Recursive method is concise‣ But it requires - time (method call) - memory (deep tree!)
- 96. Recursion: the limits‣ Recursive method is concise‣ But it requires - time (method call) - memory (deep tree!)‣ In practice, faster methods exist - walking through solution staying at the same stack level
- 97. Recursion: the limits‣ Recursive method is concise‣ But it requires - time (method call) - memory (deep tree!)‣ In practice, faster methods exist - walking through solution staying at the same stack level‣ Dedicated solutions if often better - In the case of the queens problems, knowing the pieces move can greatly help to write a dedicated algorithm (one per row, one per column...)
- 98. Creationism or Darwinism? 24
- 99. Genetic Algorithm: an introduction‣ A problem ⇒ a fitness function
- 100. Genetic Algorithm: an introduction‣ A problem ⇒ a fitness function‣ A candidate solution ⇒ a score given by the fitness function
- 101. Genetic Algorithm: an introduction‣ A problem ⇒ a fitness function‣ A candidate solution ⇒ a score given by the fitness function‣ The higher the fit, the fittest the candidate
- 102. Genetic Algorithm: an introduction (cont’d)‣ Searching for a solution simulating a natural selection
- 103. Genetic Algorithm: an introduction (cont’d)‣ Searching for a solution simulating a natural selection‣ One candidate solution ⇔ one gene
- 104. Genetic Algorithm: an introduction (cont’d)‣ Searching for a solution simulating a natural selection‣ One candidate solution ⇔ one gene‣ population ⇔ set of genes
- 105. Genetic Algorithm: an introduction (cont’d)‣ Searching for a solution simulating a natural selection‣ One candidate solution ⇔ one gene‣ population ⇔ set of genes‣ Start : initialize a random population
- 106. Genetic Algorithm: an introduction (cont’d)‣ Searching for a solution simulating a natural selection‣ One candidate solution ⇔ one gene‣ population ⇔ set of genes‣ Start : initialize a random population‣ One generation - fittest genes are selected - cross-over between those genes - random mutation
- 107. GA for the 8 queens problem
- 108. GA for the 8 queens problem‣ Gene ⇔ 8 positions
- 109. GA for the 8 queens problem‣ Gene ⇔ 8 positions‣ Fitness ⇔ -board.countConflicts()
- 110. GA for the 8 queens problem‣ Gene ⇔ 8 positions‣ Fitness ⇔ -board.countConflicts()‣ Cross-over ⇔ mixing pieces of two boards
- 111. GA for the 8 queens problem‣ Gene ⇔ 8 positions‣ Fitness ⇔ -board.countConflicts()‣ Cross-over ⇔ mixing pieces of two boards‣ Mutation ⇔ moving randomly one piece
- 112. A GA in practice (Evolution.groovy)class Evolution { int nbGenes=200 double mutationRate = 0.1 int nbKeepBest = 50 int nbAddRandom = 10 Random randomGenerator = new Random() def geneFactory List genePool...}
- 113. A GA in practice (Evolution.groovy) def nextGeneration(){ //select a subset of the best gene + mutate them according to a rate List reproPool=selectBest().toList().unique{it} //keep the repro pool in the best genePool=reproPool }
- 114. A GA in practice (Evolution.groovy) def nextGeneration(){ //select a subset of the best gene + mutate them according to a rate List reproPool=selectBest().toList().unique{it} //keep the repro pool in the best genePool=reproPool //finally mutate genes with the given rate genePool.each {gene -> if(randomGenerator.nextDouble() < mutationRate) gene.mutate() } }
- 115. A GA in practice (Evolution.groovy) def nextGeneration(){ //select a subset of the best gene + mutate them according to a rate List reproPool=selectBest().toList().unique{it} //keep the repro pool in the best genePool=reproPool //from the fittest reproPool, rebuild the total population by crossover (1..<((nbGenes-genePool.size())/2) ).each{ def geneA = reproPool[randomGenerator.nextInt(nbKeepBest)].clone() def geneB = reproPool[randomGenerator.nextInt(nbKeepBest)].clone() geneA.crossOver(geneB) genePool << geneA genePool << geneB } //finally mutate genes with the given rate genePool.each {gene -> if(randomGenerator.nextDouble() < mutationRate) gene.mutate() } }
- 116. A GA in practice (Evolution.groovy) def nextGeneration(){ //select a subset of the best gene + mutate them according to a rate List reproPool=selectBest().toList().unique{it} //keep the repro pool in the best genePool=reproPool //add a few random to the pool buildRandom(nbAddRandom).each{ genePool << it } //from the fittest reproPool, rebuild the total population by crossover (1..<((nbGenes-genePool.size())/2) ).each{ def geneA = reproPool[randomGenerator.nextInt(nbKeepBest)].clone() def geneB = reproPool[randomGenerator.nextInt(nbKeepBest)].clone() geneA.crossOver(geneB) genePool << geneA genePool << geneB } //finally mutate genes with the given rate genePool.each {gene -> if(randomGenerator.nextDouble() < mutationRate) gene.mutate() } }
- 117. Evolution.groovy = problem agnostic 30
- 118. 31
- 119. GA: more evolution
- 120. GA: more evolution‣ Mutation rate can be time dependent (decrease over time...)
- 121. GA: more evolution‣ Mutation rate can be time dependent (decrease over time...)‣ Different population pools (different parameters), long term cross-over
- 122. GA: more evolution‣ Mutation rate can be time dependent (decrease over time...)‣ Different population pools (different parameters), long term cross-over‣ Regular introduction of new random genes
- 123. Genetic algorithm: a solution for everything?
- 124. Genetic algorithm: a solution for everything?‣ GA looks like a magic solution to any optimization process
- 125. Genetic algorithm: a solution for everything?‣ GA looks like a magic solution to any optimization process‣ In practice, hard to tune evolution strategy & parameters
- 126. Genetic algorithm: a solution for everything?‣ GA looks like a magic solution to any optimization process‣ In practice, hard to tune evolution strategy & parameters‣ For a given problem: a dedicated solution always better (when possible)
- 127. Genetic algorithm: a solution for everything?‣ GA looks like a magic solution to any optimization process‣ In practice, hard to tune evolution strategy & parameters‣ For a given problem: a dedicated solution always better (when possible)‣ For the queens problems, the recursive method is much faster
- 128. Genetic algorithm: a solution for everything?‣ GA looks like a magic solution to any optimization process‣ In practice, hard to tune evolution strategy & parameters‣ For a given problem: a dedicated solution always better (when possible)‣ For the queens problems, the recursive method is much faster‣ For 32 knights: GA is much faster (not all solutions!)
- 129. 32 Knights on the board 34
- 130. Board with knights
- 131. Board with knights‣ ChessBoard.groovy:boolean isPieceConflict(List<Integer> pA, List<Integer> pB){ //same row or same column if((pA[0] == pB [0]) || (pA[1] == pB[1])) return true //first diagonal if((pA[0] - pA [1]) == (pB[0] - pB[1])) return true //second diagonal if((pA[0] + pA [1]) == (pB[0] + pB[1])) return true return false }
- 132. Shall we redefine all the previous methods from the ChessBoard with queens? DRY! 36
- 133. A generic ChessBoard : abstract class
- 134. A generic ChessBoard : abstract class‣ ChessBoard.groovy:abstract class ChessBoard{ ... all other methods/fields are the same ... abstract boolean isPieceConflict(List<Integer> pA, List<Integer> pB);}
- 135. Queen specialization
- 136. Queen specialization
- 137. Queen specialization‣ Then a implementation class class ChessBoardWithQueens extends ChessBoard{ //only method boolean isPieceConflict(List<Integer> pA, List<Integer> pB){ //same row or same column if((pA[0] == pB [0]) || (pA[1] == pB[1])) return true //first diagonal if((pA[0] - pA [1]) == (pB[0] - pB[1])) return true //second diagonal if((pA[0] + pA [1]) == (pB[0] + pB[1])) return true return false }
- 138. Knight specialization
- 139. Knight specialization‣ ChessBoardWithKnights.groovy:class ChessBoardWithKnights extends ChessBoard{ //only method boolean isPieceConflict(List<Integer> pA, List<Integer> pB){ if( (Math.abs(pA[0]-pB[0])==2) && (Math.abs(pA[1]-pB[1])==1) ) return true if( (Math.abs(pA[1]-pB[1])==2) && (Math.abs(pA[0]-pB[0])==1) ) return true return false }
- 140. And from the exploration script
- 141. And from the exploration script‣ In main script: //ChessBoardWithQueens board=[size:8, maxPieces:8] ChessBoardWithKnights board=[size:8, maxPieces:32] explore(board)
- 142. And from the exploration script‣ In main script: //ChessBoardWithQueens board=[size:8, maxPieces:8] ChessBoardWithKnights board=[size:8, maxPieces:32] explore(board)‣ Nothing more...
- 143. Do not forget unit tests! 41
- 144. abstract class testing‣ Not possible to instantiate new ChessBoard()
- 145. abstract class testing‣ Not possible to instantiate new ChessBoard()‣ Create a fake ChessBoard class for test class ChessBoardTest extends GroovyTestCase { class ChessBoardDummy extends ChessBoard{ boolean isPieceConflict(List<Integer> pA, List<Integer> pB){ return ( (pA[0]==pB[0]) && (pA[1]==pB[1]) ) } } ... }
- 146. abstract class testing‣ Not possible to instantiate new ChessBoard()‣ Create a fake ChessBoard class for test class ChessBoardTest extends GroovyTestCase { class ChessBoardDummy extends ChessBoard{ boolean isPieceConflict(List<Integer> pA, List<Integer> pB){ return ( (pA[0]==pB[0]) && (pA[1]==pB[1]) ) } } ... }‣ Then all tests are with instances ChessBoardDummy board=[size:4, maxPieces:3]
- 147. abstract class testing (cont’d)
- 148. abstract class testing (cont’d)‣ ChessBoardWithQueens only test for pieces conflict class ChessBoardWithQueensTest extends GroovyTestCase { public void testPieceConflict(){ ChessBoardWithQueens board=[size:4, maxPieces:3] //same spot assert board.isPieceConflict([0, 0], [0, 0]) //same row assert board.isPieceConflict([0, 2], [0, 0]) //same column assert board.isPieceConflict([2, 0], [0, 0]) ... }

Be the first to comment