/****************************************************************************************** Hounds.java - Hare and Hounds board game Version 2.0 www.mazeworks.com Copyright (c) 2002 Robert Kirkland All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, provided that the above copyright notice and this permission notice appear in all copies of the Software and that both the above copyright notice and this permission notice appear in supporting documentation. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Except as contained in this notice, the name of the copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization of the copyright holder. ******************************************************************************************/ import java.applet.* ; import java.awt.* ; import java.awt.image.*; import java.net.* ; import java.util.* ; /******** HOUNDS ******** main class; initializes applet panel, starts all games, handles piece movement */ public class Hounds extends Applet { // applet info public String getAppletInfo() { return "Hare and Hounds 2.0 - Copyright (c) 2002 Robert Kirkland"; } String parameterInfo[][] = { {"bgColor", "integer", "Background color (24-bit RGB hex int)"}, {"boardBgColor", "integer", "Board background color (24-bit RGB hex int)"}, {"title", "string", "Applet title text"}, {"newGame", "string", "New Game button text"}, {"player", "string", "Player Side label text"}, {"hounds", "string", "Player Side Hounds checkbox text"}, {"hare", "string", "Player Side Hare checkbox text"}, {"level", "string", "Level label text"}, {"beginner", "string", "Beginner level text"}, {"intermediate", "string", "Intermediate level text"}, {"expert", "string", "Expert level text"}, {"score", "string", "Score label text"}, {"player2", "string", "Player Score label text"}, {"computer", "string", "Computer Score label text"}, {"firstMove", "string", "Hounds first status text"}, {"stalling", "string", "Hounds Stalling status text"}, {"hareWins", "string", "Hare Wins status text"}, {"houndsWin", "string", "Hounds Win status text"} } ; public String[][] getParameterInfo() { return parameterInfo ; } static final Color DF_BG_COLOR =Color.white ; // default background color static final String DF_sTITLE ="Hare and Hounds", // default text strings DF_sNEW_GAME ="NEW GAME", DF_sPLAYER ="PLAYER", DF_sHOUNDS ="Hounds", DF_sHARE ="Hare", DF_sLEVEL ="LEVEL", DF_sBEGINNER ="Beginner", DF_sINTERMED ="Intermediate", DF_sEXPERT ="Expert", DF_sSCORE ="SCORE", DF_s2PLAYER ="Player", DF_sCOMPUTER ="Computer", DF_sFIRST_MOVE="The Hounds move first..", DF_sSTALLING ="The Hounds are stalling ! The Hare wins !", DF_sHARE_WINS ="The Hare escapes !", DF_sHOUNDS_WIN="The Hare is trapped ! The Hounds win !" ; static final int bcWidth=440, bcHeight=276, NULL=-1, PLAYER=0, COMPUTER=1, HOUND=1, HARE=2 ; protected Color BG_COLOR, BOARD_BG_COLOR ; protected String sTITLE, sNEW_GAME, sPLAYER, sHOUNDS, sHARE, sLEVEL, sBEGINNER, sINTERMED, sEXPERT, sSCORE, s2PLAYER, sCOMPUTER, sFIRST_MOVE, sSTALLING, sHARE_WINS, sHOUNDS_WIN ; private int playerAnimal=HOUND, computerAnimal=HARE, playerScore=0, computerScore=0, startSq=NULL, endSq ; private boolean gameOver ; private Label lTitle ; private TextField tfStatus ; private Board bd ; private BoardCanvas bc ; private ControlPanel cp ; private Image boardImage, gifletsImage ; private AI hnh ; public void init() { // --- get applet parameters --- // background color String bgColorString = getParameter("bgColor") ; try { BG_COLOR = bgColorString==null ? DF_BG_COLOR : new Color(Integer.parseInt(bgColorString,16)) ; } catch (NumberFormatException e) { BG_COLOR = DF_BG_COLOR ; System.out.println("ERROR: Invalid bgColor parameter.") ; } // board background color String boardBgColorString = getParameter("boardBgColor") ; try { BOARD_BG_COLOR = boardBgColorString==null ? BG_COLOR : new Color(Integer.parseInt(boardBgColorString,16)) ; } catch (NumberFormatException e) { BOARD_BG_COLOR = BG_COLOR ; System.out.println("ERROR: Invalid boardBgColor parameter.") ; } // text sTITLE = getParameter("title") ; if (sTITLE==null) sTITLE = new String(DF_sTITLE) ; sNEW_GAME = getParameter("newGame") ; if (sNEW_GAME==null) sNEW_GAME = new String(DF_sNEW_GAME) ; sPLAYER = getParameter("player") ; if (sPLAYER==null) sPLAYER = new String(DF_sPLAYER) ; sHOUNDS = getParameter("hounds") ; if (sHOUNDS==null) sHOUNDS = new String(DF_sHOUNDS) ; sHARE = getParameter("hare") ; if (sHARE==null) sHARE = new String(DF_sHARE) ; sLEVEL = getParameter("level") ; if (sLEVEL==null) sLEVEL = new String(DF_sLEVEL) ; sBEGINNER = getParameter("beginner") ; if (sBEGINNER==null) sBEGINNER = new String(DF_sBEGINNER) ; sINTERMED = getParameter("intermediate") ; if (sINTERMED==null) sINTERMED = new String(DF_sINTERMED) ; sEXPERT = getParameter("expert") ; if (sEXPERT==null) sEXPERT = new String(DF_sEXPERT) ; sSCORE = getParameter("score") ; if (sSCORE==null) sSCORE = new String(DF_sSCORE) ; s2PLAYER = getParameter("player2") ; if (s2PLAYER==null) s2PLAYER = new String(DF_s2PLAYER) ; sCOMPUTER = getParameter("computer") ; if (sCOMPUTER==null) sCOMPUTER = new String(DF_sCOMPUTER) ; sFIRST_MOVE = getParameter("firstMove") ; if (sFIRST_MOVE==null) sFIRST_MOVE = new String(DF_sFIRST_MOVE) ; sSTALLING = getParameter("stalling") ; if (sSTALLING==null) sSTALLING = new String(DF_sSTALLING) ; sHARE_WINS = getParameter("hareWins") ; if (sHARE_WINS==null) sHARE_WINS = new String(DF_sHARE_WINS) ; sHOUNDS_WIN = getParameter("houndsWin") ; if (sHOUNDS_WIN==null) sHOUNDS_WIN = new String(DF_sHOUNDS_WIN) ; // load images MediaTracker tracker = new MediaTracker(this) ; URL url = getCodeBase() ; boardImage = getImage(url,"board.gif") ; gifletsImage = getImage(url,"giflets.gif") ; tracker.addImage(boardImage,0) ; tracker.addImage(gifletsImage,1) ; try { tracker.waitForAll(); } catch (InterruptedException e) {} // create board canvas and control panel cp = new ControlPanel(this) ; bc = new BoardCanvas(boardImage,gifletsImage,this) ; bc.resize(bcWidth,bcHeight) ; Panel p1 = new Panel() ; p1.setBackground(Color.lightGray) ; p1.setLayout(new FlowLayout(FlowLayout.CENTER,5,10)) ; p1.add(cp) ; // create status panel Panel sp = new Panel() ; sp.setLayout(new BorderLayout(10,5)) ; sp.setBackground(Color.lightGray) ; sp.add("West",lTitle=new Label(sTITLE,Label.CENTER)) ; lTitle.setFont(cp.titleFont) ; tfStatus = new TextField() ; tfStatus.setFont(cp.statusFont) ; tfStatus.setForeground(Color.white) ; tfStatus.setBackground(Color.black) ; tfStatus.setEditable(false) ; sp.add("Center",tfStatus) ; // initialize applet layout setBackground(BG_COLOR) ; Panel mainPanel = new Panel() ; mainPanel.setLayout(new BorderLayout(0,0)) ; mainPanel.setBackground(BOARD_BG_COLOR) ; Panel p2 = new Panel() ; p2.setLayout(new FlowLayout(FlowLayout.CENTER,10,10)) ; mainPanel.setLayout(new BorderLayout()) ; mainPanel.add("Center",bc) ; mainPanel.add("East",p1) ; mainPanel.add("South",sp) ; p2.add(mainPanel) ; add(p2) ; validate() ; // force class file load Ref r = new Ref() ; cp.setPlayerScore(playerScore) ; cp.setComputerScore(computerScore) ; newGame() ; } // startup void newGame() { System.gc() ; if (playerAnimal==HOUND) setStatus(sFIRST_MOVE) ; else setStatus(" ") ; gameOver = false ; bd = new Board(cp,this) ; hnh = new AI(bd,cp,this) ; bc.drawBoard(bd) ; setFocus() ; // hounds move first if (computerAnimal==HOUND) computerMove() ; } private void endGame(int side) { if (side==COMPUTER) cp.setComputerScore(++computerScore) ; else cp.setPlayerScore(++playerScore) ; gameOver = true ; bc.drawBoard(bd) ; } private void computerMove() { hnh.move(computerAnimal) ; if (bd.isWin(computerAnimal)) endGame(COMPUTER) ; else { bc.drawBoard(bd) ; setStatus(" ") ; } } // board mouse down event void selectPiece(int x,int y) { if (!gameOver) { startSq = bc.pixelToSquare(x,y) ; if (bd.selectPiece(playerAnimal,startSq)) bc.drawBoard(bd,x,y) ; else startSq = NULL ; } } // board mouse drag event void dragPiece(int x,int y) { if (!gameOver && startSq!=NULL) bc.drawBoard(bd,x,y) ; } // board mouse up event void dropPiece(int x,int y) { if (!gameOver && startSq!=NULL) { endSq = bc.pixelToSquare(x,y) ; if (bd.movePlayerPiece(startSq,endSq)) { if (bd.isWin(playerAnimal)) endGame(PLAYER) ; else { bc.drawBoard(bd) ; setStatus(" ") ; computerMove() ; } } else bc.drawBoard(bd) ; } startSq = NULL ; } // handle control panel mouse events void setPlayerAnimal(int animal) { if (animal!=playerAnimal) { if (animal==HARE) { playerAnimal = HARE ; computerAnimal = HOUND ; } else { playerAnimal = HOUND ; computerAnimal = HARE ; } setFocus() ; // changing sides makes it the computer's turn if (!gameOver) computerMove() ; } } void setStatus(String s) { tfStatus.setText(" " + s) ; } int getPlayerAnimal() { return playerAnimal ; } void setFocus() { bc.requestFocus() ; } } /******** BOARD ******** controls board layout, rules of the game */ final class Board { static final int EMPTY=0, HOUND=1, HARE=2, // square connections: // 0 - not connected // 1 - connected, backwards for hounds // 2 - connected // 3 - connected, advancing for hounds connect[][] = { {0,3,3,3,0,0,0,0,0,0,0}, {1,0,2,0,3,3,0,0,0,0,0}, {1,2,0,2,0,3,0,0,0,0,0}, {1,0,2,0,0,3,3,0,0,0,0}, {0,1,0,0,0,2,0,3,0,0,0}, {0,1,1,1,2,0,2,3,3,3,0}, {0,0,0,1,0,2,0,0,0,3,0}, {0,0,0,0,1,1,0,0,2,0,3}, {0,0,0,0,0,1,0,2,0,2,3}, {0,0,0,0,0,1,1,0,2,0,3}, {0,0,0,0,0,0,0,1,1,1,0} } ; // the board array: 1 - 4 - 7 // 0 - 2 - 5 - 8 - 10 // 3 - 6 - 9 // they're called squares even though most of them aren't... private int b[] = new int[11], // trace value for each square is used // to calculate opposition traceSq[] = {5,3,4,3,1,2,1,0,1,0,-1} ; // stallCount is used to track the hounds' progress private int stallCount=0 ; private ControlPanel cp ; private Hounds main ; // constructor Board(ControlPanel cp, Hounds main) { this.cp = cp ; this.main = main ; // initialize board for (int i=0; i<11; i++) b[i] = EMPTY ; b[0] = b[1] = b[3] = HOUND ; b[10] = HARE ; } boolean isEmpty(int i) { return (b[i] == EMPTY) ; } private void setEmpty(int i) { b[i] = EMPTY ; } private void setSquare(int i,int value) { b[i] = value ; } int getSquare(int i) { return b[i] ; } int getHare() { for (int i=10; i>=0; i--) if (b[i]==HARE) return i ; return main.NULL ; } boolean isHound(int i) { return (b[i] == HOUND) ; } private boolean isValidMove(int source,int target,int animal) { if (source>=0 && source<=10 && target>=0 && target<=10) { if (b[target]==EMPTY) { if ((animal==HOUND)&&(connect[source][target]>1)) return true ; else if ((animal==HARE)&&(connect[source][target]>0)) return true ; } } return false ; } boolean isReference() { int total=0 ; // number of positions to reference is based // on game level switch (cp.getLevel()) { case cp.LEVEL1: total = 42 ; break ; case cp.LEVEL2: total = 46 ; break ; case cp.LEVEL3: total = 64 ; break ; } for (int i=0; i=0; i--) { if (b[i]==HOUND) if ((int)((i-1)/3)>(int)(hareSquare/3)) passedCount++ ; } if (passedCount==1) { // #2 if ((hareSquare!=3)&&(hareSquare!=5)) return true ; // #3 else if ((b[5]==HOUND)&&((b[4]==HOUND)||(b[6]==HOUND))) return true ; } // #4 else if (passedCount>1) return true ; return false; } boolean isWin(int animal) { if (animal==HARE) { if (hareEscapes()) { main.setStatus(main.sHARE_WINS) ; return true ; } else if (stallCount==10) { main.setStatus(main.sSTALLING) ; return true ; } } else if (hareIsTrapped()) { main.setStatus(main.sHOUNDS_WIN) ; return true ; } return false ; } private boolean hareIsTrapped() { // the hare can only be trapped on 3 squares switch (getHare()) { case 4: if ( (b[1]==HOUND)&&(b[5]==HOUND)&&(b[7]==HOUND) ) return true ; break ; case 6: if ( (b[3]==HOUND)&&(b[5]==HOUND)&&(b[9]==HOUND) ) return true ; break ; case 10: if ( (b[7]==HOUND)&&(b[8]==HOUND)&&(b[9]==HOUND) ) return true ; break ; } return false ; } private boolean hareEscapes() { int hareSquare=getHare() ; // the wascally wabbit escapes when he's passed all 3 hounds if (hareSquare==0) return true ; hareSquare-- ; for (int i=0; i<10; i++) { if (b[i]==HOUND) { if ( (int)((i-1)/3)>(int)(hareSquare/3) ) return true ; else return false ; } } return false ; } boolean selectPiece(int animal,int sq) { if ((sq>=0)&&(sq<=10)&&(animal==getSquare(sq))) { setEmpty(sq) ; return true ; } return false ; } boolean movePlayerPiece(int source,int target) { int animal = main.getPlayerAnimal() ; if (isValidMove(source,target,animal)) { if (animal==HOUND) { if (connect[source][target]==2) stallCount++ ; else stallCount = 0 ; } setSquare(target,animal) ; return true ; } setSquare(source,animal) ; return false ; } void moveHound(int source,int target) { if (connect[source][target]==2) stallCount++ ; else stallCount = 0 ; movePiece(source,target) ; } void movePiece(int source,int target) { b[target] = b[source] ; setEmpty(source) ; } // used by AI to generate move lists boolean testMove(int s,int t,int animal) { if (b[t]==EMPTY) { if ((animal==HOUND)&&(connect[s][t]>1)) return true ; else if ((animal==HARE)&&(connect[s][t]>0)) return true ; } return false ; } } /******** AI ******** generates computer moves */ final class AI { static final int PLAYER=0, COMPUTER=1, HOUND=1, HARE=2 ; private int houndList[]=new int[3], moveList[]=new int[8], refList[][]=new int[10][2], oppList[][]=new int[10][2], harePref[]={2,5,8,10,1,3,7,9,4,6}, refPtr, oppPtr, source, choices, level ; private Board bd ; private ControlPanel cp ; private Hounds main ; AI(Board bd,ControlPanel cp,Hounds main) { this.bd = bd ; this.cp = cp ; this.main = main ; } void move(int animal) { level = cp.getLevel() ; if (animal==HARE) moveHare() ; else moveHound() ; } private void moveHare() { oppPtr = 0 ; // generate move list source = bd.getHare() ; choices = makeMoveList(source,HARE) ; for (int i=0; i0) { bd.moveHound(source,moveList[randomInt(choices)]) ; break ; } } } } // generates list of all possible moves for one piece private int makeMoveList(int source,int animal) { int ptr=0 ; for (int i=0; i<11; i++) { if (bd.testMove(source,i,animal)) moveList[ptr++] = i ; } return ptr ; } // generates list of hound positions private void makeHoundList() { int ptr=0 ; for (int i=0; i<11; i++) if (bd.isHound(i)) houndList[ptr++] = i ; } private int randomInt(int n) { return (int)(n*Math.random()) ; } } /******** REF ******** reference class, contains array of winning P-positions for the Hounds */ final class Ref { static final int positions[][] = { // 2-ply positions (1) {0,0,0,0,0,1,0,1,2,1,0}, // 20 // 4-ply positions (5) {0,1,0,0,0,0,0,1,0,1,2},{0,0,0,1,0,0,0,1,0,1,2}, // 22 {0,0,1,0,0,0,0,1,0,1,2}, // 21 {0,0,0,0,1,0,0,1,0,1,2},{0,0,0,0,0,0,1,1,0,1,2}, // 19 // 6-ply positions (2) {0,0,0,0,0,1,1,1,0,2,0},{0,0,0,0,1,1,0,2,0,1,0}, // 18 // 8-ply positions (4) {0,1,0,0,2,1,0,0,0,1,0},{0,0,0,1,0,1,2,1,0,0,0}, // 17 {0,1,0,0,0,1,0,0,2,1,0},{0,0,0,1,0,1,0,1,2,0,0}, // 10-ply positions (4) {0,0,1,0,0,1,0,2,0,1,0},{0,0,1,0,0,1,0,1,0,2,0}, // 16 {0,0,0,1,0,0,1,1,0,0,2},{0,1,0,0,1,0,0,0,0,1,2}, // 37 // 12-ply positions (7) {0,1,0,0,0,1,0,1,2,0,0},{0,0,0,1,0,1,0,0,2,1,0}, // 15 {0,0,1,0,0,1,0,0,1,0,2}, // 14 {0,0,1,1,0,0,0,1,0,0,2},{0,1,1,0,0,0,0,0,0,1,2}, // 11 {1,0,0,0,0,1,0,0,0,1,2},{1,0,0,0,0,1,0,1,0,0,2}, // 5 // 14-ply positions (8) {0,1,1,0,0,0,0,1,0,0,2},{0,0,1,1,0,0,0,0,0,1,2}, // 36 {0,1,0,0,1,1,0,2,0,0,0},{0,0,0,1,0,1,1,0,0,2,0}, // 35 {0,0,0,1,0,1,0,0,1,2,0},{0,1,0,0,0,1,0,2,1,0,0}, // 13 {0,1,0,0,0,0,1,1,0,0,2},{0,0,0,1,1,0,0,0,0,1,2}, // 12 // 16-ply positions (6) {0,1,0,1,0,0,0,0,1,0,2},{1,0,0,0,0,1,0,0,1,0,2}, // 10,6 {0,1,0,0,0,1,1,2,0,0,0},{0,0,0,1,1,1,0,0,0,2,0}, // 9 {0,1,0,0,0,1,1,0,0,2,0},{0,0,0,1,1,1,0,2,0,0,0}, // 18-ply positions (9) {0,1,0,1,2,1,0,0,0,0,0},{0,1,0,1,0,1,2,0,0,0,0}, // 8 {0,1,0,1,0,1,0,0,2,0,0}, {1,0,0,0,0,1,0,2,0,1,0},{1,0,0,0,0,1,0,1,0,2,0}, // 5 {1,0,0,0,0,1,0,0,2,1,0},{1,0,0,0,0,1,0,1,2,0,0}, {1,0,0,0,0,1,1,0,2,0,0},{1,0,0,0,1,1,0,0,2,0,0}, // 4 // 20-ply positions (18) {0,1,0,1,1,0,0,0,0,0,2},{0,1,0,1,0,0,1,0,0,0,2}, // 34 {1,0,0,0,1,0,0,1,0,0,2},{1,0,0,0,0,0,1,0,0,1,2}, // 33 {1,0,0,0,0,0,1,1,0,0,2},{1,0,0,0,1,0,0,0,0,1,2}, // 32 {1,1,0,0,0,0,0,1,0,0,2},{1,0,0,1,0,0,0,0,0,1,2}, // 31 {1,0,0,1,0,0,0,1,0,0,2},{1,1,0,0,0,0,0,0,0,1,2}, // 30 {0,0,1,1,0,1,0,2,0,0,0},{0,1,1,0,0,1,0,0,0,2,0}, // 7 {0,0,1,1,0,1,0,0,0,2,0},{0,1,1,0,0,1,0,2,0,0,0}, {1,0,0,0,0,1,1,0,0,2,0},{1,0,0,0,1,1,0,2,0,0,0}, // 4 {1,0,0,0,0,1,1,0,0,0,2},{1,0,0,0,1,1,0,0,0,0,2} } ; } /******** BOARD CANVAS ******** controls all graphics, handles all mouse events and pixel<->square conversions */ final class BoardCanvas extends Canvas { // giflet coordinates final static int hareCoord[]={0,0,45,45}, houndCoord[]={45,0,45,45}, pixelCoord[][] = { {14,96},{96,14},{96,96},{96,178},{178,14},{178,96},{178,178}, {260,14},{260,96},{260,178},{342,96} }, SQUARE=45, OFFSET=20 ; final static Color panelColor = new Color(102,51,51) ; private Image bufferImage, boardImage, gifletsImage, hareImage, houndImage ; private MediaTracker tracker ; private Graphics buffer ; private Hounds main ; BoardCanvas(Image bI,Image gI,Hounds main) { boardImage = bI ; gifletsImage = gI ; this.main = main ; // Extract little images from giflets GIF tracker = new MediaTracker(main) ; hareImage = extractImage(hareCoord) ; houndImage = extractImage(houndCoord) ; try { tracker.waitForAll() ; } catch (InterruptedException e) {} } void drawBoard(Board bd) { drawBoard(bd,main.NULL,main.NULL) ; } void drawBoard(Board bd,int dragX,int dragY) { if (buffer==null) { bufferImage = createImage(main.bcWidth,main.bcHeight) ; buffer = bufferImage.getGraphics() ; } // draw the board buffer.drawImage(boardImage,0,0,main.BOARD_BG_COLOR,this) ; // add the pieces for (int i=0; i<11; i++) { if (bd.getSquare(i)==bd.HARE) buffer.drawImage(hareImage,squareToPixelX(i),squareToPixelY(i),this) ; else if (bd.getSquare(i)==bd.HOUND) buffer.drawImage(houndImage,squareToPixelX(i),squareToPixelY(i),this) ; } // add the dragged piece if any if (dragX!=main.NULL && dragY!=main.NULL) { if (main.getPlayerAnimal()==main.HOUND) buffer.drawImage(houndImage,dragX-22,dragY-22,this) ; else buffer.drawImage(hareImage,dragX-22,dragY-22,this) ; } repaint() ; } public void paint(Graphics g) { update(g) ; } public void update(Graphics g) { g.drawImage(bufferImage,0,0,this) ; } // conversion routines int pixelToSquare(int x,int y) { for (int i=0; i<11; i++) { if ( (pixelCoord[i][0]+OFFSET<=x)&&(x<=pixelCoord[i][0]+OFFSET+SQUARE)&& (pixelCoord[i][1]+OFFSET<=y)&&(y<=pixelCoord[i][1]+OFFSET+SQUARE) ) return i ; } return main.NULL ; } private int squareToPixelX(int i){ return pixelCoord[i][0]+OFFSET ; } private int squareToPixelY(int j){ return pixelCoord[j][1]+OFFSET ; } // mouse event handler public boolean mouseDrag(Event e,int x,int y) { main.dragPiece(x,y) ; return true ; } public boolean mouseUp(Event e,int x,int y) { main.dropPiece(x,y) ; return true ; } public boolean mouseDown(Event e,int x,int y) { // player selects piece to move main.selectPiece(x,y) ; return true ; } // Extracts GIF images private Image extractImage(int[] xyCoord) { Image newImage ; ImageFilter filter; ImageProducer producer; filter = new CropImageFilter(xyCoord[0],xyCoord[1],xyCoord[2],xyCoord[3]); producer = new FilteredImageSource(gifletsImage.getSource(), filter); newImage = main.createImage(producer); tracker.addImage(newImage,0); return newImage ; } } /******** CONTROL PANEL ******** the UI components */ final class ControlPanel extends Panel { static final int LEVEL1=1, LEVEL2=2, LEVEL3=3 ; static final Font titleFont=new Font("SansSerif", Font.BOLD, 12), textFont=new Font("SansSerif", Font.PLAIN, 12), monoFont=new Font("Courier", Font.BOLD, 12), statusFont=new Font("Dialog", Font.PLAIN, 12) ; private Label lPlayer, lScore, lPlayer2, lComputer ; private Button bNewGame ; private CheckboxGroup cbgAnimal ; private Checkbox cbHounds, cbHare ; private Choice cLevel ; private TextField tfPlayerScore, tfComputerScore ; private Hounds main ; // constructor ControlPanel(Hounds main) { this.main = main ; // main layout setLayout(new GridLayout(9,1,0,4)) ; setBackground(Color.lightGray) ; setFont(textFont) ; // New Game button add(bNewGame=new Button(main.sNEW_GAME)) ; // Player Animal checkbox group add(new Label(main.sPLAYER,Label.CENTER)) ; cbgAnimal=new CheckboxGroup() ; Panel pa1 = new Panel() ; pa1.setLayout(new FlowLayout(FlowLayout.LEFT,10,0)) ; pa1.add(cbHounds=new Checkbox(main.sHOUNDS,cbgAnimal,true)) ; add(pa1) ; Panel pa2 = new Panel() ; pa2.setLayout(new FlowLayout(FlowLayout.LEFT,10,0)) ; pa2.add(cbHare=new Checkbox(main.sHARE,cbgAnimal,false)) ; add(pa2) ; // Level pulldown add(new Label(main.sLEVEL,Label.CENTER)) ; add(cLevel = new Choice()) ; cLevel.addItem(main.sBEGINNER); cLevel.addItem(main.sINTERMED); cLevel.addItem(main.sEXPERT); cLevel.select(main.sBEGINNER) ; // Scoreboard panels add(new Label(main.sSCORE,Label.CENTER)) ; Panel psp = new Panel() ; psp.setLayout(new FlowLayout(FlowLayout.RIGHT,3,0)) ; psp.add(new Label(main.s2PLAYER,Label.CENTER)) ; psp.add(tfPlayerScore = new TextField(2)) ; tfPlayerScore.setFont(monoFont) ; add(psp) ; Panel csp = new Panel() ; csp.setLayout(new FlowLayout(FlowLayout.RIGHT,3,0)) ; csp.add(new Label(main.sCOMPUTER,Label.CENTER)) ; csp.add(tfComputerScore = new TextField(2)) ; tfComputerScore.setFont(monoFont) ; add(csp) ; validate() ; } // handle control panel events public boolean action(Event e,Object o) { if (main.sNEW_GAME.equals(o)) main.newGame() ; else if (e.target==cbHounds) main.setPlayerAnimal(main.HOUND) ; else if (e.target==cbHare) main.setPlayerAnimal(main.HARE) ; else main.setFocus() ; return true ; } int getLevel() { switch (cLevel.getSelectedIndex()) { case 1: return LEVEL2 ; case 2: return LEVEL3 ; default: return LEVEL1 ; } } void setComputerScore(int i) { String s = Integer.toString(i) ; switch (s.length()) { case 1: s = " " + s ; break ; case 2: s = " " + s ; break ; } tfComputerScore.setText(s) ; } void setPlayerScore(int i) { String s = Integer.toString(i) ; switch (s.length()) { case 1: s = " " + s ; break ; case 2: s = " " + s ; break ; } tfPlayerScore.setText(s) ; } }