Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old May 14th, 2008, 10:53 AM   #1
cwl157
Professional Programmer
 
Join Date: Feb 2005
Posts: 343
Rep Power: 4 cwl157 is on a distinguished road
back to online battleship

Now that it is summer I have some more time to work on that online battleship game. I have it where 1 client can send moves to the server and the server executes the moves on the board and sends the board back to the client and detects when all the ships have been sunk and the game is over. Now I need to figure out how to make it turn based so 2 people running the client can take turns playing the game. If someone could look at this code and tell me how to do that. I know its probably not the cleanest or the best way to do what i am doing. This is the first time i have ever done a client server thing like this before so the organization of it is probably wrong and thats probably why i cant get 2 players to take turns. When i try to run the commented out code for the second person i get a nullPointerException on the one client and a cast exception on the other client. How should i organize this where 2 people can run this client connect to a server and exchange moves with the server and play battleship against each other? I know i can't be that far off. Thanks here is the code:
Client class
java Syntax (Toggle Plain Text)
  1. import java.net.*;
  2. import java.io.*;
  3. import java.util.*;
  4. import ship.*;
  5.  
  6. public class Client
  7. {
  8. private static Socket connection;
  9. private static ObjectOutputStream output;
  10. private static ObjectInputStream input;
  11. static Board b;
  12.  
  13. public static void main(String[] args) throws IOException
  14. {
  15. int counter = 0;
  16. initializePlayer();
  17. boolean playerWins = false;
  18. while (!playerWins)
  19. {
  20. takeTurn();
  21. counter = (Integer) receiveObject();
  22. if (counter == 4)
  23. {
  24. playerWins = true;
  25. } // end if
  26. } // end while
  27. if (playerWins)
  28. {
  29. receive();
  30. b = (Board) receiveObject();
  31. System.out.println();
  32. b.printBoard();
  33. System.out.println();
  34. } // end if
  35.  
  36. } // end main
  37.  
  38. // this initializes 1 player by sending its board and playerName to the Server
  39. static void initializePlayer()
  40. {
  41. b = new Board();
  42. try
  43. {
  44. connection = new Socket(InetAddress.getByName("192.168.1.102"), 1234);
  45. streams();
  46.  
  47. // receiving to send name
  48. receive();
  49. String getName = promptUser();
  50. send(getName);
  51. send(b);
  52. b.printBoard();
  53. b = ((Board) receiveObject());
  54. System.out.println();
  55. System.out.println("Board after ships are added");
  56. b.printBoard();
  57. } // end try
  58. catch(IOException e)
  59. {
  60. System.out.println("Caught IOException in initializePlayer " + e);
  61. } // end catch
  62. } // end initializePlayer
  63. static void takeTurn()
  64. {
  65. try
  66. {
  67. // receiving to take turn
  68. String receive = receive();
  69. String rowCol = promptUser();
  70. send(rowCol);
  71. send(b);
  72. receive();
  73. b = ((Board) receiveObject());
  74. System.out.println();
  75. System.out.println("Board after move");
  76. b.printBoard();
  77. } // end try
  78. catch(IOException e)
  79. {
  80. System.out.println("Caught IOException in takeTurn" + e);
  81. } // end catch
  82. } // end takeTurn
  83. // establish the streams
  84. private static void streams() throws IOException
  85. {
  86. output=new ObjectOutputStream(connection.getOutputStream());
  87. output.flush();
  88. input=new ObjectInputStream(connection.getInputStream());
  89. } // end streams
  90.  
  91. private static void send(Object b)
  92. {
  93. try
  94. {
  95. output.writeObject(b);
  96. output.flush();
  97. } // end try
  98. catch(IOException e)
  99. {
  100. System.out.println("Caught IOException in send " + e);
  101. } // end catch
  102. } // end send
  103.  
  104. private static String receive() throws IOException
  105. {
  106. String test = "";
  107. try
  108. {
  109. test = (String) input.readObject();
  110. System.out.print("\n" + test);
  111. } // end try
  112. catch(ClassNotFoundException classNotFoundException)
  113. {
  114. System.out.print("\nUnknown object recieved");
  115. } // end catch
  116. return test;
  117. } // end receiveObject
  118.  
  119. private static Object receiveObject() throws IOException
  120. {
  121. Object test = new Object();
  122. try
  123. {
  124. test = input.readObject();
  125. } // end try
  126. catch(ClassNotFoundException classNotFoundException)
  127. {
  128. System.out.print("\nUnknown object recieved");
  129. } // end catch
  130. return test;
  131. } // end receiveObject
  132.  
  133. // take the row line from the client
  134. private static String getRow(String line)
  135. {
  136. String row = "";
  137. // take the first char in the string which is the row
  138. char rowC = line.charAt(0);
  139. // convert it to a string and return it.
  140. row = Character.toString(rowC);
  141. System.out.println(row);
  142. return row;
  143. } // end getRow
  144.  
  145. // take the column line from the client
  146. private static String getCol(String line)
  147. {
  148. String col = "";
  149. // take the first char in the string which is the row
  150. char colC = line.charAt(2);
  151. // convert it to a string and return it.
  152. col = Character.toString(colC);
  153. System.out.println(col);
  154. return col;
  155. } // end getRow
  156.  
  157. // get input from the user to play game or exit
  158. public static String promptUser() throws IOException
  159. {
  160. BufferedReader keyInput = new BufferedReader(new InputStreamReader(System.in));
  161. int lineToInt = 0;
  162.  
  163. String line = null;
  164. try
  165. {
  166. line = keyInput.readLine();
  167. } // end try
  168. //catches bad user input and throws exception
  169. catch (NumberFormatException ex)
  170. {
  171. System.out.print("Error bad data: ");
  172. } // end catch
  173.  
  174. return line;
  175. } // end promptUser
  176.  
  177. } // end Server
