GAMES TWO: LESSON Fifteen: Searching For Scoring Patterns
Scoring the game of CANTRIS requires that the applet keep track of the
values of the individual cells used in the game. So, instead of having the
CAN as the smallest unit in the game, the CELL is now the smallest unit in
the game. In fact, we no longer use the CAN class at all (although we do
have an array named can which serves as a temporary holder of the single
active can).
Try the game out. Note that the down arrow now produces a rotation of the
cells in the active can.
There are three classes involved in this game: 1) CC4 (the applet class),
2) GRID2, and 3) CELL.
import java.awt.*;
class CELL{
int x, y;
Color c;
CELL(int dd, Color cc){
y = 20-dd;
x = 60;
c = cc;
}
public Color getColor(){
return c;
}
public void setColor(Color cc){
c = cc;
}
public void moveX(int n){
if(x>30 && n == -1){
x-=10;
}
else if(x<80 && n == 1){
x+=10;
}
}
public void moveY(){
y+=2;
}
public void draw(Graphics g){
g.setColor(c);
g.fillRect(x,y,10,10);
}
}
CELL contains the basic methods needed to move the cell and change its
color. CELL is used exclusively by GRID2.
GRID2 contains all the methods needed to deal with the elements displayed
within the grid area of the game. There are two particularly important
methods: scoreGrid and hit_bottom. As the name suggests, scoreGrid searches
for scoring patterns. It is called each time a can hits the bottom of its
current column. The method hit_bottom transfers the contents of the can
array (which represents the active can) to the grid (which keeps track of
each individual cell). It is called each time a can hits the bottom of its
current column.
import java.awt.*;
import java.util.*;
public class GRID2{
CELL[] cells = new CELL[120];
CELL[] can = new CELL[3];
int[] grid = new int[300];
int col=3;
int bottom[] = {210,210,210,210,210,210};
Color sel[] = { Color.red, Color.blue, Color.cyan,
Color.green, Color.magenta, Color.yellow };
int next=0;
Random r = new Random();
int cnt, lastCHKD, score;
boolean gameOn = true;
GRID2(){
for(int i = 0; i0 && m==-1){
if(test_bottom(m)){
col--;
can[0].moveX(m);
can[1].moveX(m);
can[2].moveX(m);
}
}
else if(col<5 && m==1){
if(test_bottom(m)){
col++;
can[0].moveX(m);
can[1].moveX(m);
can[2].moveX(m);
}
}
}
public void rotate(){
Color hold = can[0].getColor();
can[0].setColor(can[1].getColor());
can[1].setColor(can[2].getColor());
can[2].setColor(hold);
}
public void settle_cells(){
//for future use
}
public boolean check_gaps(){
//for future use
return false;
}
public void move_can(){
can[0].moveY();
can[1].moveY();
can[2].moveY();
}
public void scoreGrid(){
for(int i=0; icells.length-3) return false;
return gameOn;
}
public void spawn(){
if(next=cells.length-4){
gameOn=false;
return true;
}
if(can[0].y >= bottom[col]){
for(int i=0; i<3; i++){
int grid_index=col+(210-bottom[col])*6/10+i*6;
//System.out.println("GI: " + grid_index);
grid[grid_index]=next;
cells[next]=can[i];
next++;
}
bottom[col]-=30;
return true;
}
if(bottom[col]<10) gameOn=false;
return false;
}
public boolean test_bottom(int n){
if(can[0].y < bottom[col+n]) return true;
return false;
}
public void draw(Graphics g){
if(next>0){
for(int i=0; i
CC4 is the applet class. The most important parts of this class to study are
the lines dealing with events and the code within the run method.
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.util.*;
public class CC4 extends Applet implements Runnable{
Dimension d;
Thread tm;
Random r = new Random();
Image offI;
int speed = 33;
String title[] = { "C", "A", "N", "T", "R", "I", "S" };
GRID2 grid = new GRID2();
public void init(){
d = getSize();
offI=createImage(d.width,d.height);
reset();
tm = new Thread(this);
tm.start();
requestFocus();
this.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent k) {
if(grid.keepPlaying()){
if(k.getKeyCode() == KeyEvent.VK_RIGHT){
grid.moveX(1);
}
else if(k.getKeyCode() == KeyEvent.VK_LEFT){
grid.moveX(-1);
}
else if(k.getKeyCode() == KeyEvent.VK_DOWN){
grid.rotate();
}
else if(k.getKeyCode() == KeyEvent.VK_UP){
speed=100;
}
}
else{
reset();
}
repaint();
}
});
}
public void reset(){
grid=new GRID2();
}
public void run(){
while(true){
while(grid.keepPlaying()){
if(grid.check_gaps()){
grid.settle_cells();
}
else{
grid.move_can();
}
if(grid.hit_bottom()){
grid.scoreGrid();
grid.spawn();
}
repaint();
try{
Thread.sleep(speed);
}catch(InterruptedException e){};
}
}
}
public void update(Graphics g){
paint(g);
}
public void paint(Graphics g){
Graphics offG = offI.getGraphics();
offG.setColor(Color.white);
offG.fillRect(0,0,d.width,d.height);
grid.draw(offG);
offG.setColor(Color.black);
offG.setFont(new Font("sansserif", Font.BOLD, 24));
for(int i = 0; i
ASSIGNMENT:
1) Alter the functionality of the up key by making it into a toggle key
between slow speed (100) and fast speed (25). Remember that the values
altered by the up key actually reflect the amount of pause between redraws.
2) Add a shuffle method (called by a press on the s key) to GRID2 which
switches the top and bottom cell of the current can. Test your game to see
if skillful use of this alteration makes it easier to score more points.