Sei sulla pagina 1di 13

PROJECT REPORT Project Title:Brainvita Game Group Members: Ishaan Jain: ID:RM2010030 SAP:60004100030 Saurabh Ghadi ID:RM2010025 SAP:60004100025

PLATFORM USED:JAVA

SYNOPSIS Peg solitaire is a board game for one player involving movement of pegs on a boa rd with holes. Some sets use marbles in a board with indentations. There are two traditional boards, graphically depicted as follows ('.' as an initial peg, 'o' as an initial hole). A valid move is to jump a peg orthogonally over an adjacen t peg into a hole two positions away and then to remove the jumped peg.I t is ve ry easy to go wrong and find you have two or three widely spaced lone pegs. Many people never manage to solve the problem.The goal is to remove pegs from the bo ard by jumping over each peg with another peg; this removes the "jumped" peg (si milar to Checkers jumps)The rules for the game are as follows: 1. Click and drag with the mouse to move a peg. You have to eliminate as ma ny marbles as possible. 2. Only horizontal and vertical jumps are allowed. 3. The game is over when no more jumps are possible. 4. Your score is the number of marbles remaining after the game is over. 5. You win the game by removing all the pegs except one from the board. A perfect game would leave one peg in the center position. For Reverse Peg Solitaire, the goal is to add pegs to the board, creating the se lected peg pattern. Jumping over an empty hole produces a peg in that hole. The game is over when enough pegs have been created to produce the selected pattern. Description 1)Summary: In this project we have implemented the game of Brainvita. 2) Implementation & Approach We decided to use the Java programming language to implement our project, in ord er to leverage Object Oriented programming. Consequently, most of our code is ob ject centric. 3)Notation A decision central to our implementation was what notation to use. We chose to g o with the notation used by Chinook. In the Chinook notation, each hole on the g rid is assigned a number between 0 and 1.

4)Description of various Data Structures: int deadballs:This gives us the number of balls/pegs on the grid that have been jumped over and have therefore become dead. The initial value for deadballs is 0 because every location on the grid is initialized to 1 which indicates the exi stence of pegs on the grid. Boolean instructions:This variable holds true if the user specifies a wish to v iew the game instructions ,otherwise it holds false. Boolean gameend:This holds true it the game has ended and if not then it holds false. int solution[][]:A two dimensional array which explores various possible solutio ns. int board[]:An single dimensional integer array of size 49 is created initial ly and though it is single dimensional we imagine it to be a two dimensional arr ay of size seven by seven for the sake of convenience.Every block in this array is initialized to 1 initially except for the locations 0,1,5,6,7,8,12,13,35,36,4 0,41,42,43,47,48 on the array which are initialized to -1.A Boolean 1 indicated that a peg exists at a specified location on the grid whereas a 0 indicates its absence. Hence the initial grid configuration looks like this: -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1

1 1 1

The following buttons are incorporated into the game initially: public Button bsol=new Button("DEMO");//This gives the user an option to view a demo of the game. public Button inst=new Button("INSTRUCTIONS");//When a user clicks on this butto n the various instructions will be displayed. public Button back=new Button("BACK");//This helps the user to go back. public Button undo=new Button("UNDO");//This allows the user to undo his previou s move. List of methods used: public void init():This method initializes the applet.It creates memory for an a rray of type integer called board.It calls the fillboard() method to initialize it. public void addComp(Button b,int x,int y,int w,int h,boolean vis): This method is used to add components/buttons and integrate them into the existi ng interface. It calls add(b) function to add the specific component and using t he reference of the required button it calls the addActionListener(this) functi on to achieve the desired task of adding a button.Here this indicates the referenc e of the calling object. public void actionPerformed(ActionEvent ae):The parameter for actionPerformed() is a reference to an ActionEvent object, a subclass of AWTEvent. When a button i s clicked,actionPerformed() is called with a new ActionEvent parameter.For insta nce if the instructions button is clicked then the action event parameter would correspond to the variable instruction.Since the performed action corresponds to the clicking of the instructions button the visibility of other buttons like re start,undo,instructions will be set to false and the visibility of the button to go back will be set to true and variable instructions will be initialized to true.S imilarly if ae.getSource() corresponds to undo then the variable gameend will be set to false and the user will be allowed to undo his/her move. public void undoMove():This method pops the values of the previous move from the stack so that it can undo the current move. public void fixDisc(Graphics g,int x,int y,int r,Color c):This draws a disc at t he specified coordinates and fills it with the specified color.