Server class
java Syntax (Toggle Plain Text)
  1. import java.io.*;
  2. import java.net.*;
  3. import ship.*;
  4.  
  5. // this is to test sending an entire board over the network
  6.  
  7. public class testRun
  8. {
  9. private static Socket connection;
  10. private static ObjectOutputStream output;
  11. private static ObjectInputStream input;
  12. static Player p1;
  13. static Player p2;
  14. static Board b1;
  15. static Board b2;
  16. static Sub subs;
  17. static BattleShip battleShips;
  18. static Patrol patrols;
  19. static Carrier carriers;
  20.  
  21. public static void main(String[] args) throws IOException
  22. {
  23. boolean playerWins = false;
  24. boolean playerOneTurn = true;
  25.  
  26. receivePlayer1();
  27.  
  28. // this is when there is only 1 player
  29. while (!playerWins)
  30. {
  31. takeTurn1();
  32. send((Integer)p1.counter);
  33. if (p1.endGame(p1.counter))
  34. {
  35. playerWins = true;
  36. } // end if
  37. } // end while
  38. /* this is for 2 players
  39.   while (!playerWins)
  40.   {
  41.   if (playerOneTurn)
  42.   {
  43.   takeTurn1();
  44.   // check to see if player won the game
  45.   if (p1.endGame(p1.counter))
  46.   {
  47.   playerWins = true;
  48.   } // end if
  49.   playerOneTurn = false;
  50.   } // end playerOneTurn
  51.   else if (!playerOneTurn)
  52.   {
  53.   takeTurn2();
  54.   // check to see if player won the game
  55.   if (p2.endGame(p2.counter))
  56.   {
  57.   playerWins = true;
  58.   } // end if
  59.   playerOneTurn = true;
  60.   } // end else if
  61.   } // end while
  62.   */
  63. if (playerWins)
  64. {
  65. String wonGameInfo = p1.name + " has won the game!\n" + p1.name + "'s final board";
  66. send(wonGameInfo);
  67. send(b1);
  68. System.out.println();
  69. } // end if
  70. } // end main
  71.  
  72. static void receivePlayer1()
  73. {
  74. // initialize Player 1
  75. b1 = new Board();
  76. String namePrompt = "Please enter a Player name: ";
  77. String name = "";
  78. try
  79. {
  80. ServerSocket s = new ServerSocket(1234);
  81. connection = s.accept();
  82. streams();
  83. send(namePrompt);
  84. name = (String) receive();
  85. p1 = new Player(name);
  86. System.out.println("Player's name is " + p1.name);
  87. b1 = (Board)receive();
  88. System.out.println("The empty board is ");
  89. b1.printBoard();
  90. // set the board
  91. subs = new Sub();
  92. battleShips = new BattleShip();
  93. patrols = new Patrol();
  94. carriers = new Carrier();
  95. // set board
  96. p1.setSub(b1, subs);
  97. p1.setBattleShip(b1, battleShips);
  98. p1.setPatrol(b1, patrols);
  99. p1.setCarrier(b1, carriers);
  100. System.out.println(p1.name + "'s board: ");
  101. System.out.println();
  102. b1.printBoard();
  103. send((Board) b1);
  104. } // end try
  105. catch(IOException e)
  106. {
  107. System.out.println("Caught IOException in receivePlayer " + e);
  108. } // end catch
  109. } // end receivePlayer1
  110.  
  111. /*static void receivePlayer2()
  112.   {
  113.   // initialize Player 2
  114.   b2 = new Board();
  115.   String namePrompt = "Please enter a Player name: ";
  116.   String name = "";
  117.   try
  118.   {
  119.   ServerSocket s = new ServerSocket(1234);
  120.   connection = s.accept();
  121.   streams();
  122.   send(namePrompt);
  123.   name = (String) receive();
  124.   p2 = new Player(name);
  125.   System.out.println("Player's name is " + p2.name);
  126.   b2 = (Board)receive();
  127.   System.out.println("The empty board is ");
  128.   b2.printBoard();
  129.   // set the board
  130.   subs = new Sub();
  131.   battleShips = new BattleShip();
  132.   patrols = new Patrol();
  133.   carriers = new Carrier();
  134.   // set board
  135.   p2.setSub(b2, subs);
  136.   p2.setBattleShip(b2, battleShips);
  137.   p2.setPatrol(b2, patrols);
  138.   p2.setCarrier(b2, carriers);
  139.   System.out.println(p2.name + "'s board: ");
  140.   System.out.println();
  141.   b2.printBoard();
  142.   send((Board) b2);
  143.   } // end try
  144.   catch(IOException e)
  145.   {
  146.   System.out.println("Caught IOException in receivePlayer " + e);
  147.   } // end catch
  148.   } // end receivePlayer2
  149.   */
  150.  
  151. // get the move from the user and take turn
  152. static void takeTurn1() throws IOException
  153. {
  154. String getRowCol = "Please enter a row and col 0-9 so it looks like this 1,2: ";
  155. int row = 0;
  156. int col = 0;
  157. send((String) getRowCol);
  158. String receivedRowCol = (String) receive();
  159. row = Integer.parseInt(getRow((String) receivedRowCol));
  160. col = Integer.parseInt(getCol((String) receivedRowCol));
  161. String rowColAre = "The row is " + row + "\nThe Col is " + col + "\n";
  162. send((String) rowColAre);
  163. System.out.println("The row is " + row);
  164. System.out.println("The col is " + col);
  165. b1 = (Board) receive();
  166. p1.takeTurn(b1, subs, battleShips, patrols, carriers, row, col);
  167. b1.printBoard();
  168. send((Board) b1);
  169. //send((Board) b1);
  170. } // end takeTurn1
  171.  
  172. // get the move from the user and take turn for player 2
  173. /* static void takeTurn2() throws IOException
  174.   {
  175.   String getRowCol = "Please enter a row and col 0-9 so it looks like this 1,2: ";
  176.   int row = 0;
  177.   int col = 0;
  178.   send((String) getRowCol);
  179.   String receivedRowCol = (String) receive();
  180.   row = Integer.parseInt(getRow((String) receivedRowCol));
  181.   col = Integer.parseInt(getCol((String) receivedRowCol));
  182.   String rowColAre = "The row is " + row + "\nThe Col is " + col + "\n";
  183.   send((String) rowColAre);
  184.   System.out.println("The row is " + row);
  185.   System.out.println("The col is " + col);
  186.   b2 = (Board) receive();
  187.   p2.takeTurn(b1, subs, battleShips, patrols, carriers, row, col);
  188.   b2.printBoard();
  189.   send((Board) b2);
  190.   //send((Board) b1);
  191.   } // end takeTurn1
  192.   */
  193.  
  194. private static void send(Object b)
  195. {
  196. try
  197. {
  198. output.writeObject(b);
  199. output.flush();
  200. } // end try
  201. catch(IOException ioException)
  202. {
  203. }
  204. } // end send
  205.  
  206. // establish the streams
  207. private static void streams() throws IOException
  208. {
  209. output=new ObjectOutputStream(connection.getOutputStream());
  210. output.flush();
  211. input=new ObjectInputStream(connection.getInputStream());
  212. } // end streams
  213.  
  214. private static Object receive() throws IOException
  215. {
  216. Object test = new Board();
  217. try
  218. {
  219. test = input.readObject();
  220. } // end try
  221. catch(ClassNotFoundException classNotFoundException)
  222. {
  223. System.out.print("\nUnknown object recieved");
  224. } // end catch
  225. return test;
  226. } // end receive
  227.  
  228. // take the row line from the client
  229. private static String getRow(String line)
  230. {
  231. String row = "";
  232. // take the first char in the string which is the row
  233. char rowC = line.charAt(0);
  234. // convert it to a string and return it.
  235. row = Character.toString(rowC);
  236. System.out.println(row);
  237. return row;
  238. } // end getRow
  239.  
  240. // take the column line from the client
  241. private static String getCol(String line)
  242. {
  243. String col = "";
  244. // take the first char in the string which is the row
  245. char colC = line.charAt(2);
  246. // convert it to a string and return it.
  247. col = Character.toString(colC);
  248. System.out.println(col);
  249. return col;
  250. } // end getCol
  251.  
  252. } // end testRun
