forked from jewbank/TetrisProject
-
Notifications
You must be signed in to change notification settings - Fork 0
/
LameBrain.java
126 lines (102 loc) · 3.5 KB
/
LameBrain.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/**
A simple Brain implementation.
bestMove() iterates through all the possible x values
and rotations to play a particular piece (there are only
around 10-30 ways to play a piece).
For each play, it uses the rateBoard() message to rate how
good the resulting board is and it just remembers the
play with the lowest score. Undo() is used to back-out
each play before trying the next. To experiment with writing your own
brain -- just subclass off LameBrain and override rateBoard().
*/
public class LameBrain implements Brain {
/**
Given a piece and a board, returns a move object that represents
the best play for that piece, or returns null if no play is possible.
See the Brain interface for details.
*/
@Override
public int bestMove(Board board, Piece piece, int pieceX, int pieceY, int limitHeight) {
double bestScore = 1e20;
int bestX = 0;
int bestY = 0;
Piece bestPiece = null;
Piece current = piece;
// loop through all the rotations
while (true) {
final int yBound = limitHeight - current.getHeight()+1;
final int xBound = board.getWidth() - current.getWidth()+1;
// For current rotation, try all the possible columns
for (int x = 0; x<xBound; x++) {
int y = board.dropHeight(current, x);
if (y<yBound) { // piece does not stick up too far
int result = board.place(current, x, y);
if (result <= Board.PLACE_ROW_FILLED) {
if (result == Board.PLACE_ROW_FILLED) board.clearRows();
double score = rateBoard(board, x, y, current.getWidth(), current.getHeight());
if (score<bestScore) {
bestScore = score;
bestX = x;
bestY = y;
bestPiece = current;
}
}
board.undo(); // back out that play, loop around for the next
}
}
current = current.nextRotation();
if (current == piece) break; // break if back to original rotation
}
if (bestPiece == null) return(JTetris.DOWN); // could not find a play at all!
if(!piece.equals(bestPiece))
return JTetris.ROTATE;
if(bestX == pieceX)
return JTetris.DOWN;
if(bestX < pieceX)
return JTetris.LEFT;
else
return JTetris.RIGHT;
}
/*
A simple brain function.
Given a board, produce a number that rates
that board position -- larger numbers for worse boards.
This version just counts the height
and the number of "holes" in the board.
See Tetris-Architecture.html for brain ideas.
*/
public double rateBoard(Board board, int j, int h, int pwidth, int pheight) {
final int width = board.getWidth();
final int maxHeight = board.getMaxHeight();
int sumHeight = 0;
int holes = 0;
int lhole = 0;
int rhole = 0;
int close = 0;
// Count the holes, and sum up the heights
for (int x=0; x<width; x++) {
final int colHeight = board.getColumnHeight(x);
sumHeight += colHeight;
int y = colHeight - 2; // addr of first possible hole
while (y>=0) {
if (!board.getGrid(x,y)) {
if((x>=j-2 && x<=j+pwidth+2) && (y>=j-2 && y<=j+pheight+2))
holes++;
holes++;
if(x<5)
lhole++;
else
rhole++;
}
if(board.getRowWidth(y)>7);
close++;
y--;
}
}
double avgHeight = ((double)sumHeight)/width;
// 8*maxHeight + 40*avgHeight +
// Add up the counts to make an overall score
// The weights, 8, 40, etc., are just made up numbers that appear to work
return (8*maxHeight + 40*avgHeight + holes + .5*Math.abs(rhole-lhole)-1.5*close);
}
}