public void boardBall(Graphics g,int x, int y):This routine draws a ball on the board at the specified position. public void boardHole(Graphics g,int x,int y): This function draws an empty spac e at the specified location.Note :an empty space is indicated by color black. public void deadBall(Graphics g,int x,int y):Whenever a peg has been jumped ove r ,it is removed from the grid.Now in order to display the removed peg we use th e above method which basically displays the killed peg at the specified location . public void displayinst(Graphics g):This method displays various instructions. public boolean gameover():This checks if the game is over or not and accordingly returns a Boolean value.A Boolean true indicates game over whereas a false indi cates vice versa.This function basically checks if two adjacent locations are h olding a Boolean 1 at the same time.If yes,it returns false.To implement this it uses two for loops.If any of the conditions specified within the body of the l oop is satisfied it returns a false. At the end after having checked all the co nditions,it returns a true.Note:this happens only when none of the conditions we re satisfied i.e no two pegs were placed adjacently or were holding a boolean 1 at the same time. Eventually the game terminates in such a case. public void paint(Graphics g): This paint function is used to display various components of the game. Any bac kground color can be used. In this game the color magenta has been used and the corresponding function used is g.setColor(Color.magenta).Now in case the user h as not clicked on the button instructions i.e. . variable instructions is set t o false ,then in that case the method just displays the contents of the board ot herwise it displays the instructions first. If the game is over (indicated by va riable gameend), then it not only displays the pegs in their appropriate positi ons on the board but it also displays the eliminated balls outside the board. Fo r this it checks whether the corresponding position on the board is holding a 1 or 0. public void displaysol() This subroutine creates a new thread to find the list of all optimal solutions. public void run() A thread run function to calculate all the optimal solutions. public boolean mouseDrag(Event e,int x,int y): This function performs a specific action when the mouse is dragged. It first che cks whether the mouse was dragged along the Y axis i.e. vertically.If yes, then it checks whether the mouse was dragged up or down .It then checks whether th e ball jump that the user is trying to enforce is a valid one or not.After havin g checked these conditions ,if the ball jump is valid indeed then it performs t he required event and changes the values of the variables dragX and dragY accord ingly.If the first condition fails then it checks whether the mouse was dragged along the x axis.If yes, then it checks whether it was dragged to the left or t o the right.For both the cases it checks whether the ball jump is valid or not.I f its valid then it performs the required event.If none of the above conditions satisfy then it returns a Boolean false to the caller indicating that a drag ope ration cannot be performed as it is invalid. This may happen in the following tw o cases: The user tries to perform a drag operation along the diagonal The user tries to drag the mouse over an empty hole. The user tries to move the peg over a preoccupied hole holding Boolean 1(i.e. a peg). public boolean mouseUp(Event e,int x,int y): This function performs a task when the mouse is released.It first checks whether the mouse was dragged to a valid position.If yes then it performs the ball jump operation and initializes the corresponding location in the board to 1 in order to fill that hole with a peg.It removes the jumped over peg and reinitializes i ts location to 0 to indicate the creation of an empty hole. It then makes a cal l to gameover() function and if it returns a true then it initializes gameend to true.It enables variable undo by setting it to true.It also increases the var iable deadballs by 1 as a ball has been eliminated. It finally pushes the value

s of pick X,pickY,dragX,dragY onto the stack so that it can implement the undo o peration. If the ball jump was not valid in the first place then it skips the ab ove mentioned operations and instead returns a boolean false to the caller. public boolean mouseDown(Event e,int x,int y): This performs a specified action when the mouse is pressed down. It calculates the X and Y index of the corresponding positions on the board.If it is a valid p osition i.e. it lies within the two dimensional grid then it initializes pointX to x,pointY to y,pickX to y index of the specified position and pickY to x inde x respectively. At the end if it is unable to perform the required action becaus e the position on the board was not valid then it returns a false.

Source import import import import

Code: java.awt.*; java.awt.event.*; java.applet.*; java.util.*;