cwl157 is offline   Reply With Quote
Old May 14th, 2008, 1:18 PM   #2
Freaky Chris
Professional Programmer
 
Freaky Chris's Avatar
 
Join Date: Dec 2007
Location: England
Posts: 269
Rep Power: 1 Freaky Chris is on a distinguished road
Send a message via MSN to Freaky Chris
Re: back to online battleship

I don't have the time to read all of your code and write some of my own code at the moment im revise for exams, fun fun fun. But something like this may help you.

1) Player Connects to server
2) Server checks for free players, whilst player waits for a player
3) Server sends client details to each player, sets player1's turns to true
4) Player1 then moves and returns the board to the server
5) Server Checks for a win, else
6) Server changes player1 turn to false and sets player2 turn to true, and send the board to player2
7) and so on, until the game is won.

Sorry if this doesn't help at all.

Chris
__________________
Steven Skiena - Algorithms
Freaky Chris is offline   Reply With Quote
Old May 14th, 2008, 3:29 PM   #3
Wizard1988
Professional Programmer
 
Wizard1988's Avatar
 
Join Date: Oct 2005
Location: Chitown
Posts: 417
Rep Power: 4 Wizard1988 is on a distinguished road
Send a message via AIM to Wizard1988
Re: back to online battleship

If you think about it the server shouldn't really be sending the board to anyone. After each player sets up their battleships the program might send the sizes and coordinates of their ships to the server. Each player will know the location of their own ships but not the enemy's (the basis of the game). Now, when a player decides to attack you could just send that coordinate to the server and have it verify if its a hit/miss or if there is a winner and send the result back to the client so it could update the display. I didn't read your code so I'm not sure how it works, but you could just have the server update a player turn status. If it is a player's turn then the client would enable a button which would submit their next move or so.

