Skip to content

Commit 9447254

Browse files
authored
Merge branch 'master' into BAEL-4300
2 parents 4c9cac9 + a326785 commit 9447254

2,946 files changed

Lines changed: 20591 additions & 517484 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,5 @@ transaction.log
8585
*-shell.log
8686

8787
apache-cxf/cxf-aegis/baeldung.xml
88-
apache-fop/src/test/resources/input.xml
89-
apache-fop/src/test/resources/output_herold.pdf
90-
apache-fop/src/test/resources/output_html2fo.pdf
91-
apache-fop/src/test/resources/output_jtidy.pdf
88+
89+
libraries-2/*.db

algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/GraphImageGenerationUnitTest.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
package com.baeldung.jgrapht;
22

33
import static org.junit.Assert.assertTrue;
4+
45
import java.awt.Color;
56
import java.awt.image.BufferedImage;
67
import java.io.File;
78
import java.io.IOException;
9+
810
import javax.imageio.ImageIO;
11+
912
import org.jgrapht.ext.JGraphXAdapter;
1013
import org.jgrapht.graph.DefaultDirectedGraph;
1114
import org.jgrapht.graph.DefaultEdge;
15+
import org.junit.After;
1216
import org.junit.Before;
1317
import org.junit.Test;
18+
1419
import com.mxgraph.layout.mxCircleLayout;
1520
import com.mxgraph.layout.mxIGraphLayout;
1621
import com.mxgraph.util.mxCellRenderer;
@@ -20,7 +25,7 @@ public class GraphImageGenerationUnitTest {
2025

2126
@Before
2227
public void createGraph() throws IOException {
23-
File imgFile = new File("src/test/resources/graph.png");
28+
File imgFile = new File("src/test/resources/graph1.png");
2429
imgFile.createNewFile();
2530
g = new DefaultDirectedGraph<String, DefaultEdge>(DefaultEdge.class);
2631
String x1 = "x1";
@@ -34,12 +39,18 @@ public void createGraph() throws IOException {
3439
g.addEdge(x3, x1);
3540
}
3641

42+
@After
43+
public void cleanup() {
44+
File imgFile = new File("src/test/resources/graph1.png");
45+
imgFile.deleteOnExit();
46+
}
47+
3748
@Test
3849
public void givenAdaptedGraph_whenWriteBufferedImage_ThenFileShouldExist() throws IOException {
3950
JGraphXAdapter<String, DefaultEdge> graphAdapter = new JGraphXAdapter<String, DefaultEdge>(g);
4051
mxIGraphLayout layout = new mxCircleLayout(graphAdapter);
4152
layout.execute(graphAdapter.getDefaultParent());
42-
File imgFile = new File("src/test/resources/graph.png");
53+
File imgFile = new File("src/test/resources/graph1.png");
4354
BufferedImage image = mxCellRenderer.createBufferedImage(graphAdapter, null, 2, Color.WHITE, true, null);
4455
ImageIO.write(image, "PNG", imgFile);
4556
assertTrue(imgFile.exists());
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
package com.baeldung.algorithms.play2048;
2+
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.LinkedList;
6+
import java.util.List;
7+
8+
import org.slf4j.Logger;
9+
import org.slf4j.LoggerFactory;
10+
11+
public class Board {
12+
private static final Logger LOG = LoggerFactory.getLogger(Board.class);
13+
14+
private final int[][] board;
15+
16+
private final int score;
17+
18+
public Board(int size) {
19+
assert(size > 0);
20+
21+
this.board = new int[size][];
22+
this.score = 0;
23+
24+
for (int x = 0; x < size; ++x) {
25+
this.board[x] = new int[size];
26+
for (int y = 0; y < size; ++y) {
27+
board[x][y] = 0;
28+
}
29+
}
30+
}
31+
32+
private Board(int[][] board, int score) {
33+
this.score = score;
34+
this.board = new int[board.length][];
35+
36+
for (int x = 0; x < board.length; ++x) {
37+
this.board[x] = Arrays.copyOf(board[x], board[x].length);
38+
}
39+
}
40+
41+
public int getSize() {
42+
return board.length;
43+
}
44+
45+
public int getScore() {
46+
return score;
47+
}
48+
49+
public int getCell(Cell cell) {
50+
int x = cell.getX();
51+
int y = cell.getY();
52+
assert(x >= 0 && x < board.length);
53+
assert(y >= 0 && y < board.length);
54+
55+
return board[x][y];
56+
}
57+
58+
public boolean isEmpty(Cell cell) {
59+
return getCell(cell) == 0;
60+
}
61+
62+
public List<Cell> emptyCells() {
63+
List<Cell> result = new ArrayList<>();
64+
for (int x = 0; x < board.length; ++x) {
65+
for (int y = 0; y < board[x].length; ++y) {
66+
Cell cell = new Cell(x, y);
67+
if (isEmpty(cell)) {
68+
result.add(cell);
69+
}
70+
}
71+
}
72+
return result;
73+
}
74+
75+
public Board placeTile(Cell cell, int number) {
76+
if (!isEmpty(cell)) {
77+
throw new IllegalArgumentException("That cell is not empty");
78+
}
79+
80+
Board result = new Board(this.board, this.score);
81+
result.board[cell.getX()][cell.getY()] = number;
82+
return result;
83+
}
84+
85+
public Board move(Move move) {
86+
// Clone the board
87+
int[][] tiles = new int[this.board.length][];
88+
for (int x = 0; x < this.board.length; ++x) {
89+
tiles[x] = Arrays.copyOf(this.board[x], this.board[x].length);
90+
}
91+
92+
LOG.debug("Before move: {}", Arrays.deepToString(tiles));
93+
// If we're doing an Left/Right move then transpose the board to make it a Up/Down move
94+
if (move == Move.LEFT || move == Move.RIGHT) {
95+
tiles = transpose(tiles);
96+
LOG.debug("After transpose: {}", Arrays.deepToString(tiles));
97+
}
98+
// If we're doing a Right/Down move then reverse the board.
99+
// With the above we're now always doing an Up move
100+
if (move == Move.DOWN || move == Move.RIGHT) {
101+
tiles = reverse(tiles);
102+
LOG.debug("After reverse: {}", Arrays.deepToString(tiles));
103+
}
104+
LOG.debug("Ready to move: {}", Arrays.deepToString(tiles));
105+
106+
// Shift everything up
107+
int[][] result = new int[tiles.length][];
108+
int newScore = 0;
109+
for (int x = 0; x < tiles.length; ++x) {
110+
LinkedList<Integer> thisRow = new LinkedList<>();
111+
for (int y = 0; y < tiles[0].length; ++y) {
112+
if (tiles[x][y] > 0) {
113+
thisRow.add(tiles[x][y]);
114+
}
115+
}
116+
117+
LOG.debug("Unmerged row: {}", thisRow);
118+
LinkedList<Integer> newRow = new LinkedList<>();
119+
while (thisRow.size() >= 2) {
120+
int first = thisRow.pop();
121+
int second = thisRow.peek();
122+
LOG.debug("Looking at numbers {} and {}", first, second);
123+
if (second == first) {
124+
LOG.debug("Numbers match, combining");
125+
int newNumber = first * 2;
126+
newRow.add(newNumber);
127+
newScore += newNumber;
128+
thisRow.pop();
129+
} else {
130+
LOG.debug("Numbers don't match");
131+
newRow.add(first);
132+
}
133+
}
134+
newRow.addAll(thisRow);
135+
LOG.debug("Merged row: {}", newRow);
136+
137+
result[x] = new int[tiles[0].length];
138+
for (int y = 0; y < tiles[0].length; ++y) {
139+
if (newRow.isEmpty()) {
140+
result[x][y] = 0;
141+
} else {
142+
result[x][y] = newRow.pop();
143+
}
144+
}
145+
}
146+
LOG.debug("After moves: {}", Arrays.deepToString(result));
147+
148+
// Un-reverse the board
149+
if (move == Move.DOWN || move == Move.RIGHT) {
150+
result = reverse(result);
151+
LOG.debug("After reverse: {}", Arrays.deepToString(result));
152+
}
153+
// Un-transpose the board
154+
if (move == Move.LEFT || move == Move.RIGHT) {
155+
result = transpose(result);
156+
LOG.debug("After transpose: {}", Arrays.deepToString(result));
157+
}
158+
return new Board(result, this.score + newScore);
159+
}
160+
161+
private static int[][] transpose(int[][] input) {
162+
int[][] result = new int[input.length][];
163+
164+
for (int x = 0; x < input.length; ++x) {
165+
result[x] = new int[input[0].length];
166+
for (int y = 0; y < input[0].length; ++y) {
167+
result[x][y] = input[y][x];
168+
}
169+
}
170+
171+
return result;
172+
}
173+
174+
private static int[][] reverse(int[][] input) {
175+
int[][] result = new int[input.length][];
176+
177+
for (int x = 0; x < input.length; ++x) {
178+
result[x] = new int[input[0].length];
179+
for (int y = 0; y < input[0].length; ++y) {
180+
result[x][y] = input[x][input.length - y - 1];
181+
}
182+
}
183+
184+
return result;
185+
}
186+
187+
@Override
188+
public String toString() {
189+
return Arrays.deepToString(board);
190+
}
191+
192+
@Override
193+
public boolean equals(Object o) {
194+
if (this == o) {
195+
return true;
196+
}
197+
if (o == null || getClass() != o.getClass()) {
198+
return false;
199+
}
200+
Board board1 = (Board) o;
201+
return Arrays.deepEquals(board, board1.board);
202+
}
203+
204+
@Override
205+
public int hashCode() {
206+
return Arrays.deepHashCode(board);
207+
}
208+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.baeldung.algorithms.play2048;
2+
3+
import java.util.StringJoiner;
4+
5+
public class Cell {
6+
private int x;
7+
private int y;
8+
9+
public Cell(int x, int y) {
10+
this.x = x;
11+
this.y = y;
12+
}
13+
14+
public int getX() {
15+
return x;
16+
}
17+
18+
public int getY() {
19+
return y;
20+
}
21+
22+
@Override
23+
public String toString() {
24+
return new StringJoiner(", ", Cell.class.getSimpleName() + "[", "]").add("x=" + x).add("y=" + y).toString();
25+
}
26+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.baeldung.algorithms.play2048;
2+
3+
import java.security.SecureRandom;
4+
import java.util.List;
5+
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
8+
9+
public class Computer {
10+
private static final Logger LOG = LoggerFactory.getLogger(Computer.class);
11+
12+
private final SecureRandom rng = new SecureRandom();
13+
14+
public Board makeMove(Board input) {
15+
List<Cell> emptyCells = input.emptyCells();
16+
LOG.info("Number of empty cells: {}", emptyCells.size());
17+
18+
double numberToPlace = rng.nextDouble();
19+
LOG.info("New number probability: {}", numberToPlace);
20+
21+
int indexToPlace = rng.nextInt(emptyCells.size());
22+
Cell cellToPlace = emptyCells.get(indexToPlace);
23+
LOG.info("Placing number into empty cell: {}", cellToPlace);
24+
25+
return input.placeTile(cellToPlace, numberToPlace >= 0.9 ? 4 : 2);
26+
}
27+
}

0 commit comments

Comments
 (0)