//<applet code="Brainvita" width=300 height=300> //</applet> public class Brainvita extends Applet implements ActionListener,Runnable { int pickX=-1,pickY=-1,pointX=-1,pointY=-1,dragX=-1,dragY=-1; public int board[]; public int i,j,k,deadBalls; public Button restart=new Button("RESTART"); public Button bsol=new Button("DEMO"); public Button inst=new Button("INSTRUCTIONS"); public Button back=new Button("BACK"); public Button undo=new Button("UNDO"); boolean instructions; public boolean gameend; final int UP=1,RIGHT=2,DOWN=3,LEFT=4; public int solution[][]={ {3,5,1},{1,4,2},{3,3,3},{3,6,1},{2,6,1},{3,4,4},{5,4,4},{4,6,1}, {3,4,2},{0,4,2},{2,3,3},{0,3,2},{2,2,3},{2,5,1},{0,2,2},{6,4,4}, {4,3,3},{6,3,4},{4,2,3},{4,5,1},{6,2,4},{3,2,2},{4,0,3},{4,3,1}, {2,0,2},{4,0,3},{5,2,4},{3,1,3},{3,3,4},{2,1,3},{1,3,2}}; Thread t=null; int count; Stack u=new Stack(); Integer o=new Integer(0);

//INITIALISATION OF THE APPLET public void init() { setLayout(null); resize(465,300); board=new int[49]; t=new Thread(this); fillBoard(); addComp(restart,280,136,100,50,true); addComp(bsol,280,73,100,50,true); addComp(inst,280,10,100,50,true); addComp(back,280,199,100,50,false); addComp(undo,280,199,100,50,true); repaint(); } //ADD A BUTTON public void addComp(Button b,int x,int y,int w,int h,boolean vis) { b.setBounds(x,y,w,h); b.setVisible(vis); add(b); b.addActionListener(this); } //INITIALISE THE BOARD public void fillBoard() { for(i=0;i<49;i++) board[i]=1; for(i=0;i<2;i++) for(j=0;j<2;j++) { board[i*7+j]=-1; board[i*7+j+5]=-1; board[i*7+j+35]=-1; board[i*7+j+40]=-1; } board[24]=0; undo.setEnabled(false); bsol.setEnabled(true); gameend=false; instructions=false; deadBalls=0; } public void actionPerformed(ActionEvent ae) { if(ae.getSource()==restart) { u=new Stack(); if(t.isAlive()) t.stop(); fillBoard(); repaint(); } if(ae.getSource()==bsol) {

bsol.setEnabled(false); undo.setEnabled(false); displaysol(); } if(ae.getSource()==inst) { restart.setVisible(false); bsol.setVisible(false); inst.setVisible(false); back.setVisible(true); undo.setVisible(false); instructions=true; repaint(); } if(ae.getSource()==back) { restart.setVisible(true); bsol.setVisible(true); inst.setVisible(true); back.setVisible(false); undo.setVisible(true); instructions=false; repaint(); } if(ae.getSource()==undo) { gameend=false; undoMove(); repaint(); } } //POP THE VALUES OF THE PREVIOUS MOVE FROM THE STACK AND UNDO THIS MOVE public void undoMove() { o=(Integer)u.pop(); pickY=o.intValue(); o=(Integer)u.pop(); pickX=o.intValue(); o=(Integer)u.pop(); dragY=o.intValue(); o=(Integer)u.pop(); dragX=o.intValue(); board[pickY*7+pickX]=0; board[dragY*7+dragX]=1; board[((pickY+dragY)/2)*7+(pickX+dragX)/2]=1; deadBalls--; if(u.empty()) { undo.setEnabled(false); bsol.setEnabled(true); } } public void fixBox(Graphics g,int x,int y,int w,int h,Color c) { g.setColor(c);