Those are just some of my thoughts.
__________________
JG-Webdesign
Wizard1988 is offline   Reply With Quote
Old May 14th, 2008, 4:45 PM   #4
cwl157
Professional Programmer
 
Join Date: Feb 2005
Posts: 343
Rep Power: 4 cwl157 is on a distinguished road
Re: back to online battleship

wizard, i thought about this. In fact i have a version of this where all the server does is pass the moves between clients but in order for the server to verify the move it needs to have copies of the boards. I was thinking if the clients send the board and moves and the server plays the game and sends the moves and board back to the clients then it could tell when the game is over and send that as well.

Freaky Chris,
As for what you are saying how do i make the server check for free players and then how do i make the turns go back and forth, right now it just sits with one player when the other one is connected. I thought calling receivePlayer1 and receivePlayer2 would make it alternate but it doesn't work that way and i think the server gets confused about what is sent from who when and stuff

Last edited by cwl157; May 14th, 2008 at 4:55 PM.
cwl157 is offline   Reply With Quote
Old May 14th, 2008, 5:34 PM   #5
Wizard1988
Professional Programmer
 
Wizard1988's Avatar
 
Join Date: Oct 2005
Location: Chitown
Posts: 417
Rep Power: 4 Wizard1988 is on a distinguished road
Send a message via AIM to Wizard1988
Re: back to online battleship

