// JAVA code to play BATTLESHIP - April 26, 1995 // // Modified November 5, 1996 by David Dao // To (1) play with better A.I. and (2) to play accross net // // Original code by Nathaniel G. Auvil and Patrick Gillisse // CSCI 406 Internet Programming for Dr. Roger Webster // import java.applet.*; import java.awt.*; import java.io.*; import java.util.*; import java.lang.*; //==================================================================== public class battle extends Applet { final int max=10; final int num_ships=5; final String blanks=" "; AudioClip blowup, sinking, greatshotkid, taps; boolean game_starting= false; //set to true to begin game boolean first_point= true; //flag for ship placement boolean game_over= false; boolean p1_ships_placed= false; boolean turn1= true; //tells if player1 is up boolean start_firing= false; boolean computer_turn=false; boolean ship_hit= false; int com_x, com_y, start_x, start_y; int[][] ship_loc= new int [4][2]; //position for hit ships char[][] ship_info= new char[4][2]; char dir_found='N'; int ships_found=0; char ship_letter= ' '; //holds letter value of hit ship Panel player1, player2; Button[][] play1 = new Button[10][10]; Button[][] play2 = new Button [10][10]; char p1_grid[][]= new char [max][max]; char p2_grid[][]= new char [max][max]; int placed_ships=5; int firstx, firsty; TextArea display= new TextArea(2, 60); String message= "Player 1 enter starting point of aircraft carrier"; int num_players; int sunk_player1=0, sunk_player2=0, hit_ship1[]= new int [num_ships], hit_ship2[]= new int [num_ships]; //######################################################################### // initialize variables needed for game public void init() { String s_num_players= getParameter("num_players"); num_players= Integer.parseInt(s_num_players); sinking= getAudioClip(getCodeBase(), "going_down.au"); blowup= getAudioClip(getCodeBase(), "blowup.au"); greatshotkid= getAudioClip(getCodeBase(), "greatshotkid.au"); // taps= getAudioClip(getCodeBase(), "taps.au"); player1 = new Panel(); // create a panel player2 = new Panel(); player1.resize(150,150); player2.resize(250,250); add(player1); add(player2); add(display); //this is for message display display.setEditable(false); display.insertText(message, 0); player1.setBackground(Color.blue); player1.setLayout(new GridLayout(10, 10, 1, 1)); player2.setBackground(Color.red); player2.setLayout(new GridLayout(10, 10, 1, 1)); for(int i =0; i=0) && (!(computer_repeat(com_x, com_y-1)))) { com_y--; if (p1_grid[com_y][com_x]==p1_grid[start_y][start_x]) temp='V'; } break; case 1: if ((com_x+1=0) && (!(computer_repeat(com_x-1, com_y)))) { com_x--; if (p1_grid[com_y][com_x]==p1_grid[start_y][start_x]) temp='H'; } } } while ((com_x==start_x) && (com_y==start_y)); dir_found=temp; ship_info[(ships_found-1)][1]=temp; System.out.println("looking for direction "+temp+" at ("+com_x+ ", " + com_y +")"); break; case 'H': ship_horizontal(); break; case 'V': ship_vertical(); break; } } //########################################################################## // This checks shot to see if ship we are searching for will fit in the // given direction. Directions are; case- 1:north, 3:south, 0:west, 2:east public boolean check_shot(char[][] area, int x, int y, int dir, int ship_size) { int i=0; boolean ret_val=true; switch (dir) { case 1: for(i=(y+1); i<(y+ship_size); i++) { if ((i>(max-1)) || (computer_repeat(x,i))) ret_val=false; } break; case 3: for(i=(y-1); i>(y-ship_size); i--) { if ((i<0) || (computer_repeat(x,i))) ret_val=false; } break; case 0: for(i=(x-1); i>(x-ship_size); i--) { if ((i<0) || (computer_repeat(i,y))) ret_val=false; } break; case 2: for(i=(x+1); i<(x+ship_size); i++) { if ((i>(max-1)) || (computer_repeat(i,y))) ret_val=false; } break; } // end of switch (dir) return ret_val; } //##################################################################### // Generates a shot when called. Algorithm looks for random // shot in which area is large enough for a requested ship to hide public void generate_shot(char[][] area, int ship_size) { int new_dir; do { new_dir = -1; do { com_x= (int)Math.floor(Math.random() * max); com_y= (int)Math.floor(Math.random() * max); } while (computer_repeat(com_x, com_y)); do { new_dir++; } while (!(check_shot(area, com_x, com_y, new_dir, ship_size)) && (new_dir<3)); System.out.println("New coordinates (" + com_x +", "+ com_y + ") for target size "+ ship_size + " dir " + new_dir); } while (!(check_shot(area, com_x, com_y, new_dir, ship_size))); } //##################################################################### // Picks the next target size and calls shot generater to pick // shot location (picks largest ship still afloat) public void regular_shot(char[][] area) { int ship_size = 5; for (int i=0; i<(num_ships); i++) { if (hit_ship1[i] == 0) ship_size = i+1; } generate_shot(area, ship_size); } //##################################################################### // This stores the pos of initial ship hit. // the x and y should be reversed. public void store_init_hit(int com_x, int com_y) { ship_loc[(ships_found-1)][0]=com_x; ship_loc[(ships_found-1)][1]=com_y; ship_info[(ships_found-1)][0]=p1_grid[com_y][com_x]; ship_info[(ships_found-1)][1]='N'; start_x=com_x; start_y=com_y; ship_letter=p1_grid[com_y][com_x]; dir_found= 'N'; System.out.println("STORING STARTING SPOT "+start_x+" "+start_y+" "+ship_letter+" hit ship "+hit_ship1[3]); } //#################################################################### // the gets initial ship info off of stack public void get_info() { start_x=ship_loc[(ships_found-1)][0]; start_y=ship_loc[(ships_found-1)][1]; ship_letter=ship_info[(ships_found-1)][0]; dir_found=ship_info[(ships_found-1)][1];; System.out.println("RELOADING x="+start_x+" y="+start_y+" "+ship_letter+dir_found); } //#################################################################### // This function controls a one player game. public void game_cont1(int x, int y) { if (!(game_starting)) //need to place ships { human_place_ships(play1, p1_grid, x,y); if (placed_ships==0) { disable_buttons(play1); enable_buttons(play2); game_starting= true; //all ships are placed message_out("Player 1, COMMENCE FIRING!!!!!"); } } if (start_firing) { //start shooting if ((sunk_player10) special_shot(); else regular_shot(p1_grid); if (result_shot_computer(play1, p1_grid, com_x, com_y, hit_ship1)) { sunk_player1++; ships_found--; if (ships_found!=0) //pull next values off of stack get_info(); } computer_turn=false; if (sunk_player1==num_ships) { declare_winner(); disable_buttons(play2); reveal(play2, p2_grid); reveal(play1, p1_grid); game_over=true; } } else { declare_winner(); disable_buttons(play2); reveal(play2, p2_grid); reveal(play1, p1_grid); game_over=true; } } // if (!(game_over)) // message_out("Player 1 take a shot"); } start_firing=game_starting; //this will stop an automatic first shot from player } //######################################################################### // This function controls a two person game. public void game_controls2(int x, int y) { if (!(game_starting)) //need to place ships { if (!(p1_ships_placed)) { human_place_ships(play1, p1_grid, x,y); if (placed_ships==0) { placed_ships=num_ships; //reinit for player2 p1_ships_placed=true; //player1 has all ships placed first_point=true; message_out("Player 2 enter starting point of " + ship_name()); disable_buttons(play1); enable_buttons(play2); } } else { human_place_ships(play2, p2_grid, x,y); if (placed_ships==0) { game_starting= true; //all ships are placed disable_buttons(play2); enable_buttons(play2); //these two lines are needed to avoid highlight around HQ message_out("Player 1, COMMENCE FIRING!!!!!"); start_firing= true; } } } else if (start_firing) { // start shooting if ((sunk_player1(max-1)) || (area[x][i] != '-')) ret_val=false; } break; case 3: for(i=y; i>(y-placed_ships); i--) { if ((i<0) || (area[x][i] != '-')) ret_val=false; } break; case 0: for(i=x; i>(x-placed_ships); i--) { if ((i<0) || (area[i][y] != '-')) ret_val=false; } break; case 2: for(i=x; i<(x+placed_ships); i++) { if ((i>(max-1)) || (area[i][y] != '-')) ret_val=false; } break; } // end of switch (dir) return ret_val; } //######################################################################### // the x and y should be reversed public void human_place_ships(Button b[][], char area[][], int y, int x) { if ((area[x][y] == '-') && (first_point) && (usable_spot(area, x, y))) { switch(placed_ships) { case 5: { b[x][y].setLabel(ship_letter()); area[x][y]=ship_letterc(); message_out("Place endpoint of aircraft carrier(5 spaces long)"); first_point=false; break; } case 4: { b[x][y].setLabel(ship_letter()); area[x][y]=ship_letterc(); message_out("Place endpoint of battleship(4 spaces long)"); first_point=false; break; } case 3: { b[x][y].setLabel(ship_letter()); area[x][y]=ship_letterc(); message_out("Place endpoint of submarine(3 spaces long)"); first_point=false; break; } case 2: { b[x][y].setLabel(ship_letter()); area[x][y]=ship_letterc(); message_out("Place endpoint of PT boat(2 spaces long)"); first_point=false; break; } case 1: { b[x][y].setLabel(ship_letter()); area[x][y]=ship_letterc(); placed_ships--; retag_buttons(b); //reset all button labels break; } } //end of switch statement firstx=x; //store the initial position firsty=y; } //********after first point of ship is placed. else if ((area[x][y] == '-') && !(first_point)) { if (check_xy(b, area, x, y)) { first_point=true; placed_ships--; //ship placed successfully message_out("Place starting point of " + ship_name()); } } else { message_out("Location is unavailable. Try again."); } } //######################################################################### // This checks if the placement is legal public boolean check_xy(Button b[][], char area[][], int x, int y) { boolean result=true; if (firsty==y) { if (firstx+(placed_ships-1)==x) insert_down(b, area, x, y); else if (firstx-(placed_ships-1)==x) insert_up(b, area, x, y); else result=false; } else if (firstx==x) { if (firsty+(placed_ships-1)==y) insert_right(b, area, x, y); else if (firsty-(placed_ships-1)==y) insert_left(b, area, x, y); else result=false; } else { //otherwise it is not legal so need new end-point result= false; } if (!(result)) message_out("Endpoint is not legal. Try again."); return result; } //######################################################################### // This method returns the ship String for corresponding placed_ships value public String ship_letter() { String letter=" "; switch(placed_ships) { case 1: letter="H"; break; case 2: letter="P"; break; case 3: letter="S"; break; case 4: letter="B"; break; case 5: letter="A"; break; } return letter; } //######################################################################### // This method returns the ship String for corresponding placed_ships value public char ship_letterc() { char letter=' '; switch(placed_ships) { case 1: letter='H'; break; case 2: letter='P'; break; case 3: letter='S'; break; case 4: letter='B'; break; case 5: letter='A'; break; } return letter; } //######################################################################### public void insert_down(Button b[][], char area[][], int x, int y) { int i; for(i=firstx; i<=x; i++) { b[i][firsty].setLabel(ship_letter()); area[i][firsty]=ship_letterc(); } } //######################################################################### public void insert_up(Button b[][], char area[][], int x, int y) { int i; for(i=firstx; i>=x; i--) { b[i][firsty].setLabel(ship_letter()); area[i][firsty]=ship_letterc(); } } //######################################################################### public void insert_right(Button b[][], char area[][], int x, int y) { int i; for(i=firsty; i<=y; i++) { b[firstx][i].setLabel(ship_letter()); area[firstx][i]=ship_letterc(); } } //######################################################################### public void insert_left(Button b[][], char area[][], int x, int y) { int i; for(i=firsty; i>=y; i--) { b[firstx][i].setLabel(ship_letter()); area[firstx][i]=ship_letterc(); } } //######################################################################### // This method reveals the playing fields at the end of the game public void reveal(Button[][] b, char[][] area) { int ii, jj; for (ii=0; ii 0) { do { x= (int)Math.floor(Math.random() * max); y= (int)Math.floor(Math.random() * max); dir= (int)Math.floor(Math.random() * 4); } while (!(check_place(area, x, y, dir))); switch(dir) { case 0: for(i=x; i>(x-placed_ships); i--) area[i][y]=ship_letterc(); break; case 1: for(i=y; i<(y+placed_ships); i++) area[x][i]=ship_letterc(); break; case 2: for(i=x; i<(x+placed_ships); i++) area[i][y]=ship_letterc(); break; case 3: for(i=y; i>(y-placed_ships); i--) area[x][i]=ship_letterc(); break; } placed_ships--; }//end while } //######################################################################### } //end of class