g.fillRect(x,y,w,h); } public void fixDisc(Graphics g,int x,int y,int r,Color c) { g.setColor(c); g.fillOval(x,y,r,r); } public void fixCircle(Graphics g,int x,int y,int r,Color c) { g.setColor(c); g.drawOval(x,y,r,r); } //DRAW A BALL ON THE BOARD AT THE SPECIFIED LOCATION public void boardBall(Graphics g,int x, int y) { g.setColor(Color.white); g.fillRect(x,y,16,16); fixDisc(g,x+1,y+1,15,Color.black); fixDisc(g,x,y,14,Color.green); } //DRAW AN EMPTY SPACE AT THE SPECIFIED LOCATION public void boardHole(Graphics g,int x,int y) { g.setColor(Color.white); g.fillRect(x,y,16,16); fixDisc(g,x,y,14,Color.black); } //DRAW A BALL THAT HAS BEEN REMOVED public void deadBall(Graphics g,int x,int y) { fixDisc(g,x+1,y+1,15,Color.black); fixDisc(g,x,y,14,Color.cyan); } //PERFORN THE ACTION WHEN THE MOUSE IS PRESSED DOWN public boolean mouseDown(Event e,int x,int y) { pointX=-1; pointY=-1; pickX=-1; pickY=-1; dragX=-1; dragY=-1; //CALCULATE THE X AND Y INDEX OF THE POSITION ON THE BOARD i=(y-34)/17; j=(x-34)/17; //IF IT IS A VALID POSITION if((i>-1) && (i<7) && (j>-1) && (j<7)) { pointX=x; pointY=y; pickX=j; pickY=i;

} return false; } //PERFORM THE ACTION WHEN THE MOUSE IS DRAGGED public boolean mouseDrag(Event e,int x,int y) { //IF MOUSE IS DRAGGED ALONG THE Y-AXIS if((x<pointX+8) && (x>pointX-8)) { //IF MOUSE IS DRAGGED UP if((pickY>1) && (y<pointY-14)) { //IF BALL JUMP IS VALID if((board[pickY*7+pickX-7]==1) && (board[pickY*7 +pickX-14]==0)) { dragX=pickX; dragY=pickY-2; } } //IF MOUSE IS DRAGGED DOWN else if((pickY<5) && (y>pointY+14)) { //IF BALL JUMP IS VALID if((board[pickY*7+pickX+7]==1) && (board[pickY*7 +pickX+14]==0)) { dragX=pickX; dragY=pickY+2; } } } //IF MOUSE IS DRAGGED ALONG THE X AXIS else if((y<pointY+8) && (y>pointY-8)) { //IF MOUSE IS DRAGGED TO THE LEFT if((pickX>1) && (x<pointX-14)) { //IF BALL JUMP IS VALID if((board[pickY*7+pickX-1]==1) && (board[pickY*7 +pickX-2]==0)) { dragX=pickX-2; dragY=pickY; } } //IF MOUSE IS DRAGGED TO THE RIGHT else if((pickX<5) && (x>pointX+14)) { //IF BALL JUMP IS VALID if((board[pickY*7+pickX+1]==1) && (board[pickY*7 +pickX+2]==0)) { dragX=pickX+2; dragY=pickY;

} } } return false; } //PERFORM THE ACTION WHEN THE MOUSE IS RELEASED public boolean mouseUp(Event e,int x,int y) { //IF MOUSE WAS DRAGGED TO A VALID POSITION if(dragX>-1) { //PERFORM THE BALL JUMP OPERATION undo.setEnabled(true); board[pickY*7+pickX]=0; board[dragY*7+dragX]=1; board[7*(pickY+dragY)/2+(pickX+dragX)/2]=0; deadBalls++; bsol.setEnabled(false); if(gameover()) gameend=true; //PUSH THE VALUES OF pickX,pickY,dragX, //dragY ONTO THE STACK TO IMPLEMENT UNDO Integer pX=new Integer(pickX); u.push(pX); Integer pY=new Integer(pickY); u.push(pY); Integer dX=new Integer(dragX); u.push(dX); Integer dY=new Integer(dragY); u.push(dY); repaint(); } return false; } public void update(Graphics g) { paint(g); } //CHECKS IF THE GAME IS OVER public boolean gameover() { for(i=2;i<5;i++) for(j=2;j<5;j++) { if(board[i*7+j]==1) { if((board[i*7+j-7]==1) && (board[i*7+j-1 4]==0)) return false; if((board[i*7+j-1]==1) && (board[i*7+j-2 ]==0)) return false; if((board[i*7+j+7]==1) && (board[i*7+j+1 4]==0)) return false; if((board[i*7+j+1]==1) && (board[i*7+j+2

]==0)) return false; } else { if((board[i*7+j-7]==1) && (board[i*7+j-1 4]==1)) return false; if((board[i*7+j-1]==1) && (board[i*7+j-2 ]==1)) return false; if((board[i*7+j+7]==1) && (board[i*7+j+1 4]==1)) return false; if((board[i*7+j+1]==1) && (board[i*7+j+2 ]==1)) return false; } } for(i=0;i<2;i++) { if((board[i*7+2]==1) && (board[i*7+3]==1) && (board[i*7+ 4]==0)) return false; if((board[i*7+2]==0) && (board[i*7+3]==1) && (board[i*7+ 4]==1)) return false; if((board[i*7+2+35]==1) && (board[i*7+3+35]==1) && (boar d[i*7+4+35]==0)) return false; if((board[i*7+2+35]==0) && (board[i*7+3+35]==1) && (boar d[i*7+4+35]==1)) return false; if((board[2*7+i]==1) && (board[3*7+i]==1) && (board[4*7+ i]==0)) return false; if((board[2*7+i]==0) && (board[3*7+i]==1) && (board[4*7+ i]==1)) return false; if((board[2*7+i+5]==1) && (board[3*7+i+5]==1) && (board[ 4*7+i+5]==0)) return false; if((board[2*7+i+5]==0) && (board[3*7+i+5]==1) && (board[ 4*7+i+5]==1)) return false; } return true; } //PAINT FUNCTION DISPLAYS THE GAME public void paint(Graphics g) { showStatus("Welcome to Brainvita--A marble game By Ishaan Jain") ; g.setColor(Color.magenta); g.fillRect(0,0,size().width,size().height);