I'm not understanding why the client(s) would need to send the setup board to the server more than once. After the server received the two boards it should be able to figure out the results if it received the moves to be played.
__________________
JG-Webdesign
Wizard1988 is offline   Reply With Quote
Old May 14th, 2008, 9:10 PM   #6
cwl157
Professional Programmer
 
Join Date: Feb 2005
Posts: 343
Rep Power: 4 cwl157 is on a distinguished road
Re: back to online battleship

O now i see what your saying. Yea i tried that and then just had the server send the board back to the client after 1 move but for some reason the client was still receiving the board with no move done, so i looked at how i was doing it when setting up the ships and i was sending the board to the server, setting the ships and sending the board back so for the moves, i ended up sending the board to the server and then the server sending the board back and then it worked. So if there is a different way this can be done i would love to know how to do it.
cwl157 is offline   Reply With Quote
Old May 15th, 2008, 11:17 AM   #7
Freaky Chris
Professional Programmer
 
Freaky Chris's Avatar
 
Join Date: Dec 2007
Location: England
Posts: 269
Rep Power: 1 Freaky Chris is on a distinguished road
Send a message via MSN to Freaky Chris
Re: back to online battleship

AS to how you would check for free players, simple use a status flag so to speak. You spawn a thread for a new 1v1 game. Set a variable to false such as, FULL = False, then when a new client joins the server check any threads running games for any False's. If one is found then join that game and set its FULL variable to true.

Chris
__________________
Steven Skiena - Algorithms
Freaky Chris is offline   Reply With Quote
Old May 15th, 2008, 12:26 PM   #8
cwl157
Professional Programmer
 
Join Date: Feb 2005
Posts: 343
Rep Power: 4 cwl157 is on a distinguished road
Re: back to online battleship

yea i was wondering about threads for this, unfortunatly i have zero experience using threads but it would make it so more then 1 game could be going on at once right?
cwl157 is offline   Reply With Quote
Old May 15th, 2008, 12:36 PM   #9
Freaky Chris
Professional Programmer
 
Freaky Chris's Avatar
 
Join Date: Dec 2007
Location: England
Posts: 269
Rep Power: 1 Freaky Chris is on a distinguished road
Send a message via MSN to Freaky Chris
Re: back to online battleship

indeed it would. You would have to set up a few different threads, one to handle each new player and then no doubt one for games, im not entierly sure how one would set it up atm, if i have time later i'll have a think about the logic behind it and get back to you with that. Threads are reasonable easy to understand, i recomend checking threading out it could prove very useful.
there is a different approach that one could take i suppose. The server handles all connecting clients. Then it calls a different app with connection details that automatically connects to two people to play the gae and that then acts as the server for the game and the clients are no long connected to the main server. Once the game ends the clients are reconnected to the main server.

All very dodgy im guessing im just thinking about things differently thats all

Chris
__________________
Steven Skiena - Algorithms
Freaky Chris is offline   Reply With Quote