INFT 3030作业代做、代做Information Technology作业、代写Java语言作业、Java编程作业调试
A downloadable multiplayer version of snakes for windows is here: http://sandbox.yoyogames.com/games/172375/download. Inthis case there are no food items you just try to block other snakes and need to be the last snake left with somewhere to moveto win. Another example of the idea can be viewed at https://www.youtube.com/watch?v=hRy_qQLdptA although you may notunderstand the German commentary!For the purposes of this assignment, you are free to choose your own rules for the actual snakes game. The main focus for thisassessment is the way your MPGS supports multiple concurrent players.2Server designAfter they have connected and joined a game, players send to the game server their moves. These moves are very simple: Up,Down, Left, Right or No Move. A No Move could mean either keep going in the same direction as the last move or stop andwait. The game server takes all the moves from all the players and updates its copy of the game board. If you chose to havefruit the snakes eat to get points, the server will need to detect if fruit has been eaten and updates player scores. The serverthen broadcasts the game board (with all the other players shown and any fruit left or added) to each player so they can makethe next move.In a fully networked implementation of this game each player will have to display on their screen the current state of play andthen transmit moves to the server (using TCP/IP or UDP sockets) over the internet. Given this can be a time intensive exercise,in this assignment, we are going to limit the implementation to save on programming time and leave time to concentrate onthe concurrent aspects of the server and players. For the MPGS you will implement, no networking is required. In keeping withthe rest of this course we will restrict the game server and players to be threads all on the same Java process (JVM).This means that you will not have to write TCP/IP or UDP socket code, rather you will need to manage the communicationbetween players and the server using Java constructs. This also means that initially at least you can get the server to draw thegame state on a single screen where all the players can see it rather than sending a copy down to each player for them to drawon their own screen.ModellingIn addition to writing concurrent Java code for the game server and clients (players), you will need to construct a model of theirgame server and players using the LTSA tool. The modelling will need to accurately capture the concurrent behaviour of yourproposed server and show that it is both safe, i.e. it is not likely to freeze. And that it is in fact using multiple threads to performits functions in a way than can be scaled up to many different players.TestingYou will be required to demonstrate testing to show that the game can be played by 4 real players and up to 100 simulatedplayers. Simulated players just make random moves on the board. It would be expected that you apply testing concepts thathave been discussed in the lectures (JUnit assertions and mock objects).Assessment summaryFor internal students this will be a group project with teams of 4. External students will work alone on the assignment andhence will not need to provide an as complete a solution as internal students.The assessment scoring is divided into two stages.Checkpoint 1 Checkpoint 2Final Submission andPresentation TotalInternal 2.5 points scored as a group 2.5 points scored as a group 10 points scored individually5 points scored as a group 20External 2.5 2.5 15 20The following subsections provide details that are focused on internal students. Clarifications for external students are providedat the end of each section.Checkpoint 1This body of work is to be presented in the week 6 lab slot.The purpose of the check point provides an opportunity for the design of the server to be checked before implementationcommences. At this checkpoint the group should have finalised the concurrency design of the server and player roles andcreated a Java class design document. The group should also have a draft LTSA model of their concurrency design. All this is tobe gathered in a design report of approximately 3000 words (or equivalent with diagrams). The report needs to allocate Javaclasses to group members for the first sprint to implementation.External students will do this as individuals. The deliverable is the same, but they do not need to prepare such a large document(1000 words).3Checkpoint 2This body of work is to be presented in the week 8 lab slot.The purpose of this checkpoint is to evaluate some early working code as planned for the first sprint in checkpoint 1. Thereshould be an emphasis on a thread-safe monitor controlled buffer between clients and the server and some initialimplementation of the threaded server code especially the thread safe game state code. The LTSA model should be nearingcompletion. Some attention should be focused on testing and how this will be performed. Finally plans for the finalimplementation should be finalized and every team member should have some coding allocated to complete the assignment.An updated report will be required for this checkpoint and working code is required.External students do not need as large an updated report (1000 words) and the scope of code implementation will be reduced.Final Submission and PresentationThe final submission will provide working code which allows four players to engage in the game and code to allow simulatedplay for up to 100 players. There will also be a completed LTSA model of the concurrent behaviour the players and the gameserver. The model should demonstrate that the game server is capable of concurrent operation and that it has no potentialfreezes (deadlocks). A report will describe the structure of the code for both the model and the actual implementation. Thereport should be approximately 5000 words or equivalent diagrams. The group will present the server working with 4 realplayers and 100 simulated players. The group mark will be allocated for successful integration of group member’s code andmodel and the demonstration/presentation. The individual marks will be allocated to the code each student has written andtheir individual contribution to contribution to the model and the report.External students need only demonstrate one real player, and scaling up to 4 simulated players. External students need onlyprovide a report of 1000 words. External students can demonstrate via a screen capture or video.4Technical SpecificationsStage 1The first stage of the project should be to allow players to login.Each player will be modelled and coded as a concurrent thread. The server design should be able to handle concurrent loginrequests from different players.Logins must be thread-safe on the server. It is not necessary to support registration. Registering players can be handled bymanually loading their usernames and passwords into a suitable database. A suggested package is MapDB (as presented inAppendix 1) which is a good choice for a thread-safe embedded database.It is a requirement for the concurrent login code that a thread-safe standard Java collection is NOT to be used to pass messagesbetween the player logging in and the server. It is also a requirement that monitors be used to manage access to this collection.Stage 2The second stage of the project is to implement the game playing part of the server.Once the server starts it should be ready to accept logged in players playing the game.It is a requirement to use thread safe collections for the communication channels between players and the server for gameplaying and for the storage of the game state. It is a requirement to use a thread pool for game player interactions based on thejava.util.concurrent.executor model. The actual game playing will adopt the pure client server model.The server's main loop would be a concurrent version of this pseudo code:while not donefor each player in worldif input existsget player commandexecute player commandtell player of the resultssimulate the worldbroadcast to all playersThe client's main loop would be like this:while not doneif player has typed any textsend typed text to serverif output from server existsprint outputIn the case of the assignment Java threaded version with no networking the server could take care of updating the screen sinceall players can see the single screen.There is a simple snake single player code example at: https://code.google.com/p/java-snake/source/browse/trunk/javasnake/src/snake/Main.java.Code from here tested on IntelliJ 14 community edition can be found in Appendix 25Appendix 1Code for concurrent persistent hashmaps. See http://www.mapdb.orgYou need to load the library for MapDB via MavenIntelliJ: File->Project Structure->Libraries->+->Browse-> select org.mapdb.1.0.6import org.mapdb.*;import java.io.File;import java.io.Serializable;import java.util.HashMap;import java.util.concurrent.ConcurrentNavigableMap;public class Main { public static void main(String[] args) { // configure and open database using builder pattern. // all options are available with code auto-completion. DB db = DBMaker.newFileDB(new File("testdb")) .closeOnJvmShutdown() .encryptionEnable("password") .make(); // open existing an collection (or create new) ConcurrentNavigableMap<Integer, String> map = db.getTreeMap("collectionName"); // To simplfy access to the classes stored as an infostore use generics ConcurrentNavigableMap<String, InfoStor> mymap = db.getTreeMap("myInfoStoreCollection"); // example of ConcurrentNavigableMap taken from // http://examples.javacodegeeks.com/core-java/util/concurrent/concurrentnavigablemap/java-util- // concurrent-concurrentnavigablemap-example/ ConcurrentNavigableMap<Integer, String> navmap = db.getTreeMap("myNavmap"); navmap.put(1, "Sunday"); navmap.put(2, "Monday"); navmap.put(3, "Tuesday"); navmap.put(4, "Wednesday"); navmap.put(5, "Thursday"); navmap.put(6, "Friday"); navmap.put(7, "Saturday"); System.out.println("1. descendingKeySet(): " + navmap.descendingKeySet() + "\n"); System.out.println("2. descendingMap(): " + navmap.descendingMap() + "\n"); System.out.println("3. headMap(K toKey): " + navmap.headMap(3) + "\n"); System.out.println("4. headMap(K toKey, boolean inclusive): " + navmap.headMap(3, true) + "\n"); System.out.println("5. keySet(): " + navmap.keySet() + "\n"); System.out.println("6. navigableKeySet(): " + navmap.navigableKeySet() + "\n"); System.out.println("7. subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive): " + navmap.subMap(3, true, 6, true) + "\n"); System.out.println("8. subMap(K fromKey, K toKey): " + navmap.subMap(3, 6) + "\n"); System.out.println("9. tailMap(K fromKey): " + navmap.tailMap(3) + "\n"); System.out.println("10. tailMap(K fromKey, boolean inclusive): " + navmap.tailMap(3, true) + "\n"); map.put(1, "one"); map.put(2, "two"); // map.keySet() is now [1,2] System.out.println(map.get(2)); db.commit(); //persist changes into disk map.put(3, "three"); // map.keySet() is now [1,2,3] db.rollback(); //revert recent changes // map.keySet() is now [1,2] // This was taken from // http://stackoverflow.com/questions/12099843/storing-a-new-object-as-the-value-of-a-hashmap HashMap<String, InfoStor> mapper = new HashMap<String, InfoStor>(); //HashMap<String, Object> mapper = new HashMap(); //InfoStor myInfoStore = new InfoStor("NS02"); System.out.println("Trying"); mymap.put("NS02", new InfoStor("NS02")); System.out.println(mymap.get("NS02").getName()); db.close(); }}6// this class must be serializableclass InfoStor implements Serializable { private String vmName; private String platform; private Integer memory; public InfoStor (String name) { vmName = name; } String getName(){ return vmName; } void setPlatform(String p){ platform = p; } String getPlatform(){ return platform; } void setMemory(Integer m){ memory = m; } Integer getMemory(){ return memory; }}7Appendix 2Simple snake code from https://code.google.com/p/java-snake/source/browse/trunk/java-snake/src/snake/Main.javapackage snake;import java.awt.Canvas;import java.awt.Color;import java.awt.Dimension;import java.awt.Font;import java.awt.Frame;import java.awt.Graphics;import java.awt.Toolkit;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.awt.event.WindowEvent;import java.awt.event.WindowListener;import java.awt.image.BufferStrategy;import java.util.logging.Level;import java.util.logging.Logger;/*** @author Peuch*/public class Main implements KeyListener, WindowListener { // KEYS MAP public final static int UP = 0; public final static int DOWN = 1; public final static int LEFT = 2; public final static int RIGHT = 3;// GRID CONTENT
public final static int EMPTY = 0; public final static int FOOD_BONUS = 1; public final static int FOOD_MALUS = 2; public final static int BIG_FOOD_BONUS = 3; public final static int SNAKE = 4; private int[][] grid = null; private int[][] snake = null; private int direction = -1; private int next_direction = -1; private int height = 600; private int width = 600; private int gameSize = 40; private long speed = 70; private Frame frame = null; private Canvas canvas = null; private Graphics graph = null; private BufferStrategy strategy = null; private boolean game_over = false; private boolean paused = false;private int score = 0;
private int grow = 0;private int seconde,minute,milliseconde = 0; // Clock values
private long cycleTime = 0; private long sleepTime = 0; private int bonusTime = 0; private int malusTime = 0; /** * @param args * the command line arguments */ public static void main(String[] args) { Main game = new Main(); game.init(); game.mainLoop(); } public Main() { super(); frame = new Frame(); canvas = new Canvas(); grid = new int[gameSize][gameSize]; snake = new int[gameSize * gameSize][2]; } public void init() { 8 frame.setSize(width + 7, height + 27); frame.setResizable(false); frame.setLocationByPlatform(true); canvas.setSize(width + 7, height + 27); frame.add(canvas); canvas.addKeyListener(this); frame.addWindowListener(this); frame.dispose(); frame.validate(); frame.setTitle("Snake"); frame.setVisible(true); canvas.setIgnoreRepaint(true); canvas.setBackground(Color.WHITE);canvas.createBufferStrategy(2);
strategy = canvas.getBufferStrategy();
graph = strategy.getDrawGraphics(); initGame(); renderGame(); } public void mainLoop() { while (!game_over) { cycleTime = System.currentTimeMillis(); if(!paused) { direction = next_direction; moveSnake(); } renderGame(); cycleTime = System.currentTimeMillis() - cycleTime; sleepTime = speed - cycleTime; if (sleepTime < 0) sleepTime = 0; try { Thread.sleep(sleepTime); } catch (InterruptedException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); } } } private void initGame() { // Initialise tabs for (int i = 0; i < gameSize; i++) { for (int j = 0; j < gameSize; j++) { grid[i][j] = EMPTY; } } for (int i = 0; i < gameSize * gameSize; i++) { snake[i][0] = -1; snake[i][1] = -1; } snake[0][0] = gameSize/2; snake[0][1] = gameSize/2; grid[gameSize/2][gameSize/2] = SNAKE; placeBonus(FOOD_BONUS); }private void renderGame() { int gridUnit = height / gameSize; canvas.paint(graph); do { do { graph = strategy.getDrawGraphics(); // Draw Background graph.setColor(Color.WHITE); graph.fillRect(0, 0, width, height); // Draw snake, bonus ... int gridCase = EMPTY; for (int i = 0; i < gameSize; i++) { 9 for (int j = 0; j < gameSize; j++) { gridCase = grid[i][j]; switch (gridCase) { case SNAKE: graph.setColor(Color.BLUE); graph.fillOval(i * gridUnit, j * gridUnit, gridUnit, gridUnit); break;case FOOD_BONUS:
graph.setColor(Color.darkGray); graph.fillOval(i * gridUnit + gridUnit / 4, j * gridUnit + gridUnit / 4, gridUnit / 2, gridUnit / 2); break; case FOOD_MALUS: graph.setColor(Color.RED); graph.fillOval(i * gridUnit + gridUnit / 4, j * gridUnit + gridUnit / 4, gridUnit / 2, gridUnit / 2); break; case BIG_FOOD_BONUS: graph.setColor(Color.GREEN); graph.fillOval(i * gridUnit + gridUnit / 4, j * gridUnit + gridUnit / 4, gridUnit / 2, gridUnit / 2); break; default: break; } } } graph.setFont(new Font(Font.SANS_SERIF, Font.BOLD, height / 40)); if (game_over) { graph.setColor(Color.RED); graph.drawString("GAME OVER", height / 2 - 30, height / 2); graph.drawString("YOUR SCORE : " + score, height / 2 - 40, height / 2 +50); graph.drawString("YOUR TIME : " + getTime(), height / 2 - 42, height / 2 +100); } else if (paused) { graph.setColor(Color.RED); graph.drawString("PAUSED", height / 2 - 30, height / 2); } graph.setColor(Color.BLACK); graph.drawString("SCORE = " + score, 10, 20); graph.drawString("TIME = " + getTime(), 100, 20); //Clock graph.dispose(); } while (strategy.contentsRestored()); // Draw image from buffer strategy.show(); Toolkit.getDefaultToolkit().sync(); } while (strategy.contentsLost()); } private String getTime() { String temps = new String(minute + ":" + seconde); if (direction<0 || paused) return temps;milliseconde++;
if (milliseconde==14){ seconde++; milliseconde=0;} if (seconde==60){ seconde=0; minute++; }return temps;
}private void moveSnake() {
if (direction < 0) { return; } int ymove = 0; int xmove = 0;10 switch (direction) { case UP: xmove = 0; ymove = -1; break; case DOWN: xmove = 0; ymove = 1; break; case RIGHT: xmove = 1; ymove = 0; break; case LEFT: xmove = -1; ymove = 0; break; default: xmove = 0; ymove = 0; break; } int tempx = snake[0][0]; int tempy = snake[0][1]; int fut_x = snake[0][0] + xmove; int fut_y = snake[0][1] + ymove;if(fut_x < 0)
fut_x = gameSize - 1; if(fut_y < 0) fut_y = gameSize - 1; if(fut_x >= gameSize) fut_x = 0; if(fut_y >= gameSize) fut_y = 0;if (grid[fut_x][fut_y] == FOOD_BONUS)
{ grow++; score++; placeBonus(FOOD_BONUS);}
if (grid[fut_x][fut_y] == FOOD_MALUS) { grow += 2; score--; } else if(grid[fut_x][fut_y] == BIG_FOOD_BONUS) { grow += 3; score +=3; } snake[0][0] = fut_x; snake[0][1] = fut_y; if ((grid[snake[0][0]][snake[0][1]] == SNAKE)) { gameOver(); return; } grid[tempx][tempy] = EMPTY; int snakex, snakey, i; for (i = 1; i < gameSize * gameSize; i++) { if ((snake[i][0] < 0) || (snake[i][1] < 0)) { break; } grid[snake[i][0]][snake[i][1]] = EMPTY; snakex = snake[i][0]; snakey = snake[i][1]; snake[i][0] = tempx; snake[i][1] = tempy; tempx = snakex; tempy = snakey; } for (i = 0; i < gameSize * gameSize; i++) { if ((snake[i][0] < 0) || (snake[i][1] < 0)) { break;11 } grid[snake[i][0]][snake[i][1]] = SNAKE; } bonusTime--; if (bonusTime == 0) { for (i = 0; i < gameSize; i++) { for (int j = 0; j < gameSize; j++) { if(grid[i][j]==BIG_FOOD_BONUS) grid[i][j]=EMPTY; } } } malusTime --; if (malusTime == 0) { for (i = 0; i < gameSize; i++) { for (int j = 0; j < gameSize; j++) { if(grid[i][j]==FOOD_MALUS) grid[i][j]=EMPTY; } } } if (grow > 0) { snake[i][0] = tempx; snake[i][1] = tempy; grid[snake[i][0]][snake[i][1]] = SNAKE; if(score%10 == 0) { placeBonus(BIG_FOOD_BONUS); bonusTime = 100; } if(score%5 == 0) { placeMalus(FOOD_MALUS); malusTime = 100; } grow --; } } private void placeBonus(int bonus_type) { int x = (int) (Math.random() * 1000) % gameSize; int y = (int) (Math.random() * 1000) % gameSize; if (grid[x][y] == EMPTY) { grid[x][y] = bonus_type; } else { placeBonus(bonus_type); } }private void placeMalus(int malus_type) {
int x = (int) (Math.random() * 1000) % gameSize; int y = (int) (Math.random() * 1000) % gameSize; if (grid[x][y] == EMPTY) { grid[x][y] = malus_type; } else { placeMalus(malus_type); } } private void gameOver() { game_over = true; } // IMPLEMENTED FUNCTIONS public void keyPressed(KeyEvent ke) { int code = ke.getKeyCode(); Dimension dim; switch (code) { case KeyEvent.VK_UP: if (direction != DOWN) { next_direction = UP; } break;12 case KeyEvent.VK_DOWN: if (direction != UP) { next_direction = DOWN; } break; case KeyEvent.VK_LEFT: if (direction != RIGHT) { next_direction = LEFT; } break; case KeyEvent.VK_RIGHT: if (direction != LEFT) { next_direction = RIGHT; } break; case KeyEvent.VK_F11: dim = Toolkit.getDefaultToolkit().getScreenSize(); if ((height != dim.height - 50) || (width != dim.height - 50)) { height = dim.height - 50; width = dim.height - 50; } else { height = 600; width = 600; } frame.setSize(width + 7, height + 27); canvas.setSize(width + 7, height + 27); canvas.validate(); frame.validate(); break; case KeyEvent.VK_ESCAPE: System.exit(0); break;case KeyEvent.VK_SPACE:
if(!game_over) paused = !paused; break; default: // Unsupported key break; } } public void windowClosing(WindowEvent we) { System.exit(0); } // UNNUSED IMPLEMENTED FUNCTIONS public void keyTyped(KeyEvent ke) {} public void keyReleased(KeyEvent ke) {} public void windowOpened(WindowEvent we) {} public void windowClosed(WindowEvent we) {} public void windowIconified(WindowEvent we) {} public void windowDeiconified(WindowEvent we) {} public void windowActivated(WindowEvent we) {} public void windowDeactivated(WindowEvent we) {}}13AdministriviaExtensionsExtensions for assignments may be available under the following conditions: permanent or temporary disability compassionate groundsIn all cases documentary evidence (e.g. medical certificate, road accident report, obituary) must be provided.Late penaltiesLate assignments that do not have approved extensions will not be accepted.Academic conductDeliberate academic misconduct such as plagiarism is subject to penalties.You are advised to become familiar with the University's policy available at http://www.unisa.edu.au/policies/manual/.In an individual assignment or the individual part of a group assignment the work you submit must be entirely your own: no partof your submission must be anybody else’s work or work that you did together with another student or students.All use of published material (eg the Web, or a book) must be fully referenced. If you copy text from another source, you mustplace it in quotation marks and include a reference to the original source. If you make any use of ideas or information, includingdiagrams, from another source, you must reference that source.Programming code cannot be included in an assignment copied from the web unless it is separately declared at the front of theassignment. Code obtained from the web will not contribute to your individual or group grade in the assignment. If we findeven one line of code in your assignment that has been copied from the web and not declared you may receive zero for thewhole assignment. We will also check this assignment against previously submitted assignments and if we find any identicalcode or sentences you may also get a mark of zero. If you get a mark of zero you may also be reported for plagiarism whichcould lead to further consequences which are outlined in University policy. Please read the material on this page if you are notsure.There will be questions asked during presentation about the assignments which you may be unable to answer if you do not dothe assignment yourself.All use of outside assistance – e.g. essay farms on the Web or work written for you by a friend – is strictly forbidden and willattract a minimum penalty of zero for the assignment and may risk your expulsion from the university.All the requirements documents for this assignment (including this one) are copyright to the University of South Australia. Youare not authorized to reproduce these requirements documents in any form nor submit or post or transmit them to any website. In particular posting these requirements on a web site which is aimed to solicit other people to do the assignment for a feeis a breach of copyright and could be referred to the law enforcement authorities.To defend yourself in the case of any suspicion of academic misconduct, you are strongly urged to retain all evidence of howyou developed your assignment, such as rough work sheets, notes, drafts, copies of reference material, minutes of meetingsetc.You are free to discuss the assignment with others, and to give and receive help, including references and general discussion ofthe main arguments and conclusions, as long as your part of the program code and text of your part of a report is written onlyby yourself.因为专业,所以值得信赖。如有需要,请加QQ:99515681 或邮箱:
微信:codinghelp