//IF USER DOES NOT WANT TO VIEW THE INSTRUCTIONS if(instructions==false) { //DISPLAY THE BOARD fixDisc(g,2,2,187,Color.gray); fixDisc(g,0,0,185,Color.white); fixCircle(g,10,10,165,Color.black); //IF GAME IS OVER DISPLAY THE SCORE if(gameend) { g.drawString("Game Over!",55,75); g.drawString("Your Score is--"+(32-deadBalls),45 ,90); if(32-deadBalls==1) g.drawString("CONGRATULATIONS",30,105); } else { //DISPLAY THE BALLS IN THE APPROPRIATE POSITION for (i=0;i<7;i++) for (j=0;j<7;j++) if (board[i*7+j]>-1) if (board[i*7+j]==0) boardHole(g,34+j *17,34+i*17); else boardBall(g,34+j *17,34+i*17); //THE ELIMINATED BALLS OUTSIDE THE BOARD for (i=0;i<deadBalls;i++) { if(i<16) deadBall(g,5+i*17,195); else deadBall(g,5+(i-16)*17,212); } } } //DISPLAY THE INSTRUCTION else { displayinst(g); } } //CRAETE A NEW THREAD TO FIND OPTIMAL SOLUTION public void displaysol() { t=new Thread(this); t.start(); } //THREAD RUN FUNCTION TO CALCULATE THE OPTIMAL SOLUTION public void run() { for(count=0;count<solution.length;count++)

{ int X=-1,Y=-1; board[solution[count][1]*7+solution[count][0]]=0; switch(solution[count][2]) { case UP: Y=solution[count][1]-2; X=solution[count][0]; break; case DOWN: Y=solution[count][1]+2; X=solution[count][0]; break; case RIGHT: Y=solution[count][1]; X=solution[count][0]+2; break; case LEFT: Y=solution[count][1]; X=solution[count][0]-2; break; } deadBalls+=1; board[Y*7+X]=1; board[((solution[count][1]+Y)/2)*7+(solution[count][0]+X )/2]=0; repaint(); //INSERT A 1.5 SEC DELAY try { Thread.sleep(1500); } catch(InterruptedException e) errupted");} } gameend=true; t.stop(); } //DISPLAY THE INSTRUCTIONS public void displayinst(Graphics g) { g.setColor(Color. blue); g.drawString("Welcome to Brainvita--A marble game",75,15); g.drawString("**********OBJECTIVE**********",100,45); g.drawString("You have to eliminate as many marbles as possible. Select a marble",15,60); g.drawString("and jump it over an adjacent marble to remove it. (the middle marble)",15,75); g.drawString("*********INSTRUCTIONS********",100,105); g.drawString("Drag a marble using the mouse to jump it over anot her marble",15,120); g.drawString("************SCORE************",100,150); g.drawString("Your score is the number of marbles remaining afte r the game is over.",15,165); g.drawString("above 6--This game isn't for monkeys",15,195); g.drawString("6--Better luck next time",15,210); g.drawString("5--Average",15,225); g.drawString("4--Just above average",15,240);

{System.out.println("Int

g.drawString("3--Good work",15,255); g.drawString("2--Almost there",15,270); g.drawString("1--Pure Genius",15,285); } }

SAMPLE OUTPUT:

Initial Display Screen

Potrebbero piacerti anche