/src/Rogue.java

https://bitbucket.org/russtopher/cs3411-hw3 · Java · 354 lines · 309 code · 37 blank · 8 comment · 69 complexity · f56492dded45e588faab78ed7eab8b2b MD5 · raw file

  1. /*******************************************
  2. /* Rogue.java
  3. /* Engine for Text-Based Adventure Game
  4. /* COMP3411 Artificial Intelligence
  5. /* UNSW Session 1, 2013
  6. */
  7. import java.io.*;
  8. import java.net.ServerSocket;
  9. import java.net.Socket;
  10. public class Rogue {
  11. final static int EAST = 0;
  12. final static int NORTH = 1;
  13. final static int WEST = 2;
  14. final static int SOUTH = 3;
  15. private char[][] map;
  16. private char[][] view;
  17. private int nrows; // number of rows in environment
  18. private int irow,icol; // initial row and column
  19. // current row, column and direction of agent
  20. private int row,col,dirn;
  21. private boolean have_axe = false;
  22. private boolean have_key = false;
  23. private boolean have_gold = false;
  24. private boolean game_won = false;
  25. private boolean game_lost = false;
  26. private int num_dynamites_held = 0;
  27. private static void swanSong( String message ) {
  28. System.out.println( message );
  29. System.exit(-1);
  30. }
  31. private void read_map( String mapName ) {
  32. BufferedReader in;
  33. boolean agent_here;
  34. char ch;
  35. int r,c;
  36. map = new char[1024][];
  37. r=-1;
  38. try {
  39. in = new BufferedReader(new FileReader(mapName));
  40. String oneLine = in.readLine();
  41. while(( oneLine != null )&&( oneLine.length() > 0 )) {
  42. map[++r] = new char[oneLine.length()];
  43. for( c=0; c < oneLine.length(); c++ ) {
  44. map[r][c] = oneLine.charAt(c);
  45. agent_here = true;
  46. switch( map[r][c] ) {
  47. case '^': dirn = NORTH; break;
  48. case '>': dirn = EAST; break;
  49. case 'v': dirn = SOUTH; break;
  50. case '<': dirn = WEST; break;
  51. default: agent_here = false;
  52. }
  53. if( agent_here ) {
  54. row = r;
  55. col = c;
  56. }
  57. }
  58. oneLine = in.readLine();
  59. }
  60. }
  61. catch( FileNotFoundException fnfe ) {
  62. swanSong( "File Not Found: "+ mapName );
  63. }
  64. catch( IOException ioe ) {
  65. swanSong( "IO Error" );
  66. }
  67. nrows = r+1; // number of rows
  68. irow = row; // initial row
  69. icol = col; // initial column
  70. }
  71. private void print_map() {
  72. char ch=' ';
  73. int r,c;
  74. System.out.println();
  75. for( r=0; r < nrows; r++ ) {
  76. for( c=0; c < map[r].length; c++ ) {
  77. if(( r == row )&&( c == col )) { // agent is here
  78. switch( dirn ) {
  79. case NORTH: ch = '^'; break;
  80. case EAST: ch = '>'; break;
  81. case SOUTH: ch = 'v'; break;
  82. case WEST: ch = '<'; break;
  83. }
  84. }
  85. else {
  86. ch = map[r][c];
  87. }
  88. System.out.print( ch );
  89. }
  90. System.out.println();
  91. }
  92. System.out.println();
  93. }
  94. private boolean apply( char action )
  95. {
  96. int d_row, d_col;
  97. int new_row, new_col;
  98. char ch;
  99. if(( action == 'L' )||( action == 'l' )) {
  100. dirn = ( dirn + 1 ) % 4;
  101. return( true );
  102. }
  103. else if(( action == 'R' )||( action == 'r' )) {
  104. dirn = ( dirn + 3 ) % 4;
  105. return( true );
  106. }
  107. else {
  108. d_row = 0; d_col = 0;
  109. switch( dirn ) {
  110. case NORTH: d_row = -1; break;
  111. case SOUTH: d_row = 1; break;
  112. case EAST: d_col = 1; break;
  113. case WEST: d_col = -1; break;
  114. }
  115. new_row = row + d_row;
  116. new_col = col + d_col;
  117. ch = map[new_row][new_col];
  118. switch( action ) {
  119. case 'F': case 'f': // forward
  120. switch( ch ) { // can't move into an obstacle
  121. case '*': case 'T': case '-':
  122. return( false );
  123. }
  124. map[row][col] = ' '; // clear current location
  125. row = new_row;
  126. col = new_col;
  127. map[row][col] = ' '; // clear new location
  128. switch( ch ) {
  129. case 'a': have_axe = true; break;
  130. case 'k': have_key = true; break;
  131. case 'g': have_gold = true; break;
  132. case 'd': num_dynamites_held++; break;
  133. case '~': game_lost = true; break;
  134. }
  135. if( have_gold &&( row == irow )&&( col == icol )) {
  136. game_won = true;
  137. }
  138. return( true );
  139. case 'C': case 'c': // chop
  140. if(( ch == 'T' )&& have_axe ) {
  141. map[new_row][new_col] = ' ';
  142. return( true );
  143. }
  144. break;
  145. case 'O': case 'o': // open
  146. if(( ch == '-' )&& have_key ) {
  147. map[new_row][new_col] = ' ';
  148. return( true );
  149. }
  150. break;
  151. case 'B': case 'b': // blast
  152. if( num_dynamites_held > 0 ) {
  153. switch( ch ) {
  154. case '*': case 'T': case '-':
  155. map[new_row][new_col] = ' ';
  156. num_dynamites_held--;
  157. return( true );
  158. }
  159. }
  160. break;
  161. }
  162. }
  163. return( false );
  164. }
  165. private void get_view() {
  166. char ch;
  167. int i,j,r=0,c=0;
  168. // scan local 5-by-5 window, from agent's point of view
  169. for( i = -2; i <= 2; i++ ) {
  170. for( j = -2; j <= 2; j++ ) {
  171. switch( dirn ) {
  172. case NORTH: r = row+i; c = col+j; break;
  173. case SOUTH: r = row-i; c = col-j; break;
  174. case EAST: r = row+j; c = col-i; break;
  175. case WEST: r = row-j; c = col+i; break;
  176. }
  177. if( ( r >= 0 )&&( r < nrows )
  178. &&( c >= 0 )&&( c < map[r].length )) {
  179. view[2+i][2+j] = map[r][c];
  180. }
  181. else {
  182. view[2+i][2+j] = '~';
  183. }
  184. }
  185. }
  186. }
  187. private static void printUsage()
  188. {
  189. swanSong(
  190. "Usage: java Rogue [-p <port>] -i map [-m <maxmoves>] [-s]\n");
  191. }
  192. public static void main( String[] args )
  193. {
  194. Rogue rogue;
  195. boolean silent = false;
  196. String mapName = "";
  197. char action = 'F';
  198. int maxmoves = 10000;
  199. int port = 0;
  200. int k,m;
  201. rogue = new Rogue();
  202. rogue.view = new char[5][5];
  203. k=0;
  204. while( k < args.length ) {
  205. if( args[k].compareTo("-i") == 0 ) {
  206. if( ++k < args.length ) {
  207. mapName = args[k++];
  208. }
  209. else {
  210. printUsage();
  211. }
  212. }
  213. else if( args[k].compareTo("-p") == 0 ) {
  214. if( ++k < args.length ) {
  215. port = Integer.parseInt(args[k++]);
  216. }
  217. else {
  218. printUsage();
  219. }
  220. }
  221. else if( args[k].compareTo("-m") == 0 ) {
  222. if( ++k < args.length ) {
  223. maxmoves = Integer.parseInt(args[k++]);
  224. }
  225. else {
  226. printUsage();
  227. }
  228. }
  229. else if( args[k].compareTo("-s") == 0 ) {
  230. silent = true;
  231. k++;
  232. }
  233. else {
  234. printUsage();
  235. }
  236. }
  237. if( mapName.length() == 0 ) {
  238. printUsage();
  239. }
  240. rogue.read_map( mapName );
  241. if( !silent ) {
  242. rogue.print_map();
  243. }
  244. if( port != 0 ) {
  245. InputStream in = null;
  246. OutputStream out = null;
  247. ServerSocket serverSocket = null;
  248. Socket clientSocket = null;
  249. int i,j;
  250. try {
  251. serverSocket = new ServerSocket( port );
  252. clientSocket = serverSocket.accept();
  253. serverSocket.close();
  254. in = clientSocket.getInputStream();
  255. out = clientSocket.getOutputStream();
  256. }
  257. catch( IOException e ) {
  258. swanSong( "Could not listen on port: "+ port );
  259. }
  260. try {
  261. for( m=1; m <= maxmoves; m++ ) {
  262. rogue.get_view();
  263. for( i=0; i < 5; i++ ) {
  264. for( j=0; j < 5; j++ ) {
  265. if( !(( i == 2 )&&( j == 2 ))) {
  266. out.write( rogue.view[i][j] );
  267. }
  268. }
  269. }
  270. out.flush();
  271. action = (char) in.read();
  272. if( !silent ) {
  273. System.out.println("action = "+ action );
  274. }
  275. rogue.apply( action );
  276. if( !silent ) {
  277. rogue.print_map();
  278. }
  279. if( rogue.game_won ) {
  280. swanSong( "Game Won in "+ m +" moves." );
  281. }
  282. else if( rogue.game_lost ) {
  283. swanSong( "Game Lost." );
  284. }
  285. }
  286. swanSong("Exceeded maximum of "+ maxmoves +" moves.\n");
  287. }
  288. catch( IOException e ) {
  289. swanSong("Lost connection to port: "+ port );
  290. }
  291. finally {
  292. try {
  293. clientSocket.close();
  294. }
  295. catch( IOException e ) {}
  296. }
  297. }
  298. else {
  299. OldAgent oldAgent = new OldAgent();
  300. for( m=1; m <= maxmoves; m++ ) {
  301. rogue.get_view();
  302. action = oldAgent.get_action( rogue.view );
  303. rogue.apply( action );
  304. if( !silent ) {
  305. rogue.print_map();
  306. }
  307. if( rogue.game_won ) {
  308. swanSong( "Game Won in "+ m +" moves." );
  309. }
  310. else if( rogue.game_lost ) {
  311. swanSong( "Game Lost." );
  312. }
  313. }
  314. swanSong("Exceeded maximum of "+ maxmoves +" moves.");
  315. }
  316. }
  317. }