/* Ken's Checkers version 1.4 Kennett Dempster California State University Long Beach dempster@engr.csulb.edu Version list (1.0) 4-10-96 Version (1.2) 7-23-96 Version (1.3) 7-30-96 Version (1.4) 8-9-96 Version (1.5) 8-13-96 Version (1.6) 9-9-96 Last modified 9-9-96 This is my first try at Java. It was a learning experience. Hope to continue to developed more and better Java programs and applets. I have fixed some of the bugs with the 2 player game and soon hope to expand the playability of the game. I implement a move & piece risk list to decide which piece to move next. I based a lot risk list on information I found in the PC magazine artical & code. 1. Fix program lockup when computer tries to jump in certain situations. 2. Better jump decisions by computer player. 3. Use color of player instead of player number in status bar. 4. Move decsion based on : a. Check risk before move b. Check risk after move c. Check for double+ jumps d. Check for back jumps e. Check for king chase f. Check for wedge moves g. Check for be king move h. Check for side move i. Check for last pieces to move (0,1) & (0,3) 5. I have now added graphical way to move the playing pieces 6. More to come This program can be modified or copied as is given two stipulations. First it or a modified version of it can't be used to obtain any monitary compensation. Second it or a a modified version of it must contain a refrence to the origanal creator (Kennett Dempster) in it's header. */ import java.awt.*; import java.applet.*; import java.util.*; // Main Class public class checkers extends Applet { Panel GameButtons = new Panel(); // Hold status info Panel GameType = new Panel(); // Holds game buttons TitlePanel TitleBar1 = new TitlePanel(); // Holds turn info TitlePanel TitleBar2 = new TitlePanel(); // Holds turn info InfoPanel InfoArea = new InfoPanel(); // Holds last move info Panel GameArea = new Panel(); // Defines game area BoardCanvas GameBoard = new BoardCanvas(); // Holds game board Button Player1 = new Button("1 Player"); // Buttons for game Button Player2 = new Button("2 Player"); Button Replay = new Button("Show Last Move"); Button PassTurn = new Button("Pass on This Turn"); private void add(Component c, GridBagLayout gbl, GridBagConstraints gbc, int x, int y, int w, int h, int wx, int wy) { gbc.gridx = x; gbc.gridy = y; gbc.gridwidth = w; gbc.gridheight = h; gbc.weightx = wx; gbc.weighty = wy; gbl.setConstraints(c, gbc); add(c); } // Initualization function public void init() { GridBagLayout gridbag = new GridBagLayout(); // LayOut for game sections GridBagConstraints c = new GridBagConstraints(); // Constriants for gridbig int whofirst = (int)Math.floor(Math.random() * 2); // Who goes first setLayout(gridbag); GameBoard.setup(2, whofirst); // Setup GameBoard GameArea.setLayout(new GridLayout(1,1)); GameArea.add(GameBoard); c.fill = GridBagConstraints.BOTH; // Setup GridBag constraints add(GameArea, gridbag, c, 0, 0, 8, 8, 80, 100); GameType.setLayout(new GridLayout(2,1)); // Setup GameButtons GameType.add(Player1); GameType.add(Player2); GameButtons.setLayout(new GridLayout(2,1)); // Setup GameButtons GameButtons.add(Replay); GameButtons.add(PassTurn); TitleBar1.setup("Game Type"); add(TitleBar1, gridbag, c, 8, 0, 1, 1, 20, 5); c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; add(GameType, gridbag, c, 8, 1, 1, 1, 20, 5); c.fill = GridBagConstraints.BOTH; TitleBar2.setup("Game Buttons"); add(TitleBar2, gridbag, c, 8, 2, 1, 1, 20, 5); c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; add(GameButtons, gridbag, c, 8, 3, 1, 1, 20, 5); c.fill = GridBagConstraints.BOTH; InfoArea.setup(whofirst); add(InfoArea, gridbag, c, 8, 4, 1, 4, 20, 80); } // Handels button events public boolean action(Event evt, Object arg) { int whofirst; // Who goes first whofirst = (int)Math.floor(Math.random() * 2); if ("1 Player".equals(arg)){ // New Game 1 player GameBoard.setup(1, 1); GameBoard.repaint(); InfoArea.setup(1); InfoArea.repaint(); System.out.println("Newstart"); } else if ("2 Player".equals(arg)) { // New Game 2 Player GameBoard.setup(2, whofirst); GameBoard.repaint(); InfoArea.setup(whofirst); InfoArea.repaint(); } else if ("Show Last Move".equals(arg)) { // Replay Last Turn if (GameBoard.ReplayCheck()) { GameBoard.ReplaySetUp(); GameBoard.ReplayRun(); } } else if ("Pass on This Turn".equals(arg)) { // Pass on this turn GameBoard.Pass(); UpdateLabels(); } return true; } // Updates the label information public void UpdateLabels() { String[] Information = new String[10]; // Array containing update information if (GameBoard.CheckEvent()) { GameBoard.GetLabelInfo(Information); InfoArea.UpdateInfo(Information); InfoArea.repaint(); if (GameBoard.CallCumputerTurn()) { GameBoard.GetLabelInfo(Information); InfoArea.UpdateInfo(Information); InfoArea.repaint(); } } } // Updates labels after each turn public boolean mouseUp(Event evt, int x, int y) { UpdateLabels(); return true; } public static void main(String args[]) { Frame f = new Frame("Checkers Game"); checkers game= new checkers(); game.init(); game.start(); f.add("Center", game); f.resize(550, 450); f.show(); } } class TitlePanel extends Panel { String Word; // Update with out clearing window public void update(Graphics g) { paint(g); } public void setup(String Title) { Word = Title; } public void paint(Graphics g) { int w = size().width; // Width of game board canvas int h = size().height; // Height of game board canvas g.setColor(Color.black); g.setFont(new Font("TimesRoman", Font.BOLD, 20)); g.drawString(Word, 2, h-2); } } class InfoPanel extends Panel { String Turn; String PlayerTurn; String Move; String[] LastMove = new String[7]; String Left; String Player1; String Player2; boolean Full; Color Purple = new Color(155,50,155); public void setup(int player) { int i; Turn = "Player's Turn ::"; if (player == 0) PlayerTurn = "Purple"; else PlayerTurn = "Blue"; Move = "Last Player's Move ::"; for (i = 0; i < 7; i++) LastMove[i] = ""; Left = "Pieces Left For ::"; Player1 = "12"; Player2 = "12"; Full = true; } // Update with out clearing window public void update(Graphics g) { paint(g); } public void paint(Graphics g) { int i; int w = size().width; // Width of game board canvas int h = size().height; // Height of game board canvas if (Full) { g.setColor(Color.lightGray); g.fillRect(0, 0, w, h); g.setColor(Color.black); g.setFont(new Font("TimesRoman", Font.BOLD, 18)); g.drawString(Turn, 2, 15); g.setFont(new Font("TimesRoman", Font.BOLD, 15)); if (PlayerTurn.charAt(0) == 'P') g.setColor(Purple); else g.setColor(Color.blue); g.drawString(" " + PlayerTurn, 2, 35); g.setColor(Color.black); g.drawString("Player", 60, 35); g.setColor(Color.black); g.setFont(new Font("TimesRoman", Font.BOLD, 18)); g.drawString(Move, 2, 65); g.setFont(new Font("TimesRoman", Font.BOLD, 15)); for (i = 0; i < 7; i++) g.drawString(" " + LastMove[i], 2, 85+i*20); g.setFont(new Font("TimesRoman", Font.BOLD, 18)); g.drawString(Left, 2, 225); g.setFont(new Font("TimesRoman", Font.BOLD, 15)); g.setColor(Purple); g.drawString(" Purple", 2, 245); g.setColor(Color.blue); g.drawString(" Blue", 2, 265); g.setColor(Color.black); g.drawString("Player : ", 60, 245); g.drawString("Player : ", 60, 265); g.drawString(Player1, 112, 245); g.drawString(Player2, 112, 265); } else { g.setColor(Color.lightGray); g.fillRect(2, 19, 58, 31); g.fillRect(2, 69, 170, 141); g.fillRect(112, 229, 120, 241); g.setFont(new Font("TimesRoman", Font.BOLD, 15)); if (PlayerTurn.charAt(0) == 'P') g.setColor(Purple); else g.setColor(Color.blue); g.drawString(" " + PlayerTurn, 2, 35); g.setColor(Color.black); for (i = 0; i < 7; i++) g.drawString(" " + LastMove[i], 2, 85+i*20); g.drawString(Player1, 112, 245); g.drawString(Player2, 112, 265); Full = true; } } public void UpdateInfo(String Info[]) { PlayerTurn = Info[0]; Player1 = Info[1]; Player2 = Info[2]; LastMove[0] = Info[3]; LastMove[1] = Info[4]; LastMove[2] = Info[5]; LastMove[3] = Info[6]; LastMove[4] = Info[7]; LastMove[5] = Info[8]; LastMove[6] = Info[9]; Full = false; } } // Class for Game Board class BoardCanvas extends Canvas { int[][] BoardInfo = new int[8][8]; // Info of pieces on game board int[] MovesX = new int[7]; // Last move X int[] MovesY = new int[7]; // Last move Y int[] JumpedX = new int[3]; // X position of piece to jump over int[] JumpedY = new int[3]; // Y position of piece to jump over int[] JumpedPiece = new int[3]; // Holds pieces that were jumped int[] FindHold = new int[60]; // Holds FindPath information int[] ReplayX = new int[7]; // Replay last move X int[] ReplayY = new int[7]; // Replay last move Y int JumpedCount; // Number of items in Jumped int NumPlayer; // Number of players int PlayerTurn; // Player turn int Winner; // Winner flag int BlockSize; // Block Size of game board square int MoveCount; // Number of items in Moves int MoveCountHolder; // Holders MoveCount number for status label update info int TypeOfUpdate; // Type of screen update int Xpass; // Last X used int Ypass; // Last Y used int Wwidth; // Width of square int Hheight; // Height of square int PiecesPlayer1; // Number of pieces left for player 1 int PiecesPlayer2; // Number of pieces left for player 2 int SetJump; // Flag for first jump selected int UpDateLabel; // Flag to indicate update of status labels int MoveJump; // Flag for last action of player int Wait; // Play wait for computer turn int FH; // Number of items in FindHold Array String TheWinner; // Name of winner int LastX; // X place last piece moved int LastY; // Y place last piece moved boolean WhereFlag; // Flag for first WhereX set int FWhereX; // First X possion of cursor int FWhereY; // First Y possion of cursor int WhereX; // Second to last X possion of cursor int WhereY; // Second to last Y possion of cursor boolean FirstMJ; // If First Jump or Move of computer repaint double factorX; // Move factor X double factorY; // Move factor Y boolean MouseMove; // If tracking mouse move double JumpFactor; // Var to hold change of jumpfactor boolean Up; // If animation is going up/down int NumJump; // Which jump you are on boolean KingTest; // var to hold kingtest int Fcount; // Factor count int EndCount; // Value to end factor count boolean CountType; // A negative or positive Fcount boolean PaintAction; boolean FFlag; int HoldPaint; int Count; int ReplayCount; // Number of items in ReplayX int ReplayFlag; // Type of replay (jump/move) Color Purple = new Color(155,50,155); // Purple color // Set Game Board public void setup(int num, int first) { int PutPiece; // Flag for putting a piece on a spot of the board int j, i; // Counter NumPlayer = num; Winner = 0; PlayerTurn = first; MoveCount = 0; JumpedCount = 0; TypeOfUpdate = 1; Xpass = 0; Ypass = 0; Wwidth = 0; Hheight = 0; PiecesPlayer1 = 12; PiecesPlayer2 = 12; SetJump = 0; UpDateLabel = 0; MouseMove = false; FirstMJ = true; WhereFlag = false; KingTest = false; HoldPaint = 0; ReplayFlag = -1; if ((first == 0) && (NumPlayer == 1)) Wait = 1; else Wait = 0; for (i = 0;i < 8;i++) { if ((i == 0) || (i == 2) || (i == 6)) // Check if piece should go at first PutPiece = 0; // possition of row else PutPiece = 1; for (j = 0;j < 8;j++) if ((i == 3) || (i == 4)) // No pieces on these rows BoardInfo[j][i] = 100; else { if (PutPiece == 1) { // Put piece here PutPiece = 0; if (i < 3) BoardInfo[j][i] = 0; else BoardInfo[j][i] = 2; } else { // Don't put piece here PutPiece = 1; BoardInfo[j][i] = 100; } } } } // Puase command public void Pause(int interval) { Date today = new Date(); int sec = today.getSeconds() + interval; int quit = 100; if (sec > 59) sec = sec - 60; while (sec != quit) { today = new Date(); quit = today.getSeconds(); } } // Returns the square color at that part of the board public Color SquareColor(int x, int y) { int compx = (x + 1) % 2; int compy = (y + 1) % 2; if (((compx == 1) && (compy == 1)) || ((compx == 0) && (compy == 0))) return Color.red; else return Color.black; } // Update with out clearing window public void update(Graphics g) { paint(g); } // Returns the piece color given the number of the piece in the array public Color ColorPiece(int x, int y) { if (BoardInfo[x][y] > 1) return Color.blue; else return Purple; } // Check if piece becomes king public boolean IsKing(int x, int y) { int ThePiece = BoardInfo[x][y]; if ((ThePiece == 1) || (ThePiece == 3)) return true; else if ((ThePiece == 2) && (y == 0) && ((x == 1) || (x == 3) || (x == 5) || (x == 7))) { BoardInfo[x][y] = 3; return true; } else if ((ThePiece == 0) && (y == 7) && ((x == 0) || (x == 2) || (x == 4) || (x == 6))) { BoardInfo[x][y] = 1; return true; } else return false; } // Check if piece is a king now public boolean TestKing(int x, int y) { int ThePiece = BoardInfo[x][y]; if ((ThePiece == 1) || (ThePiece == 3)) return true; else return false; } // Check for reaplay public boolean ReplayCheck(){ if (ReplayFlag == -1) return false; else return true; } // Setup for replay public void ReplaySetUp() { TypeOfUpdate = 10; MouseMove = false; MoveCount = 0; repaint(); ChangeTurn(); } // Runs the replay public void ReplayRun() { int i; int TempX = ReplayX[0]; int TempY = ReplayY[0]; boolean King; for (i = 0; i < ReplayCount; i++) { MovesX[i] = ReplayX[i]; MovesY[i] = ReplayY[i]; DrawSquare(MovesX[i], MovesY[i], BlockSize, Color.black, true); } Piece(TempX, TempY, ColorPiece(TempX, TempY), KingTest, false, 1.0); if (ReplayFlag == 0) TypeOfUpdate = 12; else { for (i = 0; i < JumpedCount; i++) { if ((JumpedPiece[i] == 1) || (JumpedPiece[i] == 3)) King = true; else King = false; Piece(JumpedX[i], JumpedY[i], ColorPiece(JumpedX[i], JumpedY[i]), King, false, 1.0); } TypeOfUpdate = 13; } FirstMJ = true; repaint(); } // Paints the game board Area public void paint(Graphics g) { int w = size().width; // Width of game board canvas int h = size().height; // Height of game board canvas int i; // Counter int WCenter; // Width Center int HCenter; // Height Center boolean NotDone = true; // Done flag for end of animation int adjust = 0; // Adjust factor for piece possion boolean King; // King flag boolean MJKing = false; // If piece will become king at end of animation Color TheColor; // Color variable double LastFactor; // LastFactor holder boolean AllDone = false; // Flag for all done with animation int TempX; // Temp variable for X if (HoldPaint != 0) { TypeOfUpdate = HoldPaint; HoldPaint = 0; } if ((Wwidth != w) || (Hheight != h)) { // Window change redraw window Wwidth = w; Hheight = h; if (PaintAction) HoldPaint = TypeOfUpdate; TypeOfUpdate = 10; if (PaintAction) repaint(); } switch (TypeOfUpdate) { // Set game board case 1 : TypeOfUpdate = 10; DrawBoard(); PaintAction = false; break; // Highlight piece area case 2 : TypeOfUpdate = 10; DrawSquare(Xpass, Ypass, BlockSize-1, Color.white, false); PaintAction = false; break; // Unhighlight piece area case 3 : TypeOfUpdate = 10; ClearSpace(WhereX, WhereY, 0, false, false, 1.0); ClearSpace(FWhereX, FWhereY, 0, false, false, 1.0); for (i = 0;i < MoveCount;i++) DrawSquare(MovesX[i], MovesY[i], BlockSize, Color.black, true); Piece(Xpass, Ypass, ColorPiece(Xpass, Ypass), IsKing(Xpass, Ypass), false, 1.0); MoveCount = 0; WhereFlag = false; PaintAction = false; break; // Move piece (Human) case 4 : ClearSpace(WhereX, WhereY, 0, false, false, 1.0); ClearSpace(FWhereX, FWhereY, 0, false, false, 1.0); DrawSquare(MovesX[0], MovesY[0], BlockSize, Color.black, true); Piece(Xpass, Ypass, ColorPiece(Xpass, Ypass), IsKing(Xpass, Ypass), false, 1.0); WhereFlag = false; ChangeTurn(); TypeOfUpdate = 10; PaintAction = false; break; // Jump piece case 5 : ClearSpace(WhereX, WhereY, 0, false, false, 1.0); ClearSpace(FWhereX, FWhereY, 0, false, false, 1.0); for (i = 0;i < MoveCount-1;i++) DrawSquare(MovesX[i], MovesY[i], BlockSize, Color.black, true); for (i = 0;i < JumpedCount;i++) DrawSquare(JumpedX[i], JumpedY[i], BlockSize, Color.black, true); Piece(Xpass, Ypass, ColorPiece(Xpass, Ypass), IsKing(Xpass, Ypass), false, 1.0); JumpedCount = 0; MoveCountHolder = MoveCount-1; MoveCount = 0; WhereFlag = false; ChangeTurn(); TypeOfUpdate = 10; PaintAction = false; break; // A Winner case 6 : TypeOfUpdate = 10; WCenter = BlockSize * 4 - 140; HCenter = BlockSize * 4 - 25; g.setColor(Color.white); g.setFont(new Font("TimesRoman", Font.BOLD, 50)); g.drawString(TheWinner, WCenter, HCenter); g.setFont(new Font("TimesRoman", Font.BOLD, 75)); g.drawString("Wins!", WCenter+55, HCenter+90); WhereFlag = false; PaintAction = false; break; // window redraw case 10: DrawBoard(); if (MoveCount != 0) // Draw seleced pieces and areas to move or jump to for (i = 0;i < MoveCount;i++) DrawSquare(MovesX[i], MovesY[i], BlockSize-1, Color.white, false); if (Winner == 1) { // Draw winners banner if a winner WCenter = BlockSize * 4 - 140; HCenter = BlockSize * 4 - 25; g.setColor(Color.white); g.setFont(new Font("TimesRoman", Font.BOLD, 50)); g.drawString(TheWinner, WCenter, HCenter); g.setFont(new Font("TimesRoman", Font.BOLD, 75)); g.drawString("Wins!", WCenter+55, HCenter+90); } PaintAction = false; break; // Mouse move with piece case 11 : PaintAction = true; ClearSpace(WhereX, WhereY, 0, false, true, 1.0); if (!WhereFlag) WhereFlag = true; DrawPiece(); break; // Move piece (Computer) case 12 : MJKing = KingTest; if (FirstMJ) { Count = 0; PaintAction = true; if (MovesX[1] - MovesX[0] > 0) factorX = 1.0; else factorX = -1.0; if (MovesY[1] - MovesY[0] > 0) factorY = 1.0; else factorY = -1.0; if ((factorX < 0) && (factorY > 0)) factorX = factorX - 0.5; else if ((factorX > 0) && (factorY < 0)) factorY = factorY - 0.5; adjust = BlockSize / 2; FWhereX = MovesX[0] * BlockSize + adjust + (int)factorX; FWhereY = MovesY[0] * BlockSize + adjust + (int)factorY; if (factorX > 0) { Fcount = FWhereX; FFlag = true; EndCount = MovesX[1] * BlockSize + adjust; } else { Fcount = FWhereY; FFlag = false; EndCount = MovesY[1] * BlockSize + adjust; } if ((factorX < 0) && (factorY < 0)) CountType = true; else CountType = false; FirstMJ = false; WhereX = FWhereX; WhereY = FWhereY; } else { WhereX = FWhereX; WhereY = FWhereY; FWhereX = FWhereX + (int)factorX; FWhereY = FWhereY + (int)factorY; if (FFlag) Fcount = FWhereX; else Fcount = FWhereY; adjust = BlockSize / 2; if (((CountType) && (Fcount <= EndCount)) || ((!CountType) && (Fcount >= EndCount))) { FWhereX = MovesX[1]; FWhereY = MovesY[1]; NotDone = false; MJKing = TestKing(Xpass, Ypass); } else NotDone = true; } ClearSpace(WhereX, WhereY, 0, false, false, 1.0); Piece(FWhereX, FWhereY, ColorPiece(Xpass, Ypass), MJKing, NotDone, 1.0); System.out.println("Move " + Count); Count = Count + 1; if (NotDone) repaint(); else { FirstMJ = true; Wait = 0; ChangeTurn(); PaintAction = false; TypeOfUpdate = 10; System.out.println("Done with Move"); } break; // Jump piece (Computer) case 13 : MJKing = KingTest; adjust = BlockSize / 2; if (FirstMJ) { Count = 0; PaintAction = true; if (MovesX[NumJump+1] - MovesX[NumJump] > 0) factorX = 1.0; else factorX = -1.0; if (MovesY[NumJump+1] - MovesY[NumJump] > 0) factorY = 1.0; else factorY = -1.0; if ((factorX < 0) && (factorY > 0)) factorX = factorX - 0.5; else if ((factorX > 0) && (factorY < 0)) factorY = factorY - 0.5; for (i = 0;i < MoveCount;i++) DrawSquare(MovesX[i], MovesY[i], BlockSize-1, Color.white, false); FWhereX = WhereX = MovesX[NumJump] * BlockSize + adjust + (int)factorX; FWhereY = WhereY = MovesY[NumJump] * BlockSize + adjust + (int)factorY; if (factorX > 0) { Fcount = FWhereX; FFlag = true; EndCount = MovesX[NumJump+1] * BlockSize + adjust; } else { Fcount = FWhereY; FFlag = false; EndCount = MovesY[NumJump+1] * BlockSize + adjust; } if ((factorX < 0) && (factorY < 0)) CountType = true; else CountType = false; JumpFactor = 1.0; FirstMJ = false; WhereFlag = true; Up = true; LastFactor = 1.0; } else { WhereX = FWhereX; WhereY = FWhereY; FWhereX = FWhereX + (int)factorX; FWhereY = FWhereY + (int)factorY; if (FFlag) Fcount = FWhereX; else Fcount = FWhereY; LastFactor = JumpFactor; if (Up) JumpFactor = JumpFactor + 0.04; else if (!Up) JumpFactor = JumpFactor - 0.04; if (JumpFactor > 2.68) Up = false; else if (JumpFactor < 1.0) JumpFactor = 1.0; if (((CountType) && (Fcount <= EndCount)) || ((!CountType) && (Fcount >= EndCount))) { FWhereX = MovesX[NumJump+1] * BlockSize + adjust + (int)factorX; FWhereY = MovesY[NumJump+1] * BlockSize + adjust + (int)factorY; JumpFactor = 1.0; NotDone = false; if ((NumJump + 3) == MoveCount) { MJKing = TestKing(Xpass, Ypass); FWhereX = MovesX[NumJump+1]; FWhereY = MovesY[NumJump+1]; AllDone = true; } } else NotDone = true; } ClearSpace(WhereX, WhereY, NumJump, true, false, LastFactor); if ((JumpedPiece[NumJump] == 1) || (JumpedPiece[NumJump] == 3)) King = true; else King = false; if ((JumpedPiece[NumJump] == 0) || (JumpedPiece[NumJump] == 1)) TheColor = Purple; else TheColor = Color.blue; if (NotDone) Piece(JumpedX[NumJump], JumpedY[NumJump], TheColor, King, !NotDone, 1.0); else { DrawSquare(JumpedX[NumJump], JumpedY[NumJump], BlockSize, Color.black, true); if ((NumJump + 3) < MoveCount) { NumJump = NumJump + 1; FirstMJ = true; NotDone = true; } else for (i = 0;i < MoveCount;i++) DrawSquare(MovesX[i], MovesY[i], BlockSize, Color.black, true); } if (AllDone) Piece(FWhereX, FWhereY, ColorPiece(Xpass, Ypass), MJKing, false, 1.0); else Piece(FWhereX, FWhereY, ColorPiece(Xpass, Ypass), MJKing, true, JumpFactor); System.out.println("NumJump=" + NumJump + " Jump " + Count); Count = Count + 1; if (NotDone) repaint(); else { WhereFlag = false; FirstMJ = true; ChangeTurn(); TypeOfUpdate = 10; JumpedCount = 0; MoveCountHolder = MoveCount-1; MoveCount = 0; Wait = 0; PaintAction = false; System.out.println("Done with Jump"); } break; } } // Draws the Game Board on the screen public void DrawBoard() { Graphics g = getGraphics(); // Graphic for screen int w = size().width; // Width of game board canvas int h = size().height; // Height of game board canvas int Square; // Game board size int i, j; // Counters int X, Y; // Game square counters if (w < h) // Find minimum Square = w; else Square = h; BlockSize = Square / 8; // Set square size for (i = 0;i < 8;i++) // Draw game board for (j = 0;j < 8;j++) DrawSquare(i, j, BlockSize, SquareColor(i,j), true); for (Y = 0;Y < 8;Y++) // Draw pieces on game board for (X = 0;X < 8;X++) if (BoardInfo[X][Y] != 100) Piece(X, Y, ColorPiece(X, Y), IsKing(X, Y), false, 1); } // Draws a game piece at the specified location public void Piece(int x, int y, Color theback, boolean king, boolean move, double scale){ Graphics g = getGraphics(); // Graphic for screen int adjust = BlockSize / 2; // Size of bottom oval int adjust2 = adjust / 2; // Size of top oval int realX = 0; // Where to put piece at x int realY = 0; // Where to put piece at y int space; // Adjust dimentions of piece int scaler = (int)(adjust * scale); if (king) space = 5; else space = 3; // If piece is being called for a move if (move) { realX = x-adjust2; realY = y-adjust2; // Check for off board if (realX < 0) realX = 0; else if (realX > BlockSize * 7 + scaler - space) realX = BlockSize * 7 + scaler - space; if (realY < 0) realY = 0; else if (realY > BlockSize * 7 + scaler - space) realY = BlockSize * 7 + scaler - space; } else { realX = x * BlockSize + adjust2; realY = y * BlockSize + adjust2; } // Draw piece g.setColor(theback); g.fillOval(realX, realY, scaler, scaler); g.setColor(Color.white); g.drawOval(realX, realY, scaler, scaler); adjust2 = adjust2 / 4; realX = realX + adjust2; realY = realY + adjust2; g.setColor(theback); g.fillOval(realX, realY, scaler, scaler); g.setColor(Color.white); g.drawOval(realX, realY, scaler, scaler); if (king) { // Add king piece realX = realX + adjust2; realY = realY + adjust2; g.setColor(theback); g.fillOval(realX, realY, scaler, scaler); g.setColor(Color.white); g.drawOval(realX, realY, scaler, scaler); } } // Draw square public void DrawSquare(int x, int y, int Block, Color TheColor, boolean fill) { Graphics g = getGraphics(); // Graphic for screen int realX; int realY; g.setColor(TheColor); realX = x * BlockSize; realY = y * BlockSize; if (fill) g.fillRect(realX, realY, Block, Block); else g.drawRect(realX, realY, Block, Block); } // Find which square based on screen coordinate public int FindSpot(int At) { int found = 8; // Found at (8 not find) int BreakDown = 0; // Increment between coordinates for (int i = 0;i < 8;i++) { // Find spot in game board if ((At >= BreakDown) && (At <= (BreakDown + BlockSize))) { // Found found = i; break; } BreakDown = BreakDown + BlockSize; } return found; } // Check valid move public boolean ValidMove(int x, int y) { int FirstX = MovesX[0]; // X spot of piece to move int FirstY = MovesY[0]; // Y spot of piece to move int spotX = FirstX - x; // Difference of old X spot and new X spot int spotY = FirstY - y; // Difference of old Y spot and new Y spot if (IsKing(FirstX, FirstY)) { // If King if (((spotX == 1) || (spotX == -1)) && ((spotY == 1) || (spotY == -1))) return true; else return false; } else if (WhichPlayer(FirstX, FirstY) == 0) { // If player 1 if (((spotX == 1) || (spotX == -1)) && (spotY == -1)) return true; else return false; } else { // If player 2 if (((spotX == 1) || (spotX == -1)) && (spotY == 1)) return true; else return false; } } // Check for which player public int WhichPlayer(int x, int y) { int spot = BoardInfo[x][y]; if (spot < 2) return 0; else return 1; } // Check to see if piece to be jumped public boolean IfOtherPiece(int x, int y) { if (PlayerTurn != WhichPlayer(x, y)) return true; else return false; } // Add Jumped piece to Jumped array public void SetJumped(int x, int y) { int FirstX = MovesX[MoveCount-1]; // X spot of piece to move int FirstY = MovesY[MoveCount-1]; // Y spot of piece to move int spotX = FirstX - x; // Difference of old X spot and new X spot int spotY = FirstY - y; // Difference of old Y spot and new Y spot int JumpOverPieceX = spotX / -2 + FirstX; // Calculate where X jumped piece is int JumpOverPieceY = spotY / -2 + FirstY; // Calculate where Y jumped piece is JumpedX[JumpedCount] = JumpOverPieceX; JumpedY[JumpedCount] = JumpOverPieceY; JumpedCount++; } // Check valid jump for Human public boolean ValidJump(int x, int y, int FirstX, int FirstY) { int spotX = FirstX - x; // Difference of old X spot and new X spot int spotY = FirstY - y; // Difference of old Y spot and new Y spot int JumpOverPieceX = spotX / -2 + FirstX; // Calculate where X jumped piece is int JumpOverPieceY = spotY / -2 + FirstY; // Calculate where Y jumped piece is int JumpOverSpot = BoardInfo[JumpOverPieceX][JumpOverPieceY]; // Spot of piece to jump int AtX = MovesX[0]; int AtY = MovesY[0]; if ((JumpOverSpot != 100) && IfOtherPiece(JumpOverPieceX,JumpOverPieceY)) { if (IsKing(AtX, AtY)) { // If King // ^ Check if valid jump if (((spotX == 2) || (spotX == -2)) && ((spotY == 2) || (spotY == -2))) return true; else return false; } else if (WhichPlayer(AtX, AtY) == 0) { // If player 1 if (((spotX == 2) || (spotX == -2)) && (spotY == -2)) return true; else return false; } else { // If player 2 if (((spotX == 2) || (spotX == -2)) && (spotY == 2)) return true; else return false; } } else return false; } // Check for jump spot in list already public boolean InJumpList(int x, int y) { int i=0; // Counter while (i != (MoveCount-1)) if ((x == MovesX[i]) && (y == MovesY[i])) return false; else i++; return true; } // Changes Players turn public void ChangeTurn() { if (PlayerTurn == 0) // Change player turn & Decrement player pieces PlayerTurn = 1; else PlayerTurn = 0; } // Sets replay variables public void SetReplay(int MC, int MFlag){ int i; ReplayCount = MC; ReplayFlag = MFlag; for (i = 0; i < MC; i++) { ReplayX[i] = MovesX[i]; ReplayY[i] = MovesY[i]; } } // Processes a move or jump public void ProcessTurn(int Xspot, int Yspot) { int i; // Counter // Reset Turn or if to many MoveCount choices if (((MoveCount > 0) && (MovesX[0] == Xspot) && (MovesY[0] == Yspot)) || (MoveCount == 7)) { MouseMove = false; Xpass = Xspot; Ypass = Yspot; JumpedCount = 0; SetJump = 0; TypeOfUpdate = 3; repaint(); } // Do Jump else if ((SetJump == 1) && (MovesX[MoveCount-1] == Xspot) && (MovesY[MoveCount-1] == Yspot)) { MouseMove = false; SetJump = 0; MovesX[MoveCount] = Xpass = LastX = Xspot; MovesY[MoveCount] = Ypass = LastY = Yspot; MoveCount++; SetReplay(MoveCount, 1); BoardInfo[Xspot][Yspot] = BoardInfo[MovesX[0]][MovesY[0]]; BoardInfo[MovesX[0]][MovesY[0]] = 100; for (i = 0;i < JumpedCount;i++) { JumpedPiece[i] = BoardInfo[JumpedX[i]][JumpedY[i]]; BoardInfo[JumpedX[i]][JumpedY[i]] = 100; } if ((NumPlayer == 1) && (PlayerTurn == 0)) { KingTest = TestKing(Xspot, Yspot); TypeOfUpdate = 13; NumJump = 0; } else TypeOfUpdate = 5; if (PlayerTurn == 0) // Change player turn & Decrement player pieces PiecesPlayer2 = PiecesPlayer2 - JumpedCount; else PiecesPlayer1 = PiecesPlayer1 - JumpedCount; IsKing(Xspot, Yspot); repaint(); UpDateLabel = 1; // Set update flag MoveJump = 1; // Its a Jump } // Valid set jump else if ((MoveCount > 0) && (BoardInfo[Xspot][Yspot] == 100) && ValidJump(Xspot, Yspot, MovesX[MoveCount-1], MovesY[MoveCount-1]) && InJumpList(Xspot, Yspot)) { if (NumPlayer == 2) MouseMove = true; else if ((NumPlayer == 1) && (PlayerTurn == 1)) MouseMove = true; else MouseMove = false; SetJump = 1; SetJumped(Xspot, Yspot); MovesX[MoveCount] = Xpass = Xspot; MovesY[MoveCount] = Ypass = Yspot; MoveCount++; TypeOfUpdate = 2; NumJump = 0; repaint(); } // Move piece to here else if ((MoveCount > 0) && (BoardInfo[Xspot][Yspot] == 100) && ValidMove(Xspot, Yspot) && (SetJump == 0)) { MouseMove = false; MovesX[MoveCount] = Xpass = LastX = Xspot; MovesY[MoveCount] = Ypass = LastY = Yspot; MoveCountHolder = MoveCount+1; SetReplay(MoveCount+1, 0); MoveCount = 0; BoardInfo[Xspot][Yspot] = BoardInfo[MovesX[0]][MovesY[0]]; BoardInfo[MovesX[0]][MovesY[0]] = 100; if ((NumPlayer == 1) && (PlayerTurn == 0)) { TypeOfUpdate = 12; KingTest = TestKing(Xspot, Yspot); } else TypeOfUpdate = 4; IsKing(Xspot, Yspot); FirstMJ = true; repaint(); UpDateLabel = 1; // Set update flag MoveJump = 0; // Its a Move } // Valid piece to move else if ((BoardInfo[Xspot][Yspot] != 100) && (WhichPlayer(Xspot, Yspot) == PlayerTurn) && (SetJump == 0) && (MoveCount == 0)) { if (NumPlayer == 2) MouseMove = true; else if ((NumPlayer == 1) && (PlayerTurn == 1)) MouseMove = true; else MouseMove = false; MovesX[MoveCount] = Xpass = Xspot; MovesY[MoveCount] = Ypass = Yspot; MoveCount++; TypeOfUpdate = 2; repaint(); } } // Handles users mouse turn information public boolean mouseDown(Event evt, int x, int y) { int Xspot = FindSpot(x); // X of square spot int Yspot = FindSpot(y); // Y of square spot int InBoard = 1; // Flag for mouse click in game area int i; // Counter if ((Xspot == 8) || (Yspot == 8) || (Winner == 1)) // Click not in board InBoard = 0; if ((InBoard == 1) && (Wait == 0)) // If it is Human User's turn ProcessTurn(Xspot, Yspot); return true; } // Clears square of last draw public void ClearSpace(int WX, int WY, int MoveI, boolean Jump, boolean Move, double scale) { int adjust = 0; // Size of bottom oval int x[] = new int[9]; // x cooridante int y[] = new int[9]; // y coordinate int SpotX[] = new int[9]; // X spot on board int SpotY[] = new int[9]; // Y spot on board int SX = 0; // Temp X spot int SY = 0; // Temp Y spot int realX = 0; // adjusted x coordinate int realY = 0; // adjusted y coordinate int index = 0; // x & y index int Sindex = 0; // X & Y spot index int i, j; // Coounter int SFlag; // duplicate flag int MX = MovesX[MoveI]; // temp moves X int MY = MovesY[MoveI]; // temp moves Y int space = 0; // Adjust dimentions of piece int adj = BlockSize / 2; int adj2 = BlockSize / 4; int adj3 = 0; boolean OutOfBounds; WX = WX - adj2 - 5; WY = WY - adj2 - 5; if ((KingTest) && (!Jump)) { space = 5; adjust = (int)(BlockSize * 0.90); } else if (!Jump) { space = 3; adjust = (int)(BlockSize * 0.75); } else if (KingTest) adjust = (int)(BlockSize * 0.90 * scale); else adjust = (int)(BlockSize * 0.65 * scale); // Set initial x & y coordinates x[0] = WX; x[1] = WX + adjust; x[2] = WX; x[3] = WX + adjust; y[0] = WY; y[1] = WY; y[2] = WY + adjust; y[3] = WY + adjust; adj3 = adjust / 2; x[4] = WX + adj3; x[5] = WX; x[6] = WX + adj3; x[7] = WX + adj3; x[8] = WX + adjust; y[4] = WY + adj3; y[5] = WY + adj3; y[6] = WY; y[7] = WY + adjust; y[8] = WY + adj3; index = 9; // No off board and weed out duplicates for (i = 0; i < index; i++) { OutOfBounds = true; realX = x[i]; realY = y[i]; if (!Jump) { // Check for on board if (realX < 0) realX = 0; else if (realX > BlockSize * 7 + adj - space) realX = BlockSize * 7 + adj - space; if (realY < 0) realY = 0; else if (realY > BlockSize * 7 + adj - space) realY = BlockSize * 7 + adj - space; } SX = FindSpot(realX); SY = FindSpot(realY); if ((SX == 8) || (SY == 8)) OutOfBounds = false; // Check for duplicates SFlag = 0; if (i != 0) { for (j = 0; j < Sindex; j++) if ((SX == SpotX[j]) && (SY == SpotY[j])) SFlag = 1; } // if no duplicate add to list if ((SFlag == 0) && (OutOfBounds)) { SpotX[Sindex] = SX; SpotY[Sindex] = SY; Sindex++; } } SFlag = 0; // draw squares and pieces for (i = 0; i < Sindex; i++) { SX = SpotX[i]; SY = SpotY[i]; // draw square DrawSquare(SX, SY, BlockSize, SquareColor(SX, SY), true); // draw outline (if any) if ((Jump) || (Move)){ for (j = 0;j < MoveCount;j++) if ((SX == MovesX[j]) && (SY == MovesY[j])) DrawSquare(SX, SY, BlockSize-1, Color.white, false); } // draw piece (if any) if (BoardInfo[SX][SY] != 100) if ((SX == MX) && (SY == MY) && (Move)) SFlag = 1; else if (Move) Piece(SX, SY, ColorPiece(SX, SY), IsKing(SX, SY), false, 1.0); else if (!((SX == MovesX[MoveI+1]) && (SY == MovesY[MoveI+1]))) Piece(SX, SY, ColorPiece(SX, SY), IsKing(SX, SY), false, 1.0); } // draw shade of start piece if (SFlag == 1) Piece(MX, MY, Color.black, KingTest, false, 1.0); } // Draw Piece on move of mouse public void DrawPiece() { Piece(FWhereX, FWhereY, ColorPiece(MovesX[0], MovesY[0]), IsKing(MovesX[0], MovesY[0]), true, 1.0); WhereX = FWhereX; WhereY = FWhereY; } // To handle the piece move or jump (visually) public boolean mouseMove(Event evt, int x, int y) { if (MouseMove){ if (!WhereFlag) { WhereX = MovesX[0] * BlockSize + BlockSize / 2; WhereY = MovesY[0] * BlockSize + BlockSize / 2; KingTest = TestKing(MovesX[0], MovesY[0]); } FWhereX = x; FWhereY = y; TypeOfUpdate = 11; repaint(); } return true; } // Check to see if it is time update status info public boolean CheckEvent() { if (UpDateLabel == 1) return true; else return false; } // What to set the Status Labesl to public void GetLabelInfo(String Info[]){ int i; // Counter String JumpMove; // String of Move or Jump UpDateLabel = 0; // Set UpdateLabel to false if (PlayerTurn == 0) Info[0] = "Purple"; else Info[0] = "Blue"; Info[1] = "" + PiecesPlayer1; Info[2] = "" + PiecesPlayer2; if (MoveJump == 0) JumpMove = " Move "; else JumpMove = " Jump "; for (i = 0; i < 7; i++) if (i >= (MoveCountHolder - 1)) Info[i+3] = ""; else Info[i+3] = JumpMove + "(" + MovesX[i] + "," + MovesY[i] + ")" + " to " + "(" + MovesX[i+1] + "," + MovesY[i+1] + ")"; } // Finds the computers pieces on the board public int FindPieces(int FoundPiecesX[], int FoundPiecesY[]) { int i, j; // Counter int index = 0; // Number of index items of FoundPieces for (i = 0; i < 8; i++) for (j = 0; j < 8; j++) { if (BoardInfo[j][i] < 2) { FoundPiecesX[index] = j; FoundPiecesY[index] = i; index++; } } return index; } // Checks if a piece can jump or move in to that spot public int OnBoard(int ToX[], int ToY[], int AtX, int AtY, int size) { int TempX; // A temp for a X coordinate int TempY; // A temp for a Y coordinate int ToIndex = 0; // Number of items in ToX & ToY if (BoardInfo[AtX][AtY] == 1) { // Extra moves a king can make TempX = AtX - size; TempY = AtY - size; if ((TempX > -1) && (TempY > -1)) { // Check if off board for an up & to left move ToX[ToIndex] = TempX; ToY[ToIndex] = TempY; ToIndex++; } TempX = AtX + size; TempY = AtY - size; if ((TempX < 8) && (TempY > -1)) { // Check if off board for an up & to right move ToX[ToIndex] = TempX; ToY[ToIndex] = TempY; ToIndex++; } } TempX = AtX + size; TempY = AtY + size; if ((TempX < 8) && (TempY < 8)) { // Check if off board for an down & to left move ToX[ToIndex] = TempX; ToY[ToIndex] = TempY; ToIndex++; } TempX = AtX - size; TempY = AtY + size; if ((TempX > -1) && (TempY < 8)){ // Check if off board for an down & to right move ToX[ToIndex] = TempX; ToY[ToIndex] = TempY; ToIndex++; } return ToIndex; } // Check for jump spot in list already public boolean InFHList(int x, int y) { int i=0; // Counter while (i != FH) if ((x == FindHold[i+1]) && (y == FindHold[i+2])) return false; else i = i + 3; return true; } // Finds possible jump paths public void FindPath(int x, int y, int D) { int NumValid; // Number of items in ToX & ToY int ToX[] = new int[4]; // Holds X coordinate of possible board possion to move to int ToY[] = new int[4]; // Holds Y coordinate of possible board possion to move to int TempX; // A temp for a X coordinate int TempY; // A temp for a Y coordinate int i; // Counter if (D != 4) { D = D + 1; NumValid = OnBoard(ToX, ToY, x, y, 2); // Check if in game area for (i = 0; i < NumValid; i++) { // Check all possible ways for a piece to jump TempX = ToX[i]; TempY = ToY[i]; // Check valid jump if ((BoardInfo[TempX][TempY] == 100) && (ValidJump(TempX, TempY, x, y)) && InFHList(TempX, TempY)) { FindHold[FH++] = D; FindHold[FH++] = TempX; FindHold[FH++] = TempY; FindPath(TempX, TempY, D); } } } } // Return true if human player will become king public boolean BeKing(int x, int y) { if (y != 0) return false; else if ((x == 1) && (BoardInfo[2][1] > 1) && (BoardInfo[3][0] == 100)) return true; else if ((x == 3) && (((BoardInfo[2][1] > 1) && (BoardInfo[1][0] == 100)) || ((BoardInfo[4][1] > 1) && (BoardInfo[5][0] == 100)))) return true; else if ((x == 5) && (((BoardInfo[4][1] > 1) && (BoardInfo[3][0] == 100)) || ((BoardInfo[6][1] > 1) && (BoardInfo[7][0] == 100)))) return true; else if ((x == 7) && (BoardInfo[5][0] == 100)) return true; else return false; } // Find and process jump public boolean FindJump(int FoundPiecesX[], int FoundPiecesY[], int index) { int Jumps[][] = new int[5][11]; // Array to Hold the jump possible int NJumps = 0; // Number of possible jumps in array int AtX; // The X board coordinate of At int AtY; // The Y board coordinate of At int TempX; // A temp for a X coordinate int TempY; // A temp for a Y coordinate int MaxRank = 0; // Max Number of pieces to be jumped int CalRank; // Holds the Rank of the jump that is calculated int i, j, k; // Counter int D = 0; // Dimension of jumps int JumpFlag = 0; // Jump Flag to get out of random jump while loop int RanJump = 0; // Possion in list of jumps array int Index; // Index possion in jump path choosen int JumpKing; // Flag for if computer is jumping a king int JX[][] = new int[3][20]; // The X coordinate list when getting the info from FindPath int JY[][] = new int[3][20]; // The Y coordinate list when getting the info from FindPath int Jindex[] = new int[20]; // Number of items in JX and JY for first dimention of array int XYindex; // A temp for Jindex int Mindex; // Master index for number of items in JX and JY for first // dimention of array int KingX; int KingY; System.out.println("---- Start New FindJump ----"); for (i = 0; i < index; i++) { // Find possible jumps AtX = FoundPiecesX[i]; AtY = FoundPiecesY[i]; MovesX[0] = AtX; MovesY[0] = AtY; FH = 0; FindPath(AtX, AtY, 0); // Find possible path for 'At' piece to jump // Setup j = 0; Mindex = -1; if (j != FH) { Mindex = 0; for (k = 0; k < 20; k++) Jindex[k] = 0; } while (j != FH) { // Get results from FindPath D = FindHold[j++]; TempX = FindHold[j++]; TempY = FindHold[j++]; if (D == 1) { XYindex = Jindex[Mindex]; if (XYindex > 0) Mindex++; Jindex[Mindex]++; JX[0][Mindex] = TempX; JY[0][Mindex] = TempY; } else if (D == 2) { XYindex = Jindex[Mindex]; if (XYindex > 1) { Mindex++; JX[0][Mindex] = JX[0][Mindex-1]; JY[0][Mindex] = JY[0][Mindex-1]; Jindex[Mindex]++; } Jindex[Mindex]++; JX[1][Mindex] = TempX; JY[1][Mindex] = TempY; } else if (D == 3) { XYindex = Jindex[Mindex]; if (XYindex > 1) { Mindex++; JX[0][Mindex] = JX[0][Mindex-1]; JY[0][Mindex] = JY[0][Mindex-1]; JX[1][Mindex] = JX[1][Mindex-1]; JY[1][Mindex] = JY[1][Mindex-1]; Jindex[Mindex] = 2; } Jindex[Mindex]++; JX[2][Mindex] = TempX; JY[2][Mindex] = TempY; } } if (Mindex != -1) { // Add paths (if found) to path list Mindex++; for (k = 0; k < Mindex; k++) { Jumps[NJumps][0] = 0; JumpKing = 0; XYindex = Jindex[k]; System.out.println("FindJump (Add) NJumps=" + NJumps + " XYindex=" + XYindex + " AtX=" + AtX + " AtY=" + AtY); if (XYindex >= 1) { TempX = JX[0][k]; TempY = JY[0][k]; Jumps[NJumps][5] = TempX; Jumps[NJumps][6] = TempY; KingX = (AtX - TempX) / -2 + AtX; KingY = (AtY - TempY) / -2 + AtY; if (IsKing(KingX, KingY)) JumpKing = 1; System.out.println(" -- X1=" + TempX + " Y1=" + TempY); } if (XYindex >= 2) { TempX = JX[1][k]; TempY = JY[1][k]; Jumps[NJumps][7] = TempX; Jumps[NJumps][8] = TempY; KingX = (Jumps[NJumps][5] - TempX) / -2 + Jumps[NJumps][5]; KingY = (Jumps[NJumps][6] - TempY) / -2 + Jumps[NJumps][6]; if (IsKing(KingX, KingY)) JumpKing = 1; System.out.println(" -- X2=" + TempX + " Y2=" + TempY); } if (XYindex == 3) { TempX = JX[2][k]; TempY = JY[2][k]; Jumps[NJumps][9] = TempX; Jumps[NJumps][10] = TempY; KingX = (Jumps[NJumps][7] - TempX) / -2 + Jumps[NJumps][7]; KingY = (Jumps[NJumps][8] - TempY) / -2 + Jumps[NJumps][8]; if (IsKing(KingX, KingY)) JumpKing = 1; System.out.println(" -- X3=" + TempX + " Y3=" + TempY); } CalRank = XYindex; if (IsKing(AtX, AtY)) // If king is used to jump CalRank = CalRank + 2; if (BeKing(AtX, AtY)) CalRank = CalRank + 3; if (JumpKing == 1) // If you are jumping a king CalRank = CalRank + 4; Jumps[NJumps][1] = CalRank; Jumps[NJumps][2] = XYindex; // Add path information to array Jumps[NJumps][3] = AtX; Jumps[NJumps][4] = AtY; if (CalRank > MaxRank) MaxRank = CalRank; System.out.println(" -- Rank=" + CalRank + " MaxRank=" + MaxRank); NJumps++; } } } if (MaxRank == 0) return false; else { for (i = 0; i < NJumps; i++) { if (MaxRank != Jumps[i][1]) {// Remove all non-MaxRanks Jumps[i][0] = 2; System.out.println("FindJump (Out) i=" + i + " Rank=" + Jumps[i][1] + " AtX=" + Jumps[i][3] + " AtY=" + Jumps[i][4] + " X1=" + Jumps[i][5] + " Y1=" + Jumps[i][6]); } else System.out.println("FindJump (Keep) i=" + i + " Rank=" + Jumps[i][1] + " AtX=" + Jumps[i][3] + " AtY=" + Jumps[i][4] + " X1=" + Jumps[i][5] + " Y1=" + Jumps[i][6]); } while (JumpFlag == 0) { RanJump = (int)Math.floor(Math.random() * NJumps); // Random choose if (Jumps[RanJump][0] != 2) JumpFlag = 1; } j = 0; TempX = Jumps[RanJump][3]; TempY = Jumps[RanJump][4]; ProcessTurn(TempX, TempY); // Choose piece to jump while (j != Jumps[RanJump][2]) { Index = 2 * j + 5; TempX = Jumps[RanJump][Index]; TempY = Jumps[RanJump][Index+1]; System.out.println("FindJump (use) Index=" + Index + " MaxRank=" + MaxRank + " TempX=" + TempX + " TempY=" + TempY); ProcessTurn(TempX, TempY); j++; } ProcessTurn(TempX, TempY); return true; } } // Returns true if it is a valid square on the board public boolean ValidSquare(int x, int y) { if ((x > -1) && (x < 8) && (y > -1) && (y < 8)) return true; else return false; } // Calculate Risk for direction x & y public int CalRisk(int x, int y, int DirX, int DirY, boolean King) { int BackX = x - DirX; // Opposite direction X int BackY = y - DirY; // Opposite direction Y int ForX = x + DirX; // Forward direction X int ForY = y + DirY; // Forward direction Y int PieceType = 0; // Temp Piece Type Holder int Risk = 0; // Risk factor int TempRisk1 = 0; // Temp risk factor int TempRisk2 = 0; int TempRisk3 = 0; int TempRisk4 = 0; int X[] = new int[6]; // X table for jump back test int Y[] = new int[6]; // Y table for jump back test int PT[] = new int[3]; // Type of Piece for jump back test int i; // Counter // Check for valid square in forward direction of checker if (ValidSquare(ForX, ForY) && ValidSquare(BackX, BackY)) // Check for blank in opposite direction of computer checker if (BoardInfo[BackX][BackY] == 100) { // Check for blank in forward direction possition if (BoardInfo[ForX][ForY] == 100) { // Check for over single piece jump in all directions except where // jumper will end up if ((DirX != 1) && (DirY != 1) && ValidSquare(x - 2, y - 2) && ValidSquare(x - 3, y - 3)) if ((BoardInfo[x - 2][y - 2] < 2) && (BoardInfo[x - 3][y - 3] > 2)) TempRisk1 = CalRisk(x - 2, y - 2, DirX, DirY, true); if ((DirX != -1) && (DirY != -1) && ValidSquare(x + 2, y + 2) && ValidSquare(x + 3, y + 3)) if ((BoardInfo[x + 2][y + 2] < 2) && (BoardInfo[x + 3][y + 3] > 1)) TempRisk2 = CalRisk(x + 2, y + 2, DirX, DirY, false); if ((DirX != -1) && (DirY != 1) && ValidSquare(x + 2, y - 2) && ValidSquare(x + 3, y - 3)) if ((BoardInfo[x + 2][y - 2] < 2) && (BoardInfo[x + 3][y - 3] > 2)) TempRisk3 = CalRisk(x + 2, y - 2, DirX, DirY, true); if ((DirX != 1) && (DirY != -1) && ValidSquare(x - 2, y + 2) && ValidSquare(x - 3, y + 3)) if ((BoardInfo[x - 2][y + 2] < 2) && (BoardInfo[x - 3][y + 3] > 1)) TempRisk4 = CalRisk(x - 2, y + 2, DirX, DirY, false); // Set risk to 2 if humnan can double jump if ((Math.abs(TempRisk1) == 1) || (Math.abs(TempRisk2) == 1) || (Math.abs(TempRisk3) == 1) || (Math.abs(TempRisk4) == 1)) Risk = 2; // Set risk to risk found in direction + 2 for more than double jump // Also keep highest directional risk if (TempRisk1 > 1) Risk = TempRisk1 + 2; if ((TempRisk2 > 1) && (Risk < (TempRisk2 + 2))) Risk = TempRisk2 + 2; if ((TempRisk3 > 1) && (Risk < (TempRisk3 + 2))) Risk = TempRisk3 + 2; if ((TempRisk4 > 1) && (Risk < (TempRisk4 + 2))) Risk = TempRisk4 + 2; return Risk; } // Check for Human piece in forward possition else if ((BoardInfo[ForX][ForY] == 3) || ((BoardInfo[ForX][ForY] == 2) && (!King))) { PieceType = BoardInfo[x][y]; BoardInfo[x][y] = 100; BoardInfo[BackX][BackY] = BoardInfo[ForX][ForY]; Risk = 1; if ((DirX == 1) && (DirY == 1)) { X[0] = X[2] = X[4] = x - 2; X[1] = X[3] = X[5] = x; Y[0] = Y[1] = Y[5] = y - 2; Y[2] = Y[3] = Y[4] = y; PT[0] = PT[2] = 1; PT[1] = 0; } else if ((DirX == -1) && (DirY == -1)) { X[0] = X[2] = X[4] = x + 2; X[1] = X[3] = X[5] = x; Y[0] = Y[1] = Y[5] = y + 2; Y[2] = Y[3] = Y[4] = y; PT[0] = PT[2] = 0; PT[1] = 1; } else if ((DirX == 1) && (DirY == -1)) { X[0] = X[1] = X[5] = x - 2; X[2] = X[3] = X[4] = x; Y[0] = Y[2] = Y[4] = y + 2; Y[1] = Y[3] = Y[5] = y; PT[0] = PT[1] = 0; PT[2] = 1; } else { X[0] = X[1] = X[5] = x + 2; X[2] = X[3] = X[4] = x; Y[0] = Y[2] = Y[4] = y - 2; Y[1] = Y[3] = Y[5] = y; PT[0] = PT[1] = 1; PT[2] = 0; } // Check for back jump in all directions except in DirX & DirY direction for (i = 0; i < 3; i++) if (ValidSquare(X[i], Y[i]) && ValidSquare(X[i+3], Y[i+3])) if ((BoardInfo[X[i]][Y[i]] <= PT[i]) && (BoardInfo[X[i+3]][Y[i+3]] == 100)) Risk = -1; BoardInfo[x][y] = PieceType; BoardInfo[BackX][BackY] = 100; return Risk; } } return 0; } // Get final risk based on all directions public int GetRisk(int x, int y) { int TempR1 = 0; // Temp risk factor int TempR2 = 0; int TempR3 = 0; int TempR4 = 0; int Risk; // Final risk int TempHigh; // High risk // Find all directional risk for piece x & y and send back highest risk TempR1 = CalRisk(x, y, 1, 1, false); TempR2 = CalRisk(x, y, -1, -1, true); if (TempR2 > TempR1) TempHigh = TempR2; else TempHigh = TempR1; TempR3 = CalRisk(x, y, -1, 1, false); if (TempR3 > TempHigh) TempHigh = TempR3; TempR4 = CalRisk(x, y, 1, -1, true); if (TempR4 > TempHigh) TempHigh = TempR4; if (TempHigh >= 2) Risk = TempHigh; else if ((TempR1 == 1) || (TempR2 == 1) || (TempR3 == 1) || (TempR4 == 1)) Risk = 1; else if ((TempR1 == -1) || (TempR2 == -1) || (TempR3 == -1) || (TempR4 == -1)) Risk = -1; else Risk = 0; return Risk; } // Find and process move public void FindMove(int FoundPiecesX[], int FoundPiecesY[], int index) { int AMove[][] = new int[24][5]; // Holds possible moves int MoveIndex = 0; // Number of items in AMove int AtX = 0; // The X board coordinate of At int AtY = 0; // The Y board coordinate of At int TempX = 0; // A temp for a X coordinate int TempY = 0; // A temp for a Y coordinate int ToIndex; // Number of items in ToX & ToY int ToX[] = new int[4]; // Holds X coordinate of possible board possion to move to int ToY[] = new int[4]; // Holds Y coordinate of possible board possion to move to int ToMove = 0; // Random index of AMove int i, j; // Counter int Risk = 0; // Risk factor int MaxRisk = -3; // Max Risk found int MoveFlag = 0; // Move Flag int PieceType = 0; // Type of Peice int DirRisk = 0; // Directional risk factor int TempRisk = 0; // Temp risk factor int DirX = 0; // X direction int DirY = 0; // Y direction boolean King; // If needs to be king int KingCount = 0; // Kings checked int KingLow = 100; // Closest King to move int KingVec = 0; // How close a king is int WedgeCount = 12; // Wedge counter int DoubleRisk = 0; // Double jump risk after move System.out.println("---- Start New FindMove ----"); for (i = 0; i < index; i++) { // Find possible moves AtX = FoundPiecesX[i]; AtY = FoundPiecesY[i]; ToIndex = OnBoard(ToX, ToY, AtX, AtY, 1); // Check if in game area Risk = GetRisk(AtX, AtY); // Find Risk System.out.println("FindMove (before) AtX=" + AtX + " AtY=" + AtY + " Risk=" + Risk); MovesX[0] = AtX; MovesY[0] = AtY; for (j = 0; j < ToIndex; j++) { TempX = ToX[j]; TempY = ToY[j]; if ((BoardInfo[TempX][TempY] == 100) && (ValidMove(TempX, TempY))) { // Check if moves are valid for 'At' piece AMove[MoveIndex][0] = Risk; AMove[MoveIndex][1] = AtX; AMove[MoveIndex][2] = AtY; AMove[MoveIndex][3] = TempX; AMove[MoveIndex][4] = TempY; MoveIndex++; } } } // Check after move Risk for (i = 0; i < MoveIndex; i++) { TempRisk = AMove[i][0]; AtX = AMove[i][1]; AtY = AMove[i][2]; TempX = AMove[i][3]; TempY = AMove[i][4]; PieceType = BoardInfo[AtX][AtY]; BoardInfo[AtX][AtY] = 100; BoardInfo[TempX][TempY] = PieceType; DoubleRisk = 0; Risk = GetRisk(TempX, TempY); // If jump back risk check for human double jump if (Risk == -1) { // Set up for test of directional risk DirX = TempX - AtX; if (DirX == 0) DirX = -1; DirY = TempY - AtY; if (DirY == 0) DirY = -1; if (((DirX == 1) && (DirY == 1)) || ((DirX == -1) && (DirY == 1))) King = true; else King = false; DoubleRisk = CalRisk(AtX - DirX*2, AtY - DirY*2, DirX, DirY, King); } BoardInfo[AtX][AtY] = PieceType; BoardInfo[TempX][TempY] = 100; // If move will make double risk if ((TempRisk == 0) && (Risk == -1) && (DoubleRisk >= 2)) AMove[i][0] = -2; // No before move risk, but there is after move risk else if ((TempRisk == 0) && (Risk != 0)) AMove[i][0] = -2; // Yes before move risk, but no after move risk else if ((TempRisk == 1) && (Risk == 0)) AMove[i][0] = 24; // Yes before move risk and yes on after move risk else if ((TempRisk == 1) && (Risk != 0)) AMove[i][0] = -2; // If more than single jump risk else if (TempRisk >= 2) { // Set up for test of directional risk DirX = TempX - AtX; if (DirX == 0) DirX = -1; DirY = TempY - AtY; if (DirY == 0) DirY = -1; if (((DirX == 1) && (DirY == 1)) || ((DirX == -1) && (DirY == 1))) King = true; else King = false; DirRisk = CalRisk(AtX, AtY, DirX, DirY, King); // If direction is the direction that the risk is coming from and after // move risk is less than to risk before if ((TempRisk == DirRisk) && (Risk < TempRisk)) { // Set risk based on where this piece is in the jump order if (TempRisk == 2) AMove[i][0] = 28; else if (TempRisk == 4) AMove[i][0] = 27; else if (TempRisk == 6) AMove[i][0] = 26; else AMove[i][0] = 25; } // If not direction where risk is coming from and after move has no risk else if ((TempRisk != DirRisk) && (Risk == 0)) AMove[i][0] = 24; } System.out.println("FindMove (after) AtX=" + AtX + " AtY=" + AtY + " ToX=" + TempX + " ToY=" + TempY + " BRisk=" + TempRisk + " ARisk=" + AMove[i][0]); } // Check other possible moves for (i = 0; i < MoveIndex; i++) { TempX = AMove[i][3]; TempY = AMove[i][4]; PieceType = BoardInfo[AMove[i][1]][AMove[i][2]]; // Last to move if ((AMove[i][0] == 0) && (TempY == 0) && ((TempX == 1) || (TempX == 3))) AMove[i][0] = -3; // Check if be king if ((AMove[i][0] == 0) && (TempY == 7) && (PieceType == 0)) AMove[i][0] = 23; // Check chase with king (give 40% chance of moving) if ((AMove[i][0] == 0) && (PieceType == 1)) { KingVec = Math.abs(LastX - TempX) + Math.abs(LastY - TempY); if ((KingVec <= KingLow) && ((int)Math.floor(Math.random() * 2) == 1)) { KingLow = KingVec; AMove[i][0] = 13 + KingCount++; } } // Wedge move if ((AMove[i][0] == 0) && (TempX != 0) && (TempX != 7)) AMove[i][0] = WedgeCount--; // If side move if ((AMove[i][0] == 0) && ((TempX == 0) || (TempX == 7))) AMove[i][0] = 1; System.out.println("FindMove (poss) AtX=" + AMove[i][1] + " AtY=" + AMove[i][2] + " ToX=" + AMove[i][3] + " ToY=" + AMove[i][4] + " Risk=" + AMove[i][0]); } if (MoveIndex == 0) // Test for no move possible Pass(); else { for (i = 0; i < MoveIndex; i++) if (MaxRisk < AMove[i][0]) // Find MaxRank MaxRisk = AMove[i][0]; while (MoveFlag == 0) { ToMove = (int)Math.floor(Math.random() * MoveIndex); // Random choose if (AMove[ToMove][0] == MaxRisk) MoveFlag = 1; } System.out.println("FindMove (use) AtX=" + AMove[ToMove][1] + " AtY=" + AMove[ToMove][2] + " ToX=" + AMove[ToMove][3] + " ToY=" + AMove[ToMove][4] + " Risk=" + AMove[ToMove][0]); ProcessTurn(AMove[ToMove][1], AMove[ToMove][2]); // Choose piece to move ProcessTurn(AMove[ToMove][3], AMove[ToMove][4]); // Place to move to } } // Preforms computer's turn public void ComputerTurn() { int[] FoundPiecesX = new int[12]; // X possion for piece int[] FoundPiecesY = new int[12]; // X possion for piece int index; // Number of pieces found index = FindPieces(FoundPiecesX, FoundPiecesY); // Find pieces left on board // for computer player if (FindJump(FoundPiecesX, FoundPiecesY, index) == false) // Check if jump found FindMove(FoundPiecesX, FoundPiecesY, index); } // Do computers Turn public boolean CallCumputerTurn() { CheckWinner(); // Check if a player won // If One player && Computer's Turn if ((Winner == 0) && (NumPlayer == 1) && (PlayerTurn == 0) && (Wait == 0)) { Wait = 1; ComputerTurn(); return true; } else return false; } public void CheckWinner() { // Check to see if a player won if (PiecesPlayer1 == 0) { // Player 1 Won TypeOfUpdate = 6; TheWinner = "Blue Player"; Winner = 1; repaint(); } else if (PiecesPlayer2 == 0) { // Player 2 Won TypeOfUpdate = 6; TheWinner = "Purple Player"; Winner = 1; repaint(); } } public void Pass() { // Player or Computer passes on this turn UpDateLabel = 1; MoveCountHolder = 1; if (PlayerTurn == 0) // Change player turn PlayerTurn = 1; else PlayerTurn = 0; if (MoveCount != 0) { Xpass = MovesX[0]; // Reset Turn or if to many MoveCount choices Ypass = MovesY[0]; JumpedCount = 0; SetJump = 0; TypeOfUpdate = 3; repaint(); } } }